Чи є в ElasticSearch можливість семантичного пошуку?
Для початку потрібно уточнити, який результат хочеться отримати від семантичного пошуку. Зазвичай, коли йдеться про пошукові системи, мається на увазі, задача по збільшенню релевантний результатів у пошуковій видачі.
Наприклад:
Як приготувати яблука -> як приготувати яблука, як приготувати фрукти Відпочинок у шармі -> відпочинок у Шарм-еш-Шейх, відпочинок єгипет
Тобто коли ми розуміємо «контекст» пошукового запиту і повертаємо документи у спаданні релевантності яка рахується на базі нашого контексту. У es цю задачу можна звести до задачі токінізації (N-gram, синоніми).
слово яблуко ми будемо заміняти на яблуко, фрукт, слава победителям, гала, apple
Яблуко це фрукт, а також яблуко може мати різні сорти або слово написане на різних мовах. Якщо ми додамо такі синоніми, то із запита «як приготувати гала у мікрохвильовці» ми зможемо зрозуміти, що гала це сорт яблука і повернути документи які відповідають «як приготувати яблука у мікрохвильовці». Користаючись таким прийомом, можна досягти ефекту семантичного пошуку. Приклади можуть бути набагато складнішими, коли ми застосуємо n-gram. наприклад запит республіка кіпер може повернути документи які містять середземне море. Ось ця логіка, що яблуко відповідає яблуко, фрукт, гала... або республіка кіпер відповідає середземне море, лягає на плечі інженера. Він це може отримати за допомогою мл моделі, або за допомогою людей які самостійно, руками зададуть ці відповідності.
У даного підхода є нюанси. Наприклад я запросив «як приготувати гала у мікрохвильовці» і хочу щоб саме документи які містять ці терми були повернуті першими. Щоб таке реалізувати потрібно індексувати 2 поля title та title_semantic. У title ми індексуємо без нашого механізма синомізації а у title_semantic з нашими відповідностями. Тоді при побудові пошуку ми можемо вказати, що документи які співпадають по title мають більшу вагу а title_semantic мають трохи меншу.
Ще один із можливих варіантів реалізувати семантичний пошук, це підхід keywords. Нам потрібний чорний ящик який отримує на вході текст, а на виході список ключових слів (мл модель або щось інше). Тоді ми можемо при індексації документа індексувати окрім title ще поле title_keyword. При пошуку ми будемо шукати по title, а документи у яких співпав ще й title_keyword піднімати додатково з якимось коефіціентом.
Загалом прийомів багато, і всі вони побудовані з певними допущеннями, що чимось ми повинні нехтувати, тому який обрати залежить від конкретної задачі. Якщо потрібний пошук через вектори (коли ми «контекст» перетворюємо у вектор розмірністю n) можна скористатися dense vectors, але він буде дуже не ефективним, так як він не використовує інвертний індекс і повністю перебирає індекс. Якщо dense vectors вам потрібний і у вас є es можете спробувати, але якщо ви придивляєтеся на es як до інструмента який може вирішити дану проблему, то краще звернути увагу на пошукові движки які заточені саме під це.
Для початку потрібно уточнити, який результат хочеться отримати від семантичного пошуку. Зазвичай, коли йдеться про пошукові системи, мається на увазі, задача по збільшенню релевантний результатів у пошуковій видачі.
Наприклад:
Як приготувати яблука -> як приготувати яблука, як приготувати фрукти
Відпочинок у шармі -> відпочинок у Шарм-еш-Шейх, відпочинок єгипет
Тобто коли ми розуміємо «контекст» пошукового запиту і повертаємо документи у спаданні релевантності яка рахується на базі нашого контексту. У es цю задачу можна звести до задачі токінізації (N-gram, синоніми).
слово яблуко ми будемо заміняти на яблуко, фрукт, слава победителям, гала, apple
Яблуко це фрукт, а також яблуко може мати різні сорти або слово написане на різних мовах. Якщо ми додамо такі синоніми, то із запита «як приготувати гала у мікрохвильовці» ми зможемо зрозуміти, що гала це сорт яблука і повернути документи які відповідають «як приготувати яблука у мікрохвильовці». Користаючись таким прийомом, можна досягти ефекту семантичного пошуку. Приклади можуть бути набагато складнішими, коли ми застосуємо n-gram. наприклад запит республіка кіпер може повернути документи які містять середземне море. Ось ця логіка, що яблуко відповідає яблуко, фрукт, гала... або республіка кіпер відповідає середземне море, лягає на плечі інженера. Він це може отримати за допомогою мл моделі, або за допомогою людей які самостійно, руками зададуть ці відповідності.
У даного підхода є нюанси. Наприклад я запросив «як приготувати гала у мікрохвильовці» і хочу щоб саме документи які містять ці терми були повернуті першими. Щоб таке реалізувати потрібно індексувати 2 поля title та title_semantic. У title ми індексуємо без нашого механізма синомізації а у title_semantic з нашими відповідностями. Тоді при побудові пошуку ми можемо вказати, що документи які співпадають по title мають більшу вагу а title_semantic мають трохи меншу.
Ще один із можливих варіантів реалізувати семантичний пошук, це підхід keywords. Нам потрібний чорний ящик який отримує на вході текст, а на виході список ключових слів (мл модель або щось інше). Тоді ми можемо при індексації документа індексувати окрім title ще поле title_keyword. При пошуку ми будемо шукати по title, а документи у яких співпав ще й title_keyword піднімати додатково з якимось коефіціентом.
Загалом прийомів багато, і всі вони побудовані з певними допущеннями, що чимось ми повинні нехтувати, тому який обрати залежить від конкретної задачі. Якщо потрібний пошук через вектори (коли ми «контекст» перетворюємо у вектор розмірністю n) можна скористатися dense vectors, але він буде дуже не ефективним, так як він не використовує інвертний індекс і повністю перебирає індекс. Якщо dense vectors вам потрібний і у вас є es можете спробувати, але якщо ви придивляєтеся на es як до інструмента який може вирішити дану проблему, то краще звернути увагу на пошукові движки які заточені саме під це.