master
/ 9.3 词云.ipynb

9.3 词云.ipynb @masterview markup · raw · history · blame

Notebook

中英文词云

英文词云

绘制词云可以使用wordcloud库,安装方法如下:

pip install wordcloud

wordcloud库安装时若出现__“ Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools”__相关错误时,可到以下网址: https://www.lfd.uci.edu/~gohlke/pythonlibs/
https://pypi.org/project/wordcloud/#files
下载预编译好的对应版本的安装包

wordcloud‑1.8.1‑cp311‑cp311‑win_amd64.whl wordcloud‑1.8.1‑cp311‑cp311‑win32.whl wordcloud‑1.8.1‑cp310‑cp310‑win_amd64.whl wordcloud‑1.8.1‑cp310‑cp310‑win32.whl

苹果电脑下,在python 3.9环境 下安装wordcloud-1.8.1失败,先在终端中用以下命令安装xcode-select,再安装wordcloud即可成功。
xcode-select --install

In [ ]:
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='auto', 
                    regexp=None, collocations=True, colormap=None, 
                    normalize_plurals=True, contour_width=0, 
                    contour_color='black', repeat=False, include_numbers=False, 
                    min_word_length=0, collocation_threshold=30)
wordcloud属性 作用
font_path 字符串类型, 字体路径(windows下默认字体路径为C:\Windows\Fonts\如果是自行安装的字体,可能会在C:\Users\用户名\AppData\Local\Microsoft\Windows\Fonts\)
width 整数类型, 生成词云的宽度, 默认:400
height 整数类型, 生成词云的高度, 默认:200
prefer_horizontal 浮点类型,词语水平方向排版出现的频率,默认:0.9
mask 遮罩图, 下方会详细介绍。默认:无
scale 浮点类型, 按照比例进行放大画布, 默认:1
min_font_size 整数类型, 显示的最小的字体大小, 默认:4
max_font_size 整数类型, 显示的最大的字体大小, 默认:无
margin 整数类型, 边缘空白宽度, 默认:2
font_step 整数类型, 字体步长, 默认:1
max_words 整数类型,要显示的词的最大个数 ,默认:200
background_color 字符串类型, 背景颜色,默认:黑色
stopwords 设置需要屏蔽的词,如果为空,则使用内置的STOPWORDS
relative_scaling 浮点类型,词频和字体大小的关联性,默认:auto。
regexp 字符串类型,使用正则表达式分隔输入的文本
collocations 布尔类型, 是否包括两个词的搭配
colormap 给每个单词随机分配颜色,若指定color_func,则忽略该方法。
normalize_plurals 布尔类型,是否删除单词中的s,如果使用generate_from_frequencies,则将其忽略。默认:True
contour_width 浮点类型,如果mask遮罩不是None和contour_width > 0,则绘制mask遮罩轮廓。默认:0
contour_color 字符串类型, mask遮罩轮廓颜色。默认: black
repeat 布尔类型,是否重复单词和短语,直到达到max_words或min_font_size。默认:False
include_numbers 布尔类型,是否将数字包含为短语。默认:False
min_word_length 整数类型,一个单词必须包含的最小字母数。默认:0
mode 颜色模式,默认“RGB”。如果想设置透明底色的云词图,那么可以设置background_color=None, mode=“RGBA”

常用方法有以下五种

fit_words(frequencies) 根据词频生成词云,参数为包含词与词频的字典,为generate_from_frequencies的别名
generate(text) 根据文本生成词云,是generate_from_text的别名
generate_from_frequencies(frequencies) 根据词频生成词云,参数为词频字典
generate_from_text(text) 根据文本生成词云,如果参数是排序的列表,需设置'collocations=False',否则会导致每个词出现2次。
process_text(text) 将长文本分词并去除stopwords,返回值为词频字典
recolor(self[,random_state,color_func,…]) 重着色
to_array(self) 转为 numpy数组
to_file(self,filename) 导出为图片文件
to_svg(self[,embed_font,…]) 导出为SVG

英文文本中单词间用空格进行分隔,所以英文文本的词云制作比较简单,将读取__文本__文件对象作为参数传递给WordCloud()的__generate()函数__就可以了,默认词云的背景为黑色,下面例子将背景色设为白色。
从绘制结果可以发现,里面有很多无意义的虚词,如:of、the、and、is、to等,可以考虑加停用词将其过滤掉。
停用词可以用内置的STOPWORDS,也可以自己构建:

In [ ]:
pip uninstall wordcloud -y
In [ ]:
pip uninstall pillow -y
In [ ]:
pip install wordcloud
In [ ]:
pip install wordcloud==1.8.2.2
In [ ]:
pip install scipy==1.7.1
In [2]:
from wordcloud import WordCloud, STOPWORDS
import matplotlib.pyplot as plt
import matplotlib as mpl

mpl.rcParams['figure.figsize'] = (20,10)  # 修改图片大小
plt.rcParams['figure.dpi'] = 300          # default for me was 75



def file_to_string(filename):                   # 读取文件,返回字符串
    with open(filename, 'r', encoding='utf-8') as f:            # 文字来源
        return f.read()                       # 返回读取文件内容得到的字符串

def draw(text):                               # 绘制词云,设定各参数,传入参数为字符串
    wc = WordCloud(max_words=80,              #设置显示高频单词数量
                   width=600,                 # 设置图片的宽度
                   height=400,                # 设置图片的高度
                   background_color='White',  # 设置背景颜色
                   max_font_size=150,         # 设置字体最大值
                   stopwords=STOPWORDS,       # 去除停用词
                   margin=5,                  # 设置图片的边缘
                   scale=1.5)                 #按照比例进行放大画布,如设置为1.5,则长和宽都是原来画布的1.5倍。
    wc.generate(text)                         # 根据文本内容直接生成词云
    plt.imshow(wc)                            # 负责对图像进行处理,并显示其格式,但是不能显示。
    plt.axis("off")                           # 不显示坐标轴
    wc.to_file('dream.png')                   # 词云保存为图片
    plt.show()                                # 显示图像


if __name__ == '__main__':
    filename ='images/ch8/Who Moved My Cheese.txt'       # 用于生成词云的文本文件名
    txt = file_to_string(filename)            # 读取文件中的文本,生成字符串
    draw(txt)                                 # 绘制词云
In [3]:
from wordcloud import WordCloud, STOPWORDS
import matplotlib.pyplot as plt
import matplotlib as mpl
import os

# 设置 matplotlib 参数
mpl.rcParams['figure.figsize'] = (20,10)  # 修改图片大小
plt.rcParams['figure.dpi'] = 300          # 修改图像分辨率

def file_to_string(filename):
    try:
        with open(filename, 'r', encoding='utf-8') as f:
            content = f.read()
        print("文件读取成功")
        return content
    except Exception as e:
        print(f"读取文件时出错: {e}")
        return ""

def draw(text):
    if not text:
        print("没有文本内容可用于生成词云")
        return
    try:
        wc = WordCloud(
            max_words=80,
            width=600,
            height=400,
            background_color='white',  # 使用小写
            max_font_size=150,
            stopwords=STOPWORDS,
            margin=5,
            scale=1.5,
            font_path='images/ch9/Arial Unicode.ttf'  # 可选:指定字体路径
        )
        wc.generate(text)
        plt.imshow(wc, interpolation='bilinear')  # 添加插值参数
        plt.axis("off")
        wc.to_file('dream.png')
        print("词云已保存为 dream.png")
        plt.show()
    except Exception as e:
        print(f"生成词云时出错: {e}")

if __name__ == '__main__':
    filename = 'images/ch8/Who Moved My Cheese.txt'  # 确认文件路径正确
    # 打印当前工作目录以帮助调试路径问题
    print("当前工作目录:", os.getcwd())
    txt = file_to_string(filename)
    draw(txt)
当前工作目录: /home/jovyan/work
文件读取成功
词云已保存为 dream.png

中文词云

中文词之间无分隔,所以中文词云的制作略麻烦,需要提前对文本进行分词处理。
jieba是目前应用较广泛的一个中文分词库,可以导入__jieba__利用它进行__分词__再绘制词云。
jieba分词有三种模式:
精确模式(默认)
全模式
搜索引擎模式
其参数是一个字符串,返回值是元素为中文分词的列表。
下面对这三种模式分别举例介绍:

In [ ]:
import jieba

txt = '武汉理工大学是教育部直属全国重点大学'
print(f'精确模式:{jieba.lcut(txt)}')                # 精确模式
In [ ]:
import jieba

txt = '武汉理工大学是教育部直属全国重点大学'
print(f'全模式:{jieba.lcut(txt, cut_all=True)}')    # 全模式
In [ ]:
import jieba

txt = '武汉理工大学是教育部直属全国重点大学'
print(f'搜索引擎模式:{jieba.lcut_for_search(txt)}')  # 搜索引擎模式

从输出结果可以看到:
精确模式的可以准确的分词;
全模式时,输出所有可能组合的词,冗余较多;
搜索引擎模式是精确分词,再对长词进一步切分。

一般情况下,推荐使用__精确模式__

中文文本能够切分成词就可以用英文词云相同的方法制作词云了,一个需要注意的地方是,制作中文词云时,务必要明确指定__中文字体__,否则中文无法正确显示。

In [ ]:
import jieba.analyse
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from wordcloud import WordCloud
import matplotlib as mpl

mpl.rcParams['figure.figsize'] = (20,10)  # 修改图片大小
plt.rcParams['figure.dpi'] = 300          # default for me was 75


def file_to_string(file):
    """接收表示文件名的字符串为参数,读取文本文件内容为一个字符串,返回这个字符串。"""
    with open(filename, 'r', encoding='utf-8') as f:  # 文字来源
        text = f.read()  # 文章内容读取为字符串
    return text  # 返回读取文件内容得到的字符串


def text_analysis(text):
    """接收一个字符串类型的参数,应用jieba.analyse.textrank()的方法分词,统计每个词的权重,将其转为词频字典并返回这个字典。"""
    result = jieba.analyse.textrank(text, topK=50, withWeight=True)
    word = dict()
    for i in result:  # 遍历列表,生成字典
        word[i[0]] = i[1]
    return word  # 返回关键字与权值字典


def draw(word, image):
    """接收词的权值字典和背景图片文件对象为参数,绘制背景为白色的带背景图片的词云,设置字体最大值为240,不显示坐标轴,绘制的词云保存为文件。"""
    graph = np.array(image)  # 图片转数组
    wc = WordCloud(font_path='simsun.ttc',    # 中文字体,未指定中文字体时词云的汉字显示为方框,根据系统修改字体名
                   background_color='White',  # 设置背景颜色
                   # background_color=None,   # 设置透明背景
                   # mode='RGBA',
                   mask=graph,  # 设置背景图片
                   max_font_size=240,  # 设置字体最大值
                   scale=1.5)  # 按照比例进行放大画布,如设置为1.5,则长和宽都是原来画布的1.5倍。
    wc.generate_from_frequencies(word)
    plt.imshow(wc)  # 负责对图像进行处理,并显示其格式,但是不能显示。
    plt.axis("off")  # 不显示坐标轴
    wc.to_file('dream.png')  # 词云保存为图片
    plt.show()  # 显示图像


if __name__ == '__main__':
    filename = 'images/ch9/校长2018毕业讲话.txt'  # 用于生成词云的文本文件名
    txt = file_to_string(filename)  # 读取文件中的文本,生成字符串
    words = text_analysis(txt)  # 利用jieba对文本进行分词,并统计词频
    images = Image.open('images/ch9/980.jpeg')  # 打开背景图片,创建文件对象
    draw(words, images)  # 调用函数绘制词云
In [ ]: