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

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

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

Ответ 1

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

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

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

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

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

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

  • Несколько изменчивых состояний. Это означает, что передача одного и того же параметра функции, эта функция всегда дает тот же результат, поэтому в FP легко выполняется отладка.

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

  • Написание кода в FP - это весело.

Ответ 2

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

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

Ответ 3

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

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

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

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

Ответ 4

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

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

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

Ответ 5

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

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

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

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

Ответ 6

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

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

Ответ 7

В качестве примеров Haskell и Ocaml в машинном обучении см. материал в Hal Daume и Ллойд Эллисон homepages. ИМО гораздо проще достичь С++-подобной производительности в Ocaml, чем в Haskell. Благодаря, как уже говорилось, Haskell имеет гораздо более приятное сообщество (пакеты, инструменты и поддержку), синтаксис и функции (например, FFI, вероятностные монады с помощью классных классов) и поддержку параллельного программирования.

Ответ 8

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

Вкратце, я бы пошел на "пилотный R из OCaml".

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

Ответ 10

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

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