用Py做文本分析3:制作詞云圖

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()
image.png

說(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()
image.png

最后我們保存一下詞云

#保存詞云
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')
image.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()
image.png

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()
image.png

更換背景圖片

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()
image.png

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


射雕背景2.png

(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()
image.png

(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()
image.png

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容