Solr-gestützte ISFDB – Teil #10: Optimierung der Relevanz
Dies ist Teil 10 einer (nicht enden wollenden?) Artikelserie über das Indizieren und Durchsuchen der ISFDB.org-Daten mit Solr. Die Umstände…
Dies ist Teil 10 einer (nicht enden wollenden?) Artikelserie über das Indizieren und Durchsuchen der ISFDB.org-Daten mit Solr.
Die Umstände haben mich länger von dieser Serie ferngehalten, als ich eigentlich vorhatte. Deshalb möchte ich heute gleich loslegen und über die Verbesserung der Nutzererfahrung durch die Verbesserung der Relevanz sprechen.
(Wenn Sie zu Hause mitarbeiten möchten, können Sie den Code auf github auschecken. Ich beginne mit dem blog_9-Tag und werde im Laufe des Artikels auf bestimmte Commits verweisen, in denen ich etwas geändert habe, bis hin zum blog_10-Tag, der das Endergebnis dieses Artikels enthält).
Akademisch vs. Praktisch
In der akademischen Welt wird „Relevanz“ in der Regel in Form von„Precision vs. Recall“ diskutiert (wenn Ihnen diese Begriffe nicht geläufig sind, empfehle ich Ihnen, den Link zu lesen), aber meiner Erfahrung nach sind solche Metriken nur der Ausgangspunkt. Während es den Nutzern in der Regel wichtig ist, dass Ihr „Recall“ gut ist (es sollten keine Ergebnisse fehlen), ist die „Präzision“ in der Regel weniger wichtig als die „Reihenfolge“. Die meisten Nutzer möchten (verständlicherweise), dass die „besten“ Ergebnisse an erster Stelle stehen, und kümmern sich nicht um die Gesamtzahl der Ergebnisse.
Die Definition der „besten“ Ergebnisse ist der Punkt, an dem es knifflig wird. Wie gesagt, es gibt viele großartige Algorithmen, über deren Vor- und Nachteile Akademiker ständig diskutieren. Aber häufig ist der beste Ansatz, um Ihren Nutzern die „besten“ Ergebnisse zu liefern, nicht etwa ein Doktortitel in IR, sondern „schummeln“ und die Algorithmen verzerren und „bereichsspezifisches Wissen“ anwenden – aber ich greife mir selbst vor, lassen Sie uns mit einem echten Beispiel beginnen.
Schlechte Ergebnisse in unserem Bereich
Jede Domain ist anders, und der Schlüssel zu einem guten Sucherlebnis liegt darin, dass Sie Ihre Domain wirklich verstehen und wissen, wie Ihre Nutzer (und Daten) mit ihr in Verbindung stehen.
Sehen wir uns ein konkretes Beispiel mit unseren ISFDB-Daten an. Eine der berühmtesten Sci-Fi-Kurzgeschichten, die je geschrieben wurden, ist Nightfall von Isaac Asimov, der später mit Robert Silverberg zusammenarbeitete, um sie zu einem Roman auszubauen. Wenn ein Benutzer (der weiß, dass er in der ISFDB sucht) nach dem Wort „Nightfall“ sucht, würde er verständlicherweise erwarten, dass einer dieser beiden Titel ziemlich weit oben in der Ergebnisliste erscheint, aber das ist genau das, was er auf Seite 1 unserer Suche in ihrer jetzigen Konfiguration erhält…
- Titel: Nightfall INTERIORART – Autor: Kolliker
- Titel: Nightfall: Body Snatchers ANTHOLOGY- Autor: uncredited
- Titel: Cover: Nightfall One COVERART – Autor: Ken Sequin
- Titel: Cover: Nightfall One COVERART – Autor: Ken Sequin
- Titel: Nightfall SHORTFICTION – Autor: Tom Chambers
- Titel: Glossar (Nightfall at Algemron) ESSAY – Autor: uncredited
- Titel: Cover: Nightfall One COVERART – Autor: Ken Sequin
- Titel: Cover: Nightfall Two COVERART – Autor: Ken Sequin
- Titel: Nightfall POEM – Autor: Susan A. Manchester
- Titel: Cover: Nightfall One COVERART – Autor: Ken Sequin
Diese Ergebnisse sind nicht sonderlich überraschend, da wir in dieser Serie bisher keine Arbeit in die Relevanzoptimierung gesteckt haben, sondern nur ein einfaches „Auffangfeld“ durchsuchen. Bevor wir die Situation verbessern können, ist es wichtig, dass wir verstehen, warum wir bekommen, was wir bekommen und warum wir nicht bekommen, was wir wollen.
Erklärungen zum Ergebnis
Eine der am schwersten zu verstehenden Funktionen von Solr ist „Score Explanation“ – nicht, weil sie schwer zu benutzen ist, sondern weil die Ausgabe wirklich voraussetzt, dass Sie die Grundlagen der Lucene/Solr-Bewertung verstehen. Wenn wir das Debugging für unsere Abfrage aktivieren, erhalten wir für jedes Ergebnis einen neuen „Erklären“-Link, über den wir die Punktzahl und die Art und Weise, wie diese Punktzahl berechnet wurde, sehen können. Aber damit können wir nicht mit Dokumenten vergleichen, die nicht auf Seite 1 stehen. Dazu verwenden wir die explainOther
und wechseln Sie zur XML-Ansicht, da die Velocity-Vorlagen derzeit keine explainOther
Informationen anzeigen. Jetzt können wir die Erklärungen zwischen den beiden Dokumenten vergleichen, die wir eigentlich zu finden hofften, und das beste Ergebnis…
- TITLE_847094 (Nachteinbruch INTERIORART)
2.442217 = (MATCH) fieldWeight(catchall:nightfall in 274241), product of: 1.0 = tf(termFreq(catchall:nightfall)=1) 9.768868 = idf(docFreq=98, maxDocs=636658) 0.25 = fieldNorm(field=catchall, doc=274241)
- TITEL_11852 (Nightfall NOVEL)
1.7269082 = (MATCH) fieldWeight(catchall:nightfall in 11741), product of: 1.4142135 = tf(termFreq(catchall:nightfall)=2) 9.768868 = idf(docFreq=98, maxDocs=636658) 0.125 = fieldNorm(field=catchall, doc=11741)
- TITLE_46434 (Nightfall SHORTFICTION)
1.7269082 = (MATCH) fieldWeight(catchall:nightfall in 41784), product of: 1.4142135 = tf(termFreq(catchall:nightfall)=2) 9.768868 = idf(docFreq=98, maxDocs=636658) 0.125 = fieldNorm(field=catchall, doc=41784)
Der Teufel steckt in den Unterschieden, die ich fett gedruckt habe. Ohne auf eine komplizierte Erklärung einzugehen, liegt der Kern des Problems darin, dass die Dokumente, nach denen wir suchen, zwar zweimal das Wort „nightfall“ im Catchall-Feld enthalten (und das Ergebnis mit der höchsten Punktzahl nur einmal), dies aber durch die „fieldNorm“ ausgeglichen wird, die die Tatsache widerspiegelt, dass das Catchall-Feld bei unseren „guten“ Dokumenten viel länger ist als bei unseren „schlechten“ Dokumenten.
Unser Scoring verfeinern
Dies ist eines dieser Beispiele, bei denen die Wissenschaft nicht immer mit der Realität Ihres Fachgebiets übereinstimmt. Wenn Sie das in Lucene/Solr verwendete TF/IDF-Scoring-Modell verwenden, benötigen Sie in der Regel einen „Längennormalisierungsfaktor“, um den häufigen Fall auszugleichen, dass ein wirklich langes Dokument von Natur aus mehr Wörter enthält, so dass eine statistische Wahrscheinlichkeit besteht, dass die Suchbegriffe häufiger vorkommen. Kurz und gut: Wenn alle anderen Dinge gleich sind, ist kürzer besser. Diese Argumentation ist im Allgemeinen stichhaltig, aber die Standardimplementierung in Lucene/Solr kann in einigen häufigen Fällen ein Hindernis darstellen:
- Ein Korpus voller wirklich kurzer Dokumente – unser ISFDB-Index besteht nicht aus ganzen Büchern, sondern nur aus einer Reihe von Metadatenfeldern
- Ein Korpus, bei dem länger wirklich besser ist – in den ISFDB-Daten haben populärere Titel/Autoren tendenziell mehr Daten, was bedeutet, dass das Feld
catchall
natürlich länger ist.
Es gibt einige tolle Möglichkeiten, die Klasse Similarity zu verbessern, aber am einfachsten ist es, mit omitNorms
zu beginnen, um diesen Faktor aus der Auswertung zu entfernen. Mit unserem neuen Schema führen wir eine erneute Indizierung durch und sehen einige bemerkenswerte Änderungen…
- Titel: Nightfall NOVEL – Autoren: Robert Silverberg, Isaac Asimov
- Titel: Nightfall und andere Geschichten COLLECTION – Autor: Isaac Asimov
- Titel: Nightfall SHORTFICTION – Autor: Isaac Asimov
- Titel: Die Legende von Nightfall NOVEL – Autor: Mickey Zucker Reichert
- Titel: Nightfall NOVEL – Autor: John Farris
- Titel: The Road to Nightfall COLLECTION – Autor: Robert Silverberg
- Titel: Road to Nightfall SHORTFICTION – Autor: Robert Silverberg
- Titel: Ein Tiger bei Nachteinbruch SHORTFICTION – Autor: Harlan Ellison
- Titel: Nightfall SHORTFICTION – Autor: David Weber
- Titel: Nightfall SHORTFICTION – Autor: Charles Stross
Bereichsspezifische Vorurteile
Das Weglassen der Längennormen hat dazu beigetragen, das Feld für unsere Dokumente zu ebnen, und in diesem einen Beispiel sieht es auf den ersten Blick wie eine enorme Verbesserung aus, aber das ist hauptsächlich ein Glücksfall. Wenn Sie sich die Erklärungen zu den Ergebnissen ansehen, erhalten wir jetzt viele identische Ergebnisse, und die endgültige Reihenfolge ist in erster Linie auf die Reihenfolge zurückzuführen, in der sie indiziert wurden.
Hier kann das Hinzufügen eines bereichsspezifischen Bias nützlich sein. Wenn wir uns unser Schema ansehen, sehen wir die Felder views
und annualviews
, die angeben, wie viele Seitenaufrufe ein bestimmter Autor/Titel (in letzter Zeit) auf der ISFDB-Website erhalten hat. Indem wir diese Anzahl der Seitenaufrufe in unsere Bewertung einfließen lassen, sorgen wir für eine gewisse „Dokumentverzerrung“, um sicherzustellen, dass im Falle eines Gleichstands bei der grundlegenden Relevanzbewertung die populäreren Dokumente „gewinnen“ (d.h. mehr Punkte erhalten).
Die einfachste Möglichkeit, die Bewertung zu beeinflussen, ist der BoostQParser, der die Bewertung einer Abfrage für jedes Dokument mit einer beliebigen Funktion (für dieses Dokument) multipliziert. In seiner einfachsten Form können wir ihn direkt in unserem q
param verwenden, um die Scores mit der einfachen Summe der beiden „Views“-Felder zu multiplizieren: q={!boost b=sum(views,annualviews)}nightfall
und jetzt erhalten wir eine viel interessantere Reihenfolge…
- Titel: Nightfall SHORTFICTION – Autor: Isaac Asimov
- Titel: Nightfall NOVEL – Autoren: Robert Silverberg, Isaac Asimov
- Titel: Nightfall und andere Geschichten COLLECTION – Autor: Isaac Asimov
- Titel: Nightfall SHORTFICTION – Autor: Charles Stross
- Titel: Die Rückkehr: Nightfall NOVEL – Autor: L. J. Smith
- Titel: Nightfall SHORTFICTION – Autor: Arthur C. Clarke
- Titel: Nightfall SHORTFICTION – Autor: David Weber
- Titel: The Road to Nightfall COLLECTION – Autor: Robert Silverberg
- Titel: Die Legende von Nightfall NOVEL – Autor: Mickey Zucker Reichert
- Titel: Nightfall Revisited ESSAY – Autoren: Pat Murphy, Paul Doherty
Diese neue Reihenfolge für die Ergebnisse auf Seite 1 ist für den Bereich der ISFDB viel besser geeignet und entspricht einer allgemeinen Regel der Relevanzverzerrung: „Benutzer wollen in der Regel die populären Dinge sehen.“ Allerdings wollen die Benutzer in der Regel nicht Dinge wie {!boost b=sum(views,annualviews)}...
in das Suchfeld eingeben, also müssen wir dies in unserer Konfiguration kapseln. Mit Local Params ist das sehr einfach, aber leider bedeutet das, dass wir unseren „Haupt“-Abfrageparameter von q
in etwas anderes ändern müssen.
Wir beginnen damit, dass wir die defaults
und invariants
unseres Request Handlers so ändern, dass unsere Boost-Funktion immer als q
Parameter verwendet wird, aber einen neuen qq
Parameter als Hauptabfrage (deren Ergebnis mit der Funktion multipliziert wird) verwendet. Das funktioniert gut für unsere Standardabfrage, aber um nützlich zu sein , muss auch unsere Benutzeroberfläche geändert werden, damit sie weiß, dass der qq
Parameter jetzt für die Benutzereingabe verwendet wird.
Fazit (vorläufig)
Und damit ist diese neueste Ausgabe des blog_10-Tags abgeschlossen. Wir haben die Benutzerfreundlichkeit drastisch verbessert, indem wir die Berechnung der Relevanzwerte auf der Grundlage von Kenntnissen über unsere Domäne, insbesondere durch Document Biases, optimiert haben. In meinem nächsten Beitrag werde ich das Thema der Verbesserung der Benutzerfreundlichkeit fortsetzen, indem ich DisMax verwende, um „Field Biases“ hinzuzufügen.