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


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

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

10 59

10 ответов:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

О, если вы посмотрите дальше в Haskell обязательно подпишитесь на Haskell Beginners и 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, которые предназначены для гораздо более быстрой перекрестной проверки, чем обычные реализации. Он основан на следующем документе алгебраические классификаторы: общий подход к быстрой перекрестной проверке, онлайн-обучение, и параллельное обучение. Авторы утверждают, что 400-кратное ускорение по сравнению с та же задача в Weka.