Blog der SHI GmbH

Solr Analysekette – Stemming

Solr findet Treffer anhand eines Suchbegriffs, wenn sich der Suchbegriff mittels festgelegter Analysekette in einen Term zerlegen oder transformieren lässt, der einem Element des Index entspricht. Die Elemente des Index laufen vor der Indexierung ebenfalls durch einen Analyseprozess durch.

Dieser Analyseprozess wird in der Konfigurationsdatei schema.xml für jeden Feldtypen definiert und beinhaltet genau einen Tokenizer und optional einen bis mehrere CharFilter und/oder TokenFilter.

In diesem Artikel möchte ich näher auf den TokenFilter angehen. In diesem Artikel möchte ich zeigen, wie man eine bestimmte Art TokenFilter definiert einbaut.

Die TokenFilter ermöglichen sogenanntes StemmingStemming ist ein Begriff aus der Sprachwissenschaft und bedeutet so viel wie die Reduzierung einer Vollform auf den Stamm dieses Wortes. Im weiter folgenden Beispiel wird dieser Prozess näher erläutert.

Jedes in einem Text vorkommende Wort ist prinzipiell eine Vollform. Nehmen wir die beiden Wörter „laufe“ und „gelaufen“. Es sind flektierte Formen des Verbs „laufen“. Dadurch, dass das „e“ in „laufe“ abgeschnitten wird, entsteht der Stamm des Worts, nämlich „lauf“. Bei „gelaufen“ sind zwei Schritte notwendig, um den Wortstamm zu bekommen. Das Suffix „en“ sowie das Präfix „ge“ müssen entfernt werden, um zum Stamm zu gelangen.

Warum ist dieses Thema für Apache Solr relevant?

Dieses Thema ist nicht nur für Solr, sondern für Suchtechnologie im Allgemeinen wichtig. Wenn ein Benutzer „Boote“ eingibt, möchte er dann wirklich nur Dokumente, in denen „Boote“ steht oder möchte er vielmehr auch Dokumente, in denen „Boot“ oder „Booten“ steht, finden? Letzteres ist wohl eher wahrscheinlich.

Einsatz von Stemming in Apache Solr

Daher ist es möglich in Solr Stemming-Algorithmen zu verwenden, die es einem ermöglichen, solche Szenarien zu berücksichtigen.

Einer in der Wissenschaft bekannter Algorithmus ist der sogenannte Porter-Stemmer-Algorithmus. Dieser ist bei Solr bereits out-of-the-box enthalten und kann sofort eingesetzt werden.

Folgender Quellcode-Ausschnitt zeigt, wie eine solche Einbindung von einem TokenFilter aussehen kann:

<fieldtype name="snowball" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
		<filter class="solr.LowerCaseFilterFactory"/>
		<filter class="solr.SnowballPorterFilterFactory" language="German2"/>
</analyzer>
</fieldtype>

Dieser Stemmer wird sprachspezifisch angewandt, d.h. wenn Sie in Ihrem Textfeld englische Inhalte haben, sollten Sie als Sprache auch Englisch angeben.

Es ist unbedingt ratsam die Analyseseite von Solr zur prototypischen Entwicklung des Feldtypen zur Rate zu ziehen. Mit dem Porter-Stemmer-Algorithmus ist es möglich akzeptable Ergebnisse zu erzielen. Jedoch wird es Fälle geben, in denen dieser Filter Sie im Stich lässt und keine zufriedenstellende Ergebnisse liefert. Dies ist vor allem im Deutschen recht einfach erläutert. Eine so stark flektierende Sprache wie das Deutsche, ist algorithmisch sehr schwer in den Griff zu bekommen. Folgendes Beispiel soll zur Veranschaulichung dienen:

Sollten „laufen“, „laufe“, „lief“, „liefen“, „gelaufen“ auf den gleichen Stamm reduziert werden? Sie alle stammen von ein und demselben Verb ab und unterscheiden sich nur in Zeit und/oder Person. Da es sich um ein unregelmäßiges Verb handelt, können „lief“ und „liefen“ nicht einfach auf „lauf“ reduziert werden. Und genau deswegen sollte man beim Einsatz linguistischer Mittel bei der Suche immer vorsichtig sein. Was anfangs wie eine gute Idee oder „Best Practice“ klingt, kann sich schnell zum Boomerang entwickeln.

Mit oben erwähntem Beispiel hat der Porter-Stemmer-Algorithmus auch die beschriebenen Probleme. Zusätzlich wird das Präfix „ge“ nicht von „gelaufen“ entfernt. Es ist jedoch möglich mit den Solr zugänglichen Bordmitteln Anpassungen in bestimmten Fällen vorzunehmen. Dazu verwendet man zusätzlich den StemmerOverrideFilterFactory nach dem Stemmer in der Analysekette:

<fieldtype name="snowball" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
		<filter class="solr.LowerCaseFilterFactory"/>
		<filter class="solr.SnowballPorterFilterFactory" language="German2"/>
                <filter class="solr.StemmerOverrideFilterFactory" dictionary="override.txt" ignoreCase="false"/>
</analyzer>
</fieldtype>

Alles was zudem noch notwendig ist, ist eine Textdatei (hier: override.txt), die pro Zeile eine Regel beinhaltet, die folgendermaßen aussehen muss: Das zu ersetzende Wort (z.B. „lief“) bildet den Anfang einer Zeile gefolgt von einem Tabspace, gefolgt von dem Stamm, zu dem es „reduziert“ werden soll (z.B. lauf). Also in etwa folgendermaßen:

gelauflauf
lieflauf

Andererseits kann es natürlich auch vorkommen, dass eine Regel „zu aggressiv“ für die Anwendung scheint. Auch für diesen Fall ist vorgesorgt:

<fieldtype name="snowball" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
		<filter class="solr.LowerCaseFilterFactory"/>
		<filter class="solr.SnowballPorterFilterFactory" language="German2"/>
                <filter class="solr.StemmerOverrideFilterFactory" dictionary="override.txt" ignoreCase="false"/>
	       <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
</analyzer>
</fieldtype>

Der KeyWordMarkerFilterFactory markiert alle in der Datei (hier: „protwords.txt“) befindlichen und bei der Indexierung bzw. Suche vorkommenden Wörter und somit werden sie vom Stemmer nicht berührt.

Fazit

Stemming ist ein spannendes Thema, da es höchst sprachabhängig ist, und noch lange kein algorithmisch gelöstes Problem der Sprachwissenschaft darstellt.

Daher sollte es in Suchlösungen mit Bedacht eingesetzt werden, denn es erhöht den Recall auf Kosten der Precision. Zudem ist es oft nicht von vornherein absehbar, was aus einem Eingabestring wird, wenn er das Stemming durchläuft.

Gebrauch machen sollte man auf jeden Fall von angepassten Regeln bzw. der Definition von Wörtern, die nicht behandelt werden sollen.

Weitere Anwendungsgebiete der Computerlinguistik, für die Stemming wichtig ist:

  • Maschinelle Übersetzung
  • Automatische Textzusammenfassung
  • Thesauruserstellung
In unseren Schulungen lernen Sie die modernen Features von Solr kennen, um eine performante Suchanwendung zu entwickeln. Interesse?

Markus Klose