当前位置:   article > 正文

TF-IDF算法提取文章的关键词_tfidf如何提取好几篇文档中的关键词并给出矩阵的

tfidf如何提取好几篇文档中的关键词并给出矩阵的

初学中文文本分词,从最简单的TF-IDF算法入手,理解其中的逻辑结构,其中使用jieba分词包作为分词模型。这里部分内容参考了_hahaha的博客

TF-IDF原理

jieba分词提取关键词是按照词频(即每个词在文章中出现的次数)来提取的,比如要提取文章的前五个关键词,那么就是提取文章中出现次数最多的前五个词。而TF-IDF算法不仅统计每个词的词频,还为每个词加上权重。

举个例子

我们在大学选修了数学和体育两门课,数学为9学分,体育为1学分,期末的时候考试成绩分别为60和100分,那么如果我们说平均分是80分合理吗?其实是不合理的,因为一个9学分,一个1学分,我们投入的时间和精力是不一样的,所以应该用(9/10*60)+(1/10*100)=64分这样更为合理一些,这里80分是平均值,64分是数学期望,所以我们也说数学期望是加权的平均值。


TF-IDF计算公式

  1. TF = 该词在文档中出现的次数
  2. IDF = log2(文档总数/包含该词的文档数量 + 1)
  3. TF-IDF = TF * IDF

  • 开发环境

系统: Win10; 开发软件: PyChram CE; 运行环境: Python3.6

  • 导入所需用的包
  1. import os
  2. import codecs
  3. import pandas
  4. import re
  5. import jieba
  6. import numpy
  • 创建语料库
  1. # 创建语料库
  2. filePaths = []
  3. fileContents = []
  4. for root, dirs, files in os.walk(
  5. 'data/SogouC.mini/Sample'
  6. ):
  7. for name in files:
  8. filePath = os.path.join(root, name)
  9. f = codecs.open(filePath, 'r', 'utf-8')
  10. fileContent = f.read()
  11. f.close()
  12. filePaths.append(filePath)
  13. fileContents.append(fileContent)
  14. corpus = pandas.DataFrame({
  15. 'filePath': filePaths,
  16. 'fileContent': fileContents
  17. })

运行结果:


  • 分词
  1. # 匹配中文分词
  2. zhPattern = re.compile(u'[\u4e00-\u9fa5]+')
  3. # 分词
  4. segments = []
  5. filePaths = []
  6. for index, row in corpus.iterrows(): # 对语料库按行进行遍历
  7. filePath = row['filePath']
  8. fileContent = row['fileContent']
  9. segs = jieba.cut(fileContent)
  10. for seg in segs:
  11. if zhPattern.search(seg): # 匹配中文分词
  12. segments.append(seg)
  13. filePaths.append(filePath)
  14. segmentDF = pandas.DataFrame({
  15. 'segment': segments,
  16. 'filePath': filePaths
  17. })

运行结果:


  • 停用词过滤
  1. # 停用词过滤
  2. stopWords = pandas.read_csv( # 读取停用词表
  3. 'data/StopwordsCN.txt',
  4. encoding='utf-8',
  5. index_col=False,
  6. quoting=3,
  7. sep='\t'
  8. )
  9. segmentDF = segmentDF[~segmentDF['segment'].isin(stopWords['stopword'])]

  • 按文章进行词频统计
  1. # 按文章进行词频统计
  2. segStat = segmentDF.groupby(
  3. by=['filePath', 'segment']
  4. )['segment'].agg({
  5. '计数': len
  6. }).reset_index().sort_values( # reset_index()
  7. '计数',
  8. ascending=False # 倒序排列
  9. )
  10. # 把词频为小于1的词删掉
  11. segStat = segStat[segStat['计数'] > 1]

运行结果:


  • 文档向量化

文档向量化:

        假设有m篇文章d1d2d3......、dm,对它们分别进行分词,得到n个分词向量w1w2w3......、wn,那么就得到这m篇文档的分词向量矩阵F。其中fij代表第i篇文章中分词j出现的频率。

那么单篇文档的向量化,即i篇文章,使用矩阵F的第i行数据进行表,即 Di ={ fi1, fi2, ..., fin }。


  1. # 文档向量化
  2. TF = segStat.pivot_table(
  3. index='filePath', # 数据透视表的列
  4. columns='segment', # 数据透视表的行
  5. values='计数', # 数据透视表中的值
  6. fill_value=0, # NA值统一替换为0
  7. )

运行结果:


  • 计算TF-IDF
  1. #计算TF-IDF
  2. def handler(x):
  3. return numpy.log2(len(corpus) / (numpy.sum(x > 0) + 1))
  4. IDF = TF.apply(handler)
  5. TF_IDF = pandas.DataFrame(TF * IDF)

运行结果:


  • 提取每篇文档的前五个关键词
  1. #提取每篇文档的前五个关键词
  2. tag1s = []
  3. tag2s = []
  4. tag3s = []
  5. tag4s = []
  6. tag5s = []
  7. for filePath in TF_IDF.index:
  8. tags = TF_IDF.loc[filePath].sort_values( # 用loc(索引名)遍历行,每行为一个Series
  9. ascending=False # 对每行进行倒序排列
  10. )[:5].index # 取每行前五个的索引值(即前五个分词名称)
  11. tag1s.append(tags[0])
  12. tag2s.append(tags[1])
  13. tag3s.append(tags[2])
  14. tag4s.append(tags[3])
  15. tag5s.append(tags[4])
  16. tagDF = pandas.DataFrame({
  17. 'filePath': corpus['filePath'],
  18. 'fileContent': corpus['fileContent'],
  19. 'tag1': tag1s,
  20. 'tag2': tag2s,
  21. 'tag3': tag3s,
  22. 'tag4': tag4s,
  23. 'tag5': tag5s
  24. })

运行结果:



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/342897
推荐阅读
相关标签
  

闽ICP备14008679号