Алгоритмы обнаружения фраз и ключевых слов из текста
У меня есть около 100 мегабайт текста без какой-либо разметки, разделенных примерно на 10000 записей. Я хотел бы автоматически создать список тегов. Проблема в том, что существуют группы слов (то есть фразы), которые имеют смысл только тогда, когда они сгруппированы вместе.
Если я просто посчитаю слова, я получу большое количество действительно распространенных слов (например, "за", "я" и т. Д.). Я посчитал слова и количество других слов до и после него, но теперь я действительно не могу понять, что делать дальше. Информация, относящаяся к фразам из 2 и 3 слов, присутствует, но как мне извлечь эти данные?
5 ответов
Прежде всего, попытайтесь сохранить информацию о "границах", которая появляется во входном тексте.
(если такая информация не может быть легко потеряна, ваш вопрос подразумевает, что, возможно, токенизация была легко выполнена)
Во время процесса токенизации (в данном случае синтаксического анализа слов) ищите шаблоны, которые могут определять границы выражений (такие как знаки препинания, особенно точки, а также множественное разделение LF/CR, также используйте такие слова, как "the"). используются в качестве границ. Такие выражения выражений обычно являются "отрицательными", в том смысле, что они разделяют два экземпляра токена, которые обязательно не будут включены в одно и то же выражение. Несколько положительных границ - это кавычки, особенно двойные кавычки. Этот тип информации может будет полезно отфильтровать некоторые из n-грамм (см. следующий абзац).Также в качестве границ выражения могут использоваться также такие последовательности слов, как "например" или "вместо" или "необходимость" (но с использованием таких информация продвигается с использованием "приоры", о которых я расскажу позже).
Без использования внешних данных (кроме входного текста) вы можете добиться относительного успеха, выполнив статистику по текстовым диграммам и триграммам (последовательность из 2 и 3 последовательных слов). Тогда [большинство] последовательностей со значительным (*) числом экземпляров, вероятно, будут типом "выражения / фраз", которое вы ищете.
Этот несколько грубый метод даст несколько ложных срабатываний, но в целом может оказаться работоспособным. Фильтрация n-граммов, которые, как известно, пересекают "границы", как указано в первом абзаце, может существенно помочь, поскольку в естественных языках окончание предложения и начало предложения имеют тенденцию извлекать из ограниченного подмножества пространства сообщений и, следовательно, создавать комбинации токенов, которые могут кажутся статистически хорошо представленными, но которые обычно не связаны семантически.
Лучшие методы (возможно, более дорогие, с точки зрения обработки и дизайна / инвестиций) позволят использовать дополнительные "априоры", относящиеся к области и / или национальным языкам входного текста.
- POS (Part-Of-Speech) тегирование весьма полезно, несколькими способами (обеспечивает дополнительные, более объективные границы выражений, а также классы "шумных" слов, например, все статьи, даже если они используются в контексте сущностей, как правило, мало в облаках тегов, таких, что ОП хочет произвести.
- Словари, лексиконы и тому подобное тоже могут быть весьма полезны. В частности, это те, которые идентифицируют "сущности" (также известные в WordNet) и их альтернативные формы. Сущности очень важны для облаков тегов (хотя они не являются единственным классом слов, найденных в них), и, идентифицируя их, также можно нормализовать их (множество различных выражений, которые можно использовать, скажем,"Сенатор Т.". Кеннеди "), следовательно, устраняет дубликаты, но также увеличивает частоту базовых объектов.
- если корпус структурирован как собрание документов, может быть полезно использовать различные приемы, связанные с TF (Term Frequency) и IDF (Inverse Document Frequency)
[Извините, мне пора, пока (плюс хотелось бы больше подробностей о ваших конкретных целях и т. Д.). Я постараюсь предоставить более подробную информацию и советы позже]
[Кстати, я хочу добавить сюда ответы Джонатана Файнберга и Дервина Тунка из этого поста, поскольку они дают отличные указатели с точки зрения методов и инструментов для решения поставленной задачи. В частности, NTLK и Python-в-целом обеспечивают отличную основу для экспериментов]
Я бы начал с замечательной главы Питера Норвиг в книге О'Рейли " Красивые данные". Он предоставляет данные ngram, которые вам нужны, вместе с красивым кодом Python (который может решить ваши проблемы как есть, или с некоторыми изменениями) на своем личном веб-сайте.
Похоже, вы ищете извлечение словосочетания. Мэннинг и Шютце посвящают главу этой теме, объясняя и оценивая "предложенные формулы", упомянутые в статье Википедии, на которую я ссылался.
Я не могу вписать всю главу в этот ответ; надеюсь, некоторые из их ссылок помогут. ( NSP звучит особенно уместно.) У nltk также есть модуль коллокаций, не упомянутый Мэннингом и Шютце, так как их книга предшествует этому.
Другие ответы, опубликованные до сих пор, имеют дело со статистической обработкой языка и n-граммами в целом; словосочетания являются специфической подтемой.
Одним из способов было бы создать себе автомат. скорее всего, недетерминированный конечный автомат (NFA). NFA
Другим более простым способом было бы создать файл, содержащий слова и / или группы слов, которые вы хотите игнорировать, найти, сравнить и т. Д., И сохранить их в памяти при запуске программы, а затем вы можете сравнить файл, которым вы являетесь. парсинг со словом / группами слов, которые содержатся в файле.
Сделайте матрицу для слов. Затем, если есть два последовательных слова, добавьте одно в соответствующую ячейку.
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']++;