W poprzednim wpisie kilkukrotnie wspominałem o czymś takim jak trafność otrzymanych rezultatów. Nie wyjaśniłem wtedy zbyt wiele, bo temat zasługuje na poruszenie go w odrębnym artykule. I oto jest. Postaram się teraz wyjaśnić o co w tym wszystkim chodzi.

Pamiętaj proszę, że tworząc ten wpis testowałem wszystko na Elasticsearchu w wersji 6.3 (najnowsza jaka w tamtym momencie była dostępna). Możliwe jest, że w starszych lub nowszych wydaniach wygląda to nieco inaczej.

Domyślny sposób sortowania

Czy zastanawiał[a|e]ś się może w jakiej kolejności zwracane są wyniki wyszukiwania w Elasticsearchu? Oczywiście, możesz sterować i decydować po którym polu i w jakiej kolejności ma następować sortowanie, ale które pole wybierane jest jako domyślne, kiedy nie określisz żadnego? Jest nim pole _score, a kolejność to DESC. Czyli im większa wartość w polu _score, tym wyżej znajdzie się w wynikach wyszukiwania. No dobrze, ale co znajduje się w tym polu i skąd się ono bierze?

Czym jest pole _score?

Zobaczmy na przykładzie czym jest pole _score. Na początek zróbmy sobie małą bazę filmów Marvela:

I zapytajmy się naszego Elasticsearcha o Thora:

W rezultacie dostajemy coś zbliżonego:

Każdy ze zwróconych rezultatów ma pole _score zawierające liczbę. Tak jak wspomniałem wyniki są po nim posortowane od największej wartości. Widzimy tu, że nasze zapytanie thor najbardziej pasowało do pierwszej części serii pt. Thor, a w dalszej kolejności do Thor: Mroczny światThor: Ragnarok. Dlaczego zamiast prostych liczb całkowitych 3, 2 i 1 widzimy tutaj 1,8208046, 1,2199390,9971461? To właśnie postaram się wyjaśnić. Aha! Jeszcze jedno: jest duże prawdopodobieństwo, że u Ciebie te liczby będę nieco inne. Dlaczego? To to pytanie również postaram się zaraz odpowiedzieć.

Jak obliczany jest score?

Domyślnie w Elasticsearchu do obliczania trafności poszczególnych dokumentów wykorzystany jest algorytm term frequency/inverse document frequency (znany również jako TF/IDF). Algorytm bierze pod uwagę trzy rzeczy:

  • Jak często wyszukiwane wyrażenie występuje w określonym polu? Im częściej, tym ważność jest większa.
  • Jak często każde wyrażenie występuje w indeksie? Im częściej, tym ważność takiego wyrażenia jest mniejsza.
  • Jak długie jest pole, w którym szukamy? Im pole jest dłuższe, tym trafienie ma mniejsze znaczenie. Inaczej mówiąc znalezienie wyrażenie w krótkim polu (np. title) ma większe znaczenie niż znalezienie tego samego wyrażenia w polu zawierającym dłuższą wartość (np. description).

Wpływanie na score

Nie zawsze jest tak, że to co daje podstawowy algorytm nam wystarczy. Nie ma dramatu. Na score możemy wpływać.

boosting

Podstawowym narzędziem do tego jest, wspomniany już ostatnio, boosting. Można go zastosować na dwóch poziomach. Na poziomie pól, kiedy chcemy powiedzieć, że wyszukiwanie w jednym polu ma dla nas większe znaczenie niż wyszukiwanie w innym polu, a także na poziomie zapytania, kiedy chcemy powiedzieć, że jeden fragment zapytania ma dla nas większe znaczenie niż drugi.

inne sposoby

Boosting nie wpływa jednak na zmianę sposobu obliczania trafności. Jeżeli nie podoba nam się efekt działania algorytmu TF/IDF, to i na to znajdzie się metoda. Na kilka sposobów możemy napisać funkcje, która będzie liczyła trafność po naszemu. Jest to jednak temat na kilka oddzielnych wpisów, więc na razie odsyłam do dokumentacji.

Skąd różnice w wartościach pola _score?

Na początku przygody z Elasticsearchem zdziwiło mnie dlaczego mimo dodawania tych samych plików do nowego indeksu dostaję inne wartości w polach _score? Dla przykładu odpalenie powyższego zapytania na wiernej kopii naszego indeksu dało mi takie rezultaty:

Rezultaty te same, kolejność ta sama, ale wartości w polach _score inne. Dlaczego? Ano dlatego, że dla osiągnięcia lepszej wydajności twórcy Elasticsearcha postanowili, że score nie będzie liczony na podstawie całego indeksu, ale na podstawie fragmentów indeksów umieszczonych na poszczególnych shardach. Z tego powodu finalna wartość score danego dokumentu zależy od tego w jaki sposób dokumenty są rozłożone na shardach. W skrajnych przypadkach przy małej ilości dokumentów może to nieźle zaburzać trafność. Nie ma się jednak czego bać przy solidnej porcji danych, a do tego Elasticsearch został stworzony. Żeby sprawdzić, że jest tak jak mówię wystarczy przetestować to samo zapytanie na indeksie zlokalizowanym w całości tylko na jednym shardzie. W takim przypadku scoring będzie powtarzalny.

Liczenie trafności tylko na podstawie shardów to nie jedyny zabieg optymalizacyjny, który wpływa na score. Innym przykładem jest branie pod uwagę dokumentów, które zostały usunięte. Usunąłem z naszego indeksu film Thor: Mroczny świat i odpaliłem wyszukiwanie ponownie:

Score pozostałych dwóch znalezionych filmów nam się nie zmienił. To również może zaskakiwać. Nie mogę teraz znaleźć informacji jak długo utrzymuje się taki stan, ale wydaje mi się, że informacja o usuniętych dokumentach jest odświeżana co jakiś czas i wtedy score „wraca do normy”.

Obstawiam, że te dwa przypadki nie są jedynymi, które trzeba mieć z tyłu głowy zastanawiając się dlaczego score wyszedł taki, a nie inny. Jeżeli jeszcze trafie na coś podobnego, to na pewno tutaj dopiszę.

The End

Obliczanie trafności otrzymanych rezultatów jest tym elementem Elasticsearcha (oraz innych poważnych silników wyszukiwania) który robi różnicę. O ile jako-takie wyszukiwanie pełnotekstowe da się zaimplementować na większości popularnych baz danych, o tyle scoring jest czymś nad czym trzeba by mocniej przysiąść, szczególnie chcąc otrzymać satysfakcjonujące efekty czasowe. Mam nadzieję, że dzisiejszy wpis pokazał Ci o co w tym wszystkim chodzi. Artykuł nie wyczerpuje jednak tematu. Jeżeli chcesz go zgłębić to w dokumentacji Elasticsearcha informacje na ten temat znajdziesz pod hasłami relevancescoring.

Na koniec jeszcze jedna wiadomość. W pierwszym wpisie z serii o Elasticsearchu zadeklarowałem, że będę umieszczał kolejne odcinki w dwutygodniowych odstępach czasu. Mimo, że do tej pory mi się udawało dochować terminów, to niestety muszę zwolnić tempo. Serii nie porzucam, ale jeżeli wpisy będę pojawiać się raz na miesiąc to również będę zadowolony. Tyle na dziś.


Bądź na bieżąco!

Podobają Ci się treści publikowane na moim blogu? Nie chcesz niczego pominąć? Zachęcam Cię do subskrybowania kanału RSS, polubienia fanpage na Facebooku, zapisania się na listę mailingową:

Dołączając do newslettera #NoweRozdanie2 otrzymasz dostęp do dodatkowych materiałów:

  • PDF: „Jednoosobowa działalność gospodarcza krok po kroku” (do artykułu)
  • PDF: „FAQ: Jak pracuje się dla Roche/Sii?” (do artykułu)
  • PDF: „Jak zmniejszyć prawdopodobieństwo wystąpienia kontroli i co zrobić kiedy urzędnik zapuka do Twoich drzwi?” (do artykułu)

Powyższe dane są przechowywane w systemie Mailchimp i nie są udostępniane nikomu innemu. Więcej szczegółów znajdziesz na stronie polityki prywatności.

lub śledzenia mnie na Twitterze. Generalnie polecam wykonanie wszystkich tych czynności, bo często zdarza się tak, że daną treść wrzucam tylko w jedno miejsce. Zawsze możesz zrobić to na próbę, a jeśli Ci się nie spodoba – zrezygnować :)

Dołącz do grup na Facebooku

Chcesz więcej? W takim razie zapraszam Cię do dołączenia do powiązanych grup na Facebooku, gdzie znajdziesz dodatkowe informacje na poruszane tutaj tematy, możesz podzielić się własnymi doświadczeniami i przemyśleniami, a przede wszystkim poznasz ludzi interesujących się tą samą tematyką co Ty.

W grupie Programista Na Swoim znajdziesz wiele doświadczonych osób chętnych do porozmawiania na tematy krążące wokół samozatrudnienia i prowadzenia programistycznej działalności gospodarczej. Vademecum Juniora przeznaczone jest zaś do wymiany wiedzy i doświadczeń na temat życia, kariery i problemów (niekoniecznie młodego) programisty.

Wesprzyj mnie

Jeżeli znalezione tutaj treści sprawiły, że masz ochotę wesprzeć moją działalność online, to zobacz na ile różnych sposobów możesz to zrobić. Niezależnie od tego co wybierzesz, będę Ci za to ogromnie wdzięczny.

Postaw mi kawę na buycoffee.to

Na wsparciu możesz także samemu zyskać. Wystarczy, że rzucisz okiem na listę różnych narzędzi, które używam i polecam. Decydując się na skorzystanie z któregokolwiek linku referencyjnego otrzymasz bonus również dla siebie.

Picture Credits