Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige Überarbeitung Vorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
talit:indexing [2024-09-02 11:53] – [Ranking] hoftalit:indexing [2025-11-11 06:22] (aktuell) – [Wortfrequenzen] hof
Zeile 1: Zeile 1:
 # Text Indexing # Text Indexing
  
-<nodisp 2>+<nodisp 1>
 ++++Repo| ++++Repo|
 https://github.com/tkilla77/ksr_talit_indexing/blob/main/04_text_indexing.ipynb https://github.com/tkilla77/ksr_talit_indexing/blob/main/04_text_indexing.ipynb
Zeile 20: Zeile 20:
  
 Anders als bei der Geodatenbank müssen wir hier noch den Text in einzelne Wörter (_en_. Tokens) zerlegen. Anders als bei der Geodatenbank müssen wir hier noch den Text in einzelne Wörter (_en_. Tokens) zerlegen.
- 
 ### Aufgabe 1 - Tokenizer ### Aufgabe 1 - Tokenizer
  
Zeile 46: Zeile 45:
 <code python> <code python>
 def query_index(index, query): def query_index(index, query):
-    result_set = set() 
     return index.get(query, set())     return index.get(query, set())
  
 query_index(toy_index, "James") query_index(toy_index, "James")
 </code> </code>
 +
 #### Fragen #### Fragen
   - Findet dein System einen Film über `'bond` (Kleinbuchstaben)?   - Findet dein System einen Film über `'bond` (Kleinbuchstaben)?
Zeile 107: Zeile 106:
  
 Grössere Datasets gibt es auf https://if.ksr.ch/talit/indexing (nur KSR-intern). Grössere Datasets gibt es auf https://if.ksr.ch/talit/indexing (nur KSR-intern).
- 
 ### Aufgabe 2 - Movie Index ### Aufgabe 2 - Movie Index
 Erstelle einen Index aller WP-Artikel über Filme von 1985. Schreibe dazu eine Generator-Funktion, um die WP-Artikel-Tupel aus dem ''.csv.zip'' zu yielden. Erstelle einen Index aller WP-Artikel über Filme von 1985. Schreibe dazu eine Generator-Funktion, um die WP-Artikel-Tupel aus dem ''.csv.zip'' zu yielden.
Zeile 120: Zeile 118:
         for url, text in reader:         for url, text in reader:
             yield url, text             yield url, text
 +
 +movie_index = build_text_index(read_movie_csv(filename))
 </code> </code>
 ++++ ++++
 </nodisp> </nodisp>
  
-Wieviele Filme mit `'harrison'` gibt es? Und wieviele mit einem `'delorean'`?+Wieviele Filme mit `'harrison'` gibt es? Und wieviele mit einem `'delorean'` 
 +?
 ## Stop Wording ## Stop Wording
 Wenn du den erstellten Index untersuchst, wirst du Wörter wie ''der'' oder ''ein'' finden, die in praktisch allen Artikeln vorkommen. Entsprechend benötigen die sehr viel Platz im Index, und liefern auch kaum interessante Resultate. Wenn du den erstellten Index untersuchst, wirst du Wörter wie ''der'' oder ''ein'' finden, die in praktisch allen Artikeln vorkommen. Entsprechend benötigen die sehr viel Platz im Index, und liefern auch kaum interessante Resultate.
  
 Normalerweise werden solche _Stop Words_ bereits bei der Indexierung ignoriert. Natürlich könnten wir eine Stop-Word-Liste aus dem Internet laden - aber eigentlich haben wir ja alle Informationen selber bereits zur Hand, um eine solche zu erstellen: Wir kennen die Häufigkeit jedes Wortes, also in wie vielen Artikeln es vorkommt. Wörter, die in mehr als der Hälfte der Artikel vorkommen, dürften kaum interessant sein. Mehr als an der _absoluten_ Häufigkeit sind wir also interessiert an der _relativen_ Dokumentenhäufigkeit (_en._ document frequency): $\frac{frequency}{n}$. Normalerweise werden solche _Stop Words_ bereits bei der Indexierung ignoriert. Natürlich könnten wir eine Stop-Word-Liste aus dem Internet laden - aber eigentlich haben wir ja alle Informationen selber bereits zur Hand, um eine solche zu erstellen: Wir kennen die Häufigkeit jedes Wortes, also in wie vielen Artikeln es vorkommt. Wörter, die in mehr als der Hälfte der Artikel vorkommen, dürften kaum interessant sein. Mehr als an der _absoluten_ Häufigkeit sind wir also interessiert an der _relativen_ Dokumentenhäufigkeit (_en._ document frequency): $\frac{frequency}{n}$.
- 
 ### Aufgabe 3 - Stop Words ### Aufgabe 3 - Stop Words
 Erstelle eine Liste aller Wörter in unserem Index, absteigend sortiert nach relativer Dokumentenhäufigkeit. Erstelle eine Liste aller Wörter in unserem Index, absteigend sortiert nach relativer Dokumentenhäufigkeit.
Zeile 141: Zeile 141:
 cutoff = 0.5 cutoff = 0.5
 freqs = [(word, len(docs) / n) for word, docs in movie_idx.items() if len(docs) / n > cutoff] freqs = [(word, len(docs) / n) for word, docs in movie_idx.items() if len(docs) / n > cutoff]
 +# Absteigend sortieren nach relativer Frequenz:
 import operator import operator
 freqs.sort(reverse=True, key=operator.itemgetter(1)) freqs.sort(reverse=True, key=operator.itemgetter(1))
Zeile 151: Zeile 152:
     import re     import re
     for token in re.findall("\w+", text):     for token in re.findall("\w+", text):
 +        token = token.lower()
         if not token in stop_words:         if not token in stop_words:
-            yield token.lower()+            yield token
          
 </code> </code>
 ++++ ++++
 </nodisp> </nodisp>
 +
 +
 ## Ranking ## Ranking
 Beim Information Retrieval geht es nicht nur darum, welche Dokumente zur Query passen, sondern welche _am besten_ dazu passen. Ranking ist eine komplexe und manchmal undurchsichtige Wissenschaft, die von vielen gegenläufigen Interessen getrieben ist: Beispielsweise möchten ganz viele Webseitenbetreiber zuoberst in den Suchresultaten von Google landen - andererseits möchten die Benutzer die wirklich relevante Webseite zuoberst haben. Und Google möchte irgendwie Geld verdienen, indem es die obersten Plätze verkauft. Beim Information Retrieval geht es nicht nur darum, welche Dokumente zur Query passen, sondern welche _am besten_ dazu passen. Ranking ist eine komplexe und manchmal undurchsichtige Wissenschaft, die von vielen gegenläufigen Interessen getrieben ist: Beispielsweise möchten ganz viele Webseitenbetreiber zuoberst in den Suchresultaten von Google landen - andererseits möchten die Benutzer die wirklich relevante Webseite zuoberst haben. Und Google möchte irgendwie Geld verdienen, indem es die obersten Plätze verkauft.
Zeile 162: Zeile 166:
 Nehmen wir folgendes Beispiel: Wir indexieren alle Film-Artikel der 1980er Jahre und wollen möglichst gute Suchresultate für folgende Queries: Nehmen wir folgendes Beispiel: Wir indexieren alle Film-Artikel der 1980er Jahre und wollen möglichst gute Suchresultate für folgende Queries:
   * ''michael fox delorean''   * ''michael fox delorean''
 +  * ''michael fox''
 +  * ''michael fox wortdasesnichtgibt''
  
 Unsere Query-Funktion muss erstens mit mehreren Wörtern umgehen können - es bietet sich an, die `tokenize` Funktion auch hier anzuwenden und eine Suchanfrage für jedes Token in der Query durchzuführen. Die Frage ist allerdings, wie wir die einzelnen Resultatlisten kombinieren...  Unsere Query-Funktion muss erstens mit mehreren Wörtern umgehen können - es bietet sich an, die `tokenize` Funktion auch hier anzuwenden und eine Suchanfrage für jedes Token in der Query durchzuführen. Die Frage ist allerdings, wie wir die einzelnen Resultatlisten kombinieren... 
Zeile 170: Zeile 176:
 Schreibe eine neue Query-Funktion, die mehrere Wörter kombinieren kann. Welche Kombinationsmethode wählst du? Schreibe eine neue Query-Funktion, die mehrere Wörter kombinieren kann. Welche Kombinationsmethode wählst du?
  
-<nodisp 2>+<nodisp 1>
 ++++Lösung| ++++Lösung|
  
Zeile 201: Zeile 207:
  
 Die Vereinigungsmenge hingegen liefert sehr viele Resultate für eine Query wie ''michael fox delorean''. Die Vereinigungsmenge hingegen liefert sehr viele Resultate für eine Query wie ''michael fox delorean''.
 +#### Wortfrequenzen
 +Zuerst werden die Document Frequencies in ein Dictionary überführt, das einfach auszulesen ist:
 +
 +<code python>
 +word_frequencies = {word: freq for word, freq in freqs}
 +
 +table = [['Term', 'Relative Document Frequency']]
 +for token in tokenize("michael fox delorean"):
 +    table.append([token, word_frequencies[token]])
 +
 +%pip install tabulate
 +from tabulate import tabulate
 +tabulate(table, headers="firstrow", floatfmt=".2%", tablefmt='html')
 +</code>
  
 #### Inverse Document Frequency #### Inverse Document Frequency
Zeile 247: Zeile 267:
 Statt eine strikte AND-Verknüpfung aller Suchterme möchten wir ein Ranking erstellen, das alle Dokumente einschliesst, die mindestens einen Suchterm enthält. Jeder Such-Begriff soll entsprechend seiner _Inverse-Document-Frequency_ (IDF) zum Rang beitragen. Das bedeutet, dass das Auftreten des seltenen Begriffs ''delorean'' mehr zum Rang beiträgt als ein häufiges Wort wie ''michael''. Trotzdem sollte ein einzelnes seltenes Wort nicht alles andere ausblenden dürfen. Statt eine strikte AND-Verknüpfung aller Suchterme möchten wir ein Ranking erstellen, das alle Dokumente einschliesst, die mindestens einen Suchterm enthält. Jeder Such-Begriff soll entsprechend seiner _Inverse-Document-Frequency_ (IDF) zum Rang beitragen. Das bedeutet, dass das Auftreten des seltenen Begriffs ''delorean'' mehr zum Rang beiträgt als ein häufiges Wort wie ''michael''. Trotzdem sollte ein einzelnes seltenes Wort nicht alles andere ausblenden dürfen.
  
-<nodisp 2>+<nodisp 1>
 ++++Lösung| ++++Lösung|
 <code python> <code python>
  • talit/indexing.1725277983.txt.gz
  • Zuletzt geändert: 2024-09-02 11:53
  • von hof