词云

词云统计

绝大不扽词频统计工具都是基于分词后构建词条的list进行,因此首先需要完成相应的分词工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import pandas as pd
f = open(r"C:\Users\Wang\Desktop\PythonData\金庸-射雕英雄传txt精校版.txt" , encoding = "GBK")
raw = pd.read_table(f,names = ['txt'],sep='aaa')#sep设置成"aaa"是为了把一整段当一个东西读入
#print(raw)

def m_head(tmpstr):
return tmpstr[:1]

def m_mid(tmpstr):
return tmpstr.find("回 ")

raw['head'] = raw.txt.apply(m_head)#apply怎么用?
raw['mid'] = raw.txt.apply(m_mid)
raw['len'] = raw.txt.apply(len)
raw.head(10)

chapnum = 0

for i in range(len(raw)):
if raw['head'][i] == "第" and raw['mid'][i]>0 and raw['len'][i]<30:
chapnum+=1
if chapnum > 40 and raw['txt'][i] == "附录一:成吉思汗家族":
chapnum = 0
raw.loc[i,'chap'] = chapnum#设定一个chap列

#删除临时变量
del raw['head']
del raw['mid']
del raw['len']

rawgrp = raw.groupby('chap')
chapter = rawgrp.agg(sum)#agg怎么用?
chapter = chapter[chapter.index!=0]
c:\users\wang\appdata\local\programs\python\python36-32\lib\site-packages\ipykernel_launcher.py:3: ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support regex separators (separators > 1 char and different from '\s+' are interpreted as regex); you can avoid this warning by specifying engine='python'.
  This is separate from the ipykernel package so we can avoid doing imports until
1
2
3
4
import jieba 

word_list = jieba.lcut(chapter.txt[1])
word_list[:10]
['第一回', ' ', '风雪', '惊变', '钱塘江', '浩浩', '江水', ',', '日日夜夜', '无穷']

构建完list之后,也可以自行编写词频统计程序,框架如下:

遍历整个list,对每个词条:

if word in d:

d[word] + = 1

else:

d[word] = 1

使用Pandas统计

1
2
3
4
import pandas as pd

df = pd.DataFrame(word_list,columns = ['word'])
df.head(5)































word
0 第一回
1
2 风雪
3 惊变
4 钱塘江

1
2
3
4
5
result = df.groupby(['word']).size()#按照word来分组,使用size来获得词频
print(type(result))

freqlist = result.sort_values(ascending=False)
freqlist[:20]
<class 'pandas.core.series.Series'>





word
,      2034
。       714
了       400
“       344
:       343
”       342
的       291
道       210
他       187
是       168
杨铁心     148
在       140
?       136
包惜弱     114
那       108
又        97
我        94
得        91
也        88
!        85
dtype: int64

使用NLTK统计

NLTK生成的结果为频数字典,在和某些程序包对接时比较有用

1
2
import nltk
word_list[:10]
['第一回', ' ', '风雪', '惊变', '钱塘江', '浩浩', '江水', ',', '日日夜夜', '无穷']
1
2
fdist = nltk.FreqDist(word_list) #生成完整的词条频数字典
fdist
FreqDist({',': 2034, '。': 714, '了': 400, '“': 344, ':': 343, '”': 342, '的': 291, '道': 210, '他': 187, '是': 168, ...})
1
fdist['颜烈'] #就像普通的字典一样操作
37
1
fdist.keys() #列出词条列表,以list形式出现
dict_keys(['第一回', ' ', '风雪', '惊变', '钱塘江', '浩浩', '江水', ',', '日日夜夜', '无穷', '无休', '的'....])
1
fdist.most_common(5) #显示最高频和相应的频数
[(',', 2034), ('。', 714), ('了', 400), ('“', 344), (':', 343)]

词云展示

什么是词云

  • 本质上是对分词结果频数表的图形化展示
  • 对文本中出现频率较高的“关键词”予以视觉上的突出,从而过滤掉大量的文本信息,使浏览网页者只要一眼扫过文本就可以领略文本的主旨
  • 可以在基础词云的基础上进一步衍生,用于表达更富的信息
    • 多彩渲染
    • 加入背景图片
    • 不同主题的结果比较

常见的词云绘制工具

  • Python
    • 比较标准的词云生成功能
    • 可进行背景图片的进一步修饰
  • R
    • 可以展示不用类别间的词云比较
    • 可以实现彩色动态效果的词云
    • 可进行背景图片的进一步修饰
  • Tableau
    • 可以实现词云结果的动态检测和展示
  • 专用工具/网站

绘制词云

###WordCloud的基本语法

class worldcloud.WordCloud

常用功能:

font_path:在图形中使用的字体,默认使用系统字体

width:图形的宽度/高度

max_words = 需要绘制的最多词条数

stopwords = None:停用词列表,不用定时使用系统默认停用词列表

字体设定:

min_font_size = 4/min_font_size = None :字符大小范围

font_step = 1 :字号增加的步长

relative_scaling = 5 :词条频数比例和字号大小比例的换算关系,默认为504

prefer_horizontal = 0.90 : 图中词条水平显示的比例

颜色设定:

background_color = “black” : 图形背景色

mode = “RGB” : 图形颜色编码,如果指定为“RGBA”且背景色为None时,背景色为透明

color_func = None : 生成新颜色的函数,使用matplotlib的colormap

背景淹模:
mask = None : 词云使用的背景图(遮罩)

用原始文本直接分词并绘制

cloudobj = WordCloud().generate(text)

generate实际上是generate_from_text的别名

文本需要用空格/标点符号(英文的标点)分隔单词,否则不能正确分词

import wordcloud
myfont = r'C:\Windows\Fonts\MSYH.ttc'
text = 'this is shanghai, 郭靖,和, 哀牢山 三十六剑'
cloudobj = wordcloud.WordCloud(font_path = myfont).generate(text)
print(cloudobj) # <wordcloud.wordcloud.WordCloud object at 0x16601610>



<wordcloud.wordcloud.WordCloud object at 0x16601610>




import matplotlib.pyplot as plt
plt.imshow(cloudobj)
plt.axis("off") # 关掉坐标轴
plt.show()# 默认词表中有 this is 和

png

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()

png

cloudobj.to_file("词云.png")# wordcloud.WordCloud(font_path = myfont).generate(text).to_file(r"词云.png")





    <wordcloud.wordcloud.WordCloud at 0x179fa5d0>




import pandas as pd
import jieba

stoplist = list(pd.read_csv('C:/Users/Wang/Desktop/PythonData/停用词.txt', names = ['w'], sep = 'aaa',encoding = 'utf-8',engine='python').w)

def m_cut(intxt):
    return [w for w in jieba.cut(intxt) if w not in stoplist]




cloudobj = wordcloud.WordCloud(font_path = myfont,
                              width = 1200, height = 800,
                              mode = "RGBA", background_color = None).generate(' '.join(m_cut(chapter.txt[1])))

plt.imshow(cloudobj)
plt.axis("off")
plt.show()

png

cloudobj.to_file("词云2.png")


    <wordcloud.wordcloud.WordCloud at 0x17d4d0d0>

基于分词频数绘制

generate()实际操作

调用分词函数process_text()

调用基于频数的绘制函数fit_words()

fit_words(dict)

实际上是generate_from_frequencies的别名

Dict: 由词条和频数构成的字典



txt_freq = {'张三':100,'李四':90,'王二麻子':50000000} #绝对数量对大小影响不大
cloudobj = wordcloud.WordCloud(font_path = myfont).fit_words(txt_freq)

plt.imshow(cloudobj)
plt.axis("off")
plt.show()

png

用频数生成射雕第一章的词云

import nltk
from nltk import FreqDist

tokens = m_cut(chapter.txt[1])
fdist = FreqDist(tokens) # 生成完整的词条频数字典
type(fdist)

cloudobj = wordcloud.WordCloud(font_path = myfont,stopwords = stoplist).fit_words(fdist)

plt.imshow(cloudobj)
plt.axis("off")
plt.show()

png