Как получить часто встречающиеся фразы с Lucene
Я хотел бы получить некоторые часто встречающиеся фразы с Lucene. Я получаю некоторую информацию из файлов TXT, и я теряю много контекста из-за отсутствия информации для фраз, например, "поиск информации" индексируется как два отдельных слова.
Как получить такие фразы? Я не могу найти ничего полезного в интернете, все советы, ссылки, советы, особенно примеры приветствуются!
РЕДАКТИРОВАТЬ: я храню свои документы только по названию и содержанию:
Document doc = new Document();
doc.add(new Field("name", f.getName(), Field.Store.YES, Field.Index.NOT_ANALYZED));
doc.add(new Field("text", fReader, Field.TermVector.WITH_POSITIONS_OFFSETS));
потому что для того, что я делаю, наиболее важным является содержание файла. Названия слишком часто не носят описательного характера (например, у меня есть много научных работ в формате PDF, названия которых являются кодами или числами).
Я отчаянно нуждаюсь в том, чтобы проиндексировать наиболее часто встречающиеся фразы в текстовом содержимом, просто сейчас я вижу, насколько неэффективен этот простой подход "мешок слов".
3 ответа
Юлия, Кажется, вы ищете н-граммы, а именно биграммы (также называемые коллокациями).
Вот глава о поиске словосочетаний (PDF) из Основ статистической обработки естественного языка Мэннинга и Шутце.
Чтобы сделать это с Lucene, я предлагаю использовать Solr с ShingleFilterFactory. Пожалуйста, смотрите это обсуждение для деталей.
Хорошо, проблема потери контекста для фраз может быть решена с помощью PhraseQuery.
Индекс по умолчанию содержит информацию о позициях терминов, если вы не создали чистые логические поля путем индексации с помощью параметра omitTermFreqAndPositions. PhraseQuery использует эту информацию для поиска документов, где термины находятся на определенном расстоянии друг от друга.
Например, предположим, что поле содержит фразу "быстрая коричневая лиса перепрыгнула через ленивую собаку". Не зная точной фразы, вы по-прежнему можете найти этот документ, выполнив поиск документов с полями, рядом с которыми расположены слова "Быстрая" и "Фокс". Конечно, простой TermQuery мог бы найти этот документ, зная одно из этих слов, но в этом случае нам нужны только документы с фразами, в которых слова либо находятся рядом (быстрый лис), либо имеют одно слово между ними (быстрая [неактуальная] лиса). Максимально допустимое позиционное расстояние между терминами, которые должны рассматриваться как совпадение, называется наклонным. Расстояние - это количество позиционных перемещений терминов для восстановления фразы по порядку.
Проверьте JavaDoc Lucene для PhraseQuery
Посмотрите этот пример кода, который демонстрирует, как работать с различными объектами запроса:
Вы также можете попробовать объединить различные типы запросов с помощью класса BooleanQuery.
А что касается частоты фраз, я полагаю, что оценка Lucene учитывает частоту терминов, встречающихся в документах.
Можно ли опубликовать написанный вами код?
В основном многое зависит от того, как вы создаете свои поля и храните документы в lucene.
Давайте рассмотрим случай, когда у меня есть два поля: ID и Комментарии; и в моем поле идентификатора я разрешаю значения типа 'находки nemo', т.е. строки с пробелом. Принимая во внимание, что "Комментарии" - это текстовое поле свободного потока, т.е. я разрешаю все и вся, что позволяет моя клавиатура и что может понять lucene.
Теперь в сценарии реальной жизни не имеет смысла указывать мой идентификатор: "находя немо" как две разные строки для поиска. Принимая во внимание, что я хочу проиндексировать все в комментариях.
Так что я сделаю, я создам документ (org.apache.lucene.document.Document
) объект позаботиться об этом... как то так
Document doc = new Document();
doc.add(new Field("comments","Finding nemo was a very tough job for a clown fish ...", Field.Store.YES, Field.Index.ANALYZED));
doc.add(new Field("id", "finding nemo", Field.Store.YES, Field.Index.NOT_ANALYZED));
Итак, по сути, я создал два поля:
- комментарии: где я предпочел проанализировать это с помощью
Field.Index.ANALYZED
- id: где я указывал lucene хранить его, но не анализировать
Field.Index.NOT_ANALYZED
Так вы настраиваете lucene для токенайзера и анализатора по умолчанию. В противном случае вы можете написать свой собственный токенизатор и анализаторы.
Ссылка (ы) http://darksleep.com/lucene/
Надеюсь, что это поможет вам...:)