python词云进阶——三国版

1 实验内容

             在进行了上一个实验《利用Python定制个性化词云》之后,掌握了初步的词云制作。出于对三国历史的喜爱,因此想制作一个关于《三国演义》版的词云,以一个新的角度去看这段历史。但由于本人掌握的数据分析技术有限,直接处理原版的《三国演义》难度很大(因为原版中很多简称,例如“公”、只称名不称姓等),因此文本内容使用的是《白话三国》(电子赵括 著)的TXT版本(讲真~找个可以分析的白话版TXT文档真的不容易)。

2 前期准备

实验环境: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两个文档。

3 词云的生成

关于词云的生成,在上一个实验《利用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。

  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值