解释文档中单词的TF-IDF分数之和

时间:2017-02-16 09:06:15

标签: python statistics nlp tf-idf gensim

首先,让每个文档每个术语提取TF-IDF分数:

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]

打印出来:

for doc in corpus_tfidf:
    print doc

[OUT]:

[(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)]

如果我们想要查找此语料库中单词的“显着性”或“重要性”,我们可以简单地对所有文档中的tf-idf分数求和,并将其除以文档数量吗?

>>> 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})

观察输出,我们可以假设语料库中最“突出”的词是:

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

如果是这样,文件中单词的TF-IDF分数总和的数学解释是什么?

5 个答案:

答案 0 :(得分:5)

语料库中TF-IDF的解释是给定术语中语料库中最高的TF-IDF。

查找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

输出比较车:
注意:无法使用gensim,与dictionary创建匹配的corpus_tfidf
 只能显示Word Indizies。

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  

TF-IDF的计算总是考虑到语料库。

使用Python测试:3.4.2

答案 1 :(得分:2)

有两种情况可以计算出显着性。

  1. 语料库中的显着性
  2. 单个文档中的显着性
  3. 语料库中的显着性可以通过计算语料库中特定单词的出现或通过对单词出现的文档(IDF =倒置文档频率)的计数的倒数来计算。因为具有特定含义的词语并未出现在任何地方。

    文档中的显着性由tf_idf计算。因为那是由两种信息组成的。全局信息(基于语料库)和本地信息(基于文档)。声称“文档中频率较大的单词在当前文档中更重要”并不完全正确或错误,因为它取决于单词的全局显着性。在一个特定的文档中,你有很多像“it,is,am,are,...”这样的词,频率很高。但是这些词在任何文件中都不重要,你可以把它们作为停用词!

    ----编辑---

    分母(= len(corpus_tfidf))是一个常数值,如果你想处理普通性而不是测量的基数,可以忽略它。另一方面,我们知道IDF意味着Inverted Document Freqeuncy,因此IDF可以通过1 / DF重新发送。我们知道DF是语料库级别值,TF是文档级别值。 TF-IDF Summation将文档级TF转换为语料库级TF。实际上总和等于这个公式:

    count( word )/ count(文档包含 word

    此测量可称为反向散射值。当值上升意味着单词被收集到较小的文档子集中,反之亦然。

    我相信这个公式不太有用。

答案 2 :(得分:2)

这是一个很好的讨论。感谢您启动此线程。通过@avip包含文档长度的想法似乎很有趣。将不得不试验和检查结果。在此期间,让我尝试稍微改变一下这个问题。在查询TF-IDF相关性分数时,我们试图解释什么?

  1. 可能试图理解文档级别的相关性一词
  2. 可能试图理解每个班级的相关性
  3. 可能试图理解整体上的相关性这个词 语料库)

     # # 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))
    
  4. 结果:

    # 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 ]]
    

    如果我们仔细观察,我们会发现所有文件中发生的feature1巫婆都没有被完全忽略,因为添加了idf = log [n / df(d,t)] + 1 + 1的sklearn实现,以便在所有文件中恰好发生的重要词语不会被忽略。例如。单词' bike'在将特定文件归类为' motorcyle' (20_newsgroup数据集)。

    1. 现在关于前两个问题,一个是试图解释和理解文档中可能出现的最常见的功能。在这种情况下,以某种形式聚合,包括文档中所有可能出现的单词,即使在数学上也不会带走任何东西。 IMO这样的查询非常有用,可以探索数据集并帮助理解数据集的内容。该逻辑也可以应用于使用哈希进行矢量化。

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

    2. 问题3非常重要,因为它可能有助于 选择用于构建预测模型的特征。仅仅使用TF-IDF分数进行特征选择可能会在多个层面上产生误导。采用更理论的统计测试,例如' chi2'加上TF-IDF相关性分数可能是一种更好的方法。此类统计测试还评估该特征相对于相应目标类别的重要性。

    3. 当然,将这种解释与模型的学习特征权重相结合,对于完全理解文本派生特征的重要性非常有帮助。

      **这里要详细介绍这个问题。但是,希望以上有所帮助。别人有什么感受?

      参考:https://arxiv.org/abs/1707.05261

答案 3 :(得分:0)

我偶然发现了同样的问题。我将在这里分享我的解决方案,但我真的不知道它的有效性。

基本上,在计算tf-idf之后,我们所拥有的就像术语和文档的矩阵。

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

我们可以将doc1,doc2 ... docn列视为根据n个不同指标为每个术语赋予的分数。如果我们对各列求和,我们只是对分数进行平均,这是一种幼稚的方式,并不完全代表捕获的信息。我们可以做得更好,因为这是top-k检索问题。一种有效的算法是Fagin的算法,它可以解决这个问题:

扫描已排序的列表,直到找到k个数据项为止。 在所有列表中都可以看到,则算法可以停止,并且可以确保 到目前为止看到的所有数据项,即使不是所有列表中都存在的数据项, 可以找到前k个数据项。

这里的排序列表仅表示特定文档的单个列成为列表,而我们有n个这样的列表。因此,对它们中的每一个进行排序,然后对其进行细化。

详细了解here

答案 4 :(得分:-1)

  

如果我们想要找到内容词的“显着性”或“重要性”   这个语料库,我们可以简单地做所有tf-idf得分的总和   文件并按文件数除以?如果是这样,那是什么   数字解释TF-IDF词的总和   跨文件?

如果您在文档中总结了td-idf分数,那么本来会得分较低的术语可能会得到提升,而得分较高的术语可能会降低分数。

我不认为简单地除以文件总数就足以解决这个问题。也许将文档长度纳入归一化因子?无论哪种方式,我认为所有这些方法仍然需要针对每个域进行调整。

所以,一般来说,从数学上来说,我希望你会得到一个不受欢迎的平均效应。