Продолжаю делиться впечатлениями по алгоритму Яровского.
tl;dr Отличный инструмент для снятия омонимии. Только его надо правильно приготовить.
Код, на примере которого знакомился с алгоритмом, при близком рассмотрении больше похож на лабораторную работу. Неэффективен ни по архитектуре, ни по оптимизации. После причесывания, понять алгоритм оказалось еще проще.
Назначение алгоритма:
Вначале я ошибся, посчитав его полноценным классификатором, способным классифицировать 100% фраз. На самом деле, алгоритм классифицирует 30-40% фраз, но с количеством ошибок стремящихся к 0. Для чего надо вручную разметить
очень небольшое количество образцов.
Исследование алгоритма:
Провел 3 пробы. В каждой из которых, последовательно размечал по 10 случайно выбранных из корпуса фраз, после чего проводил обучение и смотрел, сколько фраз доразметилось автоматически.
Код: Выделить всё
[631, 0, 0, 15, 0, 0, 8, 6, 0, 1, 1, 0, 38, 6, 5] Всего: 711
[0, 0, 0, 0, 642, 1, 19, 9, 1, 44, 11, 6, 1, 7, 12] Всего: 753
[0, 711, 4, 0, 8, 0, 3, 2, 21, 5, 0, 4, 3, 0, 6] Всего: 767
Основной выхлоп дала разметка соответственно 10, 50, 20 фраз. Что дает результативность от 1:13 до 1:63 (количество автоматических на 1 ручную). Если же во главу угла ставить не минимизацию ручного труда, а качество классификации в целом, оптимально размечать 10-20% от размера корпуса. Который в моем случае составлял чуть больше 2000 записей.
Примечание: Насколько понял работу алгоритма, его эффективность зависит не столько от количества размеченных, сколько от размера самого корпуса, количества фраз доступных алгоритму для оценки.
Оценка ошибок: Проверив вручную результат работы первой пробы, нашел 17 ошибок классификации или 2.4% (помечены -1 в файле log_auto.txt). Отмечу, что многие из них, следствие работы стемминга (удаления окончаний и суффиксов). Заменив стемминг на нормализацию (заперта, запер, заперев -> запереть) из pymorphy, количество ошибок сократилось до 5 (0.8%) без существенного влияния на количество размеченных. Но так как это внешняя зависимость затрудняющая исследование алгоритма, за основу взят именно стемминг.
Применение алгоритма:
Тут скорее мои фантазии и наброски идей. В общем же, это совсем иной, не словарный способ предобработки текста, который в идеале требует отдельного встраивания в процесс и интерфейса работы со "словарем" (где "словарем" выступает корпус фраз). Тема требующая отдельного обсуждения и выходящая за рамки данной заметки. На мой взгляд, это должно быть расширением обработки словарем формата hmg.
Но какое бы ни было применение, для работы нужен корпус фраз. Он может быть сформирован пользователем самостоятельно, на основе свой библиотеки. Но оптимально, чтобы его формировала сама программа. Встретился омограф, извлекли фразу с ним и сохранили в соответствующий файл. Думаю скрипты Демагога от ув.
flegont с этим справятся легко.
В идеале, это совместно формируемый корпус, куда сливаются результаты работы программы у всех пользователей. В отличии от уникальных и личных словарей, здесь никакой уникальности нет, главное размер. (см. примечание из "Исследование алгоритма")
а) Формирование правил для словарей. Трудность представляет правило k_nearest анализирующее слова на отдалении от омографа и предварительное удаление стоп-слов. Если это не получится автоматически напрямую, составителям словарей такая подсказка общих признаков, окажет существенное подспорье.
б) проверка правил в словарях. Многие правила уже добавлены в них, но также представляю какой в них бардак. Так как точность алгоритма высока, есть резон классифицировать фразу с омографом алгоритмом и сравнивать с результатом его обработки словарями, в случае расхождения уведомлять пользователя.
в) непосредственная классификация. Перед применением классических словарей.
Код стеммера и классификатора, исходный корпус, результат 3 проб.