Машинное обучение в OCaml или Haskell?

Я надеюсь использовать Haskell или OCaml в новом проекте, потому что R слишком медленный. Мне нужно иметь возможность использовать машины поддержки векторов, идеально отделяя каждое выполнение для параллельного выполнения. Я хочу использовать функциональный язык, и у меня такое чувство, что эти два являются лучшими в отношении производительности и элегантности (мне нравится Clojure, но это было не так быстро в коротком тесте). Я склоняюсь к OCaml, потому что, похоже, больше поддержки для интеграции с другими языков, так что это может быть лучше подходит в долгосрочной перспективе (например,OCaml-R).

кто-нибудь знает хороший учебник для такого анализа или пример кода в Haskell или OCaml?

10 ответов


Hal Daume написал несколько основных алгоритмов машинного обучения во время его PH. D. (теперь он является доцентом и восходящей звездой в сообществе машинного обучения)

на его веб-странице есть SVM, простое дерево решений и логистическая регрессия в OCaml. Читая этот код, вы можете почувствовать, как модели машинного обучения реализованы в OCaml.

еще один хороший пример написания базовых моделей машинного обучения Сова библиотека для научных и численных вычислений в OCaml.

Я также хотел бы упомянуть F#, новый язык .Net, подобный OCaml. Вот!--11-->модель факторного графа написано в F# анализ данных шахматной игры. Это исследование также имеет публикацию NIPS.

в то время как FP подходит для реализации моделей машинного обучения и интеллектуального анализа данных. Но то, что вы можете получить здесь больше всего, - это не производительность. Правильно, что FP поддерживает параллельные вычисления лучше, чем императив языки, как C# или Java. Но реализация параллельного SVM, или дерева решений, имеет очень мало отношения к языку! Параллель есть параллель. Численные оптимизации машинного обучения и интеллектуального анализа данных, как правило, являются императивными, писать их чисто функционально, как правило, трудно и менее эффективно. Сделать эти сложные алгоритмы параллельными-очень сложная задача на уровне алгоритмов, а не на уровне языка. Если вы хотите запустить 100 SVM параллельно, FP поможет здесь. Но я не вижу сложность запуска 100 libsvm параллельно в C++, не учитывать, что один поток libsvm является более эффективным, чем не-хорошо протестированный пакет Haskell svm.

тогда что дают языки FP, такие как F#, OCaml, Haskell?

  1. легко проверить свой код. Языки FP обычно имеют интерпретатор верхнего уровня, вы можете проверить свои функции на лету.

  2. несколько изменяемых состояний. Это означает, что передача одного и того же параметра функция, эта функция всегда дает такой же результат, таким образом отладка легка в ФПС.

  3. код лаконичен. Тип вывода, соответствия шаблону, закрытия и т. д. Вы больше фокусируетесь на логике домена и меньше на языковой части. Поэтому, когда вы пишете код, ваш ум в основном думает о самой логике программирования.

  4. написание кода в FPs-это весело.


единственная проблема, которую я вижу, заключается в том, что OCaml не поддерживает многоядерный параллелизм, в то время как GHC имеет отличную поддержку и производительность. Если вы хотите использовать несколько потоков выполнения, при нескольких вызовах GHC Haskell будет намного проще.

во-вторых, FFI Haskell более мощный (то есть он делает больше с меньшим кодом) , чем OCaml, и доступно больше библиотек (через Hackage:http://hackage.haskell.org) поэтому я не думаю, что внешние интерфейсы будет решающим фактором.


Что касается многоязычной интеграции, объединение C и Haskell удивительно легко, и я говорю это как кто-то, кто (в отличие от dons) не очень большой эксперт по любому. Любой другой язык, который хорошо интегрируется с C, не должен быть намного сложнее; вы всегда можете вернуться к тонкому интерфейсному слою в C, если ничего другого. К лучшему или худшему, C по-прежнему лингва франка программирования, поэтому Haskell более чем приемлемо для большинства случаи.

...но. Вы говорите, что мотивированы проблемами производительности и хотите использовать "функциональный язык". Из этого я заключаю, что вы ранее не знакомы с языками, о которых вы спрашиваете. Среди определяющих особенностей Haskell является то, что по умолчанию он использует нестрогая оценка и неизменяемые структуры данных--которые оба невероятно полезны во многих отношениях, но это также означает, что оптимизация Haskell для производительности часто резко отличается от другие языки и хорошо отточенные инстинкты могут сбить вас с пути истинного. Вы можете просмотреть темы, связанные с производительностью на Haskell wiki чтобы почувствовать проблемы.

Это не значит, что вы не можете делать то, что хотите в Хаскелле-вы, конечно, можете. Как лень, так и неизменность могут быть фактически использованы для повышения производительности (диссертация Криса Окасаки предоставляет некоторые хорошие примеры). Но имейте в виду, что будет немного кривой обучения, когда дело доходит до производительности.

и Haskell и OCaml обеспечивают прекрасные преимущества использования языка ML-family, но для большинства программистов OCaml, вероятно, предложит более мягкую кривую обучения и лучшие немедленные результаты.


трудно дать окончательный ответ на этот. У Haskell есть преимущества, о которых упоминал Дон, а также более мощная система типов и более чистый синтаксис. OCaml будет легче узнать, если вы пришли почти с любого другого языка (это потому, что Haskell является такой же функцией, как функциональные языки), и работа с изменяемыми структурами случайного доступа может быть немного неуклюжей в Haskell. Вы также, вероятно, найдете характеристики производительности вашего кода OCaml более интуитивными, чем Хаскелл из-за ленивой оценки Хаскелла.

действительно, я бы рекомендовал вам оценить оба, если у вас есть время. Вот некоторые соответствующие ресурсы Haskell:

О, если вы посмотрите дальше в Haskell обязательно зарегистрируйтесь на Haskell Начинающих и Haskell Cafe списки. Сообщество дружелюбно и готово помочь новичкам (показывает ли моя предвзятость?).


Если скорость-ваша главная забота, тогда идите на C. Haskell довольно хорошая производительность, но вы никогда не получите так быстро, как C. Насколько мне известно, единственный функциональный язык, который улучшил C в бенчмарке, - это схема Сталина, но это очень старый, и никто не знает, как это работает.

Я написал библиотеки генетического программирования, где производительность была ключевой, и я написал ее в функциональном стиле В C. функциональный стиль позволил мне легко распараллелить его с помощью OMP и он линейно масштабируется до 8 ядер в рамках одного процесса. Вы, конечно, не можете сделать это в OCaml, хотя Haskell все время улучшается в отношении параллелизма и параллелизма.

недостатком использования C было то, что мне потребовались месяцы, чтобы наконец найти все ошибки и остановить основные дампы, что было чрезвычайно сложно из-за параллелизма. Haskell, вероятно, поймал бы 90% этих ошибок в первой компиляции.

Итак, скорость любой ценой ? Оглядка Я бы хотел использовать Haskell, поскольку я мог бы выдержать это в 2-3 раза медленнее, если бы я сэкономил больше месяца во время разработки.


в то время как dons правильно, что многоядерный параллелизм в нить уровень лучше поддерживается в Haskell, похоже, вы могли бы жить с параллелизмом уровня процесса (из вашей фразы: идеально отделяя каждое выполнение для параллельного выполнения.) который поддерживается довольно хорошо в OCaml. Кит отметил, что Haskell имеет более мощную систему типов, но также можно сказать, что OCaml имеет более мощную модульную систему, чем Haskell.

Как и другие указывали, что кривая обучения OCaml будет ниже, чем у Haskell; вы, вероятно, будете более продуктивными быстрее в OCaml. Тем не менее, изучение OCaml-отличный шаг к изучению Haskell, потому что многие из основополагающих концепций очень похожи, поэтому вы всегда можете перейти на Haskell позже и найти там много вещей, знакомых. И, как вы указали, Есть мост OCaml-R.


в качестве примеров Haskell и Ocaml в машинном обучении см. Материал в Hal Daume и Ллойд Элисон страницы. IMO гораздо проще добиться производительности на C++в Ocaml, чем в Haskell. Через, Как уже было сказано, Haskell имеет гораздо более приятное сообщество (пакеты, инструменты и поддержка), синтаксис и функции (т. е. FFI, вероятностные монады через typeclasses) и поддержку параллельного программирования.


обновив OCaml-R, у меня есть несколько комментариев по интеграции OCaml и R. возможно, стоит использовать OCaml для вызова кода R, он работает, но пока не совсем прост. Поэтому использовать его для пилотирования R стоит. Интеграция функциональности R намного более тщательно по-прежнему громоздка, так как, например, многое еще предстоит сделать для экспорта системы типов R и данных в OCaml бесшовным способом (вам придется работать). Кроме того, взаимодействие GC R и GC OCaml является деликатным точка: вы освобождаете N значений в O (n^2) времени, что нехорошо (чтобы решить эту проблему, вам нужен более гибкий R API, насколько я понимаю, или реализовать GC в самой привязке как большой массив R для правильного взаимодействия между GCs).

в двух словах, я бы пошел на подход "пилот R из OCaml".

вклады на уровне взаимодействия GC и на сопоставлении типов данных R с OCaml приветствуются.


вы можете взглянуть на это:http://www.haskell.org/pipermail/haskell-cafe/2010-May/077243.html


поздний ответ, но библиотека машинного обучения в Haskell доступна здесь:https://github.com/mikeizbicki/HLearn

эта библиотека реализует различные алгоритмы ML, которые предназначены для гораздо более быстрой перекрестной проверки, чем обычные реализации. Он основан на следующем документе алгебраические классификаторы: общий подход к быстрой перекрестной проверке, онлайн-обучение, и параллельное обучение. Авторы утверждают, что 400X ускорение по сравнению с та же задача в веке.