python系列
python第一章(上)
python第一章(下)
python第二章
python第三章(上)
python第三章(下)
python第四章(上)
python第四章(下)
python第五章
python第六章
中文文本分析
前言
- 中文分词
- 词云图绘制
中文分词
jieba库
简介
- 在自然语言处理过程中,为了能更好地处理句子,往往需要把句子拆开分成一个一个的词语,这样能更好的分析句子的特性,这个过程叫就叫做分词。
- jieba是一个Python实现的中文分词组件,在中文分词界非常出名,支持简、繁体中文,高级用户还可以加入自定义词典以提高分词的准确率。
主要函数
函数 | 描述 |
---|---|
jieba.cut(s) | 精确模式,返回一个可迭代的数据类型 |
jieba.cut(s,cut_all=True) | 全模式,输出文本s中所有可能单词 |
jieba.cut_for_search(s) | 搜索引擎模式,适合搜索引擎建立索引的分词结果 |
jieba.lcut(s) | 精确模式,返回一个列表类型 |
jieba.lcut(s,cut_all=True) | 全模式,返回一个列表类型 |
jieba.lcut_for_search(s) | 搜索引擎模式,返回一个列表类型 |
jieba.add_word(w) | 向分词词典中增加新词w |
精确模式分词
- 试图将句子最精确地切开,适合文本分析。
import jieba
jieba.setLogLevel(jieba.logging.INFO)
s="我爱北京天安门"
for i in jieba.cut(s):#返回的是可迭代类型
print(i,end=' ')
print()
print(jieba.lcut(s))#返回的是一个列表
- 运行截图
全模式分词
- 把句子中所有的可以成词的词语都扫描出来。
import jieba
jieba.setLogLevel(jieba.logging.INFO)
s="我爱北京天安门"
for i in jieba.cut(s,cut_all=True):
print(i,end=' ')
print()
print(jieba.lcut(s,cut_all=True))
- 运行截图
搜索引擎模式分词
- 在精确模式的基础上,对长词再次切分。
import jieba
jieba.setLogLevel(jieba.logging.INFO)
s="李明硕士毕业于中国科学院计算所"
print(jieba.lcut(s))#精确模式
print(jieba.lcut(s,cut_all=True))#全模式
print(jieba.lcut_for_search(s))#搜索引擎模式
- 运行截图
jieba.add_word()
import jieba
jieba.setLogLevel(jieba.logging.INFO)
test="李元帅是计科系主任也是云计算方面的专家"
word=jieba.cut(test)
print('/'.join(word))
- 运行截图
- 在使用cut直接分词后,我们发现“李元帅”,“计科系”和“云计算”三个词jieba进行了拆分。如果希望将它们作为新词,可以使用jieba.add_word()临时添加
import jieba
jieba.setLogLevel(jieba.logging.INFO)
test="李元帅是计科系主任也是云计算方面的专家"
word=jieba.cut(test)
jieba.add_word('李元帅')
jieba.add_word('计科系')
jieba.add_word('云计算')
print('/'.join(word))
- 运行截图
- 如果加入的新词较多,我们可以使用自定义词典来分词。
- 创建一个文本文件,存入如下内容:
import jieba
jieba.setLogLevel(jieba.logging.INFO)
test="李元帅是计科系主任也是云计算方面的专家"
word=jieba.cut(test)
jieba.load_userdict("F:\\code\\编程\\py\\学习代码\\savetext\\abc.txt")
print('/'.join(word))
- 运行截图
词性标注
- 不同的语言有不同的词性标注集。为了方便指明词的词性,可以给每个词性编码,可以具体参考ICTCLAS汉语词性标注集。
- 其中,常见的有a:形容词,c:连词,d:副词,m:数词,n:名词,ns:地名,p:介词,r:代词,v:动词等。
import jieba.posseg as psg
text="我和同学一起去北京故宫玩"
seg=psg.cut(text)
for i in seg:
print(i,end="")
- 红字忽略
- 运行截图
import jieba.posseg as psg
text="其实走曼谷线+海岛不是只有沙美岛,还有象岛也可以去,就是远了一点,上面的酒店价格很贵,格兰岛就算了," \
"全是旅游团~我们是走的曼谷+芭提雅+象岛6天5晚的行程,比其他的行程要累一点,到芭提雅了坐车还要3个多小时," \
"但是人少~不喜欢热闹的可以考虑一下这个行程,很安静~"
seg=psg.cut(text)
print(type(seg))#可迭代类型
lst=[x.word for x in seg if x.flag=='ns']#筛选所有地名
print(lst)
- 筛选所有地名
- 运行截图
关键字提取
from jieba import analyse
text='''很多人不知道的是,金庸开始武侠小说的创作,是一次很偶然的机会。1955年,《大公报》下一个晚报有个武侠小说写得很成功的年轻人,
和金庸是同事,他名叫梁羽生。那年梁羽生的武侠小说即将完结,而他的创作又到了疲惫期,于是,报纸总编辑邀请金庸将武侠小说继续写下去。
虽然此前从未写过小说,但凭借他对武侠小说的了解与喜爱,金庸还是答应接替梁羽生的任务。他把自己名字中的镛字拆开,
做了一个笔名,《书剑恩仇录》正是他的第一部武侠作品,作品一炮而红。此书成功之后,金庸又在短短的几年内创作了《碧血剑》《雪山飞狐》和《射雕英雄传》等作品,
一时间风靡全港。十余年间,他写下15部洋洋大作。'''
keywords=analyse.extract_tags(text,topK=10,withWeight=True)
print("key by tfidf:")
for i in keywords:
print("{:<5}weight:{:4.2f}".format(i[0],i[1]))
- 基于TF-IDF算法进行关键词抽取
topK表示最大抽取个数,默认为20个
withWeight表示是否返回关键词权重值,默认值为 False
还有一个参数allowPOS默认为(‘ns’,‘n’,‘vn’,‘v’)即仅提取地名、名词、动名词、动词 - 运行截图
词云图绘制
- wordcloud库,是Python非常优秀的词云展示第三方库。词云以词语为基本单位,更加直观和艺术的展示文本,是对文本中出现频率较高的“关键词”予以视觉化的展现,词云过滤掉大量的低频低质的文本信息,使得浏览者只要一眼扫过文本就可领略文本的主旨。
- wordcloud于jieba库安装一样
使用方法
- 首先从wordcloud库引入WordCloud类:
from wordcloud import WordCloud
- 构造一个WordCould对象
wc = WordCloud(width = 1000, height =800,background_color=‘white’)
- 利用该对象的generate()生成词云图
wc.generate(字符串) #参数必须是用空格分隔的字符串 ‘AA BB AA CC’
- 利用该对象的to_file()将词云图保存为图片文件(png, jpg等)
wc.to_file(‘tu.png’)
from wordcloud import WordCloud
s = 'With the improving of semiconductor technology, a single chip integrates more and more processing cores. ' \
'Highly parallel applications are distributed to tens of processing units. ' \
'The inter-processor communication delay becomes more and more important for parallel applications.'
wc = WordCloud(background_color='white', width=1000, height=800)
wc.generate(s)
wc.to_file('wc.png') # 生成的图片默认保存在程序所在的目录
# 也可以写为
# WordCloud(background_color='white', width=1000, height=800).generate(s).to_file('wc.png')
# 在IPython中执行下面命令可显示图片
from IPython.display import Image
Image('wc.png')
- 运行结果截图
指定形状生成词云图
- 找张指定形状的图片存入
from wordcloud import WordCloud
import numpy as np
import PIL.Image as image
s = 'With the improving of semiconductor technology, a single chip integrates more and more processing cores. ' \
'Highly parallel applications are distributed to tens of processing units. ' \
'The inter-processor communication delay becomes more and more important for parallel applications.'
mask = np.array(image.open("F:\\code\\编程\\py\\学习代码\\savepng\\heart.png"))
wc = WordCloud(background_color='white', width=1000, height=800, mask=mask)
wc.generate(s)
wc.to_file('F:\\code\\编程\\py\\学习代码\\savepng\\wc3.png')
- 运行结果截图
中文文本云图
import jieba
from wordcloud import WordCloud
str = '编写程序就是用计算机语言实现算法的过程。可以证明,任何问题都可以由三种基本结构表达出来。这三种基本结构包括顺序结构、选择结构和循环结构。'
jbstr = ' '.join(jieba.lcut(str)) # 用空格将分词列表连接为 字符串
wc = WordCloud(font_path='simkai.ttf', background_color='white', width=500, height=400) # 楷体,指定中文字体
wc.generate(jbstr) # 生成词云
wc.to_file('wc2.png') # 存为wc2.png
- 另一方法:按频次生成, dic是一个字典,数据类似 {‘a’:10, ‘b’:21, ‘c’:30}
WordCloud().generate_from_frequencies(dic).to_file(‘w.png’)
- 运行结果截图
中文文本分析
import jieba
txt = open("F:\\code\\编程\\py\\学习代码\\savetext\\三国演义.txt", "r", encoding='utf-8').read()
words = jieba.lcut(txt)
#统计词频
counts = {}
for word in words:
if len(word) == 1: #排除单个字符的分词结果
continue
else:
counts[word] = counts.get(word,0) + 1
#按词频排序
items = list(counts.items())
items.sort(key=lambda x:x[1], reverse=True)
#输出结果
for i in range(15):
word, count = items[i]
print ("{0:<10}{1:>5}".format(word, count))
- 运行结果
- 观察结果,发现同一个人物会有不同的名字, 这种情况需要整合处理。 同时, 与英文词频统计类似, 需要排除一些人名无关词汇, 如“却说” 、 “将军” 等。为此,对程序做进一步优化。
import jieba
jieba.setLogLevel(jieba.logging.INFO)
#增加一个停用词的集合excludes
excludes = {"将军","却说","荆州","二人","不可","不能","如此"}
txt = open("F:\\code\\编程\\py\\学习代码\\savetext\\三国演义.txt", "r", encoding='utf-8').read()
words = jieba.lcut(txt)
counts = {}
#处理同名情况
for word in words:
if len(word) == 1:
continue
elif word == "诸葛亮" or word == "孔明曰":
rword = "孔明"
elif word == "关公" or word == "云长":
rword = "关羽"
elif word == "玄德" or word == "玄德曰":
rword = "刘备"
elif word == "孟德" or word == "丞相":
rword = "曹操"
else:
rword = word
counts[rword] = counts.get(rword,0) + 1
#删除停用词
for word in excludes:
del(counts[word])
items = list(counts.items())
items.sort(key=lambda x:x[1], reverse=True)
for i in range(5):
word, count = items[i]
print ("{0:<10}{1:>5}".format(word, count))
- 运行截图
- 在生成词云图
import jieba
jieba.setLogLevel(jieba.logging.INFO)
from wordcloud import WordCloud
#增加一个停用词的集合excludes
excludes = {"将军","却说","荆州","二人","不可","不能","如此"}
txt = open("F:\\code\\编程\\py\\学习代码\\savetext\\三国演义.txt", "r", encoding='utf-8').read()
words = jieba.lcut(txt)
counts = {}
#处理同名情况
for word in words:
if len(word) == 1:
continue
elif word == "诸葛亮" or word == "孔明曰":
rword = "孔明"
elif word == "关公" or word == "云长":
rword = "关羽"
elif word == "玄德" or word == "玄德曰":
rword = "刘备"
elif word == "孟德" or word == "丞相":
rword = "曹操"
else:
rword = word
counts[rword] = counts.get(rword,0) + 1
#删除停用词
for word in excludes:
del(counts[word])
items = list(counts.items())
items.sort(key=lambda x:x[1], reverse=True)
dic={}
for i in range(5):
word, count = items[i]
dic[word]=count
print ("{0:<10}{1:>5}".format(word, count))
st=str(dic)#转化成字符串
jbstr = ' '.join(jieba.lcut(st)) # 用空格将分词列表连接为 字符串
wc = WordCloud(font_path='simkai.ttf', background_color='white', width=500, height=400) # 楷体,指定中文字体
wc.generate(jbstr) # 生成词云
wc.to_file('F:\\code\\编程\\py\\学习代码\\savepng\\三国人物.png')
- 运行结果截图
文件图片已上传到资源,自取