Найти тему

Stemming в Машинном обучении простыми словами

Оглавление
Фото: Clémence Bergougnoux / Unsplash
Фото: Clémence Bergougnoux / Unsplash

Стемминг – способ подготовки текста для использования в Модели (Model) Машинного обучения (ML), сокращение слов до своих грамматических основ (основа слова "Африки" – "Африк"). Основа слова – стем, не обязательно совпадает с корнем, он может включать и суффиксы. Это неизменяемая при склонении часть.

Алгоритмы стемминга обычно основаны на правилах: слово проходит через ряд условных предложений, которые определяют, как его сократить. Например, существует правило суффиксов: в английском языке «-ed» и «-ing» отрезают, чтобы сопоставить "cooking" и "cooked" с одной и той же основой "cook".

Перестемминг и недостемминг

Поскольку стемминг обычно основан на эвристике, он далек от совершенства. На самом деле он "страдает" от двух проблем: пере- и недостемминга.

Перестемминг (англ. overstemming) происходит, когда слишком большая часть слова обрезается. Это может привести к бессмысленным стемам, где значение слова потеряно. Или же к тому, что совершенно неродственные слова будут приведены к одной и той же основе.

Возьмите четыре слова university (университет), universal (всобщий), universities (университеты) и universe (вселенная). Алгоритм стемминга, который преобразует эти четыре слова в основу 'univers', перегнул палку. Было бы неплохо, если university и universities продемонстрировали свою связь при стемминге, также как и universal и universe, причем попарно, но нет, основы получаются одинаковые. Соблюдение правил стемминга может привести к возникновению дополнительных проблем.

Недостемминг — противоположная проблема. Он происходит, когда у нас есть несколько слов, которые на самом деле являются формами друг друга. Было бы хорошо, если бы они все "разрешались" в одно древо родственных слов, но, к сожалению, этого не происходит. Это легко понять, если использовать алгоритм, генерирующий основы для слов data (данные) – dat, и datum (данная величина) – datu. Легко предположить: даваайте просто разрешим оба до стема 'dat'. Однако что тогда делать с date (дата)? Существует ли хорошее общее правило? Или мы просто применяем очень конкретное правило для очень конкретного примера?

Эти вопросы быстро становятся проблемами, когда дело доходит до стемминга. Применение новых правил и эвристик может быстро выйти из-под контроля. Решение одной или двух проблем с чрезмерным или недостаточным стеммингом может привести к появлению еще двух! Создание хорошего алгоритма стемминга — тяжелая работа.

Примеры алгоритма стемминга

Не будем вдаваться в подробности алгоритмов, составим предварительное впечатление:

  • Стеммер Портера: это старый алгоритм из 1980-х годов, и его главная задача — удалить общие окончания слов. Он не слишком сложный и развитие метода приостановлено. Как правило, это хороший базовый стеммер для начинающих, но на самом деле не рекомендуется использовать его для любого более-менее сложного приложения. Вместо этого он занимает свое место хорошего базового алгоритма поиска основ и гарантирует воспроизводимость. Это также очень щадящий алгоритм стемминга по сравнению с другими.
  • Стеммер Snowball ("Снежок") также известен как алгоритм стемминга Porter2. Почти повсеместно считается, что он лучше, чем собрат выше по списку, даже сам Портер согласился с утверждением. Snowball более агрессивен. Многие его особенности, были спровоцированы проблемами портеровского стеммера. Разница между ними составляет около 5%.
  • Ланкастерский стеммер — это еще один агрессивный алгоритм. Однако, если вы используете стеммер в NLTK, популярной библиотеки для Обработки естественного языка (NLP), то легко добавить свои собственные правила. Одна претензия к ланкастерскому алгоритму заключается в том, что иногда он слишком агрессивен и действительно может приводить слова к странным основам. Просто убедитесь, что он делает то, что вы хотите, прежде чем использовать этот вариант!

Стемминг: NLTK

Посмотрим, как алгоритм приведения к основе реализован в NLTK. Для начала импортируем портеровский стеммпер и инициируем одну такую сущность. Затем приведем список слов words к их основам:

from nltk.stem import PorterStemmer

ps = PorterStemmer()

words = ["program", "programs", "programmer", "programming", "programmers"]

for w in words:
print(w, " : ", ps.stem(w))

Библиотека сгенерирует такие выходные данные:

program : program

programs : program

programmer : program

programming : program

programmers : program

Автор оригинальной статьи: Hunter Heidenreich

Поддержите нас, поделившись статьей в социальных сетях и подписавшись на канал. И попробуйте курсы на Udemy.