Comments 16
Спасибо за статью! Было бы интересно почитать о работе с ML.NET в формате «для чайников». Если у вас найдутся время и желание писать такое, конечно.
+1
Linq. Они намного удобнее, чем List Comprehension (LC) в Питоне.
Так в ML у вас pandas / numpy стек должен быть, и list comprehensions в норме в коде вообще не должны встретиться.
Интересно, кто как встраивает Python-код в свои проекты на .Net. Опишите свои сценарии и ощущения от них в комментариях, пожалуйста.
Микросервисы. Однажды был вариант, где из другой инфраструктуры Python дергали через баш как скрипты — после этого точно микросервисы.
Скорость. В коде на Питоне пришлось отказаться от фич, которые были завязаны на то, какое решение по склейке было принято в прошлых предложениях — если подавать классификатору предложения по-одному, то общая скорость получится ниже плинтуса. Чтобы обработка данных на Питоне была быстрой, необходимо максимально векторизовать её и иногда это заставляет отказываться от потенциально полезных вариантов, либо делать их очень сложно.
Очень спорное утверждение. Scientific Python stack позволяет писать хорошо векторизированный код очень легко, а C# с ним по перфомансу никогда не сравнится.
0
Спасибо за ваш кейс.
В основном соглашусь — Pandas/Numpy позволяют многое легко и элегантно векторизовать. При этом код получается простой и производительный. Но такими кейсами все не ограничивается. По крайней мере у меня. Нередко, приходится фичи выводить на деревьях. Или тот момент, который я приводил в статье — когда в качестве фичи передается то, что классификатор выдал для предыдущих сэмплах. В таких случаях и векторизация ломается, и со списками приходится работать, и еще много чего нестандартного. Вот в таких случаях большая производительность чистого C#-кода заметна. Просто рабочий момент, на который обращается внимание, когда один и тот же код пишешь там и здесь.
В основном соглашусь — Pandas/Numpy позволяют многое легко и элегантно векторизовать. При этом код получается простой и производительный. Но такими кейсами все не ограничивается. По крайней мере у меня. Нередко, приходится фичи выводить на деревьях. Или тот момент, который я приводил в статье — когда в качестве фичи передается то, что классификатор выдал для предыдущих сэмплах. В таких случаях и векторизация ломается, и со списками приходится работать, и еще много чего нестандартного. Вот в таких случаях большая производительность чистого C#-кода заметна. Просто рабочий момент, на который обращается внимание, когда один и тот же код пишешь там и здесь.
0
Вот в таких случаях большая производительность чистого C#-кода заметна. Просто рабочий момент, на который обращается внимание, когда один и тот же код пишешь там и здесь.
Справедливо. Но тогда Python-код можно скомпилировать через numba и опять таки получить перфоманс, который в C# так просто не выжать.
Или тот момент, который я приводил в статье — когда в качестве фичи передается то, что классификатор выдал для предыдущих сэмплах.
Код я не смотрел, а в статье я такого почему-то не вижу.
-1
Код я не смотрел, а в статье я такого почему-то не вижу.
В коде этой фичи сейчас и нет, а в статье — как раз в пункте о скорости:
В коде на Питоне пришлось отказаться от фич, которые были завязаны на то, какое решение по склейке было принято в прошлых предложениях — если подавать классификатору предложения по-одному, то общая скорость получится ниже плинтуса.
Насчет numba — какие преимущества и недостатки по сравнению с Cython на практике?
0
UFO just landed and posted this here
достаточно только проверить, по какую сторону от границы они
находятся.
Поиск таких границ метод опорных векторов осуществляет в два
этапа:
На основании чего здесь делается вывод о конце абзаца (между предложениями)?
0
Вы имеете в виду, на основании чего делает такой вывод алгоритм? Или аннотатор (т.е., я)? Я, в данном случае, смотрю на «геометрию» строк. В предыдущей строке только одно слово, заканчивается знаком препинания. Следующая строка достаточно длинная, начинается с заглавного символа. Это характерно для абзаца. В реальности, конечно же, я так не взвешиваю, а быстро вставляю символ "*" в начало строки и перевожу курсор к следующей.
Думаю, алгоритм базируется на комбинации этих же признаков, которая кодируется в весах логистической регрессии.
Если же пруф, что абзац тут есть — то вот оригинальный фрагмент. Это фрагмент книги «Глубокое обучение на Python»
Думаю, алгоритм базируется на комбинации этих же признаков, которая кодируется в весах логистической регрессии.
Если же пруф, что абзац тут есть — то вот оригинальный фрагмент. Это фрагмент книги «Глубокое обучение на Python»
0
Т.е. если предложение тянется до правой границы, то переноса абзаца не будет? Есть ли в таком случае смысл переходить от логики к статистике?
Вот в другой встречающейся задаче по определению кодировки текста без статистики тяжело.
Вот в другой встречающейся задаче по определению кодировки текста без статистики тяжело.
0
Т.е. если предложение тянется до правой границы, то переноса абзаца не будет? Есть ли в таком случае смысл переходить от логики к статистике?
Смысл есть как раз потому, что тексты бывают разные. Для данной задачи — с разной типичной длиной строки (разные шрифты, разное количество колонок). И как только окажется, что какой-то текст плохо обрабатывается — логические правила нужно подправлять. Когда их количество превышает определенное число — их поддержание становится очень трудозатратным. ML же сильно упрощает адаптацию к новым условиям.
И я бы не формулировал, что ML=статистика. Те же деревья решений (их тоже можно применить с минимальным изменением программы) — это уже больше похоже на логические правила. Очень большой набор правил.
Вот в другой встречающейся задаче по определению кодировки текста без статистики тяжело.
Не поверите, но эту (точнее, очень похожую — определение языка) задачу также решал без машинного обучения. Основа — подсчет количества уникальных для языка фрагментов (1..4 буквы и целых слов). Это если очень упрощенно. Но ML-подход опять-таки, позволяет решить её более качественно именно для тех текстов, которых у вас больше. Статистика текстов очень отличается в зависимости от вашей предметной области. Твиты и статьи из журналов имеют существенно отличающиеся языковые модели.
0
Подправлять правила несложно, есть же параметризация программ. Вопрос в их количестве. И поскольку я тоже, правда очень давно, решал аналогичую задачу (обрезанный по правому краю текст -> HTML), то не могу назвать несколько десятков правил (при практическом отсутствии вероятностых) стимулом перехода к стат.методам (или к деревьям, раз уж упомянули).
В задаче определения кодировки вероятности следования одних букв и знаков за другими зависимы от группы языков, описывать это правилами, а не матрицей просто неудобно. Ну а лобовой метод «чтения со словарем» хоть и обходится фактически без обучения, требует наличия этих самых словарей.
К чему я все это написал? Мне кажется, что задачка детектирования кодировки или даже языка выглядела бы гораздо нагляднее для демонстрации пользы от применения ML.
В задаче определения кодировки вероятности следования одних букв и знаков за другими зависимы от группы языков, описывать это правилами, а не матрицей просто неудобно. Ну а лобовой метод «чтения со словарем» хоть и обходится фактически без обучения, требует наличия этих самых словарей.
К чему я все это написал? Мне кажется, что задачка детектирования кодировки или даже языка выглядела бы гораздо нагляднее для демонстрации пользы от применения ML.
0
Несколько десятков правил — мне такое уже сложно поддерживать. Именно поэтому сейчас, когда освоил азы (как минимум) sklearn, пошел именно этим путем. У каждого свой порог, когда лучше отходить от логики жесткого алгоритма в ML. Например, подзадача восстановления разбитых жесткими переносами слов решалась без ML. Хотя, не исключено, что когда все процессоры будут квантовыми, и тут станет проще научить, чем запрограммировать. Просто удивительно, что творят нейросети с последовательностями символов — вот тут недавно скрещивал базу от гугла и пример переводчика для кераса: github.com/serge-sotnyk/seq2seq-compress. После такого начинаешь верить, что если есть достаточно данных и времени, то нейросеть можно обучить чему угодно…
Это действительно актуальная для многих задача. Но в общем виде она практически решена. Вот хороший список библиотек для Питона: stackoverflow.com/a/47106810/4884761
А задача постобработки PDF мне понравилась тем, что она пошла практически по классическому сюжету:
1. Посмотрели — не видно публичных готовых библиотек.
2. Собрали данные для обучения.
3. Проаннотировали.
4. Выбрали метрики качества.
5. Обучили бэйзлайн-решение. Так получилось, что оно удовлетворило по качеству. Это просто приятный бонус. Иначе нужен был бы этап 6.
6. Улучшаем качество.
Так получилось, что все необходимые компоненты уже есть и в .NET — поэтому была возможность еще и сравнить особенности решения и там, и там.
Где применение ML оправдано — каждый решает для себя сам. В данном случае, решая задачу уже не первый раз, я получил большее удовольствие от работы и большую уверенность в легкости поддержки. Поэтому мне показалось оправданным. Раньше, до того, как на практике закрепил навыки по ML, тоже часто предпочитал все сделать и настроить своими руками.
Мне кажется, что задачка детектирования кодировки или даже языка выглядела бы гораздо нагляднее для демонстрации пользы от применения ML.
Это действительно актуальная для многих задача. Но в общем виде она практически решена. Вот хороший список библиотек для Питона: stackoverflow.com/a/47106810/4884761
А задача постобработки PDF мне понравилась тем, что она пошла практически по классическому сюжету:
1. Посмотрели — не видно публичных готовых библиотек.
2. Собрали данные для обучения.
3. Проаннотировали.
4. Выбрали метрики качества.
5. Обучили бэйзлайн-решение. Так получилось, что оно удовлетворило по качеству. Это просто приятный бонус. Иначе нужен был бы этап 6.
6. Улучшаем качество.
Так получилось, что все необходимые компоненты уже есть и в .NET — поэтому была возможность еще и сравнить особенности решения и там, и там.
Где применение ML оправдано — каждый решает для себя сам. В данном случае, решая задачу уже не первый раз, я получил большее удовольствие от работы и большую уверенность в легкости поддержки. Поэтому мне показалось оправданным. Раньше, до того, как на практике закрепил навыки по ML, тоже часто предпочитал все сделать и настроить своими руками.
0
ML — молоток полезный, поэтому есть опасность уверовать, что все задачи вокруг суть гвозди :)
Основное отличие классического программирования в детерминированности: отлаженная программа дает 100% результат на исходных тестах. В ML всегда будет присутствовать вероятность ошибки (10% в вашем примере).
Если не брать вероятностных по своей сути задачи, то выбор идет между ценой ошибки и сложностью программирования.
Притягательность нейросетей в ощущении «магии», хотя бы и зная, что внутри неенеонка все та же неявно сформированная очень сложная статистическая функция(и), пробразующая входы в выходы.
Основное отличие классического программирования в детерминированности: отлаженная программа дает 100% результат на исходных тестах. В ML всегда будет присутствовать вероятность ошибки (10% в вашем примере).
Если не брать вероятностных по своей сути задачи, то выбор идет между ценой ошибки и сложностью программирования.
Притягательность нейросетей в ощущении «магии», хотя бы и зная, что внутри нее
0
С переносами как-то жестоко захардкоженно обошлись.
Явно же просматриваются случаи:
- не-буквенные сочетания — дефис надо оставлять (8-800- / 223-322)
- буква-Буква — дефис, наверное, надо оставлять (вряд ли в тексте будет кемелКейс)
- буква-буква, БУКВА-БУКВА — надо смотреть в словарь или как-то отдельно классифицировать
0
Согласен, что здесь можно сделать лучше. Почему не сделано:
— На практике оказалось, что случаев, когда такое склеивание что-то ломает — не так уж и много. Например, при верстке есть правила, когда стараются не ставить дефис в конце слова, где непонятно, перенос ли это. Если же это телефон, то дефис тут играет вспомогательную роль и его потеря не особо мешает (и при правильной верстке, его тоже стараются поместить полностью на одной строке).
— Не хотелось завязываться на определенный язык. А смотреть в словаре — это именно такой, языкозависимый подход.
Если дадите большое количество примеров, где существующий код плохо срабатывает (желательно только реальные — как я писал, на практике их встречается гораздо меньше, чем могло бы показаться), можно посмотреть, как стоит модифицировать эту часть кода.
Лучше всего — открытием ишью на гитхабе проекта. Если же сделаете пул-риквест, вообще будет идеально.
— На практике оказалось, что случаев, когда такое склеивание что-то ломает — не так уж и много. Например, при верстке есть правила, когда стараются не ставить дефис в конце слова, где непонятно, перенос ли это. Если же это телефон, то дефис тут играет вспомогательную роль и его потеря не особо мешает (и при правильной верстке, его тоже стараются поместить полностью на одной строке).
— Не хотелось завязываться на определенный язык. А смотреть в словаре — это именно такой, языкозависимый подход.
Если дадите большое количество примеров, где существующий код плохо срабатывает (желательно только реальные — как я писал, на практике их встречается гораздо меньше, чем могло бы показаться), можно посмотреть, как стоит модифицировать эту часть кода.
Лучше всего — открытием ишью на гитхабе проекта. Если же сделаете пул-риквест, вообще будет идеально.
0
Sign up to leave a comment.
Как решить старую задачу с помощью ML на Python и .Net