1.詞頻統(tǒng)計(jì)
在詞頻統(tǒng)計(jì)之前,需要先完成分詞工作。因?yàn)樵~頻統(tǒng)計(jì)是基于分詞后所構(gòu)建的list進(jìn)行的。
import jieba
#對(duì)小說(shuō)文本第一回分詞
word_list = jieba.lcut(chapter.txt[1])
word_list[:10]
['第一回', ' ', '風(fēng)雪', '驚變', '錢(qián)塘江', '浩浩', '江水', ',', '日日夜夜', '無(wú)窮']
1.1使用Pandas統(tǒng)計(jì)
#使用pandas統(tǒng)計(jì)
#將數(shù)據(jù)放入DataFrame
import pandas as pd
df = pd.DataFrame(word_list, columns = ['word'])
df.head(10)
word
0 第一回
1
2 風(fēng)雪
3 驚變
4 錢(qián)塘江
5 浩浩
6 江水
7 ,
8 日日夜夜
9 無(wú)窮
#統(tǒng)計(jì)并降序排列
result = df.groupby(['word']).size()
print(type(result))
freqlist = result.sort_values(ascending=False)
freqlist[:10]
<class 'pandas.core.series.Series'>
word
, 2034
。 714
了 400
“ 344
: 343
” 342
的 291
道 210
他 187
是 167
dtype: int6
1.2 使用NLTK統(tǒng)計(jì)
NLTK的生成結(jié)果為頻數(shù)字典,可以被一些程序包直接調(diào)用
import nltk
#生成完整的詞條頻數(shù)字典
fdist = nltk.FreqDist(word_list)
fdist
#查看某詞出現(xiàn)的次數(shù)
fdist['顏烈']
37
#列出詞條列表
fdist.keys()
#頻率分布表
fdist.tabulate(10)
, 。 了 “ : ” 的 道 他 是
2034 714 400 344 343 342 291 210 187 167
#高頻詞匯Top10
fdist.most_common(10)
[(',', 2034),
('。', 714),
('了', 400),
('“', 344),
(':', 343),
('”', 342),
('的', 291),
('道', 210),
('他', 187),
('是', 167)]
2.詞云圖
詞云實(shí)際上是對(duì)分詞結(jié)果頻數(shù)表的圖形化展示,使得瀏覽者能快速發(fā)現(xiàn)文本的核心內(nèi)容。
常見(jiàn)的詞云工具有:
-
Python
- 生成比較標(biāo)準(zhǔn)的詞云
- 可以對(duì)背景圖片進(jìn)行修飾
-
R
- 可以展示不同類(lèi)別間的詞云比較
- 可以實(shí)現(xiàn)彩色動(dòng)態(tài)效果的詞云
- 可以對(duì)背景圖片進(jìn)行修飾
-
Tableau
- 可以實(shí)現(xiàn)詞云結(jié)果的動(dòng)態(tài)監(jiān)測(cè)和展示
2.1wordcloud包安裝
wordcloud包不太好安裝,這里給一些攻略:
Anaconda 3.6安裝wordcloud 詞云出現(xiàn)問(wèn)題
Anaconda安裝jieba、wordcloud等第三方庫(kù)
對(duì)于wordcloud,我們需要指定中文字體支持
WordCloud(font_path='xxx')
以上需要寫(xiě)字體文件所在的完整路徑
2.2 wordcloud包用法
class wordcloud.WordCloud(
font_path=None,
width=400,
height=200,
margin=2,
ranks_only=None,
prefer_horizontal=0.9,
mask=None,
scale=1,
color_func=None,
max_words=200,
min_font_size=4,
stopwords=None,
random_state=None,
background_color='black',
max_font_size=None,
font_step=1,
mode='RGB',
relative_scaling=0.5,
regexp=None,
collocations=True,
colormap=None,
normalize_plurals=True)
常用功能:
- font_path = None:字體路徑,默認(rèn)使用系統(tǒng)字體
- width = 400 :寬度
- height = 200:高度
- max_words = 200:需要繪制的詞條最大數(shù)目
- stopwords = None:停用詞列表
字體設(shè)定:
- min_font_size=4 / max_font_size=None:字符大小范圍
- font_step=1:字號(hào)增加的步長(zhǎng)
- relative_scaling=0.5:詞頻和字號(hào)的換算關(guān)系
- prefer_horizontal=0.9:詞條水平顯示的比例
顏色設(shè)定:
- background_color='black':圖形背景色
- mode='RGB':圖形顏色編碼,如果指定為“RGBA”且背景色為None時(shí),背景色為透明
- color_func=None:生成新顏色的函數(shù),使用matplotlib的colormap
背景掩模:
- mask=None:詞云使用過(guò)的背景圖
用wordcloud繪制特定文本的詞云時(shí),需要用空格或標(biāo)點(diǎn)符號(hào)對(duì)文本進(jìn)行分隔,以便后續(xù)對(duì)文本進(jìn)行分詞處理
#對(duì)原始文本直接分詞并繪制
import wordcloud
myfont = 'C:/Windows/Fonts/simkai.ttf'
text = 'this is hangzhou, 郭靖, 和, 哀牢山 三十六劍'
cloudobj = wordcloud.WordCloud(font_path = myfont).generate(text)
print(cloudobj)
<wordcloud.wordcloud.WordCloud object at 0x00000289345D7908>
#顯示詞云
import matplotlib.pyplot as plt
plt.imshow(cloudobj)
plt.axis('off')
plt.show()

說(shuō)明:上圖中沒(méi)有‘this’,'is',‘和’是因?yàn)槟J(rèn)的停用表中包含上述詞。
#優(yōu)化詞云
cloudobj = wordcloud.WordCloud(font_path = myfont,
width = 360, height = 180,
mode = 'RGBA', background_color = None).generate(text)
plt.imshow(cloudobj)
plt.axis('off')
plt.show()

最后我們保存一下詞云
#保存詞云
cloudobj.to_file('詞云test.png')
接下來(lái)制作射雕英雄傳第一章的詞云
#射雕英雄傳第一章詞云
import pandas as pd
import jieba
stoplist_path = 'D:/Files/program data/nlp/PythonData/停用詞.txt'
stoplist = list(pd.read_csv(stoplist_path, names = ['w'], sep = 'aaa',
encoding = 'utf-8', engine = 'python').w)
cloudobj = wordcloud.WordCloud(font_path = myfont,
width = 1200, height = 800,
mode = 'RGBA', background_color = None,
stopwords = stoplist).generate(' '.join(jieba.lcut(chapter.txt[1])))
plt.imshow(cloudobj)
plt.axis('off')
plt.show()
#保存圖片
cloudobj.to_file('詞云test2.png')

generate()操作背后實(shí)際上執(zhí)行了兩個(gè)函數(shù)
- 調(diào)用分詞函數(shù)process_text()
- 調(diào)用基于頻數(shù)的繪制函數(shù)fit_words()
fit_words(dict)
- dict:由詞條和頻數(shù)構(gòu)成的字典
#基于分詞頻數(shù)繪制詞云
def m_cut(intext):
return [w for w in jieba.cut(intext) if w not in stoplist]
import nltk
from nltk import FreqDist
tokens = m_cut(chapter.txt[1])
fdist = FreqDist(tokens)
cloudobj = wordcloud.WordCloud(font_path = myfont).fit_words(fdist)
plt.imshow(cloudobj)
plt.axis('off')
plt.show()

2.3詞云美化
(1)設(shè)置背景圖片
Mask 掩模/遮罩
- 用于控制詞云的整體形狀
- 設(shè)定Mask后,設(shè)定的高度和寬度值將被忽略,遮罩形狀被指定圖形的形狀取代。除全白的部分仍然保留外,其余部分會(huì)用于繪制詞云。因此背景圖片的畫(huà)布一定要設(shè)置為白色(#FFFFFF)
- 字的大小,布局和顏色也會(huì)基于Mask生成
- 必要時(shí)可以調(diào)整顏色來(lái)增強(qiáng)可視化效果
from scipy.misc import imread
def m_cut(intext):
return [w for w in jieba.cut(intext) if w not in stoplist and len(w) >1]
cloudobj = wordcloud.WordCloud(font_path = myfont,
mask = imread('D:/Files/program data/nlp/PythonData/射雕背景1.png'),
mode = 'RGBA', background_color =None
).generate(' '.join(m_cut(chapter.txt[1])))
plt.imshow(cloudobj)
plt.axis('off')
plt.show()

更換背景圖片
from scipy.misc import imread
def m_cut(intext):
return [w for w in jieba.cut(intext) if w not in stoplist and len(w) >1]
cloudobj = wordcloud.WordCloud(font_path = myfont,
mask = imread('D:/Files/program data/nlp/PythonData/射雕背景2.png'),
mode = 'RGBA', background_color =None
).generate(' '.join(m_cut(chapter.txt[1])))
plt.imshow(cloudobj)
plt.axis('off')
plt.show()

對(duì)比下原圖,出現(xiàn)不同的原因在于弓箭的弓背很細(xì),詞條和圖不能很好的適配。因此在選擇圖片時(shí)要注意。

(2)指定圖片的色系
我們可以選擇合適圖片,將其色系運(yùn)用在詞云中。
import numpy as np
imgobj = imread('D:/Files/program data/nlp/PythonData/射雕背景2.png')
image_colors = wordcloud.ImageColorGenerator(np.array(imgobj))
cloudobj.recolor(color_func = image_colors)
plt.imshow(cloudobj)
plt.axis('off')
plt.show()

(3)指定單詞組上色
理想的情況是分組比較詞頻,在兩組中都高頻的詞條在圖形中相互抵消。Python目前只能實(shí)現(xiàn)詞條分組上色。
from wordcloud import get_single_color_func
class GroupedColorFunc(object):
def __init__(self, color_to_words, default_color):
self.color_func_to_words = [
(get_single_color_func(color), set(words))
for (color, words) in color_to_words.items()
]
self.default_color_func = get_single_color_func(default_color)
def get_color_func(self, word):
try:
color_func = next(
color_func for (color_func, words) in self.color_func_to_words
if word in words
)
except StopIteration:
color_func = self.default_color_func
return color_func
def __call__(self, word, **kwargs):
return self.get_color_func(word)(word, **kwargs)
color_to_words = {
'#00ff00': ['顏烈', '武官', '金兵', '官兵'],
'red': ['包惜弱', '郭嘯天', '楊鐵心', '丘處機(jī)']
}
default_color = 'grey'
grouped_color_func = GroupedColorFunc(color_to_words, default_color)
cloudobj.recolor(color_func = grouped_color_func)
plt.imshow(cloudobj)
plt.axis('off')
plt.show()

參考資料:
Python數(shù)據(jù)分析--玩轉(zhuǎn)文本挖掘
自然語(yǔ)言處理NLTK之入門(mén)
wordCloud的基本使用