文本知识提取
目录
1.安装jieba
2.TF-IDF算法
2.1算法的定义
2.2算法的应用
(1)词性标注
(2)去停用词
(3)关键词提取
1.安装jieba
Jieba分词官网:https://github.com/fxsjy/jieba
解压到相应文件夹 ,打开控制台
切换到setup所在的路径,然后 输入python setup.py install 进行安装
测试安装成功
2.TF-IDF算法
基于TF-IDF算法抽取关键词的主调函数是TFIDF.extract_tags函数,主要是在jieba/analyse/tfidf.py中实现
源码分析如下:
def extract_tags(self, sentence, topK=20, withWeight=False, allowPOS=(), withFlag=False):
# 传入了词性限制集合
if allowPOS:
allowPOS = frozenset(allowPOS)
# 调用词性标注接口
words = self.postokenizer.cut(sentence)
# 没有传入词性限制集合
else:
# 调用分词接口
words = self.tokenizer.cut(sentence)
freq = {}
for w in words:
if allowPOS:
if w.flag not in allowPOS:
continue
elif not withFlag:
w = w.word
wc = w.word if allowPOS and withFlag else w
# 判断词的长度是否小于2,或者词是否为停用词
if len(wc.strip()) < 2 or wc.lower() in self.stop_words:
continue
# 将其添加到词频词典中,次数加1
freq[w] = freq.get(w, 0.0) + 1.0
# 统计词频词典中的总次数
total = sum(freq.values())
for k in freq:
kw = k.word if allowPOS and withFlag else k
# 计算每个词的tf-idf值
freq[k] *= self.idf_freq.get(kw, self.median_idf) / total
# 根据tf-idf值进行排序
if withWeight:
tags = sorted(freq.items(), key=itemgetter(1), reverse=True)
else:
tags = sorted(freq, key=freq.__getitem__, reverse=True)
# 输出topK个词作为关键词
if topK:
return tags[:topK]
else:
return tags
2.1算法的定义
(1)TF词频的计算
词频(TF)=某个词语在文章中的出现次数 / 文章的总词数 或者 词频(TF)
=某个词语在文章中的出现次数 / 这篇文章出现最多的词的出现次数
(2)IDF的计算
逆文档频率(IDF)= log(语料库的文档总数 / 包含该词的文档数+1),
如果一个词越常见,那么分母就越大,逆文档频率就越小越接近0。分母之所以要加1,是为了避免分母为0(即所有文档都不包含该词)。log表示对得到的值取对数。
(3)计算TF-IDF的值
TF-IDF = 词频(TF)* 逆文档频率(IDF)
比如:词频(tf)是一词语出现的次数除以该文件的总词语数。
假如一篇文件的总词语数是100个,而词语“母牛”出现了3次,
那么“母牛”一词在该文件中的词频就是3/100=0.03。
一个计算文件频率(DF)的方法是测定有多少份文件出现过“母牛”一词,
然后除以文件集里包含的文件总数。所以,如果“母牛”一词在1,000份文件出现过,
而文件总数是10,000,000份的话,其逆向文件频率就是log(10,000,000 / 1,000)=4。
最后的tf-idf的分数为0.03 * 4=0.12。
2.2算法的应用
(1)词性标注
import jieba.posseg as pseg
words = pseg.cut("姑娘别怂,加油干")
# words类别为:generator
for word, flag in words:
print('%s %s' % (word, flag))
import jieba
seg_list = jieba.cut("我要成为研究生", cut_all=True)
# join是split的逆操作
# 即使用一个拼接符将一个列表拼成字符串
print("/ ".join(seg_list)) # 全模式
seg_list = jieba.cut("我要成为研究生", cut_all=False)
print("/ ".join(seg_list)) # 精确模式
seg_list = jieba.cut("论文真是令人头秃") # 默认是精确模式
print("/ ".join(seg_list))
seg_list = jieba.cut_for_search("我要成为研究生,最后改论文真实令人头秃") # 搜索引擎模式
print("/ ".join(seg_list))
(2)去停用词
先进性了词性标注,然后通过加载停用词文件过滤掉无关词,停用词表是根据原文本我自己往里面加的,比如数词,形容词。
import jieba
# jieba.load_userdict('userdict.txt')
# 创建停用词list
def stopwordslist(filepath):
stopwords = [line.strip() for line in open(filepath, 'r').readlines()]
return stopwords
# 对句子进行分词
def seg_sentence(sentence):
# 对文档中的每一行进行中文分词
#print("正在分词...")
sentence_seged = jieba.cut(sentence.strip())
stopwords = stopwordslist('D:\jieba-0.42.1\jieba\stop_words.txt') # 这里加载停用词的路径
# 输出结果为outstr
outstr = ''
# 去停用词
for word in sentence_seged:
if word not in stopwords:
if word != '\t':
outstr += word
outstr += " "
return outstr
# 给出文档路径
inputs = open('D:\jieba-0.42.1\jieba\cainiao.txt', 'r', encoding='utf-8')
outputs = open('D:\jieba-0.42.1\jieba\out_words.txt', 'w',encoding='utf-8')
# # 将输出结果写入out_words.txt中
for line in inputs:
line_seg = seg_sentence(line) # 这里的返回值是字符串
outputs.write(line_seg + '\n')
#print("-------------------正在分词和去停用词-----------")
outputs.close()
inputs.close()
#print("删除停用词和分词成功!!!")
(3)关键词提取
两个都可以,区别就是加不加 -*- coding: utf-8 -*- 也可以 #coding:utf-8
from jieba import analyse
# 引入TF-IDF关键词抽取接口
tfidf = analyse.extract_tags
# 原始文本
text = u"线程是程序执行时的最小单位,它是进程的一个执行流,\
是CPU调度和分派的基本单位,一个进程可以由很多个线程组成,\
线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。\
线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。\
同样多线程也可以实现并发操作,每个请求分配一个线程来处理。"
# 基于TF-IDF算法进行关键词抽取
keywords = tfidf(text,topK=10,withWeight=True,allowPOS=())
for keyword in keywords:
print (keyword )
# # -*- coding: utf-8 -*-
# import jieba.analyse
# # 字符串前面加u表示使用unicode编码
# content = u'安全、防止水合物和段塞生成的重要措施之一。因此,针对未来还上油田开发技术,' \
# u'我们预先开展了水深1500米管道式油气水分离器的概念设计。通过该研究,提出适合海洋环境的体积小、' \
# u'重量轻、分离效率高、便于操作和维护的新型油气水三相分离器,使' \
# u'其成为海洋深水油气田开'
#
# keywords = jieba.analyse.extract_tags(content, topK=3, withWeight=True, allowPOS=())
# # 访问提取结果
# for item in keywords:
# # 分别为关键词和相应的权重
# print(item[0], item[1])