Apprentissage Machine en OCaml ou Haskell?
j'espère utiliser soit Haskell soit OCaml sur un nouveau projet parce que R est trop lent. J'ai besoin de pouvoir utiliser des machines de support vectory, idéalement en séparant chaque exécution pour fonctionner en parallèle. Je veux utiliser un langage fonctionnel et j'ai le sentiment que ces deux-là sont les meilleurs en ce qui concerne la performance et l'élégance (J'aime Clojure, mais ce n'était pas aussi rapide dans un court test). Je penche pour OCaml parce qu'il semble y avoir plus de soutien à l'intégration avec d'autres les langues de sorte qu'il pourrait être un meilleur ajustement à long terme (par exemple OCaml-R ).
est-ce que quelqu'un connaît un bon tutoriel pour ce genre d'analyse, ou un exemple de code, dans Haskell ou OCaml?
10 réponses
Hal Daume a écrit plusieurs algorithmes majeurs d'apprentissage machine au cours de son Doctorat (maintenant il est un assistant professeur et une étoile montante dans la communauté d'apprentissage machine)
sur sa page web, il y a un SVM, un simple arbre de décision et une régression logistique tout en OCaml. En lisant ces codes, vous pouvez avoir une idée de la façon dont les modèles d'apprentissage machine sont implémentés en OCaml.
un autre bon exemple d'écriture de base machine learning models est Owl library pour les calculs scientifiques et numériques en OCaml.
j'aimerais aussi mentionner F#, un nouveau langage .Net similaire à OCaml. Voici un modèle de graphique de facteur écrit en F # analysant les données de jeu D'Échecs. Cette recherche a également une publication du NIPS.
tandis que FP est adapté pour la mise en œuvre de l'apprentissage machine et des modèles d'exploration de données. Mais ce que vous pouvez obtenir ici le plus N'est pas performance. Il est juste que FP supporte mieux l'informatique parallèle que les langues impératives, comme C# ou Java. Mais la mise en œuvre d'un SVM parallèle, ou arbre de décision, n'a pas grand chose à voir avec le langage! En parallèle parallèle. Les optimisations numériques derrière l'apprentissage machine et l'exploration de données sont généralement impératives, en les écrivant pur-fonctionnellement est généralement difficile et moins efficace. Rendre ces algorithmes sophistiqués parallèles est une tâche très difficile au niveau de l'algorithme, pas dans le niveau de langue. Si vous voulez exécuter 100 SVM en parallèle, FP aide ici. Mais je ne vois pas la difficulté d'exécuter 100 libsvm en parallèle en C++, pour ne pas considérer que le fil simple libsvm est plus efficace qu'un paquet svm Haskell pas bien testé.
Alors que faites-FP langues, comme F#, OCaml, Haskell, donner?
-
facile de tester votre code. FP langues ont généralement un interprète de haut niveau, vous pouvez tester vos fonctions sur le voler.
-
Quelques mutable unis. Cela signifie que passer le même paramètre à une fonction, Cette fonction donne toujours le même résultat, donc déboguer est facile en FPs.
-
Code est succinct. L'inférence de Type, pattern matching, fermetures, etc. Vous vous concentrez davantage sur la logique du domaine, et moins sur la partie linguistique. Donc quand vous écrivez le code, votre esprit pense principalement à la logique de programmation elle-même.
-
l'Écriture de code dans les FPs, c'est amusant.
le seul problème que je peux voir est que OCaml ne supporte pas vraiment le parallélisme multicore, alors que GHC a un excellent support et la performance. Si vous cherchez à utiliser plusieurs threads d'exécution, sur plusieurs appels, GHC Haskell sera beaucoup plus facile.
deuxièmement, le FFI Haskell est plus puissant (c'est-à-dire qu'il en fait plus avec moins de code) qu'OCaml, et plus de bibliothèques sont disponibles (via Hackage: http://hackage.haskell.org ) so I don't pense que les interfaces étrangères seront un facteur décisif.
en ce qui concerne l'intégration plurilingue, combiner C et Haskell est remarquablement facile, et je le dis en tant que quelqu'un qui (contrairement à dons ) n'est pas vraiment un expert sur l'un ou l'autre. Tout autre langage qui s'intègre bien avec C ne devrait pas être beaucoup plus compliqué; vous pouvez toujours vous rabattre sur une couche d'interface mince en C si rien d'autre. Pour le meilleur et pour le pire, C est toujours le lingua franca de la programmation, donc Haskell est plus qu'acceptable pour la plupart cas.
...mais. Vous dites que vous êtes motivé par des problèmes de performance, et que vous voulez utiliser "un langage fonctionnel". J'en déduis que vous ne connaissez pas les langues sur lesquelles vous posez des questions. Parmi les caractéristiques définissant Haskell sont qu'il, par défaut, utilise évaluation non-stricte et immuable structures de données qui sont à la fois incroyablement utiles à de nombreux égards, mais il signifie également que l'optimisation Haskell pour la performance est souvent radicalement différent des autres langues, et des instincts bien affinés peuvent vous égarer de manière déconcertante. Vous pouvez vouloir parcourir des sujets liés aux performances sur le wiki Haskell pour avoir une idée des problèmes.
ce qui ne veut pas dire que vous ne pouvez pas faire ce que vous voulez à Haskell--vous le pouvez certainement. La paresse et l'immutabilité peuvent en fait être exploitées pour des avantages de performance ( la thèse de Chris Okasaki fournit une certaine nice exemple.) Mais sachez qu'il y aura une certaine courbe d'apprentissage en ce qui concerne la performance.
Haskell et OCaml offrent tous les deux les beaux avantages d'utiliser un langage de famille ML, mais pour la plupart des programmeurs, OCaml est susceptible d'offrir une courbe d'apprentissage plus douce et de meilleurs résultats immédiats.
il est difficile de donner une réponse définitive à ce sujet. Haskell a les avantages que Don a mentionnés avec un système de type plus puissant et une syntaxe plus propre. OCaml sera plus facile à apprendre si vous venez de presque n'importe quelle autre langue (c'est parce que Haskell est aussi fonction que les langues fonctionnelles obtenir), et de travailler avec des structures d'accès aléatoire mutable peut être un peu grotesque à Haskell. Vous trouverez également probablement les caractéristiques de performance de votre code OCaml plus intuitif que Haskell à cause de son évaluation paresseuse.
vraiment, je vous recommande d'évaluer les deux si vous avez le temps. Voici quelques ressources pertinentes de Haskell:
- http://hackage.haskell.org/package/hslibsvm
- http://hackage.haskell.org/package/HSvm
- Real World Haskell : c'est un grand disponible gratuitement livre pour Haskell
- vous apprendre un Haskell : ce tutoriel est tout simplement amusant de lire
Oh, si vous regardez plus loin dans Haskell assurez-vous de vous inscrire pour les Haskell débutants et Haskell café listes. La communauté est amicale et désireuse d'aider les nouveaux arrivants (est-ce que mon parti pris?).
si la vitesse est votre principale préoccupation alors allez pour C. Haskell est assez bonne performance sage, mais vous n'allez jamais obtenir aussi vite que C. à ma connaissance le seul langage fonctionnel qui a amélioré C dans un benchmark est le schéma de Staline mais qui est très vieux et personne ne sait vraiment comment cela fonctionne.
j'ai écrit des bibliothèques de programmation génétique où la performance était la clé et je l'ai écrit dans un style fonctionnel en C. le style fonctionnel m'a permis de facilement paralléliser en utilisant OMP et it, les échelles linéairement jusqu'à 8 noyaux au sein d'un même processus. Vous ne pouvez certainement pas faire cela en OCaml bien que Haskell améliore tout le temps en ce qui concerne la concurrence et le parallélisme.
l'inconvénient de L'utilisation de C était qu'il m'a fallu des mois pour finalement trouver tous les bogues et arrêter les décharges du noyau qui était extrêmement difficile en raison de la simultanéité. Haskell aurait probablement attrapé 90% de ces bogues sur la première compilation.
So la vitesse à tout prix ? En y repensant, J'aurais aimé utiliser Haskell car je supportais qu'il soit 2 à 3 fois plus lent si j'avais économisé plus d'un mois en temps de développement.
alors que dons a raison de dire que le parallélisme multicore au niveau du thread level est mieux supporté dans Haskell, il semble que vous pourriez vivre avec le parallélisme au niveau du processus (à partir de votre phrase: séparant idéalement chaque exécution pour exécuter en parallèle ).) qui est assez bien supporté en OCaml. Keith a souligné que Haskell a un système de type plus puissant, mais on peut aussi dire Qu'OCaml a un système de module plus puissant que Haskell.
comme d'autres l'ont souligné, la courbe d'apprentissage de L'OCaml sera plus basse que celle de Haskell; vous serez probablement plus productif plus rapidement en OCaml. Cela dit, apprendre L'OCaml est un excellent tremplin vers l'apprentissage de Haskell parce que beaucoup des concepts sous-jacents sont très similaires, de sorte que vous pouvez toujours migrer vers Haskell plus tard et y trouver beaucoup de choses familières. Et comme vous l'avez souligné, il y a un pont OCaml-R.
comme exemples de Haskell et Ocaml dans l'apprentissage machine, Voir stuff à Hal Daume et Lloyd Allison homepages. IMO it's est beaucoup plus simple pour atteindre la performance de type C++dans Ocaml, qu'à Haskell. Grâce, comme déjà dit, Haskell dispose d'une communauté beaucoup plus agréable (paquets, outils et support), d'une syntaxe et de fonctionnalités (i.e. FFI, monades de probabilité via typeclasses) et d'un support de programmation parallèle.
ayant réorganisé OCaml-R, j'ai quelques commentaires à faire sur l'intégration de OCaml et R. Il pourrait être intéressant D'utiliser OCaml pour appeler le code R, cela fonctionne, mais n'est pas encore tout à fait simple. Donc l'utiliser pour piloter R vaut la peine. L'intégration beaucoup plus poussée de la fonctionnalité R est encore lourde, car, par exemple, il reste beaucoup à faire pour exporter le système de type R et les données vers OCaml d'une manière transparente (vous aurez du travail à faire). De plus, L'interaction entre le GC de R et le GC D'OCaml est point délicat: vous libérez des valeurs n dans le temps O(N^2), ce qui n'est pas agréable (pour résoudre ce point, vous avez besoin d'une API r plus flexible, pour autant que je le comprenne, ou pour implémenter un GC dans la liaison elle-même comme un grand tableau R pour une interaction correcte entre les GCs).
en un mot, j'opterais pour l'approche" pilot R from OCaml".
les Contributions sur la couche d'interaction GC et sur la cartographie des types de données R à OCaml sont les bienvenues.
vous pouvez jeter un oeil à ceci: http://www.haskell.org/pipermail/haskell-cafe/2010-May/077243.html
réponse tardive mais une bibliothèque d'apprentissage machine à Haskell est disponible ici: https://github.com/mikeizbicki/HLearn
cette bibliothèque implémente divers algorithmes ML qui sont conçus pour avoir une validation croisée beaucoup plus rapide que les implémentations habituelles. Il est basé sur le document suivant classificateurs algébriques: une approche générique à la validation croisée rapide, formation en ligne et formation parallèle . Auteur demande une vitesse de 400x comparé à la même tâche à Weka.