zoukankan      html  css  js  c++  java
  • TF-IDF简介与应用

    一、TF-IDF简介


      在自然语言处理中,TF-IDF(term frequency–inverse document frequency)常用于挖掘文章中的关键词, 算法以简单高效著称。TF-IDF有两层意思,一层是"词频"(Term Frequency,缩写为TF),另一层是"逆文档频率"(Inverse Document Frequency,缩写为IDF)。

      理论来讲, 一篇文章中词频的高低能反应该篇文章词语的关键性。可是在文章中词频高的往往是“的”、“了”之类的词语,这些在文档中最常见但对结果毫无帮助、需要过滤掉的词,用TF可以统计到这些停用词并把它们过滤。当高频词过滤后就只需考虑剩下的有实际意义的词。

      但这样又会遇到了另一个问题,我们可能发现某些常见的词语在文章中也挺多的,但是这些词语依旧不能可靠地作为该篇文章的关键词,因为它们在其他文章中也比较常见,所以这个时候就需要IDF,IDF会给常见的词较小的权重,它的大小与一个词的常见程度成反比。

      当有TF(词频)和IDF(逆文档频率)后,将这两个词相乘,就能得到一个词的TF-IDF的值。某个词在文章中的TF-IDF越大,那么一般而言这个词在这篇文章的重要性会越高,所以通过计算文章中各个词的TF-IDF,由大到小排序,排在最前面的几个词,就是该文章的关键词。

    二、算法步骤


    第一步,计算词频:

    [词频(TF)= 某词在文章中出现的次数 ]

    考虑到文章有长短之分,为了便于不同文章的比较,进行“词频”标准化。

    [词频(TF)= frac{某词在文章中出现的次数}{文章的总词数} ]

    第二步,计算逆文档频率:

    这时,需要一个语料库(corpus),用来模拟语言的使用环境。

    [逆文档频率(IDF)= log(frac{语料库的文档总数}{包含该词的文档数+1}) ]

    如果一个词越常见,那么分母就越大,逆文档频率就越小越接近0。分母之所以要加1,是为了避免分母为0(即所有文档都不包含该词)。

    第三步,计算TF-IDF:

    [TF-IDF=词频(TF) imes 逆文档频率(IDF) ]

    可以看到,TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比。所以,自动提取关键词的算法就很清楚了,就是计算出文档的每个词的TF-IDF值,然后按降序排列,取排在最前面的几个词。

    三、算法实现


    import math
    import jieba
    from collections import Counter
    
    STOP_WORDS = {' ', ',', ',', '!', '!', ':', ':', '的', '了', '是'}
    
    corpus = [
        '作死!国王前锋感染新冠并未隔离 不戴口罩外出打球',
        '湖人媒体抱怨赛程安排太难:快船那么轻松不公平',
        '弥补财政损失的最快捷办法就是增加球队,得到的扩张费用会非常可观,而这笔钱他们无需跟球员分享'
    ]
    
    word_list = []
    for i in range(len(corpus)):
        word_list.append([token for token in jieba.lcut(corpus[i]) if token not in STOP_WORDS])
    print(word_list)
    
    count_list = []
    for i in range(len(word_list)):
        count = Counter(word_list[i])
        count_list.append(count)
    print(count_list)
    
    
    # word可以通过count得到,count可以通过count_list得到
    # count[word]可以得到每个单词的词频, sum(count.values())得到整个句子的单词总数
    def tf(word, count):
        return count[word] / sum(count.values())
    
    
    # 统计的是含有该单词的句子数
    def n_containing(word, count_list):
        return sum(1 for count in count_list if word in count)
    
    
    # len(count_list)是指句子的总数,n_containing(word, count_list)是指含有该单词的句子的总数,加1是为了防止分母为0
    def idf(word, count_list):
        return math.log(len(count_list) / (1 + n_containing(word, count_list)))
    
    
    # 将tf和idf相乘
    def tf_idf(word, count, count_list):
        return tf(word, count) * idf(word, count_list)
    
    
    for i, count in enumerate(count_list):
        print("Top words in document {}".format(i + 1))
        scores = {word: tf_idf(word, count, count_list) for word in count}
        sorted_words = sorted(scores.items(), key=lambda x: x[1], reverse=True)
        for word, score in sorted_words[:]:
            print("	Word: {}, TF-IDF: {}".format(word, round(score, 5)))
    
  • 相关阅读:
    XML to Excel
    C# 位域[flags]
    使用windows7的System帐户
    VS.NET 控件命名规范
    Microsoft Robotics Studio到底能做什么?
    SQLServer系统表及其应用(转)
    利用xslt、xml,ajax实现了一个无限级树型导航
    利用xslt实现一个树形导航
    网页信息抓取如何获取延迟加载的网页数据
    站长盈利盈利方式面面观
  • 原文地址:https://www.cnblogs.com/selfcs/p/13201591.html
Copyright © 2011-2022 走看看