jieba 是一个python实现的分词库,对中文有着很强大的分词能力。
git链接:https://github.com/fxsjy/jieba
本文主要包括几个版本的wordcloud输出方式
版本一是标准的wordcloud进行分词和展现
可以看出直接采用wordcloud也能分词,但分词效果不佳
版本二是直接采用jieba进行分词和展现
可以看出直接采用jieba也能分词,分词效果比wordcloud强一些,但一些无关紧要的词未过滤
版本三是对jieba进行简单的介绍
主要包括jieba.cutjieba.add_word, jieba.suggest_freq ,jieba.load_userdict,但jieba未整合停用词库,需要靠代码来处理,这个比较奇怪,估计后续版本会追加吧
版本四是进行自定义词库后再通过jieba进行分词和展现
加入自定义词库后,可以看到jieba提升了一些解析效率,但无关的词汇还是未过滤。
版本五是采用停用词以后再通过jieba进行分词和展现
加入停用词库后,终于可以看到我们熟悉的微信、小程序、用户、小游戏、平台之类的词汇了,当然如果想做好分词,还需要不断的丰富和完善自定义词库
通过版本一、二、四、五演示了如何一步步提升分词的可用性,当然一两天的功夫很难全部了解jieba的全部功能,我也是看不懂的时候,偶尔翻阅了一下源代码,源代码的阅读性和规范性还是不错的,想提升python能力,阅读这些package确实很有收获,不过我的代码能力还是太弱了些。
代码示例
from os import path
import numpy as np
import jieba
import jieba.posseg as pseg
import matplotlib.pyplot as plt
import pprint
import matplotlib.pyplot as plt
from collections import Counter
from PIL import Image
from wordcloud import WordCloud, STOPWORDS,ImageColorGenerator
d = path.dirname(__file__)
#此处下载并读取张小龙关于微信产品的演讲
content = open(path.join(d,'speechchinese.txt')).read()
#------------------------版本一,标准的WordCloud输出-------------------------------
stopwords = set(STOPWORDS)
stopwords.add('said')
wordcloud=WordCloud(font_path='/home/djh/win_font/simhei.ttf',max_words=50).generate(content)
process_word=WordCloud.process_text(wordcloud,content)
sort = sorted(process_word.items(),key=lambda e:e[1],reverse=True)
print(sort[:50])
# 词云展示
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")
plt.show()
# 结论:
# wordcloud可以直接使用,但需要指定加载中文字符集
# wordcloud对于中文的分词基本上没什么价值,具体参考下面的分词
#('去中心化', 8), ('用完即走', 4), ('当然', 3), ('所以', 2), ('跳一下', 2), ('对微信来说', 2),
# 因此必须寻找新的词库才行
#-------------------------------版本二、jieba分词------------------------------------
# 最简单的jieba分词
# 采用结巴进行分词
wordlist_after_jieba = jieba.cut(content, cut_all=True)
# 输出结果是:<generator object Tokenizer.cut at 0x0000020DCD754410> Prefix dict has been built succesfully.
word_split = " ".join(wordlist_after_jieba)
process_word=WordCloud.process_text(wordcloud,word_split)
sort = sorted(process_word.items(),key=lambda e:e[1],reverse=True)
print(sort[:50])
# 获取top50的分词输出结果是:
# [('我们', 220), ('一个', 189), ('小程 程序', 64), ('用户', 49), ('很多', 46), ('一些', 45), ('这个', 43), ('大家', 42),
# 分词结果应用于wordcloud
my_wordcloud = WordCloud(font_path='/home/djh/win_font/simhei.ttf',max_words=50).generate(word_split)
# 词云展示
plt.imshow(my_wordcloud)
plt.axis("off")
plt.show()
#-----------------------------版本三、jieba分词&详解---------------------------------
# 精确模式,试图将句子最精确地切开,适合文本分析,默认。
# 全模式,把句子中所有的可以成词的词语都扫描处理,速度非常快,但是不能解决歧义;
# 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于引擎分词。
# jieba.cut 方法接受三个输入参数: 需要分词的字符串;cut_all 参数用来控制是否采用全模式;HMM 参数用来控制是否使用 HMM 模型
# HMM模型:对于未登录词,采用了基于汉字成词能力的 HMM (隐马尔科夫)模型,使用了 Viterbi 算法
# jieba.cut_for_search 方法接受两个参数:需要分词的字符串;是否使用 HMM 模型。该方法适合用于搜索引擎构建倒排索引的分词,粒度比较细
# 待分词的字符串可以是 unicode 或 UTF-8 字符串、GBK 字符串。
# jieba.cut 以及 jieba.cut_for_search 返回的结构都是一个可迭代的 generator
# 可以使用 for 循环来获得分词后得到的每一个词语(unicode)
# 或者用jieba.lcut 以及 jieba.lcut_for_search 直接返回 list
# jieba.Tokenizer(dictionary=DEFAULT_DICT) 新建自定义分词器,可用于同时使用不同词典。
# jieba.dt 为默认分词器,所有全局分词相关函数都是该分词器的映射。
teststr='老杜是大数据专家、云计算专家、微信小程序牛人,他是台湾台中人,如果放到国际中将出问题'
print( '/'.join(jieba.cut(teststr))) #默认等效于精确模式
#老杜是/大/数据/专家/、/云/计算/专家/、/微信/小/程序/牛/人/,/他/是/台湾/台中人/,/如果/放到/国际/中将/出/问题
print( '/'.join(jieba.cut(teststr,cut_all=False))) #精确模式
print( '/'.join(jieba.cut(teststr,cut_all=True))) #全模式
#老/杜/是/大数/数据/专家///云/计算/专家///微/信/小程/程序/牛人///他/是/台湾/台中/台中人/中人///如果/放到/国际/中将/出/问题
#使用 add_word(word, freq=None, tag=None) 和 del_word(word) 可在程序中动态修改词典。
#使用 suggest_freq(segment, tune=True) 可调节单个词语的词频,使其能(或不能)被分出来。
#jieba对大数据、云计算、小程序切分不是很好,所以添加自定义词汇后,再输出观察
jieba.add_word('老杜')
jieba.add_word('大数据')
jieba.add_word('云计算')
jieba.add_word('小程序')
print( '/'.join(jieba.cut(teststr,cut_all=False))) #精确模式
#老杜/是/大数据/专家/、/云计算/专家/、/微信/小程序/牛/人/,/他/是/台湾/台中人/,/如果/放到/国际/中将/出/问题
jieba.suggest_freq(('中', '将'), True) #将中将切分
print( '/'.join(jieba.cut(teststr,cut_all=False, HMM=False))) #精确模式
#老杜/是/大数据/专家/、/云计算/专家/、/微/信/小程序/牛/人/,/他/是/台湾/台中人/,/如果/放到/国际/中/将/出/问题
jieba.suggest_freq(('中将'), True) #将中将合并
print( '/'.join(jieba.cut(teststr,cut_all=False, HMM=False))) #精确模式
#老杜/是/大数据/专家/、/云计算/专家/、/微/信/小程序/牛/人/,/他/是/台湾/台中人/,/如果/放到/国际/中将/出/问题
#删除之前定义的词语
jieba.del_word('老杜')
jieba.del_word('大数据')
jieba.del_word('云计算')
jieba.del_word('小程序')
print( '/'.join(jieba.cut(teststr,cut_all=False))) #精确模式
#老杜是/大/数据/专家/、/云/计算/专家/、/微信/小/程序/牛/人/,/他/是/台湾/台中人/,/如果/放到/国际/中将/出/问题
#在userdict.txt中增加老杜、大数据、云计算、小程序,注意保存为utf-8格式
jieba.load_userdict('userdict.txt')
print( '/'.join(jieba.cut(teststr,cut_all=False))) #精确模式
#老杜/是/大数据/专家/、/云计算/专家/、/微信/小程序/牛/人/,/他/是/台湾/台中人/,/如果/放到/国际/中将/出/问题
#-----------------------------版本四、重新用jieba分词--------------------------------
# 采用结巴进行分词
jieba.suggest_freq(('小程序'), True) #将小程拆解掉
wordlist_after_jieba = jieba.cut(content, cut_all=False)
# 输出结果是:<generator object Tokenizer.cut at 0x0000020DCD754410> Prefix dict has been built succesfully.
# 将分词结果输出展示
word_split = " ".join(wordlist_after_jieba)
process_word=WordCloud.process_text(wordcloud,word_split)
sort = sorted(process_word.items(),key=lambda e:e[1],reverse=True)
print(sort[:50])
# 获取top50的分词输出结果是:
#[('我们', 229), ('一个', 187), ('微信', 65), ('小程序', 64), ('用户', 48), ('一些', 45), ('大家', 42), ('里面', 42), ('所以', 42)】
# 分词结果应用于wordcloud
my_wordcloud = WordCloud(font_path='/home/djh/win_font/simhei.ttf',max_words=50).generate(word_split)
# 词云展示
plt.imshow(my_wordcloud)
plt.axis("off")
plt.show()
#------------------------版本五、追加停用词库,重新用jieba分词-------------------------
#从网上下载了停用词词库,并追加了一些中英文标点符号,当然也可以自己再补充
# 采用结巴进行分词
jieba.load_userdict('userdict.txt')
wordlist_after_jieba = jieba.cut(content, cut_all=False)
# 输出结果是:<generator object Tokenizer.cut at 0x0000020DCD754410> Prefix dict has been built succesfully.
# 将分词结果输出展示
word_split = " ".join(wordlist_after_jieba)
wordlists = word_split.split(' ')
stopwords = open(path.join(d,'stopword.txt'),encoding='gbk',errors='ignore').read()
#此处使用遍历停用词库生成新的分词
new_text = []
for w in wordlists:
if w not in stopwords:
new_text.append(w)
counter = Counter(new_text)
pprint.pprint(counter.most_common(20))
# 获取top50的分词输出结果是:
##[('微信', 77), ('小程序', 64), ('用户', 53), ('小游戏', 32), ('平台', 32), ('希望', 32), ('事情', 30)]
# 分词结果应用于wordcloud
#初始化wordcloud实例,并指定字体类型
wc = WordCloud(font_path='/home/djh/win_font/simhei.ttf',max_words=50)
#根据文本绘制云图
wc.generate_from_text(" ".join(new_text))#根据文本绘制云图
# 词云展示
plt.imshow(wc)
plt.axis("off")
plt.show()