在进行了上一个实验《利用Python定制个性化词云》之后,掌握了初步的词云制作。出于对三国历史的喜爱,因此想制作一个关于《三国演义》版的词云,以一个新的角度去看这段历史。但由于本人掌握的数据分析技术有限,直接处理原版的《三国演义》难度很大(因为原版中很多简称,例如“公”、只称名不称姓等),因此文本内容使用的是《白话三国》(电子赵括 著)的TXT版本(讲真~找个可以分析的白话版TXT文档真的不容易)。
实验环境:python 3.6
涉及扩展包:re、pandas、pickle、codecs、jieba、wordcloud (这里需要安装jieba、wordcloud,此处采用了pip安装)
jieba:
pip install jieba
wordcloud:
pip install wordcloud
古代很多人都有自己的“字号”,如诸葛亮,字孔明。例如在白话文中大部分称诸葛亮,但仍有部分称作孔明。因此需要我们找到这些对应关系,并进行替换。这里使用的是百度知道上一个较为完整的回答,并且格式较为标准,便于处理。
问题及回答的地址:https://zhidao.baidu.com/question/192918537.html,部分数据如下,
将内容复制到TXT文档中,并以utf-8格式进行保存(因为之后的处理过程中是默认以utf-8的方式进行的)。要想进行替换,我们需要将上述数据处理为字典格式。观察数据格式,需要做以下处理:
1、去掉多余的空格;
2、通过split拆分数据,并作成字典格式;
3、用生成的字典替换原文中的字号,并保存替换后的文本;
4、将姓名及词性以字典的形式保存(该文件用于之后的词云生成)。
代码如下:
import re
import pandas as pd
import pickle
with open('F:/sanguo/namelist.txt','r',encoding='utf-8') as f:
result = f.readline()
f.close()
#去掉多余的空格
result=re.sub(r'\s+', '', result)
#以括号切分数据 ,把姓名和字号整理为字典格式
a=result.split(")")
del a[len(a)-1]
dict_ming_zi=pd.DataFrame(columns=['ming','zi'])
j=0
for i in a:
dict_ming_zi.loc[j,'ming']=str(i).split("(")[0]
dict_ming_zi.loc[j,'zi']=str(i).split("(")[1]
j+=1
#替换原文中的字号,并保存替换文本
with open('F:/sanguo/三国演义白话本.txt','r',encoding='utf-8') as f1:
original_text = f1.read()
f1.close()
for i in range(len(dict_ming_zi)):
original_text=original_text.replace(dict_ming_zi.iloc[i,1],dict_ming_zi.iloc[i,0])
with open('F:/sanguo/三国演义替换文.txt','w',encoding='utf-8') as f2:
f2.write(original_text)
f2.close()
#将姓名及词性以字典的形式保存(该文件用于之后的词云生成)
list_ming=[]
list_ming= dict_ming_zi['ming']
name_dict={}
for i in list_ming:
name_dict[i]='nr'
with open('F:/sanguo/dict_name.txt','wb') as f3:
pickle.dump(name_dict,f3)
f3.close()
通过以上操作,我们得到了三国演义替换文本.txt和dict_name.txt两个文档。
关于词云的生成,在上一个实验《利用Python定制个性化词云》中已经做出了较为详细的介绍,此处不再赘述。此处的背景用的是三国鼎立时期的势力划分图。
经美图秀秀处理后的结果:
接下来是完整的词云生成代码:
import codecs
import jieba
import pickle
import numpy as np
from scipy.misc import imread
from wordcloud import WordCloud
import matplotlib.pyplot as plt
#生产词云文本
def seg_sentence(file_name):
file=open('f:/sanguo/dict_name.txt','rb') #读取dict_name文档,用于jieba的自定义词典和关键词的筛选
dict_name = pickle.load(file)
jieba.load_userdict(dict_name)
with codecs.open(file_name,encoding='utf-8') as f: #读取文档
original_text = f.read()
wordList = jieba.cut(original_text) #全文分词,结果存储在wordlist中
print('---全文分词完成---')
allow_pos = ('nr',) #设置筛选参数为”nr“,名字
tags = jieba.analyse.extract_tags(original_text, topK=1000, withWeight=False, allowPOS=allow_pos) #从原文文本original_text中,筛选词性为”nr“的前30个词汇作为关键词
print('---关键词筛选完成---')
stags=" ".join(tags) #将关键词通过空格连接为字符串stags
f2=open(u"stags.txt","w+") #将获得的关键词存储到stags.txt文件中(供调试查看)
f2.write(stags)
f2.write("\n")
f2.close()
count=0
outstr = ''
for word in wordList: #遍历全文分词结果wordlist
if word in stags: #与关键词字符串比较,只保留关键词
if word in dict_name: #在关键词中只保留人名
if len(word) > 1: # 去掉长度小于1的词
if word != '\t':
outstr += word
outstr += " "
count=count+1
print ("---词云文本完成---")
return outstr #将保留下的词输出到字符串outstr中,通过空格连接为字符串
# 绘制词云
def draw_wordcloud(file_name):
outstr=seg_sentence(file_name) #调用分词函数,生成只包含关键词的分词文本outstr,字符串格式
f2=open(u"分词后.txt","w+") #将outstr保存到 分词后.txt文件中 (供调试查看)
f2.write(outstr)
f2.write("\n")
f2.close()
font='C:\Windows\Fonts\STXINGKA.TTF' #选择字体路径
color_mask = imread("F:\sanguo\map_副本.jpg") #读取模板图片,这里使用了一张五角星图片
#设置词云参数,字体,模板,背景白色,最大词量1000个,最大字体尺寸60
cloud = WordCloud(font_path=font,background_color='white',mask=color_mask,max_words=1000,min_font_size=1,max_font_size=60,scale=2,height=500,width=500,relative_scaling=1)
word_cloud = cloud.generate(outstr) # 产生词云数据 word_cloud
print ("---词云完成---")
word_cloud.to_file("w_cloud.jpg") #词云保存为图片w_cloud.jpg
print ("---词云保存成功---")
return word_cloud
file_name = 'F:\sanguo\三国演义替换文.txt' #设置小说文本所在路径
word_cloud=draw_wordcloud(file_name) #调用词云生成函数,生成词云word_cloud,并保存成为图片
plt.figure(figsize=(20,20))
plt.imshow(word_cloud)
plt.axis("off")
plt.show() #显示词云图
生成的词云是这样的:
此时词云参数relative_scaling设置为1,反应的是词频与词大小的关联度为1,只能说曹操的出场率很高呀,刘皇叔、诸葛亮等众人只能算配角了。(ps.词的位置是随机的)
这样可以准确的反映词频,词频高的关键词字体会比较大。但是这样的词云看起来并不美观,因此我们将relative_scaling改为了0.5,此时生成的词云如下:
这样看上去,比刚才好多了。
至此此次分析实验结束,可能还有小伙伴感觉不是很美观,这个可以根据自己的喜好调整背景图和词云参数。此次是在上篇文章的基础上完成的,因此介绍的基础内容比较少,只是讲了分析处理流程。源码、文档及图片资源已经上传,如需下载请点击:python词云进阶——三国版
欢迎大家交流学习,QQ:285899326。