Поиск и ранжирование коротких фраз (например, заголовков фильмов) - PullRequest
6 голосов
/ 18 ноября 2009

Я пытаюсь улучшить наши возможности поиска по коротким фразам (в нашем случае названия фильмов) и в настоящее время изучаю полнотекстовый поиск SQL Server 2008, который предоставляет некоторые функции, которые нам нужны:

  • Слово происходит от слова (например, «пила» также означает «видеть», «видел» и т. Д.)
  • Синонимы (например, «6» является синонимом «VI»)

Однако алгоритм ранжирования оказывается проблематичным, используя FREETEXTTABLE с поисковым термином и извлекая поле RANK. Например, когда пользователь вводит «увидел», то результаты, которые мы получаем с нашим каталогом:

RANK | Title
---------------------------------------------------------------------
180  | The Exorcist: The version you've never seen
180  | Saw IV
180  | Saw V
180  | Anybody Here Seen Jeannie?
180  | Seeing Red

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

Аналогичным образом, ввод "луны" дает следующие результаты:

RANK | Title
---------------------------------------------------------------------
144  | Pink Floyd - The Dark Side of the Moon
144  | Fly Me To The Moon 3D
144  | Twilight: New Moon
144  | Moon

И здесь, несмотря на отсутствие исходящих совпадений, человеку будет ясно, что лучшим совпадением для «луны» является «Луна», а не более длинные заголовки, которые содержат его только как часть заголовка, однако FTS оценивает их в равной степени .

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

Я действительно не хочу заново изобретать колесо, так есть ли какие-нибудь поисковые решения, которые бы работали для названий и давали бы хороший рейтинг плюс функциональность stemming / thesaurus? Было бы также неплохо, если бы в нем была функция проверки орфографии для реализации функций «Вы имели в виду…», таких как Google, поэтому слово «saww» будет исправлено на «saw» и «mon» на «moon» и т. Д.

Ответы [ 3 ]

7 голосов
/ 23 ноября 2009

Похоже, рейтинг SQL FTS близок, но не совсем то, что вы ищете, и что вы сократили количество «не совсем» дел до трех:

  • изгибы ранжируются так же, как и не изогнутые формы
  • слова ранжируются идентично их синонимам
  • точные совпадения (или короткие заголовки) ранжируются одинаково как совпадения из одного слова в более длинных заголовках

Общим для всех трех является то, что очень простой автоматизированный постпроцессор результатов может использовать эти правила для разрыва связей между результатами с одинаковым ранжированием: если есть точное совпадение, ранжируйте его выше неточного совпадения и ранжировать более короткие названия впереди более длинных. Возможно, вы захотите сохранить FTS и просто поместить некоторый код (либо в хранимой процедуре, либо в вашем приложении) поверх FTS, который сортирует группы связанных результатов по указанным вами критериям. Вероятно, это будет проще, чем переключиться на Lucene или другую реализацию полнотекстового поиска, производимого не Microsoft.

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

Если это недостаточно хорошо, я бы начал с просмотра Lucene.NET (бесплатно), Solr (бесплатно) и dtSearch ($ $$). Обратите внимание, что ни одна из них не будет такой простой, как FTS - особенно Lucene.NET, которая является AFAIK самой популярной и очень полнофункциональной, но требует достаточного количества кода, конфигурации, обслуживания и т. Д. Вы можете увидеть в этой ветке SO для некоторых других мнений, возможно, существует больше потоков, подобных этой, на SO и в других местах, если вам нужно больше мнений.

Если вам нужна функция предложения правописания "ты имел в виду ...". Существует пример построения подобного рода функций поверх FTS в Pro Полнотекстовый поиск в SQL Server 2008 (ссылка содержит некоторые выдержки из Google Книг). Будет ли это соответствовать вашим потребностям? Если нет, есть множество других опций , как бесплатных, так и нет.

2 голосов
/ 26 ноября 2009

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

' Как сыграть в матче ' - одно из моих любимых сообщений на эту тему. В нем автор сопоставляет строки на основе сходства последовательных дублетов между словами.

Например, 'search' и 'smirch' разбиты на двойные буквы: se, ea, ar, rc, ch для поиска и sm, mi, ir, rc, ch для ухмылки. Затем количество совпадающих дублетов умножается на два (rc и ch match, так что 2 * 2) и делится на общее количество дублетов (5 + 5 = 10 в этом случае). 4/10 = 40% совпадения между поиском и ухмылкой.

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

Во втором примере этот алгоритм выделил бы луну в качестве лучшего примера, но не исключил бы сохранение Темной стороны Луны и т. Д. - он бы просто стал ниже. В вашем первом примере вы должны будете применить какое-то лексическое преобразование перед вызовом этого алгоритма, потому что он не сможет найти похожие слова, которые меняют ствол (например, see / saw / seen), хотя он будет хорошо работать с не-stem чейнджер (Франция / французский).

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

0 голосов
/ 30 ноября 2009

Работая с SQL Server (2005) FullText и Lucene (.NET) в производственной среде, я действительно считаю, что Lucene - лучший выбор:

SQL Server FTS хорош и быстр; но вы не можете реально манипулировать способом генерации индексов. Кроме того, вы не можете просто «увидеть» таблицы индексов. Вся реализация скрыта, и, как таковой, этот инструмент отлично подходит для готового универсального FTS, но сложнее для конкретных приложений.

Lucene, с другой стороны, использовался и тестировался во множестве сценариев (я настоятельно рекомендую Lucene в действии , если вы решите пойти по этому маршруту). Даже если существующие реализации не совсем соответствуют вашим потребностям, вы всегда можете создать «новую» конкретную реализацию (напишите свой собственный анализатор / токенизатор / фильтр - stemmer !! - 1), хотя количество параметризации lucene достаточно много (2) и вы всегда можете проверить содержимое индекса, используя Luke (3). Вы также получаете приложение поиска, которое не зависит от хранилища данных (4), и одинаково хорошо работает для Java && .NET (5). Кроме того, и если это ставит вас в тупик, есть также реализация Hibernate && NHibernate ( Поиск Hibernate - 6).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...