赞
踩
初学中文文本分词,从最简单的TF-IDF算法入手,理解其中的逻辑结构,其中使用jieba分词包作为分词模型。这里部分内容参考了_hahaha的博客。
jieba分词提取关键词是按照词频(即每个词在文章中出现的次数)来提取的,比如要提取文章的前五个关键词,那么就是提取文章中出现次数最多的前五个词。而TF-IDF算法不仅统计每个词的词频,还为每个词加上权重。
举个例子
我们在大学选修了数学和体育两门课,数学为9学分,体育为1学分,期末的时候考试成绩分别为60和100分,那么如果我们说平均分是80分合理吗?其实是不合理的,因为一个9学分,一个1学分,我们投入的时间和精力是不一样的,所以应该用(9/10*60)+(1/10*100)=64分这样更为合理一些,这里80分是平均值,64分是数学期望,所以我们也说数学期望是加权的平均值。
TF-IDF计算公式
- TF = 该词在文档中出现的次数
- IDF = log2(文档总数/包含该词的文档数量 + 1)
- TF-IDF = TF * IDF
系统: Win10; 开发软件: PyChram CE; 运行环境: Python3.6
- import os
- import codecs
- import pandas
- import re
- import jieba
- import numpy
- # 创建语料库
- filePaths = []
- fileContents = []
- for root, dirs, files in os.walk(
- 'data/SogouC.mini/Sample'
- ):
- for name in files:
- filePath = os.path.join(root, name)
- f = codecs.open(filePath, 'r', 'utf-8')
- fileContent = f.read()
- f.close()
- filePaths.append(filePath)
- fileContents.append(fileContent)
-
- corpus = pandas.DataFrame({
- 'filePath': filePaths,
- 'fileContent': fileContents
- })
运行结果:
- # 匹配中文分词
- zhPattern = re.compile(u'[\u4e00-\u9fa5]+')
-
- # 分词
- segments = []
- filePaths = []
- for index, row in corpus.iterrows(): # 对语料库按行进行遍历
- filePath = row['filePath']
- fileContent = row['fileContent']
- segs = jieba.cut(fileContent)
- for seg in segs:
- if zhPattern.search(seg): # 匹配中文分词
- segments.append(seg)
- filePaths.append(filePath)
- segmentDF = pandas.DataFrame({
- 'segment': segments,
- 'filePath': filePaths
- })
运行结果:
- # 停用词过滤
- stopWords = pandas.read_csv( # 读取停用词表
- 'data/StopwordsCN.txt',
- encoding='utf-8',
- index_col=False,
- quoting=3,
- sep='\t'
- )
- segmentDF = segmentDF[~segmentDF['segment'].isin(stopWords['stopword'])]
- # 按文章进行词频统计
- segStat = segmentDF.groupby(
- by=['filePath', 'segment']
- )['segment'].agg({
- '计数': len
- }).reset_index().sort_values( # reset_index()
- '计数',
- ascending=False # 倒序排列
- )
-
- # 把词频为小于1的词删掉
- segStat = segStat[segStat['计数'] > 1]
运行结果:
文档向量化:
假设有m篇文章d1、d2、d3、......、dm,对它们分别进行分词,得到n个分词向量w1、w2、w3、......、wn,那么就得到这m篇文档的分词向量矩阵F。其中fij代表第i篇文章中分词j出现的频率。
那么单篇文档的向量化,即第i篇文章,使用矩阵F的第i行数据进行表,即 Di ={ fi1, fi2, ..., fin }。
- # 文档向量化
- TF = segStat.pivot_table(
- index='filePath', # 数据透视表的列
- columns='segment', # 数据透视表的行
- values='计数', # 数据透视表中的值
- fill_value=0, # NA值统一替换为0
- )
运行结果:
- #计算TF-IDF
- def handler(x):
- return numpy.log2(len(corpus) / (numpy.sum(x > 0) + 1))
- IDF = TF.apply(handler)
- TF_IDF = pandas.DataFrame(TF * IDF)
运行结果:
- #提取每篇文档的前五个关键词
- tag1s = []
- tag2s = []
- tag3s = []
- tag4s = []
- tag5s = []
- for filePath in TF_IDF.index:
- tags = TF_IDF.loc[filePath].sort_values( # 用loc(索引名)遍历行,每行为一个Series
- ascending=False # 对每行进行倒序排列
- )[:5].index # 取每行前五个的索引值(即前五个分词名称)
- tag1s.append(tags[0])
- tag2s.append(tags[1])
- tag3s.append(tags[2])
- tag4s.append(tags[3])
- tag5s.append(tags[4])
-
- tagDF = pandas.DataFrame({
- 'filePath': corpus['filePath'],
- 'fileContent': corpus['fileContent'],
- 'tag1': tag1s,
- 'tag2': tag2s,
- 'tag3': tag3s,
- 'tag4': tag4s,
- 'tag5': tag5s
- })
运行结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。