Частотный алгоритм для обработки естественного языка - PullRequest
32 голосов
/ 18 сентября 2008

Не получив степени по поиску информации, я хотел бы знать, существуют ли какие-либо алгоритмы подсчета частоты, с которой слова встречаются в данном тексте. Цель состоит в том, чтобы получить «общее представление» о том, что люди говорят через набор текстовых комментариев. По линии Wordle .

Что бы я хотел:

  • игнорировать артикли, местоимения и т. Д. («А», «ан», «the», «он», «их» и т. Д.)
  • сохранить собственные имена
  • игнорировать переносы, кроме мягких

Достигнув звезд, это было бы замечательно:

  • обработка стеблей и множественного числа (например, нравится, нравится, нравится, нравится совпадение с тем же результатом)
  • группировка прилагательных (наречий и т. Д.) По предметам («великое служение» в отличие от «великого», «служение»)

Я пробовал некоторые базовые вещи, используя Wordnet, но я просто настраиваю их вслепую и надеюсь, что это сработает для моих конкретных данных. Было бы замечательно что-то более общее.

Ответы [ 8 ]

70 голосов
/ 18 сентября 2008

Вам понадобится не один, а несколько хороших алгоритмов, как показано ниже.

  • игнорирование местоимений осуществляется с помощью stoplist .
  • сохранение имен собственных? Вы имеете в виду обнаружение именованных сущностей, таких как Пылесос Дам и произнесение «это одно слово» или составных существительных, таких как программирование язык ? Я дам вам подсказку: это сложно, но существуют библиотеки для обоих. Ищите NER (названное имя пользователя) и лексическое чанкинг. OpenNLP - это Java-Toolkit, который выполняет обе функции.
  • игнорирование переносов? Ты имеешь в виду, как на разрывы строк? Используйте регулярные выражения и проверьте полученное слово с помощью словаря.
  • Обработка множественного числа / стемминга: вы можете взглянуть на Снежок . Это хорошо сработало.
  • "группировка" прилагательных с их существительными, как правило, является задачей поверхностного разбора . Но если вы ищете именно качественные прилагательные (хорошие, плохие, дерьмовые, удивительные ...), вас может заинтересовать анализ настроений . LingPipe делает это и многое другое.

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

Если вы используете Java, объедините Lucene с инструментарием OpenNLP . Вы получите очень хорошие результаты, так как в Lucene уже есть встроенный стеммер и множество учебников. Набор инструментов OpenNLP, с другой стороны, плохо документирован, но вам не нужно слишком много из него. Вас также может заинтересовать NLTK , написанный на Python.

Я бы сказал, что вы отбрасываете последнее требование, так как оно включает мелкий анализ и определенно не повлияет на ваши результаты.

Ах, кстати. Точный термин того документа, который вы ищете, называется tf-idf . Это в значительной степени лучший способ поиска частоты документа для терминов. Для того, чтобы сделать это правильно, вы не сможете использовать многомерные векторные матрицы.

... Да, я знаю. После семинара по IR мое уважение к Google стало еще сильнее. После того, как я сделал кое-что в IR, мое уважение к ним упало так же быстро.

16 голосов
/ 18 сентября 2008

Добро пожаловать в мир НЛП ^ _ ^

Все, что вам нужно, это немного базовых знаний и некоторые инструменты.

Уже есть инструменты, которые сообщат вам, является ли слово в предложении существительным, прилагательным или глаголом. Они называются тегами части речи . Как правило, они принимают в качестве исходного текста на английском языке и выводят слово, его базовую форму и часть речи. Вот вывод популярного тэгера части речи UNIX в первом предложении вашего поста:

$ echo "Without getting a degree in information retrieval, I'd like to know if there exists any algorithms for counting the frequency that words occur in a given body of text." | tree-tagger-english 
# Word  POS     surface form
Without IN  without
getting VVG get
a   DT  a
degree  NN  degree
in  IN  in
information NN  information
retrieval   NN  retrieval
,   ,   ,
I   PP  I
'd  MD  will
like    VV  like
to  TO  to
know    VV  know
if  IN  if
there   EX  there
exists  VVZ exist
any DT  any
algorithms  NNS algorithm
for IN  for
counting    VVG count
the DT  the
frequency   NN  frequency
that    IN/that that
words   NNS word
occur   VVP occur
in  IN  in
a   DT  a
given   VVN give
body    NN  body
of  IN  of
text    NN  text
.   SENT    .

Как видите, он идентифицировал «алгоритмы» как форму множественного числа (NNS) «алгоритма», а «существует» как сопряжение (VBZ) слова «существовать». Он также определил «а» и «как» как «определители (DT)» - другое слово для статьи. Как вы можете видеть, POS-тег также маркировал пунктуацию.

Чтобы сделать все, кроме последней точки в вашем списке, вам просто нужно пропустить текст через POS-тег, отфильтровать категории, которые вас не интересуют (определители, местоимения и т. Д.) И посчитать частоты базовые формы слов.

Вот некоторые популярные теги POS:

TreeTagger (только двоичный код: Linux, Solaris, OS-X)
GENIA Tagger (C ++: откомпилируйте себя)
Stanford POS Tagger (Java)

Чтобы сделать последнюю вещь в вашем списке, вам нужно больше, чем просто информация на уровне слов. Самый простой способ начать с подсчета последовательностей из слов , а не только сами слова. Они называются н-грамм . Хорошее место для начала - UNIX для поэтов . Если вы готовы инвестировать в книгу по НЛП, я бы порекомендовал Основы статистической обработки естественного языка .

4 голосов
/ 18 сентября 2008

Вот пример того, как вы можете сделать это в Python, концепции похожи на любом языке.

>>> import urllib2, string
>>> devilsdict = urllib2.urlopen('http://www.gutenberg.org/files/972/972.txt').read()
>>> workinglist = devilsdict.split()
>>> cleanlist = [item.strip(string.punctuation) for item in workinglist]
>>> results = {}
>>> skip = {'a':'', 'the':'', 'an':''}
>>> for item in cleanlist:
      if item not in skip:
        try:
          results[item] += 1
        except KeyError:
          results[item] = 1

>>> results
{'': 17, 'writings': 3, 'foul': 1, 'Sugar': 1, 'four': 8, 'Does': 1, "friend's": 1, 'hanging': 4, 'Until': 1, 'marching': 2 ...

Первая строка просто получает библиотеки, которые помогают с частями проблемы, как во второй строке, где urllib2 загружает копию «Словаря дьявола» Амброуза Бирса. В следующих строках представлен список всех слов в тексте, без знаки препинания. Затем вы создаете хеш-таблицу, которая в этом случае похожа на список уникальных слов, связанных с числом. Цикл for проходит по каждому слову в книге Bierce, если в таблице уже есть запись этого слова, каждое новое вхождение добавляет единицу к значению, связанному с этим словом в таблице; если слово еще не появилось, оно добавляется в таблицу со значением 1 (имеется в виду одно вхождение). В тех случаях, о которых вы говорите, вам следует уделять гораздо больше внимания деталям, например, с использованием заглавных букв. чтобы помочь определить собственные имена только в середине предложений и т. д., это очень грубо, но выражает концепцию.

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

2 голосов
/ 18 сентября 2008

Первая часть вашего вопроса звучит не так уж плохо. Все, что вам в основном нужно сделать, это прочитать каждое слово из файла (или потока w / e) и поместить его в дерево префиксов, и каждый раз, когда вы встречаетесь с уже существующим словом, вы увеличиваете значение, связанное с ним. Конечно, у вас также будет список игнорирования всего, что вы хотели бы исключить из своих расчетов.

Если вы используете дерево префиксов, вы гарантируете, что найти любое слово будет O (N), где N - максимальная длина слова в вашем наборе данных. Преимущество префиксного дерева в этой ситуации состоит в том, что если вы хотите искать множественное число и основание, вы можете проверить в O (M + 1), возможно ли это для слова, где M - длина слова без основы или множества (это слово? хе-хе). После того, как вы построите свое дерево префиксов, я бы повторно проанализировал его на предмет основ и тому подобного и сжал его так, чтобы корневое слово было тем, что содержит результаты.

После поиска у вас могут быть некоторые простые правила, чтобы совпадение возвращалось положительным в случае корня или стебля или чего-то еще.

Вторая часть кажется чрезвычайно сложной. Моя наивная склонность состояла бы в том, чтобы держать отдельные результаты для групп прилагательного-предмета. Используйте те же принципы, что и выше, но просто держите их отдельно.

Другим вариантом семантического анализа может быть моделирование каждого предложения в виде дерева отношений субъекта, глагола и т. Д. (У предложения есть субъект и глагол, у субъекта есть существительное и прилагательное и т. Д.). После того, как вы разбили весь свой текст таким образом, может показаться, что вам будет довольно просто пробежаться и быстро подсчитать, какие произошли соответствующие пары.

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

2 голосов
/ 18 сентября 2008

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

Вот код (asp.net/c#): h ttp: //naspinski.net/post/Findingcounting-Keywords-out-of-a-Text-Document.aspx

1 голос
/ 18 сентября 2008

Алгоритм, который вы только что описали. Программа, которая делает это из коробки с большой кнопкой с надписью «Сделай это» ... Я не знаю.

Но позвольте мне быть конструктивным. Я рекомендую вам эту книгу Программирование Коллективного Разума . Главы 3 и 4 содержат очень прагматичные примеры (на самом деле, никаких сложных теорий, только примеры).

0 голосов
/ 13 января 2019

Все, что вы перечислили, хорошо обрабатывается spacy .

  1. Игнорировать некоторые слова - используйте стоп-слова
  2. Извлечь тему - использовать часть речевого тега для ее идентификации (работает из коробки). После разбора предложения найдите «ROOT» - основной глагол предложения. Путем навигации по дереву разбора вы найдете существительное, которое относится к этому глаголу. Это будет предметом.
  3. Игнорировать переносы - их токенизатор обрабатывает дефисы в большинстве случаев. Это может быть легко расширено, чтобы обращаться с более особыми случаями.

Если список тем предопределен и невелик, вы можете даже пойти дальше: построить модель классификации, которая будет предсказывать тему. Допустим, у вас есть 10 предметов. Вы собираете образцы предложений или текстов. Вы загружаете их в другой продукт: вундеркинд . Используя его отличный интерфейс, вы быстро назначаете предметы для образцов. И, наконец, используя классифицированные образцы, вы тренируете пространственную модель, чтобы предсказать тему текстов или предложений.

0 голосов
/ 01 сентября 2009

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

...