За последние несколько лет, когда я работал с поиском, и в частности с Solr, я стал свидетелем часто повторяющейся проблемы, связанной с многоцелевым поиском и тем, как оцениваются документы. Возможно, лучший способ понять эту проблему — это посмотреть на пример:
Допустим, вы Zappos и вы продаете одежду онлайн. Когда ваши пользователи ищут «зеленые туфли», вы хотите отобразить зеленые туфли, но вы также хотите сначала продвигать новейший продукт. Итак, вы настроили свой обработчик запросов Solr следующим образом:
http://www.zappos.com/solr/select?green shoes&defType=dismax &qf=product_description &pf=product_description &bf=recip(ms(NOW,product_date),3.16e-11,1,1)
В этом случае часть оценки основана на том, насколько хорошо «зеленые туфли» соответствуют описанию продукта, и (хотя это и немного загадочно) часть оценки основана на том, насколько новый продукт. Эти два компонента оценки суммируются вместе, чтобы сформировать окончательный результат. Или в формате уравнения для данного продукта,
(общий балл за товар) = (насколько товар соответствует поиску) + (новизна товара)
Теперь, когда поиск настроен надлежащим образом, вы запускаете поиск «зеленые туфли» и, к своему огорчению, обнаруживаете, что вместо зеленых туфель у вас есть смесь из действительно новых продуктов, которые бывают либо зелеными, либо туфлями, но редко оба одновременно. Это воняет, потому что вы знаете, что в индексе много зелёных туфель, но в последнее время их нет!
Ну, нет проблем, вы можете просто изменить вес совпадения текста, чтобы он был важнее, чем новизна продукта:
http://www.zappos.com/solr/select?green shoes&defType=dismax &qf=product_description^10&pf=product_description^10&bf=recip(ms(NOW,product_date),3.16e-11,1,1)
Или снова в форме уравнения:
(общий балл за продукт) = ** 10 *** | (насколько продукт соответствует поиску) + (новизна продукта)
И после повторного поиска вы увидите список самых новых зеленых ботинок, которые вы можете предложить.
Задача решена! Правильно?
Не так быстро. Сделайте поиск для «туфель». К вашему удивлению, вы найдете не туфли, а коллекцию недавно представленных солнцезащитных и теннисных туфель! Что на земле случилось ?!
Вот что произошло: платья и туфли в индексе встречаются гораздо чаще, чем «зеленые туфли», а поскольку они встречаются гораздо чаще, они получают меньшую оценку! (См. Подсчет очков TF-IDF для получения дополнительной информации.) Поскольку «кроссовки» весят намного меньше, относительная важность новизны возрастает, и вы получаете этот беспорядок, о котором мы здесь говорим.
С этого момента это не трудно понять , что не существует лучшего настройки. Например, если мы снова увеличим вес в текстовом сопоставлении, то, по всей вероятности, мы слишком сильно сопоставим текст «зеленые туфли», игнорируя новизну, результаты теперь будут содержать только самые старые, самые неестественные зеленые обувь в нашем инвентаре!
Визуальная интерпретация
Возможно, вы похожи на меня. Я всегда чувствую себя намного лучше, когда смотрю на визуальную интерпретацию новой концепции. Итак, вот хороший визуальный способ думать о проблеме выше.
При поиске «зеленых туфель» каждый товар в инвентаре имеет определенный балл за совпадение текста и определенный балл за новизну, как показано здесь.
Но, основываясь на этих двух оценочных показателях, нет реального очевидного порядка отображения этих продуктов? Таким образом, мы делаем лучшее, что можем придумать, и суммируем баллы вместе и превращаем их в один балл. Это можно представить в виде линии 45˚ на диаграмме. И чем дальше в этом направлении находится продукт, тем выше его общая оценка.
Но, как показано здесь, есть слишком много предметов с высокими показателями, которые не являются «зелеными туфлями» — они просто новее. Таким образом, мы повышаем счет текста — эффективно растягивая их размещение вдоль вертикальной оси. Чем больше мы это делаем, тем больше влияние текстового соответствия на порядок следования результатов.
И, как мы видели в примере с «туфлями», наш выбор наилучшего веса текста для «зеленых туфель» может совсем не подходить для «туфель».
Изучение лучших вариантов
Наиболее очевидный способ справиться с многоцелевым поиском — просто сложить отдельные баллы вместе. Однако выше мы доказали, что лучшее, что вы можете сделать для этого подхода, это оптимизировать его для одного поиска, а затем надеяться, что остальные поиски не так уж плохи. Должно быть что-то лучше. В следующих разделах я расскажу о двух идеях, которые мы недавно изучали.
Весы с автоматическим масштабированием
Возможно, вы знаете, что одна из целей более важна, а другие должны быть второстепенными. Например, в обоих приведенных выше примерах сопоставление текста является основным. Если покупатель ищет «зеленые туфли», то, черт возьми, ему следует показать им зеленые туфли, и только после этого мы должны заботиться о новизне зеленых туфель. То же самое для «туфель».
Один из способов достижения этого состоит в том, чтобы набрать два прохода следующим образом. На первом этапе текстовая оценка и оценка новизны обрабатываются индивидуально, и мы собираем статистику для обеих оценок. Например, вероятно, будет полезно отслеживать максимальный, средний и самый низкий баллы по обоим измерениям, а также дисперсию этих магазинов. Затем, на втором проходе оценки, мы складываем две оценки вместе, но мы придаем компоненту новизны вес, основанный на статистике, которую мы собрали для других компонентов оценки:
(общая оценка) = (текстовая оценка) + (вес оценки новизны) * || (оценка новизны)
Есть, конечно, несколько способов автоматически определить значения для вторичного балльного веса. Один из примеров на данный момент — сделать вес оценки новизны равным среднему текстовому баллу, деленному на средний балл новизны. Таким образом, средний вклад новизны в общий балл будет равен среднему вкладу текстового балла; два компонента будут в равных условиях.
Принципиальным недостатком здесь является то, что все соответствующие документы должны оцениваться дважды, однако можно было бы смягчить эту проблему путем разумного использования кэшей.
Недоминированные результаты «Заказ»
Совершенно другой подход заключается в том, чтобы возвращать результаты, отсортированные так, чтобы сначала отображались так называемые «недоминированные» результаты. Какой недоминируемый результат? Рассмотрим новый пример. Давайте теперь представим, что мы CareerBuilder, и наши пользователи используют нашу поисковую систему для поиска новых рабочих мест. Пользователю будет интересно одновременно оптимизировать несколько критериев. Пока мы рассматриваем два из этих критериев: расстояние и зарплата. В конкретном поиске пользователь видит следующие результаты, оцененные по обоим критериям:
«Недоминируемым» результатом является любой результат X, для которого нет другого результата, который во всех отношениях лучше, чем X. Совокупность всех таких недоминируемых результатов называется недоминируемой границей (или иногда границей Парето) ,
Теперь, когда мы определили, что не является доминирующим результатом, должно быть легче понять, почему вы хотите сначала представить вашему пользователю эти результаты. Например, с какой стати наш пользователь хотел бы видеть результат H, прежде чем увидеть результаты B или C, которые в обоих случаях ближе и обеспечивают более высокую зарплату?
Одна из главных причин того, что не доминирующее упорядочение результатов выгодно, заключается в том, что мы не можем спросить наших пользователей, насколько сильно они оценивают зарплату по сравнению с расстоянием. Для некоторых пользователей они просто не хотят перемещаться, и поэтому зарплата является вторичной по отношению к расстоянию. Для других, противоположность будет правдой. Самое замечательное в не доминирующем порядке — то, что вам не нужно спрашивать, пользователю будут представлены только результаты, которые не доминируют ни в одном измерении.
Хотя этот недоминирующий порядок обеспечивает некоторые большие преимущества, есть и недостатки. С одной стороны, это не строгий порядок. Есть несколько предметов, которые в равной степени не доминируют (те, что находятся на границе без доминирования). В каком порядке мы представляем эти результаты пользователю? Кроме того, когда мы исчерпали полностью недоминируемые результаты, как мы представим оставшиеся результаты? Наконец, вычисление недоминируемой границы в вычислительном отношении намного сложнее, чем простая сортировка документов по некоторой скалярной оценке. Эту сложность, однако, можно уменьшить, сделав некоторые приближения в нашем порядке упорядочения результатов.
Реализация этого в Solr
И все это заставляет задуматься: «Как вы на самом деле строите это в Solr?» Ответ, по крайней мере, сейчас, заключается в том, что мы не совсем знаем. Мы знаем компонент, который делает оценку; это называется сходство . И мы знаем компонент, который ищет индекс; это называется IndexSearcher . И мы даже знаем, что собирает все документы от поисковика; это называется TopDocs . Но мы не знаем, выполнены ли все вышеперечисленные требования. (Например, должны ли оценки документов быть скалярами?) — Но я знаю, что нашим клиентам нужен такой тип поиска. И чем скорее, тем лучше!
Если вы такой клиент, то сообщите нам! Чем больше людей получат взаимную выгоду от этого, тем лучше и быстрее мы осуществим это! Вы разработчик? С нами весело взломать. Если вам интересно, помогите нам построить это!
— Подробнее см .: http://www.opensourceconnections.com/2013/07/04/multiple-objective-search-scoring/#sthash.U9qUDEQa.dpuf.