Алгоритм Stemming, который производит реальные слова
Мне нужно взять абзац текста и извлечь из него список "тегов". Большая часть этого довольно проста. Однако теперь мне нужна помощь, чтобы избежать появления дубликатов в результирующем списке слов. Пример: Сообщество / Сообщества
Я использовал реализацию алгоритма Портера Стеммера (кстати, я пишу на PHP):
http://tartarus.org/~martin/PorterStemmer/php.txt
Это работает, до определенного момента, но не возвращает "настоящие" слова. Приведенный выше пример связан с "commun".
Я пробовал "Снежок" (предлагается в другой теме Stack Overflow).
http://snowball.tartarus.org/demo.php
Для моего примера (сообщество / сообщества) Snowball связан с "communiti".
Вопрос
Существуют ли какие-либо другие алгоритмы, которые будут это делать? Кто-нибудь еще решил эту проблему?
В настоящее время я думаю, что я мог бы использовать алгоритм стволовых символов, чтобы избежать дублирования, а затем выбрать самое короткое слово, которое я встречал, в качестве фактического слова для отображения.
3 ответа
Основная проблема здесь заключается в том, что основополагающие алгоритмы работают на фонетической основе исключительно на основе правил правописания языка без реального понимания языка, с которым они работают. Чтобы получить реальные слова, вам, вероятно, придется объединить вывод стеммера с некоторой формой функции поиска, чтобы преобразовать основы обратно в реальные слова. Я в основном вижу два возможных способа сделать это:
- Найдите или создайте большой словарь, который сопоставляет каждое возможное происхождение с реальным словом. (например, коммунити -> сообщество)
- Создайте функцию, которая сравнивает каждую основу со списком слов, которые были сокращены до этой основы, и пытается определить, какие из них наиболее похожи. (например, сравнение "общности" с "общиной" и "общинами" таким образом, что "общность" будет признана в качестве более похожего варианта)
Лично я думаю, что то, как я это сделал бы, было бы динамической формой #1, создавая базу данных пользовательских словарей, записывая каждое проверенное слово вместе с тем, к чему оно относится, а затем предполагая, что наиболее распространенным словом является то, которое должно быть используемый. (Например, если моя основная часть исходного текста использует "сообщества" чаще, чем "сообщество", то наносите на карту communiti -> community.) Подход на основе словаря в целом будет более точным, а построение его на основе исходных данных даст результаты адаптированные к вашим текстам, с основным недостатком является требуемое пространство, которое в наши дни, как правило, не является проблемой.
Если я правильно понимаю, то вам нужен не стеммер, а лемматизатор. Лемматизатор - это инструмент, обладающий знаниями об окончаниях, таких как -ies, -ed и т. Д., И исключительными формами слов, такими как написано и т. Д. Лемматизатор отображает входную словоформу в ее лемму, которая гарантированно будет "настоящим" словом.
Есть много лемматизаторов для английского языка, я только использовал morpha
хоть. Morpha - это просто большой lex-файл, который вы можете скомпилировать в исполняемый файл. Пример использования:
$ cat test.txt
Community
Communities
$ cat test.txt | ./morpha -uc
Community
Community
Вы можете получить морфу на http://www.informatics.sussex.ac.uk/research/groups/nlp/carroll/morph.html
Эй, я не знаю, может быть, уже слишком поздно, но есть только один сценарий PHP, который генерирует настоящие слова: http://phpmorphy.sourceforge.net/ - мне понадобились целые годы, чтобы найти его. Все остальные стеммеры должны быть скомпилированы, и даже после этого они работают только в соответствии с алгоритмом Портера, который создает стебли, а не леммы (то есть сообщество = сообщество). PhpMorphy one отлично работает, его легко установить и инициализировать, и он содержит словари английского, русского, немецкого, украинского и эстонского языков. Он также поставляется со скриптом, который вы можете использовать для компиляции других словарей. Документация на русском языке, но выложите ее через гугл переводчик и это должно быть легко.