自然语言处理TF-IDF关键词提取算法

自然语言处理TF-IDF关键词提取算法_第1张图片

1、关键词提取简介

关键词是指能反映文本主题或者主要内容的词语。关键词提取就是从文本里面把跟这篇文档意义最相关的一些词抽取出来,是NLP领域的一个重要的子任务。在信息检索中,准确的关键词提取可以大幅提升效率;在对话系统中,机器可以通过关键词来理解用户意图;在文本分类中,关键词的发现也非常有帮助。关键词能让我们快速了解文章所讲内容,但是网络上写文章的人不会像写论文那样告诉你本文的关键词是什么,这个时候就需要利用计算机自动抽取出关键词,算法的好坏直接决定了后续步骤的效果。
关键词抽从方法来说大致有两种:
第一种是 #关键词分配,就是有一个给定的关键词库,然后新来一篇文档,从词库里面找出几个词语作为这篇文档的关键词;
第二种是 #关键词抽取,就是新来一篇文档,从文档中抽取一些词语作为这篇文档的关键词。
关键词抽取从算法的角度来说主要有两类:
有监督学习算法:将关键词抽取过程视为二分类问题,先抽取出候选词,然后对于每个候选词划定标签,要么是关键词,要么不是关键词,然后训练关键词抽取分类器。当新来一篇文档时,抽取出所有的候选词,然后利用训练好的关键词抽取分类器,对各个候选词进行分类,最终将标签为关键词的候选词作为关键词;
无监督学习算法:先抽取出候选词,然后对各个候选词进行打分,然后输出topK个分值最高的候选词作为关键词。根据打分的策略不同,有不同的算法,例如TF-IDF,TextRank等算法。
 jieba分词系统中实现了两种关键词抽取算法,分别是基于TF-IDF关键词抽取算法和基于TextRank关键词抽取算法,两类算法均是无监督学习的算法,本篇文章将来学习基于TF-IDF算法的关键词抽取。

2、TF-IDF算法原理

TF-IDF是在信息检索理论中Term Frequency - Inverse Document Frequency的简写,它是一种数值统计,用于反映一个词对于语料中某篇文档的重要性。在信息检索和文本挖掘领域,它经常用于因子加权。
 TF-IDF的基本公式: TF-IDF = TF * IDF,TF-IDF在实际中主要是将二者相乘,也即TF * IDF,TF为词频表示词t在文档d中出现的频率;IDF为反文档频率表示语料库中包含词t的文档的数目的倒数。
 由公式可知:一个词在文档中出现的次数越多,其TF值就越大,整个语料库中包含某个词的文档数越少,则IDF值越大,因此某个词的TF-IDF值越大,则认为这个词具有很好的类别区分能力,关键词的概率越大。

TF-IDF的基本思想是: 词语的重要性与它在文件中出现的次数成正比,但同时会随着它在语料库中出现的频率成反比下降。

一个文档中多次出现的词总是有一定的特殊意义,但是并不是所有多次出现的词就都是有意义的,如果一个词在所有的文档中都多次出现,那么这个词就没有什么价值了。或者说,如果某个词或者短语在一个文档中出现多次,但是在其他文档中很少出现,就可以认为这个词或短语具有很好的区分性,适合用来对文档进行分类。

TF-IDF算法步骤:

第一步:计算词频(词频是一个词在文章中出现的次数)考虑到文章有长短之分,为了便于不同文章的比较,进行"词频"标准化。
词 频 ( T F ) = 某 个 词 在 文 章 中 出 现 的 次 数 文 章 的 总 词 数 词频(TF)= \frac{某个词在文章中出现的次数}{文章的总词数} TF=
第二步:计算逆文档频率

这时,需要一个语料库(corpus),用来模拟语言的使用环境。
逆 文 档 频 率 ( I D F ) = l o g 语 料 库 的 文 档 总 数 包 含 该 词 的 文 档 数 + 1 逆文档频率(IDF)= log\frac{语料库的文档总数}{包含该词的文档数+1} IDF=log+1
  如果一个词越常见,那么分母就越大,逆文档频率就越小越接近0。分母之所以要加1,是为了避免分母为0(即所有文档都不包含该词)。log表示对得到的值取对数。

第三步:计算TF-IDF
T F − I D F = 词 频 ( T F ) × 逆 文 档 频 率 ( I D F ) TF-IDF= 词频(TF)\times逆文档频率(IDF) TFIDF=TF×IDF
  可以看到,TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比。所以,自动提取关键词的算法就很清楚了,就是计算出文档的每个词的TF-IDF值,然后按降序排列,取排在最前面的几个词。
TF-IDF的优点是: 简单快速,而且容易理解。
TF-IDF的缺点是: 1、为了精确的提取一篇文档中的关键词,需要有一整个语料库来提供支持。这个问题的解决方法,通常是在一个通用的语料库上提前计算好所有词的IDF值,jieba就是这么做的。这样的解决方案对于普通文档关键词提取有一定的效果,但是对于专业性稍微强一点的文档,表现就会差很多。2、有时候用词频来衡量文章中的一个词的重要性不够全面,有时候重要的词出现的可能不够多,而且这种计算无法体现位置信息,无法体现词在上下文的重要性。如果要体现词的上下文结构,那么你可能需要使用word2vec算法来支持。

3、编程实例
 jieba分词中已经对TF-IDF进行了实现,并预先统计出了汉语中每个词的逆文档频率(IDF),我的存储目录为D:\Python\anaconda\Lib\site-packages\jieba\analyse\idf.txt
jieba默认使用以上路径的IDF词典,并计算输入文档的TF(文本词频)值,进而求出TF-IDF提取关键词。

在jieba的TF-IDF模型里面,当调用获取关键词的函数 jieba.analyse.extract_tags(sentence, topK=20, withWeight=False, allowPOS=()) 的时候,该函数会调用默认的IDF语料库。
其中:

sentence :为待提取的文本
topK: 为返回几个 TF/IDF 权重最大的关键词,默认值为 20
withWeight :为是否一并返回关键词权重值,默认值为 False
allowPOS : 仅包括指定词性的词,默认值为空,即不筛选
 当然,我们也可以自定义语料库,通过IDF计算公式去对词语逐个的计算,生成自定义语料库,通过 analyse.set_idf_path(‘自定义语料库路径’) 指定语料库,再通过 tfidf(需要处理的文本) 语句进行关键词提取。在线语料库可自行选择;语料库链接;代码如下:

import jieba
from jieba.analyse import *

def stopwordslist(filepath):    # 定义函数创建停用词列表
    stopword = [line.strip() for line in open(filepath, 'r').readlines()]    #以行的形式读取停用词表,同时转换为列表
    return stopword

filepath = 'D:/大学工作所做文档/学习资料/毕业设计学习准备/编程学习/stop_words.txt'            
stopwordslist(filepath)  #调用函数

contents = '据报道,我国国家图书馆浩瀚的馆藏古籍中,仅1.6万卷“敦煌遗书”就有 5000 余米长卷需要修复,'
contents += '而国图从事古籍修复的专业人员不过10人;各地图书馆、 博物馆收藏的古籍文献共计 3000万 册,残损情况也相当严重,'
contents += '亟待抢救性修复,但全国的古籍修复人才总共还不足百人。'
contents += '以这样少的人数去完成如此浩大的修复工程, 即使夜以继日地工作也需要近千年。'
print('\n【原文本:】'+'\n'+contents)    

content1 = contents.replace(' ','')     # 去掉文本中的空格
print('\n【去除空格后的文本:】'+'\n'+content1)
            
pattern = re.compile("[^\u4e00-\u9fa5]")    #只保留中文
content2= re.sub(pattern,'',content1)      #把文本中匹配到的字符替换成空字符
print('\n【去除符号后的文本:】'+'\n'+ content2)

jieba.suggest_freq(('百人'),tune=True)
jieba.suggest_freq(('这样少'),tune=True)
cutwords = jieba.lcut(content2)    #精确模式分词
print ('\n【精确模式分词后:】'+ '\n'+"/".join(cutwords))
        
stopwords = stopwordslist(filepath)     # 这里加载停用词的路径
words = ''
for word in cutwords:     #for循环遍历分词后的每个词语
    if word not in stopwords:     #判断分词后的词语是否在停用词表内
        if word != '\t':
            words += word
            words += "/"
print('\n【去除停用词后的分词:】'+ '\n'+ words +'\n' )

keywords = jieba.analyse.extract_tags(words,topK = 10, withWeight = True)   #使用结巴默认的idf文件进行关键词提取,展示权重前十的关键词
#或者使用keywords = tfidf(words,topK = 10, withWeight = True) 
print('【TF-IDF提取的关键词列表:】')        
print(keywords)   #采用默认idf文件提取的关键词

你可能感兴趣的:(python,自然语言处理)