Алгоритмы обнаружения фраз и ключевых слов из текста - PullRequest
43 голосов
/ 29 октября 2009

У меня около 100 мегабайт текста без какой-либо разметки, разделенных примерно на 10000 записей. Я хотел бы автоматически создать список тегов. Проблема в том, что существуют группы слов (то есть фразы), которые имеют смысл только тогда, когда они сгруппированы вместе.

Если я просто посчитаю слова, я получу большое количество действительно распространенных слов (например, для, в, я и т. Д.). Я посчитал слова и количество других слов до и после него, но теперь я действительно не могу понять, что делать дальше. Информация, относящаяся к фразам из 2 и 3 слов, присутствует, но как мне извлечь эти данные?

Ответы [ 5 ]

34 голосов
/ 29 октября 2009

Прежде всего, попытайтесь сохранить информацию о "границах", которая содержится во входном тексте.
(если такая информация не может быть легко потеряна, ваш вопрос подразумевает, что, возможно, токенизация была легко выполнена)
Во время процесса токенизации (в данном случае синтаксического анализа слов) ищите шаблоны, которые могут определять границы выражения (такие как знаки препинания, особенно точки, а также множественное разделение LF / CR, используйте их. Также слова типа " ", часто можно использовать в качестве границ. Такие границы выражений, как правило, являются" отрицательными ", в том смысле, что они разделяют два экземпляра токена, которые обязательно не будут включены в одно и то же выражение. Несколько положительных границ являются кавычками, особенно двойными кавычками. Этот тип информации может быть полезен для фильтрации некоторых из n-граммов (см. следующий абзац). Также последовательности слов, такие как «например» или «вместо» или «необходимость» может также использоваться в качестве границ выражения (но использование такой информации требует использования «априоров», о которых я расскажу позже).

Без использования внешних данных (кроме входного текста) вы можете добиться относительного успеха при этом, запустив статистику по текстовым диграммам и триграммам (последовательность из 2 и 3). последовательные слова). Тогда [большинство] последовательностей со значительным (*) числом экземпляров, вероятно, будут типом «выражения / фраз», которое вы ищете.
Этот несколько грубый метод даст несколько ложных срабатываний, но в целом может быть работоспособным. Фильтрация n-граммов, которые, как известно, пересекают «границы», как указано в первом абзаце, может существенно помочь, потому что в естественных языках окончание предложения и начало предложения имеют тенденцию извлекать из ограниченного подмножества пространства сообщений и, следовательно, создавать комбинации токена, кажутся статистически хорошо представленными, но которые обычно не связаны семантически.

Более совершенные методы (возможно, более дорогие, с точки зрения обработки и дизайна / инвестиций) позволят использовать дополнительные «априорные значения», относящиеся к области и / или национальным языкам входного текста. ,

  • POS (Part-Of-Speech) тегирование весьма полезно, несколькими способами (обеспечивает дополнительные, более объективные границы выражений, а также, например, классы «шумовых» слов) все статьи, даже если они используются в контексте сущностей, обычно имеют мало облаков тегов, так что OP хочет их создать.
  • Словари, лексики и тому подобное тоже могут быть очень полезны. В частности, они идентифицируют «сущности» (также известные как WordNet lingo) и их альтернативные формы. Сущности очень важны для облаков тегов (хотя они не являются единственным классом слов, найденных в них), и, идентифицируя их, также можно нормализовать их (множество различных выражений, которые можно использовать, скажем, «Сенатор Т.». Кеннеди "), следовательно, устраните дубликаты, но также увеличьте частоту базовых объектов.
  • , если корпус структурирован как коллекция документов, может быть полезно использовать различные приемы, связанные с TF (Term Frequency) и IDF (Inverse Document Frequency)

[Извините, сейчас надо идти (плюс хотелось бы больше подробностей о ваших конкретных целях и т. Д.). Я постараюсь предоставить более подробную информацию и советы позже]

[Кстати, я хочу добавить сюда Ответы Джонатана Файнберга и Дервина Тунка из этого поста, поскольку они предоставляют отличные указатели, с точки зрения методов и инструментов для решения поставленных задач. В частности, NTLK и Python-в-целом обеспечивают отличную основу для экспериментов]

11 голосов
/ 29 октября 2009

Я бы начал с замечательной главы, Питера Норвига , в книге О'Рейли Красивые данные . Он предоставляет данные ngram, которые вам нужны, вместе с красивым кодом Python (который может решить ваши проблемы как есть, или с некоторыми изменениями) на своем личном веб-сайте .

8 голосов
/ 29 октября 2009

Похоже, вы ищете извлечение словосочетания . Мэннинг и Шютце посвящают главу теме, объясняя и оценивая «предложенные формулы», упомянутые в статье Википедии, на которую я ссылался.

Я не могу вписать всю главу в этот ответ; надеюсь, некоторые из их ссылок помогут. ( NSP звучит особенно уместно.) Nltk также имеет модуль коллокаций , о котором Мэннинг и Шютце не упоминали, поскольку их книга предшествует ему.

Другие ответы, опубликованные до сих пор, касаются статистической обработки языка и н-граммов в целом; словосочетания - специфическая подтема.

0 голосов
/ 29 октября 2009

Один из способов - создать себе автомат. скорее всего, недетерминированный конечный автомат (NFA). NFA

Другим более простым способом было бы создать файл, содержащий слова и / или группы слов, которые вы хотите игнорировать, найти, сравнить и т. Д., И сохранить их в памяти при запуске программы, а затем сравнить файл, который вы анализируете с помощью слов / групп слов, содержащихся в файле.

0 голосов
/ 29 октября 2009

сделать матрицу для слов. Затем, если есть два последовательных слова, добавьте одно к соответствующей ячейке.

For example you have this sentence.

mat['for']['example'] ++;
mat['example']['you'] ++;
mat['you']['have'] ++;
mat['have']['this'] ++;
mat['this']['sentence'] ++;

Это даст вам значения для двух последовательных слов. Вы можете сделать это слово также тремя словами. Осторожно, для этого требуется O (n ^ 3) памяти.

Вы также можете использовать кучу для хранения данных, как:

heap['for example']++;
heap['example you']++;
...