关键词提取(1):TF-IDF算法

一、TF-IDF算法

        T F − I D F TF-IDF TFIDF(Term Frequency-Inverse Document Frquency,词频-逆文档频次算法),可以看出 T F − I D F TF-IDF TFIDF是由 T F TF TF算法和 I D F IDF IDF算法组成,它是个多文档算法, T F TF TF算法的公式为:
T F = n i ∑ i = 1 n n i TF =\frac{n_i}{\sum_{i=1}^n n_i} TF=i=1nnini
       其中,分子表示:你要求的词在文档中出现的次数,分母表示:文档中所有词的出现次数, T F TF TF算法的基本思想是:一个词在文档中出现的次数越多,对文档的表达能力也就越强。
I D F IDF IDF算法的公式为:
I D F = l o g ( ∣ D ∣ 1 + ∣ D i ∣ ) IDF =log(\frac{|D|}{1 + |D_i|}) IDF=log(1+DiD)
        其中, ∣ D ∣ |D| D表示为文档集中总的文档个数, ∣ D i ∣ |D_i| Di表示:文档集中出现词 i i i的文档的个数,加1是采用了拉普拉斯平滑,避免有部分新的词没有在预料库中出现导致分母为0, I D F IDF IDF算法的基本思想是:如果一个词在越少的文档中出现,对文档的区分能力就越大。
        T F − I D F TF-IDF TFIDF算法是 T F TF TF算法和 I D F IDF IDF算法的结合,经过大量的推到和实验,下面的公式是较为有效的计算方式之一:
T F − I D F = T F ∗ I D F = n i ∑ i = 1 n n i ∗ l o g ( ∣ D ∣ 1 + ∣ D i ∣ ) TF-IDF = TF*IDF =\frac{n_i}{\sum_{i=1}^n n_i} * log(\frac{|D|}{1 + |D_i|}) TFIDF=TFIDF=i=1nninilog(1+DiD)
        根据计算得来的 T F − I D F TF-IDF TFIDF值,进行从大到小的排序,就可以取前 n n n作为关键词。

二、代码实现

       实现下面一句话在文档集中的关键词提取(尝试只提取名词性词语,其他词语也被视为干扰词去掉):

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

1. 对要提取的文本进行处理

1.1 加载停用词表

def stopword():
    stop_word_path = r'D:\ProgrammingSoftware\pycharm\HanLp\stopword.txt'
    stopword_list = [sw.replace('\n', '') for sw in open(stop_word_path,encoding='utf-8').readlines()]
    return stopword_list

1.2 对你要提取的文本进行分词

def cut_word(sentence):
    seg_list = psg.cut(sentence)
    return seg_list

1.3 把要提取文本中除了名词之外的词和一些停用词过滤

def word_filter(seg_list):
    stopword_list = stopword()
    filter_list = []
    for seg in seg_list:
        word = seg.word
        flag = seg.flag
        if not flag.startswith('n'):
            continue
        if not word in stopword_list and len(word) > 1:
            filter_list.append(word)
    return filter_list

1.4 算出来剩下的名称的 T F TF TF

def tf_value(filter_list):
    filter_list = filter_list
    tf_value_dict = {}
    tf_value = {}
    for word in filter_list:
        tf_value_dict[word] = tf_value_dict.get(word, 0.0) + 1.0
    for key, value in tf_value_dict.items():
        tf_value[key] = float(value / len(filter_list))
    return tf_value

2.对数据集进行处理

2.1 加载数据集

def load_data():
    corpus_path = r'D:\ProgrammingSoftware\pycharm\HanLp\corpus.txt'
    doc_list = []
    for line in open(corpus_path, 'r', encoding='utf-8'):
        content = line.strip()
        seg_list = cut_word(content)
        filter_word = word_filter(seg_list)
        doc_list.append(filter_word)
    return doc_list

2.2 进行 I D F IDF IDF值的计算

def train_idf():
    doc_list = load_data()
    idf_dic = {}
    total_doc_num = 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 key, value in idf_dic.items():
        # 加1是拉普拉斯平滑,防止部分新词在语料库中没有出现导致分母为0
        idf_dic[key] = math.log(total_doc_num / (1.0 + value))
    return idf_dic

2.3 进行 T F − I D F TF-IDF TFIDF的计算

def tf_idf(tf):
    tf_value_dict = tf # tf的值,tf_value是个字典
    idf_value = train_idf() # idf的值,idf是个字典
    tf_idf_dict = {}
    for key, value in tf_value_dict.items():
        tf_idf_dict[key] = value
        for key_idf, value_idf in idf_value.items():
            if key == key_idf:
                tf_idf_dict[key] = value * value_idf
    return tf_idf_dict

2.5 对数据进行排名,提取前 n n n个作为关键词

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

    seg_list = cut_word(text)
    filter_word = word_filter(seg_list)
    tf = tf_value(filter_word)
    tf_idf(tf)
    rank()

       最后的输出结果为:

晋江市/城市/大会/爱心/中华/基金会/许嘉璐/巡视员/重庆市/人大常委会/陈健倩/民政局/

       代码和数据的地址

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值