Posts mit dem Label SCORE werden angezeigt. Alle Posts anzeigen
Posts mit dem Label SCORE werden angezeigt. Alle Posts anzeigen

Freitag, 20. August 2010

Anwendungsbeispiel für MULTI_COLUMN_DATASTORE, MDATA und Operatoren ACCUM und WEIGHT

Ist es möglich Dokumenten unterschiedlichen Formats (Dateityps) eine unterschiedliche Gewichtung zu geben? Beispielsweise ist die Vorgabe, dass Dokumente im Format PDF eine höhere Gewichtung erhalten sollen als Dokumente im Format HTML. Mit MULTI_COLUMN_DATASTORE, MDATA und den unterschiedlichen Operatoren wie ACCUM und WEIGHT kann dies möglich gemacht werden. Mehr Informationen zur MDATA-Nutzung und Multicolumn-Datastore finden Sie übrigens im Metadatensuche mit MDATA und im MData Section und MULTI_COLUMN_DATASTORE Blog.
Nehmen wir im folgenden Beispiel die Tabelle DOCUMENTS mit Spalten INHALT und DATEI_TYP.

CREATE TABLE documents
(id NUMBER, datei_typ VARCHAR2(10), INHALT blob);

Danach füllen wir die Tabelle mit unterschiedlichen Inhalten. Wir verwenden eine LOBLOAD-Prozedur, die die Spalteninhalte als Parameter übergibt. Der Dateiname gibt dabei Auskunft über den Inhalt und das Format.

execute lobload(1,'html','inhalt1.html')
execute lobload(2, 'html','inhalt2.html');
execute lobload(3,'PDF','inhalt1.PDF');
execute lobload(4,'PDF','inhalt2.PDF');

Danach erzeugen wir einen Multicolumn-Datastore über die beiden Spalten DATEI_TYP und INHALT, um eine einzige CONTAINS- Abfrage über die beiden Spalten durchzuführen. Um den Multicolumn-Datastore nutzen zu können, muss zunächst eine Preference erzeugt werden; hier werden die Spalten, welche gemeinsam indiziert werden sollen, konfiguriert. Da nur die Spalte INHALT und nicht die Spalte DATEI_TYP gefiltert werden soll, setzen wir die FILTER-Attribute auf 'N,Y'.

begin
ctx_ddl.create_preference('mds', 'multi_column_datastore');
ctx_ddl.set_attribute('mds', 'columns', 'datei_typ, inhalt');
ctx_ddl.set_attribute('mds', 'filter', 'N,Y');
end;
/

Die Spalten sind nun im Multicolumn-Datastore MDS zusammengeführt. Da die Spalte DATEI_TYP als Metadatenspalte aufgefasst werden kann und keine Aufarbeitung in Tokens benötigt, definieren wir die entsprechende MDATA-Section für DATEI_TYP.

begin 
ctx_ddl.create_section_group('bsg', 'basic_section_group');
ctx_ddl.add_mdata_section('bsg', 'datei_typ', 'datei_typ');
end;
/

Im letzten Schritt erzeugen wir noch den Index IDX auf die Spalte INHALT.

SQL> CREATE INDEX idx ON documents(inhalt) INDEXTYPE IS ctxsys.context 
     PARAMETERS ('section group bsg datastore mds filter ctxsys.auto_filter');
Index created.
SQL> SELECT err_index_name, err_timestamp, err_textkey, err_text
     FROM ctx_user_index_errors ORDER BY err_index_name, err_timestamp;
no rows selected

Überprüfen wir nun die Dokumente auf einen Inhalt zum Beispiel auf "external". Die Dokumente mit ID 1 und 3 enthalten offensichtlich das gesuchte Token.

SQL> SELECT score(1), id, datei_typ 
     FROM documents WHERE contains(inhalt, 'external', 1)>0;

   SCORE(1)         ID DATEI_TYP
---------- ---------- ----------
        12          1 html
        12          3 PDF


Im nächsten Schritt sollen PDF-Dokumente eine höhere Priorität als HTML-Dokumente erhalten. Dazu nutzen wir den Operator MDATA. Zu beachten ist dabei, dass MDATA Sektionen immer case-sensitiv sind. Das bedeutet wir müssen auf "PDF" und "html" abfragen. Zusätzlich liefert das Ergebnis des MDATA-Operators immer den Wert 0 für "keine Treffer" und 100 für "Treffer". Überprüfen wir zuerst das Scoring auf PDF-Formate . Dokument 3 und 4 sind PDF Dokumente und erhalten den Score 100.

SQL> SELECT score(1), id, datei_typ FROM documents 
     WHERE contains(inhalt, 'mdata(datei_typ, PDF)', 1)>0;
  SCORE(1)         ID DATEI_TYP
---------- ---------- ----------
       100          3 PDF
       100          4 PDF

Benutzen wir zusätzlich die Suchabfrage "external" und verbinden wir das Ganze mit dem ACCUM- Operator (hier mit Komma ','). Wir erhalten nun alle PDF-Dokumente und das HTML-Dokument mit dem entsprechenden Suchwort. Dann sieht das Ergebnis der Abfrage folgendermassen aus.

SQL> SELECT score(1), id, datei_typ FROM documents 
     WHERE contains(inhalt, 'mdata(datei_typ, PDF), external', 1)>0
     ORDER BY 1;
 SCORE(1)         ID DATEI_TYP
---------- ---------- ----------
         6          1 html
        50          4 PDF
        78          3 PDF

Wie arbeitet dabei der Operator ACCUM? Der Operator ACCUM sucht im ersten Schritt nach erfolgreichen Bedingungen und errechnet danach den Score aus der Anzahl der Treffer-Häufigkeit. Bei zwei Bedingungen und Treffer in den beiden Bedingungen (hier PDF und Suchwort) liegt dabei der Scorewert zwischen 51 und 100, ansonsten zwischen 1 und 50.
Um weitere Möglichkeiten aufzuzeigen, kombinieren wir die Abfrage mit einer zusätzlichen Gewichtung (in unserem Fall mit "*2") und nehmen zusätzlich das Format "html" hinzu. Nun können wir folgende Resultate erhalten.

SQL> SELECT score(1), id, datei_typ FROM documents 
     WHERE contains(inhalt, 'mdata(datei_typ, PDF)*2, mdata(datei_typ, html),    
     external', 1)>0 ORDER BY 1;
 SCORE(1)         ID DATEI_TYP
---------- ---------- ----------
        25          2 html
        39          1 html
        50          4 PDF
        68          3 PDF

SQL> SELECT score(1), id, datei_typ FROM documents 
     WHERE contains(inhalt, 'mdata(datei_typ, PDF)*2, mdata(datei_typ, html), 
     external*2', 1)>0 ORDER BY 1;

  SCORE(1)         ID DATEI_TYP
---------- ---------- ----------
        20          2 html
        40          4 PDF
        48          1 html
        71          3 PDF

Wie man im letzten Beispiel sehen kann, gibt es eine Vielfalt von möglichen Kombinationen. Probieren Sie es einfach aus...

Montag, 22. Juni 2009

Wie ähnlich soll es sein ...? Ein paar Worte zum FUZZY-Operator

Es ist weitgehend bekannt, dass Oracle TEXT eine Ähnlichkeitssuche mit dem Fuzzy-Operator unterstützt. Die einfachste Variante ist die Verwendung des Fragezeichens ?. Der Fuzzy-Operator ist gut geeignet, um mit etwaigen Rechtschreibfehlern in den Dokumenten umzugehen. Sucht man bspw. nach ?Spatial, so findet der Index auch Dokumente, in denen fälschlicherweise "Sptial" geschrieben wurde.
select dateiname, score(0) from dokumente where contains (content, '?Spatial', 0) > 0
Diese Ähnlichkeitssuche kann übrigens auch parametrisiert werden: Neben dem Fragezeichen steht auch das Schlüsselwort FUZZY zur Verfügung. Oder anders ausgedrückt: Obige SQL-Abfrage ließe sich auch so schreiben:
select dateiname, score(0) from dokumente where contains (content, 'FUZZY(Spatial, 60, 100, N)'), 0) > 0
Und mit diesen Parametern kann man das Verhalten des FUZZY-Operators nun steuern. Der erste Parameter legt fest, wie ähnlich die Tokens im Dokument dem Suchbegriff sein müssen. Erlaubt sind Werte von 1 bis 80. Je niedriger Ihr den Wert ansetzt, desto mehr Begriffe kommen in Frage; desto mehr Dokumente werden also gefunden. Allerdings stellt sich die Frage, wie relevant die Dokumente bei sehr niedrigen Grenzen noch sind.
Der zweite Parameter legt fest, wieviele Werte überhaupt in die Termexpansion einbezogen werden. Dazu kurz einige Worte: Oracle TEXT führt die Fuzzy-Suche über eine Termexpansion durch; es werden also zunächst aus der Token-Tabelle ($I) die ähnlichen Tokens herausgesucht (der erste Parameter legt, wie gesagt, fest, wie ähnlich die Tokens sein müssen). Mit den so gefundenen Tokens wird dann eine ODER Suche durchgeführt.
Mit dem zweiten Parameter legt man also fest, wieviele ähnliche Wörter maximal einbezogen werden sollen. Erlaubt sind Werte zwischen 1 und 5000. Ein Wert von 20 würde bewirken, dass maximal 20 ähnliche Wörter in der Suche berücksichtigt werden, auch wenn anhand des ersten Parameters mehr in Frage kämen. Hier gilt also: Je höher der Wert gesetzt wird, desto mehr Dokumente werden tendenziell gefunden ...
Der letzte Parameter wirkt sich nur auf den Score aus, den ein Dokument im Relevanz-Ranking bekommt. Mit einem W werden die Scores anhand der Ähnlichkeit der Suchwörter gewichtet; mit einem N geschieht das nicht. Ein W führt zu tendenziell höheren Scores.
Mit diesen Parametern könnt Ihr also spielen, um mit der Fuzzy-Suche mehr oder weniger Ergebnisse zu bekommen. Was konkret gebraucht wird, hängt von den Anforderungen des Projekts ab ... zur Verdeutlichung hier nochmals zwei Extrembeispiele. Das erste ist zwar "formal" eine Ähnlichkeitssuche, aber die Parameter "würgen" die Fuzzy-Logik weitgehend ab.
select dateiname, score(0) from dokumente 
where contains(content, 'fuzzy(sptial, 80, 1, W)',0) > 0;
Das zweite bohrt die Grenzen so weit auf, dass sehr viele Dokumente in Frage kommen ...
select dateiname, score(0) from dokumente 
where contains(content, 'fuzzy(sptial, 1, 5000, W)',0) > 0;
Dies lässt sich auch sehr gut mit Query Relaxation verbinden. In einer ersten Stufe würde ohne den Fuzzy-Operator suchen, in einer nächsten Stufe dann mit dem Fuzzy-Operator, aber eher restriktiven Kriterien und danach mit sehr weit gehenden Parametern. Query Relaxation arbeitet die Stufen dann bekanntlich so lange ab, bis genügend Treffer gefunden sind - mehr dazu im Blog Posting.

Dienstag, 24. Juni 2008

Scoring mit Oracle Text

Wie schon im ersten Blog angedeutet gibt es die unterschiedlichsten Arten, Oracle Text zu nutzen. Es können z.B. linguistische Suchen, Mustersuchen, Suchen mit Booleschen Operatoren, Abschnittssuchen bei XML und HTML-Formaten durchgeführt werden. Um dabei die Suchqualität zu erhöhen, wird zusätzlich die Technik des Relevanz Rankings genutzt. Im Folgenden wollen wir das Oracle Text Scoring (Ranking) Verhalten untersuchen und die neueste Entwicklung in 11g illustrieren. Folgende Beispiel-Tabelle wird als Grundlage genutzt:

SQL> SELECT * FROM texttabelle;

 ID DOKUMENT
--- ---------------------------------------------------------------------------
  1 Politik: A-Partei gewinnt Wahl in Hansestadt
  2 Politik: Terror in Nahost: Kriminalität steigt immer weiter an
  3 Wirtschaft: Erneuter Gewinnzuwachs in diesem Jahr
  4 Sport: Olympia rückt näher: Der Fackellauf ist in vollem Gange
  5 Politik: Wer wird US-Präsident? Obama und Clinton machen Wahlkampf
  6 Religion: Papst bestürzt über jüngsten Skandal!
  7 Politik: Wahlkampf in den USA geht weiter:  Clinton und Obama LIVE zu sehen
  8 Karriere: Software-Kenntnisse werden immer wichtiger
  9 Politik: Umfrage:  Alle wollen mehr Geld!
 10 Religion: Der Papst liest seine erste Messe in den USA!
 11 Wirtschaft: Muppet-Show der Steuerversprecher
 12 Politik: Bahn-Aufsichtsrat macht Weg frei für Börsengang
 13 Wissenschaft: Europäer im All
 14 Sport: EM-Gegner Türkei: Torwart Volkan bleibt gesperrt
 15 Sport: EM-Gastgeber Österreich: Trainer Hickersberger hört auf
 16 Sport: Deutschland-Gegner Türkei: Chaos als Prinzip
 17 Sport: Türkei-Spieler Altintop: "Ich habe Deutschland alles zu verdanken"
 18 Sport: Euro-Helden: Die größten Stars der EM-Geschichte
 19 Sport: WIMBLEDON Federer mühelos, Kohlschreiber enttäuscht
 20 Sport: Sport bleibt Sport!

20 rows selected.

Um ein Ranking (Scoring) für Dokumente in einer Abfrage zu erhalten, nutzt Oracle Text standardmäßig den inversen Häufigkeits-Algorithmus basierend auf Salton. Scoring nach der inversen Dokumenthäufigkeit bedeutet, dass häufiges Vorkommen eines Begriffes in Dokumenten zu einem niedrigen Scoringwert führt. Damit der Scoringfaktor hoch ist, muss ein Begriff zwar häufig im Dokument selbst, allerdings zusätzlich selten in allen Dokumenten insgesamt vorkommen. Im Handbuch Oracle® Text Reference 11g Release 1 (11.1) im Appendix F wird der Algorithmus am Beispiel erklärt. Um Relevanz-bezogene Abfragen auf Ergebnislisten durchzuführen, wird der Operator SCORE verwendet. Dabei kann auch eine Gewichtung durchgeführt werden, um das Ergebnis zu beeinflussen. Folgende Beispiele illustrieren die Gewichtung und den Einsatz des SCORE Operators: Es wird nach Dokumenten gesucht die den Suchbegriff 'Sport' oder 'Türkei' enthalten - sortiert nach ihrer Relevanz. Das Ergebnis sieht dann folgendermassen aus:

SQL> SELECT dokument, score(1) AS s FROM texttabelle
     WHERE contains(dokument, 'Sport or Türkei',1)>0
     ORDER BY score(1) DESC;

DOKUMENT                                                                      S
--------------------------------------------------------------------------- ---
Sport: Sport bleibt Sport!                                                   19
Sport: Olympia rückt näher: Der Fackellauf ist in vollem Gange                6
Sport: EM-Gegner Türkei: Torwart Volkan bleibt gesperrt                       6
Sport: EM-Gastgeber Österreich: Trainer Hickersberger hört auf                6
Sport: Deutschland-Gegner Türkei: Chaos als Prinzip                           6
Sport: Türkei-Spieler Altintop: "Ich habe Deutschland alles zu verdanken"     6
Sport: Euro-Helden: Die größten Stars der EM-Geschichte                       6
Sport: WIMBLEDON Federer mühelos, Kohlschreiber enttäuscht                    6

8 rows selected.

Gewichtet man den Suchbegriff 'Türkei', ändert sich der entsprechende Scoringwert und die Reihenfolge.

SQL> SELECT dokument, score(1) as s FROM texttabelle
     WHERE contains(dokument, 'Sport or Türkei*5',1)>0
     ORDER BY score(1) DESC
DOKUMENT                                                                      S
--------------------------------------------------------------------------- ---
Sport: EM-Gegner Türkei: Torwart Volkan bleibt gesperrt                      32
Sport: Deutschland-Gegner Türkei: Chaos als Prinzip                          32
Sport: Türkei-Spieler Altintop: "Ich habe Deutschland alles zu verdanken"    32
Sport: Sport bleibt Sport!                                                   19
Sport: Olympia rückt näher: Der Fackellauf ist in vollem Gange                6
Sport: EM-Gastgeber Österreich: Trainer Hickersberger hört auf                6
Sport: Euro-Helden: Die größten Stars der EM-Geschichte                       6
Sport: WIMBLEDON Federer mühelos, Kohlschreiber enttäuscht                    6

Wem diese Möglichkeiten des Rankings nicht ausreichen, kann in Oracle Database 11g die Möglichkeit nutzen, das Scoring weiter zu beeinflussen bzw. im Rahmen bestimmter Funktionen selbst zu definieren. Dazu stehen die neuen Operatoren DEFINESCORE und DEFINEMERGE zur Verfügung. Dem Suchbegriff können folgende Scoring-Ausdrücke und Funktionen zugeordnet werden:
  • DISCRETE: Term vorhanden 100, falls nicht 0
  • OCCURRENCE: Anzahl der Vorkommen
  • RELEVANCE: Standard-Relevanz-Ranking
  • COMPLETION: Ratio für Section Suche: Anzahl der der Treffer zu Anzahl aller Ausdrücke
  • IGNORE: Scoring des Terms ignorieren
  • LOG,ABS und Rechenoperationen
  • () für Gruppierung
  • Folgende Beispiele demonstrieren die Verwendung:
    
    SQL> SELECT dokument, score(1) as s
         FROM texttabelle
         WHERE contains(dokument,'DEFINESCORE(Sport, occurrence)', 1) >0
         ORDER BY score(1);
    
    DOKUMENT                                                                       S
    --------------------------------------------------------------------------- ----
    Sport: Olympia rückt näher: Der Fackellauf ist in vollem Gange                 1
    Sport: EM-Gegner Türkei: Torwart Volkan bleibt gesperrt                        1
    Sport: EM-Gastgeber Österreich: Trainer Hickersberger hört auf                 1
    Sport: Deutschland-Gegner Türkei: Chaos als Prinzip                            1
    Sport: Türkei-Spieler Altintop: "Ich habe Deutschland alles zu verdanken"      1
    Sport: Euro-Helden: Die größten Stars der EM-Geschichte                        1
    Sport: WIMBLEDON Federer mühelos, Kohlschreiber enttäuscht                     1
    Sport: Sport bleibt Sport!                                                     3
    
    8 rows selected.
    
    
    
    Die Scoring-Ausdrücke lassen sich auch hier gewichten, wie das nächste Beispiel zeigt:
    
    SQL> SELECT dokument, score(1) as s
         FROM  texttabelle
         WHERE contains(dokument,'DEFINESCORE(Sport, relevance*5)',1) >0
         ORDER BY score(1);
    
    DOKUMENT                                                                       S
    --------------------------------------------------------------------------- ----
    Sport: Olympia rückt näher: Der Fackellauf ist in vollem Gange                24
    Sport: EM-Gegner Türkei: Torwart Volkan bleibt gesperrt                       24
    Sport: EM-Gastgeber Österreich: Trainer Hickersberger hört auf                24
    Sport: Deutschland-Gegner Türkei: Chaos als Prinzip                           24
    Sport: Türkei-Spieler Altintop: "Ich habe Deutschland alles zu verdanken"     24
    Sport: Euro-Helden: Die größten Stars der EM-Geschichte                       24
    Sport: WIMBLEDON Federer mühelos, Kohlschreiber enttäuscht                    24
    Sport: Sport bleibt Sport!                                                    72
    
    8 rows selected.
    
    
    Möchte man die Scoring Algorithmen miteinander verbinden, ist dies mit dem AND und OR Operator in Kombination mit dem neuen DEFINEMERGE-Operator möglich. Das Scoring Endresultat wird dann über eine MERGE Methode wie AVG, ADD, MIN oder MAX bestimmt. Folgendes Beispiel zeigt die Verwendung:
    
    SQL> SELECT dokument, score(1) as s
         FROM texttabelle
         WHERE contains(dokument,'DEFINEMERGE(
    ((DEFINESCORE(Sport,occurrence)),(DEFINESCORE(Sport, relevance*5))),AND,MAX)',1) >0;
    
    DOKUMENT                                                                       S
    --------------------------------------------------------------------------- ----
    Sport: Olympia rückt näher: Der Fackellauf ist in vollem Gange                24
    Sport: EM-Gegner Türkei: Torwart Volkan bleibt gesperrt                       24
    Sport: EM-Gastgeber Österreich: Trainer Hickersberger hört auf                24
    Sport: Deutschland-Gegner Türkei: Chaos als Prinzip                           24
    Sport: Türkei-Spieler Altintop: "Ich habe Deutschland alles zu verdanken"     24
    Sport: Euro-Helden: Die größten Stars der EM-Geschichte                       24
    Sport: WIMBLEDON Federer mühelos, Kohlschreiber enttäuscht                    24
    Sport: Sport bleibt Sport!                                                    72
    
    
    Am besten probiert man das Ganze einfach einmal aus ...

    Beliebte Postings