一直想做一个词云,在看实例的时候发现了一位博主写了篇关于励志歌曲的词云,由此想分析一下陈奕迅歌词中出现的较高频率的词是什么。于是我在百度文库上找到了一部分歌词,做了这个小分析。需要用到的库有:wordcloud,jieba,PIL,numpy,matplotlib
首先是读取歌词文件
def Read(self,path): lyric = '' try: file = open(path,'r') for i in file: lyric+=file.read() return lyric except Exception as e: print(e) return finally: file.close()
在此之后,需要对歌词进行分析,用到的是jieba.analyse.extract_tags()方法,再用textrank时不能显示陈奕迅关键字,于是换了。
def Analyse(self,text): result = jieba.analyse.extract_tags(text,topK = 40,withWeight = True) keywords = dict() for i in result: keywords[i[0]]=i[1] #print(keywords) return keywords
在分析出关键词之后则进入制作词云的部分
def Picture(self,keywords): image = Image.open('F:Python_Programeason.png') graph = np.array(image) wc = WordCloud(font_path = 'C:WindowsFontsSTZHONGS.TTF',background_color='White',max_words=50,mask=graph) wc.generate_from_frequencies(keywords) image_color = ImageColorGenerator(graph) plt.imshow(wc) plt.imshow(wc.recolor(color_func=image_color)) plt.axis("off") plt.show() wc.to_file('dream.png')
完整代码
import jieba import jieba.analyse from PIL import Image,ImageSequence import numpy as np import matplotlib.pyplot as plt from wordcloud import WordCloud,ImageColorGenerator class CW_test(object): def __init__(self): self.path = r'F:Python_Programlyric.txt' def Read(self,path): lyric = '' try: file = open(path,'r') for i in file: lyric+=file.read() return lyric except Exception as e: print(e) return finally: file.close() def Analyse(self,text): result = jieba.analyse.extract_tags(text,topK = 40,withWeight = True) keywords = dict() for i in result: keywords[i[0]]=i[1] print(keywords) return keywords def Picture(self,keywords): image = Image.open('F:Python_Programeason.png') graph = np.array(image) wc = WordCloud(font_path = 'C:WindowsFontsSTZHONGS.TTF',background_color='White',max_words=50,mask=graph) wc.generate_from_frequencies(keywords) image_color = ImageColorGenerator(graph) plt.imshow(wc) plt.imshow(wc.recolor(color_func=image_color)) plt.axis("off") plt.show() wc.to_file('eason.png') def main(): ct = CW_test() text = ct.Read(ct.path) keywords = ct.Analyse(text) ct.Picture(keywords) if __name__ == "__main__": main()
得到的结果:
虽然步骤看起来很简单,但是其中也遇到了一些问题,做如下总结:
- 在生成词云时,由于是中文,所以最初的图片中是一些方框,没有字,后来知道是因为默认字体不能显示中文,于是使用了系统默认中文字体 “ font_path = 'C:WindowsFontsSTZHONGS.TTF' ”,但是使用我自己下的字体仍然显示方框。
- 生成第一个词云时,并没有“陈奕迅”关键字,私心想加上,于是在文本中添加,之后却发现不能提取出来。以为是jieba不能将“陈奕迅”正确分词,于是使用jieba.add_word,但是发现并没有什么用。于是做了一个小测试,如下:
>>>str1 = r"陈奕迅陈奕迅陈奕迅陈奕迅有一天我发现自怜资格都已没有只剩下不知疲倦的肩膀担负着简单的满足" >>>seg = jieba.cut(str1,cut_all = False) >>>print("/ ".join(seg)) >>>陈奕迅/ 陈奕迅/ 陈奕迅/ 陈奕迅/ 有/ 一天/ 我/ 发现/ 自怜/ 资格/ 都/ 已/ 没有/ 只/ 剩下/ 不知疲倦/ 的/ 肩膀/ 担负/ 着/ 简单/ 的/ 满足
发现“陈奕迅”是可以被正确分词的,于是将textrank方法换成了extract_tags方法。
- 对于jieba这个库还不太了解,会专门写一篇学习笔记。
2017.10.15更新
今天把这个代码好好捋了一遍,比之前思路更清晰,做了一点小改动,出来了下面这个效果
import jieba.analyse from PIL import Image import numpy as np import wordcloud from matplotlib import pyplot as plt class WC_eason(object): """docstring for WC_eason""" def __init__(self): self.path = r"F:/Python_Program/lyric.txt" def Read(self): lyric = '' try: file = open(self.path,'r') lyric = file.read() return lyric except: print("error") def Analyse(self,text): #jieba.analyse.extract_tags(sentence, topK = 20, withWeight = False, allowPOS = ()) results = jieba.analyse.extract_tags(text,topK = 50) #计算词频 #results = jieba.cut(text) #print("hello") #print(results) return results def Draw(self,results): image = np.array(Image.open(r"F:/Python_Program/eason.png")) my_wordcloud = wordcloud.WordCloud( background_color = 'white', #设置背景颜色 mask = image , #设置背景图片 max_words = 50, #设置最大词数 font_path = 'C:WindowsFontsSTZHONGS.TTF', #设置字体,否则不能显示中文 stopwords = wordcloud.STOPWORDS ) #my_wordcloud.generate_from_frequencies(results) #生成词云,计算好词频后使用该函数,results应为字典 cut_results = " ".join(results) my_wordcloud.generate(cut_results) image_color = wordcloud.ImageColorGenerator(image) #根据背景图片生成颜色值 #显示图片 plt.figure() plt.imshow(my_wordcloud) plt.axis("off") plt.show() def main(): we = WC_eason() text = we.Read() data = we.Analyse(text) #for item in data: # print(item) we.Draw(data) if __name__ == "__main__": main()
在这个版本里没有用到image_color这个变量,因此所产生词云颜色与背景图片并无关系。