web-dev-qa-db-fra.com

Apprentissage automatique dans OCaml ou Haskell?

J'espère utiliser Haskell ou OCaml sur un nouveau projet car R est trop lent. Je dois pouvoir utiliser des machines vectory de support, séparant idéalement chaque exécution pour fonctionner en parallèle. Je veux utiliser un langage fonctionnel et j'ai le sentiment que ces deux sont les meilleurs en termes de performance et d'élégance (j'aime Clojure, mais ce n'était pas aussi rapide dans un court test). Je penche vers OCaml car il semble y avoir plus de support pour l'intégration avec d'autres langues, donc cela pourrait être mieux adapté à long terme (par exemple OCaml-R ).

Quelqu'un connaît-il un bon tutoriel pour ce type d'analyse, ou un exemple de code, dans Haskell ou OCaml?

62
griffin

Hal Daume a écrit plusieurs algorithmes majeurs d'apprentissage automatique au cours de son doctorat. (maintenant il est professeur adjoint et étoile montante dans la communauté d'apprentissage automatique)

Sur sa page Web, il y a un SVM, un arbre de décision simple et une régression logistique tous dans OCaml. En lisant ces codes, vous pouvez sentir comment les modèles d'apprentissage automatique sont implémentés dans OCaml.

Owl library pour les calculs scientifiques et numériques dans OCaml est un autre bon exemple d'écriture de modèles d'apprentissage automatique de base.

Je voudrais également mentionner F #, un nouveau langage .Net similaire à OCaml. Voici n modèle de graphique factoriel écrit en F # analysant les données de jeu d'échecs. Cette recherche a également une publication NIPS.

Alors que FP convient à l'implémentation de modèles d'apprentissage automatique et d'exploration de données. Mais ce que vous pouvez obtenir le plus ici n'est PAS la performance. Il est vrai que FP prend en charge le calcul parallèle) mieux que les langages impératifs, comme C # ou Java. Mais l'implémentation d'un SVM parallèle, ou arbre de décision, a très peu de rapport avec le langage! Parallèle est parallèle. Les optimisations numériques derrière l'apprentissage automatique et l'exploration de données sont généralement impératives, les écrivant pures -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 au niveau du langage. Si vous voulez exécuter 100 SVM en parallèle, FP aide Mais je ne vois pas la difficulté d'exécuter 100 libsvm parallèles en C++, de ne pas considérer que le libsvm à un seul thread est plus efficace qu'un paquet svm haskell mal testé.

Alors qu'est-ce que FP langages, comme F #, OCaml, Haskell, donne?

  1. Facile à tester votre code. FP les langues ont généralement un interprète de haut niveau, vous pouvez tester vos fonctions à la volée.

  2. Peu d'états mutables. Cela signifie qu'en passant le même paramètre à une fonction, cette fonction donne toujours le même résultat, donc le débogage est facile dans les FP.

  3. Le code est succinct. Inférence de type, correspondance de modèle, fermetures, etc. Vous vous concentrez davantage sur la logique du domaine et moins sur la partie langage. Ainsi, lorsque vous écrivez le code, votre esprit pense principalement à la logique de programmation elle-même.

  4. Écrire du code dans les FP est amusant.

52
Yin Zhu

Le seul problème que je peux voir est que OCaml ne prend pas vraiment en charge le parallélisme multicœur, tandis que GHC a un excellent support et des performances excellentes. Si vous cherchez à utiliser plusieurs threads d'exécution, sur plusieurs appels, GHC Haskell sera beaucoup plus facile.

Deuxièmement, le Haskell FFI est plus puissant (c'est-à-dire qu'il fait plus avec moins de code) que OCaml, et plus de bibliothèques sont disponibles (via Hackage: http://hackage.haskell.org ) donc je ne pensez pas que les interfaces étrangères seront un facteur décisif.

23
Don Stewart

En ce qui concerne l'intégration multilingue, la combinaison de C et de Haskell est remarquablement facile, et je dis cela comme quelqu'un qui (contrairement à enfile ) pas vraiment beaucoup d'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 retomber sur une fine couche d'interface en C si rien d'autre. Pour le meilleur ou pour le pire, C est toujours le lingua franca de programmation, donc Haskell est plus qu'acceptable dans la plupart des cas.

...mais. Vous dites que vous êtes motivé par des problèmes de performances et que vous souhaitez utiliser "un langage fonctionnel". J'en déduis que vous n'êtes pas familier avec les langues que vous demandez. Parmi les caractéristiques qui définissent Haskell, il utilise par défaut évaluation non stricte et structures de données immuables - qui sont toutes deux incroyablement utiles à bien des égards, mais cela signifie également que l'optimisation de Haskell pour les performances est souvent radicalement différente des autres langues, et des instincts bien rodés peuvent vous induire en erreur de manière déconcertante. Vous voudrez peut-être parcourir 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'immuabilité peuvent en fait être exploitées pour des bénéfices de performance ( la thèse de Chris Okasaki fournit quelques exemples sympas). Mais sachez qu'il y aura un peu de courbe d'apprentissage en ce qui concerne la performance.

Haskell et OCaml offrent tous deux les avantages de l'utilisation d'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.

15
C. A. McCann

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 quel autre langage (c'est parce que Haskell est aussi fonctionnel que les langages fonctionnels), et travailler avec des structures d'accès aléatoire mutables peut être un peu maladroit dans Haskell. Vous trouverez également probablement les caractéristiques de performance de votre code OCaml plus intuitives que Haskell en raison de l'évaluation paresseuse de Haskell.

Vraiment, je vous recommanderais d'évaluer les deux si vous avez le temps. Voici quelques ressources Haskell pertinentes:

Oh, si vous regardez plus loin dans Haskell, assurez-vous de vous inscrire aux listes Haskell Beginners et Haskell Cafe . La communauté est sympathique et désireuse d'aider les nouveaux arrivants (mon parti pris est-il manifeste?).

13
Keith

Si la vitesse est votre principale préoccupation, optez pour C. Haskell est assez bon en termes de performances, mais vous n'allez jamais aussi vite que C. À ma connaissance, le seul langage fonctionnel qui a amélioré C dans une référence est le schéma de Staline, mais c'est très vieux et personne ne sait vraiment comment cela fonctionne.

J'ai écrit des bibliothèques de programmation génétique où les performances étaient essentielles et je les ai écrites dans un style fonctionnel en C. Le style fonctionnel m'a permis de le paralléliser facilement en utilisant OMP et il évolue linéairement jusqu'à 8 cœurs dans un seul processus. Vous ne pouvez certainement pas faire cela dans OCaml bien que Haskell s'améliore constamment 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 enfin trouver tous les bugs et arrêter les vidages de mémoire, ce qui était extrêmement difficile en raison de la concurrence. Haskell aurait probablement détecté 90% de ces bogues lors de la première compilation.

Alors, la vitesse à tout prix? Avec le recul, j'aurais aimé utiliser Haskell car je pourrais le supporter 2 à 3 fois plus lentement si j'avais économisé plus d'un mois en temps de développement.

9
Andrew

Bien que dons soit correct, le parallélisme multicœur au niveau niveau thread est mieux pris en charge dans Haskell, il semble que vous puissiez vivre avec le parallélisme au niveau du processus (d'après votre phrase: séparant idéalement chaque exécution à exécuter). en parallèle.) qui est assez bien supporté dans OCaml. Keith a souligné que Haskell a un système de type plus puissant, mais on peut également dire qu'OCaml a un système de modules plus puissant que Haskell.

Comme d'autres l'ont souligné, la courbe d'apprentissage d'OCaml sera inférieure à celle d'Haskell; vous serez probablement plus productif plus rapidement dans OCaml. Cela dit, l'apprentissage d'OCaml est un excellent tremplin vers l'apprentissage de Haskell car de nombreux concepts sous-jacents sont très similaires, vous pouvez donc toujours migrer vers Haskell plus tard et y trouver beaucoup de choses familières. Et comme vous l'avez souligné, il existe un pont OCaml-R.

8
aneccodeal

Comme exemples de Haskell et Ocaml dans l'apprentissage automatique, voir les pages d'accueil Hal Daume et Lloyd Allison . IMO, il est beaucoup plus simple d'obtenir des performances de type C++ dans Ocaml que dans Haskell. Grâce à, comme déjà dit, Haskell a une communauté beaucoup plus agréable (packages, outils et support), la syntaxe et les fonctionnalités (c'est-à-dire FFI, les monades de probabilité via les classes de types) et le support de programmation parallèle.

6
Cfr

Après avoir remanié OCaml-R, j'ai quelques commentaires à faire sur l'intégration d'OCaml et de R. Il pourrait être utile d'utiliser OCaml pour appeler le code R, cela fonctionne, mais ce n'est pas encore tout à fait simple. Donc, l'utiliser pour piloter R vaut la peine. L'intégration beaucoup plus approfondie de la fonctionnalité R est toujours fastidieuse car, par exemple, il reste beaucoup à faire pour exporter le système de type R et les données vers OCaml de manière transparente (vous aurez du travail à faire). De plus, l'interaction du GC de R et du GC d'OCaml est un point délicat: vous libérez n valeurs en temps O (n ^ 2), ce qui n'est pas sympa (pour résoudre ce point, vous avez besoin soit d'une API R plus flexible, pour autant que si je comprends bien, ou pour implémenter un GC dans la liaison elle-même comme un grand tableau R pour une interaction correcte entre les GC).

En un mot, j'opterais pour l'approche "pilot R from OCaml".

Les contributions sur la couche d'interaction GC et sur le mappage des types de données R à OCaml sont les bienvenues.

6
yziquel
2

Réponse tardive mais une bibliothèque d'apprentissage automatique à 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 l'article suivant Classificateurs algébriques: une approche générique pour la validation croisée rapide, la formation en ligne et la formation parallèle . Les auteurs réclament une accélération de 400x par rapport à la même tâche à Weka.

1
RUser4512