wake-up-neo.com

Interpretieren der Summe von TF-IDF-Wortwerten in Dokumenten

Zuerst extrahieren wir die TF-IDF-Scores pro Begriff pro Dokument:

from gensim import corpora, models, similarities
documents = ["Human machine interface for lab abc computer applications",
              "A survey of user opinion of computer system response time",
              "The EPS user interface management system",
              "System and human system engineering testing of EPS",
              "Relation of user perceived response time to error measurement",
              "The generation of random binary unordered trees",
              "The intersection graph of paths in trees",
              "Graph minors IV Widths of trees and well quasi ordering",
              "Graph minors A survey"]
stoplist = set('for a of the and to in'.split())
texts = [[Word for Word in document.lower().split() if Word not in stoplist] for document in documents]
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]
tfidf = models.TfidfModel(corpus)
corpus_tfidf = tfidf[corpus]

Ausdrucken:

for doc in corpus_tfidf:
    print doc

[aus]:

[(0, 0.4301019571350565), (1, 0.4301019571350565), (2, 0.4301019571350565), (3, 0.4301019571350565), (4, 0.2944198962221451), (5, 0.2944198962221451), (6, 0.2944198962221451)]
[(4, 0.3726494271826947), (7, 0.27219160459794917), (8, 0.3726494271826947), (9, 0.27219160459794917), (10, 0.3726494271826947), (11, 0.5443832091958983), (12, 0.3726494271826947)]
[(6, 0.438482464916089), (7, 0.32027755044706185), (9, 0.32027755044706185), (13, 0.6405551008941237), (14, 0.438482464916089)]
[(5, 0.3449874408519962), (7, 0.5039733231394895), (14, 0.3449874408519962), (15, 0.5039733231394895), (16, 0.5039733231394895)]
[(9, 0.21953536176370683), (10, 0.30055933182961736), (12, 0.30055933182961736), (17, 0.43907072352741366), (18, 0.43907072352741366), (19, 0.43907072352741366), (20, 0.43907072352741366)]
[(21, 0.48507125007266594), (22, 0.48507125007266594), (23, 0.48507125007266594), (24, 0.48507125007266594), (25, 0.24253562503633297)]
[(25, 0.31622776601683794), (26, 0.31622776601683794), (27, 0.6324555320336759), (28, 0.6324555320336759)]
[(25, 0.20466057569885868), (26, 0.20466057569885868), (29, 0.2801947048062438), (30, 0.40932115139771735), (31, 0.40932115139771735), (32, 0.40932115139771735), (33, 0.40932115139771735), (34, 0.40932115139771735)]
[(8, 0.6282580468670046), (26, 0.45889394536615247), (29, 0.6282580468670046)]

Wenn wir die "Ausgefallenheit" oder "Wichtigkeit" der Wörter in diesem Korpus finden wollen, können wir einfach die Summe der tf-idf-Werte über alle Dokumente hinweg berechnen und durch die Anzahl der Dokumente teilen? d.

>>> tfidf_saliency = Counter()
>>> for doc in corpus_tfidf:
...     for Word, score in doc:
...         tfidf_saliency[Word] += score / len(corpus_tfidf)
... 
>>> tfidf_saliency
Counter({7: 0.12182694202050007, 8: 0.11121194156107769, 26: 0.10886469856464989, 29: 0.10093919463036093, 9: 0.09022272408985754, 14: 0.08705221175200946, 25: 0.08482488519466996, 6: 0.08143359568202602, 10: 0.07480097322359022, 12: 0.07480097322359022, 4: 0.07411881371164887, 13: 0.07117278898823597, 5: 0.07104525967490458, 27: 0.07027283689263066, 28: 0.07027283689263066, 11: 0.060487023243988705, 15: 0.055997035904387725, 16: 0.055997035904387725, 21: 0.05389680556362955, 22: 0.05389680556362955, 23: 0.05389680556362955, 24: 0.05389680556362955, 17: 0.048785635947490406, 18: 0.048785635947490406, 19: 0.048785635947490406, 20: 0.048785635947490406, 0: 0.04778910634833961, 1: 0.04778910634833961, 2: 0.04778910634833961, 3: 0.04778910634833961, 30: 0.045480127933079706, 31: 0.045480127933079706, 32: 0.045480127933079706, 33: 0.045480127933079706, 34: 0.045480127933079706})

Wenn wir uns die Ausgabe ansehen, können wir annehmen, dass das "prominenteste" Wort im Korpus ist:

>>> dictionary[7]
u'system'
>>> dictionary[8]
u'survey'
>>> dictionary[26]
u'graph'

Wenn ja, wie lautet die mathematische Interpretation der Summe der TF-IDF-Wortwerte in Dokumenten?

17
alvas

Die Interpretation von TF-IDF im Korpus ist die höchste TF-IDF im Korpus für einen gegebenen Begriff. 

Finden Sie die Top-Wörter in corpus_tfidf.

    topWords = {}
    for doc in corpus_tfidf:
        for iWord, tf_idf in doc:
            if iWord not in topWords:
                topWords[iWord] = 0

            if tf_idf > topWords[iWord]:
                topWords[iWord] = tf_idf

    for i, item in enumerate(sorted(topWords.items(), key=lambda x: x[1], reverse=True), 1):
        print("%2s: %-13s %s" % (i, dictionary[item[0]], item[1]))
        if i == 6: break

Ausgabevergleichskorb:
NOTE: Konnte gensim nicht verwenden, um eine passende dictionary mit corpus_tfidf zu erstellen.
Kann nur Word-Indizies anzeigen. 

Question tfidf_saliency   topWords(corpus_tfidf)  Other TF-IDF implentation  
---------------------------------------------------------------------------  
1: Word(7)   0.121        1: Word(13)    0.640    1: paths         0.376019  
2: Word(8)   0.111        2: Word(27)    0.632    2: intersection  0.376019  
3: Word(26)  0.108        3: Word(28)    0.632    3: survey        0.366204  
4: Word(29)  0.100        4: Word(8)     0.628    4: minors        0.366204  
5: Word(9)   0.090        5: Word(29)    0.628    5: binary        0.300815  
6: Word(14)  0.087        6: Word(11)    0.544    6: generation    0.300815  

Die Berechnung von TF-IDF berücksichtigt immer den Korpus. 

Mit Python getestet: 3.4.2

4
stovfl

Es gibt zwei Zusammenhänge, in denen die Ausprägung berechnet werden kann.

  1. verbundenheit im Korpus 
  2. ausprägung in einem einzigen Dokument

die Ausprägung des Korpus kann einfach durch Zählen der Erscheinungen eines bestimmten Wortes im Korpus oder durch Inversion der Zählung der Dokumente berechnet werden, in denen Word vorkommt (IDF = Inverted Document Frequency). Weil die Wörter, die die spezifische Bedeutung haben, nicht überall auftauchen.

die Ausprägung des Dokuments wird von tf_idf berechnet. Weil das aus zwei Arten von Informationen besteht. Globale Informationen (korpusbasiert) und lokale Informationen (dokumentenbasiert). Die Behauptung, dass "das Wort mit größerer Dokumentfrequenz im aktuellen Dokument wichtiger ist", ist nicht vollständig wahr oder falsch, da es von der globalen Bedeutung von Word abhängt. In einem bestimmten Dokument haben Sie viele Wörter wie "es ist, bin, sind ..." mit großen Frequenzen. Dieses Wort ist jedoch in keinem Dokument wichtig und Sie können es als Stoppwörter nehmen!

---- edit ---

Der Nenner (= len (corpus_tfidf)) ist ein konstanter Wert und kann ignoriert werden, wenn Sie eher mit der Ordinalität als mit der Kardinalität der Messung arbeiten möchten. Auf der anderen Seite wissen wir, dass IDF Inverted Document Freqeuncy bedeutet, sodass IDF um 1/DF wiedergegeben werden kann. Wir wissen, dass DF ein Corpus-Level-Wert ist und TF der Document-Level-Wert ist. TF-IDF Summation verwandelt TF auf Dokumentebene in TF auf Corpus-Ebene. In der Tat entspricht die Summe dieser Formel:

count (Word)/count (Dokumente enthalten Word)

Diese Messung kann als inverse Streuung -Wert bezeichnet werden. Wenn der Wert steigt, werden die Wörter in kleinere Untermengen von Dokumenten zusammengefasst und umgekehrt.

Ich glaube, dass diese Formel nicht so nützlich ist.

2
mhbashari

Das ist eine großartige Diskussion. Vielen Dank, dass Sie diesen Thread gestartet haben. Die Idee, die Dokumentlänge in @avip aufzunehmen, erscheint interessant. Muss experimentieren und die Ergebnisse überprüfen. Lassen Sie mich in der Zwischenzeit versuchen, die Frage etwas anders zu stellen. Was versuchen wir zu interpretieren, wenn wir nach TF-IDF-Relevanzwerten abfragen?

  1. Möglicherweise versuchen Sie, die Word-Relevanz auf Dokumentebene zu verstehen 
  2. Möglicherweise versuchen Sie, die Word-Relevanz pro Klasse zu verstehen
  3. Möglicherweise versuchen Sie, die Wortrelevanz insgesamt (im gesamten Corpus) zu verstehen.

     # # features, corpus = 6 documents of length 3
     counts = [[3, 0, 1],
               [2, 0, 0],
               [3, 0, 0],
               [4, 0, 0],
               [3, 2, 0],
               [3, 0, 2]]
     from sklearn.feature_extraction.text import TfidfTransformer
     transformer = TfidfTransformer(smooth_idf=False)
     tfidf = transformer.fit_transform(counts)
     print(tfidf.toarray())
    
     # lambda for basic stat computation
     summarizer_default = lambda x: np.sum(x, axis=0)
     summarizer_mean = lambda x: np.mean(x, axis=0)
    
     print(summarizer_default(tfidf))
     print(summarizer_mean(tfidf))
    

Ergebnis:

# Result post computing TF-IDF relevance scores
array([[ 0.81940995,  0.        ,  0.57320793],
           [ 1.        ,  0.        ,  0.        ],
           [ 1.        ,  0.        ,  0.        ],
           [ 1.        ,  0.        ,  0.        ],
           [ 0.47330339,  0.88089948,  0.        ],
           [ 0.58149261,  0.        ,  0.81355169]])

# Result post aggregation (Sum, Mean) 
[[ 4.87420595  0.88089948  1.38675962]]
[[ 0.81236766  0.14681658  0.2311266 ]]

Wenn wir genau beobachten, erkennen wir, dass das Feature1, das im gesamten Dokument aufgetreten ist, nicht vollständig ignoriert wird, da die sklearn-Implementierung von idf = log [n/df (d, t)] + 1 ist. Damit wird das wichtige Wort +1 hinzugefügt was in jedem Dokument passiert, wird nicht ignoriert. Z.B. Das Wort "Fahrrad" tritt sehr häufig auf, wenn ein bestimmtes Dokument als "Motorrad" (20-Newsgroup-Datensatz) klassifiziert wird.

  1. In Bezug auf die ersten beiden Fragen wird nun versucht, die wichtigsten allgemeinen Merkmale des Dokuments zu interpretieren und zu verstehen. In diesem Fall bedeutet das Aggregieren in irgendeiner Form, einschließlich aller möglichen Vorkommen des Wortes in einem Dokument, nicht einmal mathematisch etwas. IMO Eine solche Abfrage ist sehr nützlich, um das Dataset zu untersuchen und um zu verstehen, worum es beim Dataset geht. Die Logik kann auch auf die Vektorisierung mit Hashing angewendet werden.

    relevance_score = mean (tf (t, d) * idf (t, d)) = mean ((bias + inital_wt * F (t, d)/max {F (t ', d)}) * log ( N/df (d, t)) + 1))

  2. Die Frage 3 ist sehr wichtig, da sie möglicherweise auch dazu beiträgt, dass _ Features zum Erstellen eines Vorhersagemodells ausgewählt werden. Die alleinige Verwendung von TF-IDF-Scores für die Auswahl von Features kann auf mehreren Ebenen irreführend sein. Die Verwendung eines theoretischeren statistischen Tests wie „chi2“ -Paar mit TF-IDF-Relevanzwerten könnte ein besserer Ansatz sein. Ein solcher statistischer Test bewertet auch die Bedeutung des Merkmals in Bezug auf die jeweilige Zielklasse.

Die Kombination einer solchen Interpretation mit den erlernten Merkmalsgewichten des Modells wäre natürlich sehr hilfreich, um die Bedeutung von aus Text abgeleiteten Merkmalen vollständig zu verstehen.

** Das Problem ist etwas komplexer, um es im Detail zu behandeln. Aber zu hoffen, das oben genannte hilft. Was fühlen andere? 

Referenz: https://arxiv.org/abs/1707.05261

1
Pramit

Irgendwie bin ich auf dasselbe Problem gestoßen. Ich werde meine Lösung hier vorstellen, weiß aber nicht wirklich, wie effektiv sie ist.

Nach der Berechnung von tf-idf ähnelt das, was wir haben, einer Matrix aus Begriffen und Dokumenten.

[terms/docs : doc1  ,  doc2 , doc3..... docn
 term1      : tf(doc1)-idf, tf(doc2)-idf , tf(doc3)-idf.....
 .
 .
 .
 termn ........ ]

Wir können uns die Spalten doc1, doc2 ... docn als Punktzahlen vorstellen, die für jeden Begriff nach n verschiedenen Metriken vergeben werden. Wenn wir über die Spalten summieren, berechnen wir lediglich den Durchschnitt der Bewertungen, was naiv ist und die erfassten Informationen nicht vollständig wiedergibt. Wir können etwas Besseres tun, da dies ein Top-K-Abfrageproblem ist. Ein effizienter Algorithmus ist Fagins Algorithmus und arbeitet an dieser Idee:

Die sortierten Listen werden gescannt, bis k Datenelemente gefunden wurden, die in allen Listen gesehen wurden. Dann kann der Algorithmus anhalten und es wird garantiert, dass unter allen bisher gesehenen Datenelementen auch diejenigen vorhanden sind, die nicht in allen Listen vorhanden waren. Die Top-k-Datenelemente können gefunden werden.

Hier bedeuten sortierte Listen einfach, dass eine einzelne Spalte eines bestimmten Dokuments zu einer Liste wird, und wir haben n solche Listen. Also sortiere jeden von ihnen und mache dann Fagins drauf.

Lesen Sie mehr darüber hier

0
Siddhant Tandon

Wenn wir die "Ausprägung" oder "Wichtigkeit" der Wörter in .__ finden wollen. können wir einfach die Summe der tf-idf-Scores für alle Dokumente und teilen Sie es durch die Anzahl der Dokumente? Wenn ja, was ist das mathematische Interpretation der Summe der TF-IDF-Scores von Wörtern über Dokumente hinweg?

Wenn Sie die td-idf-Scores über Dokumente summieren, können Begriffe, die andernfalls niedrige Werte aufweisen würden, einen Schub erhalten, und bei Werten mit höheren Werten werden die Werte möglicherweise herabgesetzt.

Ich denke nicht, dass das einfache Teilen durch die Gesamtzahl der Dokumente eine Normalisierung sein wird, um dieses Problem anzugehen. Möglicherweise wird die Dokumentlänge in den Normalisierungsfaktor einbezogen. Ich denke, dass alle diese Methoden noch pro Domäne angepasst werden müssen. 

Im Allgemeinen rechne ich also mathematisch mit einem unerwünschten Mittelungseffekt.

0
avip