使用Python做中文分词和绘制词云

使用Python做中文分词和绘制词云

cloud

李小璐出轨云词图

作为一门编程语言,Python的编写简单,支持库强大,应用场景多,越来越多的人开始将它作为自己的编程入门语言。

Python一个比较重要的场景是做舆情分析,比如分析社交网络上群众对某一话题的态度,分析股民的情绪作为投资参考等。最近笔者也做了一些舆情分析(八卦)方面的工作,一个完整的分析流程包括:

  1. 数据获取:使用爬虫在相关网站上获取文本内容
  2. 数据清洗:按一定格式对文本数据进行清洗和提取(文本分类,贴标签)
  3. 数据呈现:多维度呈现和解读数据(计算,做表,画图)

今天呢,作为系列分享之一,笔者就以李小璐出轨事件为例,使用从知乎热门回答上爬取的中文文本数据,绘制云词图

中文分词

所谓分词即是将文本序列按完整的意思切分成一个一个的词儿,方便进行下一步的分析(词频统计,情感分析等)。

由于英文词与词自带空格作为分隔符,相比于中文分词要简单的多。我们在做中文分词时,需要把词语从一整段话中筛出来,困难之处在于,汉语表达博大精深,一段话往往有不同的切分方法。

所幸这不是我们需要担心的,Python中的Jieba库提供了现成的解决方案:

import jieba
text="李小璐给王思聪买了微博热搜"
result=jieba.cut(text)
print("切分结果:  "+",".join(result))

jiaba调用了自己的分词算法,将切分好的文本按逗号分隔符分开,得到下面结果

切分结果:  李小璐,给,王思聪,买,了,微博热,搜,。

可见切分结果不尽如人意,比较明显的是,“微博”,“热搜”就没有被识别出来,其次有一些词,比如“了” “买”以及标点符号,显然我们不想让这些词出现在云词图里,因为它们本身没什么意义。

特殊名词

对于某些特别的名词,为了使得其切分时不被分开,我们可以选择在切分前强调一下这些名词,比如:

text="李小璐给王思聪买了微博热搜"
#强调特殊名词
jieba.suggest_freq(('微博'), True)
jieba.suggest_freq(('热搜'), True)
result=jieba.cut(text)
print("切分结果:  "+",".join(result))
切分结果:  李小璐,给,王思聪,买,了,微博,热搜,。

还可以将特殊用词加入用户自定义词典,实现相同的效果:

jieba.load_userdict("./utils/jieba_user_dict.txt")

文本清洗

  1. 切分之后一些特殊的符号会单独成词,这些词会影响我们之后的分析。这里我们可以使用一个标点符号库 stopwords.txt(点击下载),将切分出来的特殊符号剔除掉。
  2. 对于“了”,“的”这样长度为一的词,显然对我们分析文本没有任何帮助。处理的方法为将长度为1的词全部剔除掉。

实现代码

import jieba
#读取标点符号库
f=open("utils/stopwords.txt","r")
stopwords={}.fromkeys(f.read().split("\n"))
f.close()
#加载用户自定义词典
jieba.load_userdict("./utils/jieba_user_dict.txt")
segs=jieba.cut(text)
mytext_list=[]
#文本清洗
for seg in segs:
    if seg not in stopwords and seg!=" " and len(seg)!=1:
        mytext_list.append(seg.replace(" ",""))
cloud_text=",".join(mytext_list)

绘制云词图

做好了中文分词,下一步即是绘制云词图了。这里我们使用了另一个比较强大的库WordCloud

from wordcloud import WordCloud
wc = WordCloud(
    background_color="white", #背景颜色
    max_words=200, #显示最大词数
    font_path="./font/wb.ttf",  #使用字体
    min_font_size=15,
    max_font_size=50, 
    width=400  #图幅宽度
    )
wc.generate(cloud_text)
wc.to_file("pic.png")

运行以上代码就可以直接出图了:

cloud

参数说明

WordCloud在生成对象时,提供了多个参数:

Parameters
 |  ----------
 |  font_path : string
 |       使用的字体库
 |  width : int (default=400)
 |      图片宽度
 |  height : int (default=200)
 |      图片高度
 |  mask : nd-array or None (default=None)
 |      图片背景参考形状  
 |  scale : float (default=1)
 |      图幅放大、缩小系数  
 |  min_font_size : int (default=4)
 |      最小的字符
 |  min_font_size : int (default=4)
 |      最大的字符
 |  max_words : number (default=200)
 |      最多显示的词数
 |  stopwords : set of strings or None
 |      不需要显示的词
 |  background_color : color value (default="black")
 |      背景颜色
 |  ......

绘制指定形状的云词图

cloud

在绘制云词图的时候,可以通过WordCloud的mask参数,可以指定词图的轮廓,绘制成各种形状的图片。比如我们想用以上这张图片,WordCloud会识别出除纯白的的部分作为轮廓。具体实现如下:

#加载需要使用的类库
from PIL import Image
import numpy as np
from wordcloud import WordCloud, ImageColorGenerator
from matplotlib import pyplot as plt
#加载背景图片
cloud_mask = np.array(Image.open("./bc_img/heart.jpeg"))
#忽略显示的词
st=set(["东西","这是"])
#生成wordcloud对象
wc = WordCloud(background_color="white", 
    mask=cloud_mask,
    max_words=200,
    font_path="./font/wb.ttf",
    min_font_size=15,
    max_font_size=50, 
    width=400, 
    stopwords=st)
wc.generate(cloud_text)
wc.to_file("pic.png")

调用以上代码就得到了一张心形状的云词图:

cloud

使用PS稍加处理,就得到了下面这张图~

cloud

李小璐出轨云词图

关注 “果果数据”公众号,获取全部代码,还可以看到更多教程O(∩_∩)O~

果果

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试