赞
踩
此文比较适合第一次做情感分析,结巴分词,统计词频,生成词云,画统计图的同学,应该会让你们少走点弯路。
完整代码放最后面,前面是解决各种可能出现的问题。建议一步一步做,都可以理解的。
代码如下(示例):
import json
import jieba
import nltk
import os
from wordcloud import WordCloud,ImageColorGenerator
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from snownlp import SnowNLP
from snownlp import SnowNLP
from pylab import *
我是用Windows下的pycharm做的,其中的Wordcloud库的安装,pycharm会报错。以后遇到这类问题,有个很好用的办法。
步骤:
1.先到python的官网下载你想要的包,注意,要对应你python解释器的版本,满足3.91,64位机之类的一些要求。
2.进去终端,先进入到包下载位置的对应路径,然后pip install wordcloud,如果报错说没有wheel,那就在重新进入终端,输入pip install wheel,然后再安装对应的库。这样可以解决绝大多数包安装错误的问题。
我在生成统计图时,统计图的标题和横坐标全都是方框,这就是中文乱码,解决方法就是下面这两行代码放进去就好,具体看我完整代码。
# from pylab import * 这个包就是下面两句代码用的
#处理统计图中中文会出现乱码的问题
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
我这边是从一个大文件下读取文件,文件夹中有130个json文件,那就需要os库对文件夹进行遍历,获取文件夹下的文件名字,方便打开,读取。上代码:
def get_txt():
fpath = 'D:/编程project/后汉书_译文' #这是文件夹对应我电脑的路径
flist = os.listdir(fpath) #得到文件夹下的所有文件名称
data_2 = '' #我这边是把这些想要的内容拼接在一起
for file in flist: # 遍历文件夹
fpath_2 = fpath + '/' + file #这里就是每个循环要打开的文件的路径了
of = open(fpath_2, 'r', encoding='utf-8') # 打开文件
diclist = json.load(of) #读取json文件
of.close()
data_1 = str(diclist['content']) #读取的json文件内容是字典,我要的是键值对,键为content对应的值
data_2 = data_1 + data_2
return data_2 #要返回的就是最后获取的字符串了
一篇文章,你要对他的词频进行统计,那就尽量使得获取到了的大部分词频是有意义的,那就要从获取到的词频中选出那些经常出现但又没有意义的词。然后从词频中去掉这些词,这就叫去除停用词。
对了,要词频统计,要先分词啊。就先介绍一下最好用的中文分词的库,结巴库。
上代码:
text='今天天气真好,那就出去玩吧'
word1=jieba.cut(text,cut_all=False)
print("精确模式 "+' '.join(word1))
word2=jieba.cut(text,cut_all=True)
print('全模式 '+' '.join(word2))
word3=jieba.cut_for_search(text)
print('搜索引擎模式 '+' '.join(word3))
运行结果就是:
精确模式 今天天气 真 好 , 那 就 出去 玩吧
全模式 今天 今天天气 天天 天气 真好 , 那 就 出去 出去玩 玩吧
搜索引擎模式 今天 天天 天气 今天天气 真 好 , 那 就 出去 玩吧
简单的了解了结巴分词,那就可以做词频统计啦
首先构建停用词库,并写入文件存到对应的盘,我这边是用sorted函数对词频进行降序排序,也就是从大到小的顺序,其中有用replace函数去除一些存在的没有意义的符号。
def get_first_stopwords(): #获得没去除停用词的词频文档,进行构建停用词库
data=get_txt()
word = jieba.cut(data, cut_all=False)
freq = nltk.FreqDist(word)
puts_1=open('D:/编程project/make_stopwords.txt','w',encoding='utf-8')
puts_1.writelines('以下是词频结果'+'\n')
for key, val in sorted(freq.items(), key=lambda x: (x[1], x[0]), reverse=True):
work=(str(key) + ':' + str(val))
work=work.replace('’','').replace('‘','').replace('?','')
puts_1.write(work + '\n')
puts_1.close()
这时,你针对获取到的词频,选出那些高频低价值的词,构建停用词库,一行一个吧,比较简明清晰。这个停用词库是你自己新建一个txt文档自己编写。
下面这个文档就是自己编写的,然后读取返回里面的停用词。
def get_stopwords():
files=open('D:/编程project/1913206138_stopword .txt','r').read()
return files
接下来就是重点,进行分词和统计词频。
def jiebafc(data,stopwords): word = jieba.cut(data, cut_all=False) final='' for seg in word: #这个循环就是去除停用词,非常好理解 if seg not in stopwords: final +=seg final = jieba.cut(final, cut_all=False) #上面循环得到的是一个大字符串,这里要再分词 final_2= '' for seg in final: #这个循环是去除里面的空格,我也不知道为啥有空格,你们看实际情况。 if seg !='': final_2 += seg final_2 = jieba.cut(final_2, cut_all=False) freq=nltk.FreqDist(final_2) #这个就是获取词频的函数调用了,和上面获取停用词库类似。 puts_1=open('D:/编程project/new_1913206138_worddist.txt','w',encoding='utf-8') puts_1.writelines('以下是词频结果'+'\n') for key, val in sorted(freq.items(), key=lambda x: (x[1], x[0]), reverse=True): work=(str(key) + ':' + str(val)) work=work.replace('’','').replace('‘','').replace('?','') puts_1.write(work + '\n') puts_1.close() print("统计词频及写入文件结束!") #这边因为整体代码不止词频统计,这边能看到词频是不是完成写入了。
def ciyun_get(data): stopwords=get_stopwords() #用获取到的频率最高的词中去除的无意义词 word = jieba.cut(data, cut_all=False) final='' for seg in word: if seg not in stopwords: final+=seg final = jieba.cut(final, cut_all=False) stopwords_2 = {}.fromkeys(['章节', '目录', '后汉书', '一章', '』', '『', ' ','”','“','"']) final_2= '' for seg in final: if seg not in stopwords_2: final_2 += seg final_2 = jieba.cut(final_2, cut_all=False) #上面的代码任然是去除停用词和一下我爬到的一些没用的东西 background_image=np.array(Image.open('D:/壁纸/cipin_1.png')) #如下图 txt=(' '.join(final_2)) wcd=WordCloud(background_color='white',mask=background_image, max_font_size=40, max_words=4000, margin=2,font_path="C:/Windows/Fonts/simfang.ttf", ).generate(txt).to_file('cipin-yuntu.png') #这个是写成文件,会在你当前目录下生成。 image_colors=ImageColorGenerator(background_image) plt.imshow(wcd.recolor(color_func=image_colors),interpolation="bilinear") #这两行代码的意思就是从图片中提取到的颜色用到词云的颜色上 plt.axis('off') plt.show #显示词云
这个就是要用到的词云的显示模板,注意,图片的非图形部分一定要是空白背景,不然生成的词云就不是特定的形状了。用美图秀秀就可以抠图了,很简单!
这个就是我生成的词云了
先上代码:
分析在代码下面
def get_clueimage(): fpath = 'D:/编程project/后汉书_译文' flist = os.listdir(fpath) # 得到文件夹下的所有文件名称 data_2 = [] data_3 = [] for file in flist: # 获取每篇文章的名字 file = file.replace('《', '').replace('》', '').replace('_译文.json', '') file = file.replace('后汉书·', '').replace('志·', '').replace('列传·', '') file = file.replace('.json', '').replace('本纪·', '') data_3.append(file) n = 0 # 对文章名的计数器 st = [] # 存每篇文章总体的平均情感值 for file in flist: # 遍历文件夹 fpath_2 = fpath + '/' + file of = open(fpath_2, 'r', encoding='utf-8') # 打开文件 diclist = json.load(of) of.close() data_1 = str(diclist['content']) content_1 = SnowNLP(data_1) sw = [] # 存一篇文章的每个句子的情感值 for i in range(0, len(content_1.sentences)): content_2 = SnowNLP(content_1.sentences[i]) sw.append(content_2.sentiments) ave_1 = np.mean(sw) st.append(ave_1) # print(data_3[n], '情感正负面平均值:{}'.format(ave_1)) # n = n + 1 #上两行代码打印出每篇具体的情感值 fig, ax = plt.subplots(figsize=(12, 7)) ax.bar(data_3, #横坐标 st, #纵坐标 width=0.06, # 柱子宽度,默认0.8,两根柱子中心的距离默认为1.0 align="center", # 柱子的对齐方式,'center' or 'edge' color="blue", # 柱子颜色 edgecolor="blue", # 柱子边框的颜色 linewidth=2.0) # 柱子边框线的大小 plt.xticks(data_3, rotation=90, fontsize=4) # 这里是调节横坐标的倾斜度,rotation是度数 plt.ylabel('情感正负面平均值', fontsize=10) plt.xlabel('本纪', fontsize=10) ax.set_title('史书情感统计图', fontsize=15) plt.show()
其实我感觉已经很详细了,先说一下我走的弯路吧,我先是把这些文本划分成一个个句子存进列表里面的,然后做循环,进行情感分析,然后对这篇文章的情感值做平均。但是中文是不能这么进行情感分析的,当然了,英文也不能。这样得到的值差异太大了,你们可以尝试一下。划分的部分代码先贴出来。
pattern = r',|。|! |? ' # 以标点进行划分
for i in range(130):
result_lists = re.split(pattern, data_2[i])
data_4.append(result_lists)
这里面的data_2是130篇史书的字符串,这样能划分成一个个句子。但会有空字符串,下面就是去除空字符串的代码。
for i in data_4:
while '' in i: # 去除空字符串
i.remove('')
print(data_4[3])
好了好了,上最后的代码吧
可以自己一步一步调试。
import json import jieba import nltk import os from wordcloud import WordCloud,ImageColorGenerator from PIL import Image import numpy as np import matplotlib.pyplot as plt from snownlp import SnowNLP from snownlp import SnowNLP from pylab import * #处理统计图中中文会出现乱码的问题 mpl.rcParams['font.sans-serif'] = ['SimHei'] mpl.rcParams['axes.unicode_minus'] = False def get_txt(): fpath = 'D:/编程project/后汉书_译文' flist = os.listdir(fpath) # 得到文件夹下的所有文件名称 data_2 = '' for file in flist: # 遍历文件夹 fpath_2 = fpath + '/' + file of = open(fpath_2, 'r', encoding='utf-8') # 打开文件 diclist = json.load(of) of.close() data_1 = str(diclist['content']) data_2 = data_1 + data_2 return data_2 def get_stopwords(): files=open('D:/编程project/1913206138_stopword .txt','r').read() return files def get_first_stopwords(): #获得没去除停用词的词频文档,进行构建停用词库 data=get_txt() word = jieba.cut(data, cut_all=False) freq = nltk.FreqDist(word) puts_1=open('D:/编程project/make_stopwords.txt','w',encoding='utf-8') puts_1.writelines('以下是词频结果'+'\n') for key, val in sorted(freq.items(), key=lambda x: (x[1], x[0]), reverse=True): work=(str(key) + ':' + str(val)) work=work.replace('’','').replace('‘','').replace('?','') puts_1.write(work + '\n') puts_1.close() def jiebafc(data,stopwords): word = jieba.cut(data, cut_all=False) final='' for seg in word: if seg not in stopwords: final +=seg final = jieba.cut(final, cut_all=False) final_2= '' for seg in final: if seg !='': final_2 += seg final_2 = jieba.cut(final_2, cut_all=False) freq=nltk.FreqDist(final_2) puts_1=open('D:/编程project/new_1913206138_worddist.txt','w',encoding='utf-8') puts_1.writelines('以下是词频结果'+'\n') for key, val in sorted(freq.items(), key=lambda x: (x[1], x[0]), reverse=True): work=(str(key) + ':' + str(val)) work=work.replace('’','').replace('‘','').replace('?','') puts_1.write(work + '\n') puts_1.close() print("统计词频及写入文件结束!") def ciyun_get(data): stopwords=get_stopwords() #用获取到的频率最高的词中去除的无意义词 word = jieba.cut(data, cut_all=False) final='' for seg in word: if seg not in stopwords: final+=seg final = jieba.cut(final, cut_all=False) stopwords_2 = {}.fromkeys(['章节', '目录', '后汉书', '一章', '』', '『', ' ','”','“','"']) final_2= '' for seg in final: if seg not in stopwords_2: final_2 += seg final_2 = jieba.cut(final_2, cut_all=False) background_image=np.array(Image.open('D:/壁纸/cipin_1.png')) txt=(' '.join(final_2)) wcd=WordCloud(background_color='white',mask=background_image, max_font_size=40, max_words=4000, margin=2,font_path="C:/Windows/Fonts/simfang.ttf", ).generate(txt).to_file('cipin-yuntu.png') image_colors=ImageColorGenerator(background_image) plt.imshow(wcd.recolor(color_func=image_colors),interpolation="bilinear") plt.axis('off') plt.show def get_clueimage(): fpath = 'D:/编程project/后汉书_译文' flist = os.listdir(fpath) # 得到文件夹下的所有文件名称 data_2 = [] data_3 = [] for file in flist: # 获取每篇文章的名字 file = file.replace('《', '').replace('》', '').replace('_译文.json', '') file = file.replace('后汉书·', '').replace('志·', '').replace('列传·', '') file = file.replace('.json', '').replace('本纪·', '') data_3.append(file) n = 0 # 对文章名的计数器 st = [] # 存每篇文章总体的平均情感值 for file in flist: # 遍历文件夹 fpath_2 = fpath + '/' + file of = open(fpath_2, 'r', encoding='utf-8') # 打开文件 diclist = json.load(of) of.close() data_1 = str(diclist['content']) content_1 = SnowNLP(data_1) sw = [] # 存一篇文章的每个句子的情感值 for i in range(0, len(content_1.sentences)): content_2 = SnowNLP(content_1.sentences[i]) sw.append(content_2.sentiments) ave_1 = np.mean(sw) st.append(ave_1) # print(data_3[n], '情感正负面平均值:{}'.format(ave_1)) # n = n + 1 #上两行代码打印出每篇具体的情感值 fig, ax = plt.subplots(figsize=(12, 7)) ax.bar(data_3, #横坐标 st, #纵坐标 width=0.06, # 柱子宽度,默认0.8,两根柱子中心的距离默认为1.0 align="center", # 柱子的对齐方式,'center' or 'edge' color="blue", # 柱子颜色 edgecolor="blue", # 柱子边框的颜色 linewidth=2.0) # 柱子边框线的大小 plt.xticks(data_3, rotation=90, fontsize=4) # 这里是调节横坐标的倾斜度,rotation是度数 plt.ylabel('情感正负面平均值', fontsize=10) plt.xlabel('本纪', fontsize=10) ax.set_title('史书情感统计图', fontsize=15) plt.show() if __name__ == '__main__': data=get_txt() stopword=get_stopwords() jiebafc(data,stopword) ciyun_get(data) get_clueimage()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。