Tout d’abord, extrayons les scores TF-IDF par terme et par document:
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]
L'imprimer:
for doc in corpus_tfidf:
print doc
[en dehors]:
[(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)]
Si nous voulons trouver la "pertinence" ou "l'importance" des mots dans ce corpus, pouvons-nous simplement faire la somme des scores tf-idf sur tous les documents et la diviser par le nombre de documents? C'est à dire.
>>> 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})
En regardant la sortie, pourrions-nous supposer que le mot le plus "important" dans le corpus est:
>>> dictionary[7]
u'system'
>>> dictionary[8]
u'survey'
>>> dictionary[26]
u'graph'
Si oui, quelle est l'interprétation mathématique de la somme des scores de mots TF-IDF sur les documents?
L'interprétation de TF-IDF dans un corpus est la plus haute TF-IDF dans un corpus pour un terme donné.
Trouvez les mots les plus populaires dans 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
Panier de comparaison de sortie:
NOTE: N'a pas pu utiliser gensim
pour créer une dictionary
correspondante avec corpus_tfidf
.
Ne peut afficher que les mots indiscrets.
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
Le calcul de TF-IDF prend toujours en compte le corpus.
Testé avec Python: 3.4.2
Il y a deux contextes dans lesquels la saillance peut être calculée.
la saillance dans le corpus peut simplement être calculée en comptant les apparences de Word particulier dans un corpus ou en inversant le comptage des documents dans lesquels Word apparaît (IDF = fréquence de document inversée). Parce que les mots qui tiennent le sens spécifique n'apparaissent pas partout.
la saillance dans le document est calculée par tf_idf. Parce que c'est composé de deux types d'informations. Informations globales (basées sur un corpus) et locales (sur un document) .Déclarer que "la fréquence dans le document plus importante est plus importante dans le document actuel" n'est pas complètement vrai ou faux, car il dépend de la pertinence globale de Word. Dans un document particulier, vous avez beaucoup de mots comme "ça, c'est, ça, c'est, ..." avec de grandes fréquences. Mais ces mots ne sont importants dans aucun document et vous pouvez les prendre comme des mots vides!
---- modifier ---
Le dénominateur (= len (corpus_tfidf)) est une valeur constante et peut être ignoré si vous souhaitez traiter l'ordinalité plutôt que la cardinalité de la mesure. D'autre part, nous savons que IDF signifie Inverted Document Freqeuncy (Fréquences de documents inversés) de sorte que IDF puisse être rappelé par 1/DF. Nous savons que le DF est une valeur de niveau de corpus et que TF est une valeur de niveau de document. La synthèse TF-IDF transforme une TF au niveau document en une TF au niveau corpus. En effet la somme est égale à cette formule:
count ( Word )/count (les documents contiennent Word )
Cette mesure peut être appelée diffusion inverse valeur. Lorsque la valeur augmente, les mots sont rassemblés dans un sous-ensemble de documents plus petit et inversement.
Je crois que cette formule n'est pas si utile.
C'est une bonne discussion. Merci d'avoir commencé ce fil. L'idée d'inclure la longueur du document par @avip semble intéressante. Devront expérimenter et vérifier les résultats. En attendant, laissez-moi essayer de poser la question un peu différemment. Qu'essayons-nous d'interpréter lorsque nous demandons des scores de pertinence TF-IDF?
Peut-être essayer de comprendre la pertinence globale de Word (dans l'ensemble Corpus)
# # 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))
Résultat:
# 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 ]]
Si nous observons de près, nous nous rendons compte que la caractéristique 1 qui s’est produite dans tout le document n’est pas complètement ignorée, car l’implémentation en clair de idf = log [n/df (d, t)] + 1. ce qui arrive dans tous les documents n'est pas ignoré. Par exemple. le mot "vélo" apparaît très fréquemment lors de la classification d'un document particulier comme "motocyclette" (ensemble de données 20_newsgroup).
En ce qui concerne les deux premières questions, on essaie d’interpréter et de comprendre les principales caractéristiques communes du document. Dans ce cas, regrouper sous une forme quelconque incluant toutes les occurrences possibles du mot dans un document n'enlève rien, même mathématiquement. Une telle requête de l'OMI est très utile pour explorer l'ensemble de données et aider à comprendre de quoi il s'agit. La logique peut également être appliquée à la vectorisation à l'aide du hachage.
pertinence_score = moyenne (tf (t, d) * idf (t, d)) = moyenne ((biais + inital_wt * F (t, d)/max {F (t ', d)}) * log ( N/df (d, t)) + 1))
La question 3 est très importante dans la mesure où elle pourrait aussi contribuer aux caractéristiques sélectionnées pour la construction d’un modèle prédictif. Le fait d’utiliser des scores TF-IDF indépendamment pour la sélection des fonctionnalités peut être trompeur à plusieurs niveaux. L'adoption d'un test statistique plus théorique tel que le couple 'chi2' avec les scores de pertinence TF-IDF pourrait constituer une meilleure approche. Ce test statistique évalue également l’importance de la caractéristique par rapport à la classe cible respective.
Et bien sûr, combiner une telle interprétation avec les poids de caractéristiques appris par le modèle serait très utile pour comprendre complètement l’importance des caractéristiques dérivées du texte.
** Le problème est un peu plus complexe à couvrir en détail ici. Mais, en espérant que ce qui précède aide. Que ressentent les autres?
Référence: https://arxiv.org/abs/1707.05261
Si nous voulons trouver la "saillance" ou "l'importance" des mots dans ce corpus, pouvons-nous simplement faire la somme des scores tf-idf sur tous documents et diviser par le nombre de documents? Si oui, quelle est la interprétation mathématique de la somme des scores de mots TF-IDF à travers les documents?
Si vous faites la somme des scores td-idf pour tous les documents, les termes qui auraient sinon des scores bas pourraient être boostés et les termes avec des scores plus élevés pourraient voir leurs scores déprimés.
Je ne pense pas qu'une simple division par le nombre total de documents suffira à normaliser le problème. Peut-être incorporer la longueur du document dans le facteur de normalisation? Quoi qu'il en soit, je pense que toutes ces méthodes devraient encore être ajustées par domaine.
Donc, généralement, mathématiquement, je suppose que vous obtiendrez un effet de moyennage indésirable.