基于jieba分词的TF-IDF提取关键词算法中自定义所使用逆向文件频率(IDF)的文本语料库

TF-IDF的概念

TF(Term Frequency,缩写为TF)也就是词频,即一个词在文中出现的次数,统计出来就是词频TF,显而易见,一个词在文章中出现很多次,那么这个词肯定有着很大的作用,在提取关键词之前,由于待提取的语句中会有很多无用词,例如“的”,“我”等等,所以我个人理解在提取关键词之前的简单步骤如下:


待分析语句------>分词------>去除停用词------>提取关键词


使用jieba中的TF-IDF算法

两种方法使用tf-idf算法提取关键词

  • from textrank4zh import TextRank4Keyword
  • jieba中的jieba.analyse.extract_tags()

在提取关键词时,我们经常发现提取的关键词肯能无法反应改语句的中心思想,也就是提取的不好,一些重要的词没提取出来。这要从TF-IDF算法原理来分析。

TF-IDF算法计算原理

基于jieba分词的TF-IDF提取关键词算法中自定义所使用逆向文件频率(IDF)的文本语料库
词频 (term frequency, TF) 指的是某一个给定的词语在该文件中出现的次数。这个数字通常会被归一化(一般是词频除以文章总词数), 以防止它偏向长的文件。
基于jieba分词的TF-IDF提取关键词算法中自定义所使用逆向文件频率(IDF)的文本语料库
逆向文件频率 (inverse document frequency, IDF) IDF的主要思想是:如果包含词条t的文档越少, IDF越大,则说明词条具有很好的类别区分能力。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。
基于jieba分词的TF-IDF提取关键词算法中自定义所使用逆向文件频率(IDF)的文本语料库
某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。

从这里我们可以知道,提取的关键词不好的原因可能是因为语料库的问题。(通用语料库无法针对专业领域的语料进行提取重要关键词

自定义逆向文件频率的文本语料库

基于jieba自带的jieba.analyse.extract_tags()上,改变jieba默认加载的IDF语料库
jieba可以使用jieba.analyse.set_idf_path(file_path)更换默认IDF语料库,这样就很方面我们操作,我们只要创建我们需要的IDF文本语料库就行了。上代码:

import math
idf_dic = {}
#data_content是带分析文本,一个demo:如下图
doc_count  = len(data_content) # 总共有多少篇文章

for i in range(len(data_content)):
    new_content = data_content[i].split(' ')
    for word in set(new_content):
        if len(word) > 1:
            idf_dic[word] = idf_dic.get(word, 0.0) + 1.0
        # 此时idf_dic的v值:有多少篇文档有这个词,就是多少
for k,v in idf_dic.items():
    w = k
    p = '%.10f' % (math.log(doc_count / (1.0 + v))) # 结合上面的tf-idf算法公式
    if w > u'\u4e00' and w<=u'\u9fa5': # 判断key值全是中文
        idf_dic[w] = p
        
with open('G:/wdic.txt','w',encoding='utf-8') as f:
    for k in idf_dic:
        if k != '\n':
            f.write(k + ' ' + idf_dic[k] + '\n') #写入txt文件,注意utf-8,否则jieba不认

一个demo:data_content:
基于jieba分词的TF-IDF提取关键词算法中自定义所使用逆向文件频率(IDF)的文本语料库

生成后的txt图:
基于jieba分词的TF-IDF提取关键词算法中自定义所使用逆向文件频率(IDF)的文本语料库

具体使用代码:

jieba.analyse.set_idf_path(r'G:/wdic.txt')
jieba.analyse.extract_tags(content[i], topK=k, withWeight=True, allowPOS=())