NLP----关键词提取算法(TextRank,TF/IDF)

标签: geek | 发表时间:2018-12-11 00:00 | 作者:
出处:http://itindex.net/relian

参考书目:python自然语言处理实战——核心技术与算法

TF/IDF

基本思想:TF是计算一个词在一篇文档中出现的频率,IDF是一个词在多少篇文档中出现过,显然TF越高证明这个词在这篇文章中的代表性就越强,而INF越低则证明这个词在具有越强的区分能力。因此中和这两个数,就能较好地算出文档的关键词。

关键公式

tf*idf(i,j)=tf_{ij}*idf_i=\frac{n_{ij}}{\sum _kn_{kj}}*log(\frac{|D|}{1+|D_i|})

|D_i|是文档中出现词i的文档数量,|D|是文档数

附上书上抄来的代码

   import jieba
import jieba.posseg as psg
import math
import functools

# 停用词表加载方法


def get_stopword_list():
    # 停用词表存储路径,每一行为一个词,按行读取进行加载
    # 进行编码转换确保匹配准确率
    stop_word_path = './data/stopword.txt'
    stopword_list = [sw.replace('\n', '')
                     for sw in open(stop_word_path,encoding = 'utf-8').readlines()]
    return stopword_list

# 分词方法,调用结巴接口


def seg_to_list(sentence, pos=False):
    if not pos:
        # 不进行词性标注的分词方法
        seg_list = jieba.cut(sentence)
    else:
        # 进行词性标注的分词方法
        seg_list = psg.cut(sentence)
    return seg_list

# 去干扰词


def word_filter(seg_list, pos=False):
    stopword_list = get_stopword_list()
    filter_list = []
    # 根据POS参数选择是否词性过滤
    # 不进行词性过滤,则将词性都标记为n,表示全部保留
    for seg in seg_list:
        if not pos:
            word = seg
            flag = 'n'
        else:
            word = seg.word
            flag = seg.flag
        if not flag.startswith('n'):
            continue
        # 过滤高停用词表中的词,以及长度<2的词
        if not word in stopword_list and len(word) > 1:
            filter_list.append(word)

    return filter_list

# 数据加载,pos为是否词性标注的参数,corpus_path为数据集路径


def load_data(pos=False, corpus_path='./data/corpus.txt'):
    # 调用上面方法对数据集进行处理,处理后的每条数据仅保留非干扰词
    doc_list = []
    for line in open(corpus_path, 'r',encoding = 'utf-8'):
        content = line.strip()
        seg_list = seg_to_list(content, pos)
        filter_list = word_filter(seg_list, pos)
        doc_list.append(filter_list)
    return doc_list


def train_idf(doc_list):
    idf_dic = {}
    #总文档数
    tt_count = len(doc_list)
    
    #每个词出现的文档数
    for doc in doc_list:
        for word in set(doc):
            idf_dic[word] = idf_dic.get(word,0.0)+1.0

    #按公示转换为idf值,分母加一进行平滑处理
    for k,v in idf_dic.items():
        idf_dic[k]=math.log(tt_count/(1.0+v))
    
    #对于没有在字典中的词,默认其仅在一个文档中出现,得到默认idf值
    default_idf = math.log(tt_count/1.0)
    return idf_dic,default_idf

def cmp(e1,e2):
    import numpy as np
    res = np.sign(e1[1]-e2[1])
    if res != 0:
        return res
    else:
        a = e1[0]+e2[0]
        b = e2[0]+e1[0]
        if a>b:
            return 1
        elif a == b:
            return 0
        else:
            return -1

class TfIdf(object):
    #统计tf值
    def get_tf_dic(self):
        tf_dic = {}
        for word in self.word_list:
            tf_dic[word] = tf_dic.get(word,0.0)+1.0
        
        tt_count = len(self.word_list)
        for k,v in tf_dic.items():
            tf_dic[k] = float(v)/tt_count

        return tf_dic
    
    #四个参数分别是:训练好的idf字典,默认idf值,处理后的待提取文本,关键词数量
    def __init__(self,idf_dic,default_idf,word_list,keyword_num):
        self.word_list = word_list
        self.idf_dic,self.default_idf = idf_dic,default_idf
        self.tf_dic  = self.get_tf_dic()
        self.keyword_num = keyword_num

    #按公式计算tf_idf
    def get_tfidf(self):
        tfidf_dic = {}
        for word in self.word_list:
            idf = self.idf_dic.get(word,self.default_idf)
            tf = self.tf_dic.get(word,0)

            tfidf  = tf*idf
            tfidf_dic[word] = tfidf

            #根据tf_idf排序,取排名前keyword_num的词作为关键词
        for k ,v in sorted(tfidf_dic.items(),key=functools.cmp_to_key(cmp),reverse=True)[:self.keyword_num]:
            print(k+"/",end='')
        print()

def tfidf_extract(word_list, pos=False, keyword_num=10):
    doc_list = load_data(pos)
    idf_dic, default_idf = train_idf(doc_list)
    tfidf_model = TfIdf(idf_dic, default_idf, word_list, keyword_num)
    tfidf_model.get_tfidf()

if __name__ == '__main__':
    text = '6月19日,《2012年度“中国爱心城市”公益活动新闻发布会》在京举行。' + \
           '中华社会救助基金会理事长许嘉璐到会讲话。基金会高级顾问朱发忠,全国老龄' + \
           '办副主任朱勇,民政部社会救助司助理巡视员周萍,中华社会救助基金会副理事长耿志远,' + \
           '重庆市民政局巡视员谭明政。晋江市人大常委会主任陈健倩,以及10余个省、市、自治区民政局' + \
           '领导及四十多家媒体参加了发布会。中华社会救助基金会秘书长时正新介绍本年度“中国爱心城' + \
           '市”公益活动将以“爱心城市宣传、孤老关爱救助项目及第二届中国爱心城市大会”为主要内容,重庆市' + \
           '、呼和浩特市、长沙市、太原市、蚌埠市、南昌市、汕头市、沧州市、晋江市及遵化市将会积极参加' + \
           '这一公益活动。中国雅虎副总编张银生和凤凰网城市频道总监赵耀分别以各自媒体优势介绍了活动' + \
           '的宣传方案。会上,中华社会救助基金会与“第二届中国爱心城市大会”承办方晋江市签约,许嘉璐理' + \
           '事长接受晋江市参与“百万孤老关爱行动”向国家重点扶贫地区捐赠的价值400万元的款物。晋江市人大' + \
           '常委会主任陈健倩介绍了大会的筹备情况。'

    pos = True
    seg_list = seg_to_list(text, pos)
    filter_list = word_filter(seg_list, pos)

    print('TF-IDF模型结果:')
    tfidf_extract(filter_list)

TextRank

基本思路:每个词将自己的分数平均投给附近的词,迭代至收敛或指定次数即可,初始分可以打1

附上代码

   def get_stopword_list():
    path = './data/stop_words.utf8'
    stopword_list = [sw.replace('\n','') for sw in open(path,'r',encoding='utf8').readlines()]
    return stopword_list

def seg2list(text):
    import jieba
    return jieba.cut(text)

def word_filter(seg_list):
    stopword_list = get_stopword_list()
    filter_list = []
    for w in seg_list:
        if not w in stopword_list and len(w)>1:
            filter_list.append(w)
    return filter_list


str = '6月19日,《2012年度“中国爱心城市”公益活动新闻发布会》在京举行。' + \
           '中华社会救助基金会理事长许嘉璐到会讲话。基金会高级顾问朱发忠,全国老龄' + \
           '办副主任朱勇,民政部社会救助司助理巡视员周萍,中华社会救助基金会副理事长耿志远,' + \
           '重庆市民政局巡视员谭明政。晋江市人大常委会主任陈健倩,以及10余个省、市、自治区民政局' + \
           '领导及四十多家媒体参加了发布会。中华社会救助基金会秘书长时正新介绍本年度“中国爱心城' + \
           '市”公益活动将以“爱心城市宣传、孤老关爱救助项目及第二届中国爱心城市大会”为主要内容,重庆市' + \
           '、呼和浩特市、长沙市、太原市、蚌埠市、南昌市、汕头市、沧州市、晋江市及遵化市将会积极参加' + \
           '这一公益活动。中国雅虎副总编张银生和凤凰网城市频道总监赵耀分别以各自媒体优势介绍了活动' + \
           '的宣传方案。会上,中华社会救助基金会与“第二届中国爱心城市大会”承办方晋江市签约,许嘉璐理' + \
           '事长接受晋江市参与“百万孤老关爱行动”向国家重点扶贫地区捐赠的价值400万元的款物。晋江市人大' + \
           '常委会主任陈健倩介绍了大会的筹备情况。'
win={}
seg_list = seg2list(str)
filter_list = word_filter(seg_list)
#构建投分表,根据窗口
for i in range(len(filter_list)):
    if filter_list[i] not in win.keys():
        win[filter_list[i]]=set()
    if i-5 < 0:
        lindex = 0
    else:
        lindex = i-5
    for j in filter_list[lindex:i+5]:
        win[filter_list[i]].add(j)

# 投票
time = 0
score = {w:1.0 for w in filter_list}
while(time<50):
    for k,v in win.items():
        s = score[k]/len(v)
        score[k] = 0
        for i in v:
            score[i]+=s
    time+=1

l = sorted(score.items(), key=lambda score:score[1],reverse=True)
print(l)

 

相关 [nlp 关键词 算法] 推荐:

NLP----关键词提取算法(TextRank,TF/IDF)

- - IT瘾-geek
参考书目:python自然语言处理实战——核心技术与算法. 基本思想:TF是计算一个词在一篇文档中出现的频率,IDF是一个词在多少篇文档中出现过,显然TF越高证明这个词在这篇文章中的代表性就越强,而INF越低则证明这个词在具有越强的区分能力. 因此中和这两个数,就能较好地算出文档的关键词. |D_i|是文档中出现词i的文档数量,|D|是文档数.

关键词权重计算算法:TF-IDF

- - 标点符
TF-IDF(Term Frequency–Inverse Document Frequency)是一种用于资讯检索与文本挖掘的常用加权技术. TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度. 字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降.

TextRank算法提取关键词和摘要 - 小昇的博客 | Xs Blog

- -
提到从文本中提取关键词,我们第一想到的肯定是通过计算词语的TF-IDF值来完成,简单又粗暴. 但是由于 TF-IDF 的结构过于简单,有时提取关键词的效果会很不理想. 本文将介绍一个由 Google 著名的网页排序算法PageRank改编而来的算法——TextRank,它利用图模型来提取文章中的关键词.

关键词抽取算法的研究 | 吴良超的学习笔记

- -
分词–>过滤停止词,得到候选关键词–>从候选关键词中选出文章的关键词. 从候选关键词中选出文章的关键词需要通过关键词抽取算法实现,而关键词抽取算法可以根据是否需要人工标注的语料进行训练而分为有监督的提取和无监督的提取. 有监督的提取需要人工标注的语料进行训练,人工预处理的代价较高. 而无监督的抽取算法直接利用需要提取关键词的文本即可进行关键词的提取,因此适用性较强.

NLP入门之语音模型原理

- - IT瘾-bigdata
这一篇文章其实是参考了很多篇文章之后写出的一篇对于语言模型的一篇科普文,目的是希望大家可以对于语言模型有着更好地理解,从而在接下来的NLP学习中可以更顺利的学习.. 1:传统的语音识别方法:. 这里我们讲解一下是如何将声音变成文字,如果有兴趣的同学,我们可以深入的研究.. 首先我们知道声音其实是一种波,常见的MP3等都是压缩的格式,必须要转化成非压缩的纯波形的文件来处理,下面以WAV的波形文件来示例:.

谷歌最强 NLP 模型 BERT 解读

- - 雷锋网
雷锋网 AI 科技评论按:本文是追一科技潘晟锋基于谷歌论文为 AI 科技评论提供的解读稿件. 最近谷歌研究人员通过新的BERT模型在11项NLP任务中夺得STOA结果,这在自然语言处理学界以及工业界都引起了不小的热议. 作者通过在33亿文本的语料上训练语言模型,再分别在不同的下游任务上微调,这样的模型在不同的任务均得到了目前为止最好的结果,并且有一些结果相比此前的最佳成绩得到了幅度不小的提升.

15分钟入门NLP神器—Gensim

- - IT瘾-geek
   作者:李雪冬           . 编辑:李雪冬           . 作为自然语言处理爱好者,大家都应该听说过或使用过大名鼎鼎的Gensim吧,这是一款具备多种功能的神器. Gensim是一款开源的第三方Python工具包,用于从原始的非结构化的文本中,无监督地学习到文本隐层的主题向量表达.

NLP大师李中莹教你省时100条

- - 佳人
NLP大师李中莹教你省时100条,大师辛苦总结的经验,对照自己开始上进吧. 1、随身携带一本小册子,每想到要做的事都马上写下. 无需写得详细,能唤起自己记忆便可. 2、每天下班前,把所有明天需做的事依缓急程度排列写下,并且定下每项之预算时间需要,作为明天的工作计划. 3、每周的最后一天,检查一下下周需做的事.

【NLP主流最大的偏见,规则系统的手工性】

- - 我爱自然语言处理
【科普随笔:NLP主流的傲慢与偏见】中的第一条是 :. 【偏见一】规则系统的手工编制(hand-crafted)是其知识瓶颈,而机器学习是自动训练的(言下之意:因此没有知识瓶颈). NLP(Natural Language Processing)主流对规则系统和语言学家大小偏见积久成堆,这一条可以算是万偏之源.

如何在NLP领域第一次做成一件事

- - 微软亚洲研究院
周明,微软亚洲研究院首席研究员、ACL候任主席(president)、中国计算机学会中文信息技术专委会主任、中国中文信息学会常务理事、哈工大、天津大学、南开大学、山东大学等多所学校博士导师. 1985年毕业于重庆大学,1991年获哈工大博士学位. 1991-1993年清华大学博士后,随后留校任副教授.