前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 词云生成

Python 词云生成

作者头像
arcticfox
修改2019-06-26 16:47:54
4K0
修改2019-06-26 16:47:54
举报

图片来自网络

所谓“词云”就是对网络文本中出现频率较高的“关键词”予以视觉上的突出,形成“关键词云层”或“关键词渲染”,从而过滤掉大量的文本信息,使浏览网页者只要一眼扫过文本就可以领略文本的主旨。

环境准备

代码语言:txt
复制
python -m pip install wordclud
python -m pip install matplotlib
python -m pip install jieba

在Windows上,如无法成功安装,可使用已经编译好的二进制包,下载安装

https://www.lfd.uci.edu/~gohlke/pythonlibs/

wordclud

Python用于生成词云的库。 wordclud 官方文档

属性

简述

font_path

字体路径,做中文词云必须设置字体,否则无法显示

width

输出的画布宽度,默认为400像素

height

输出的画布高度,默认为200像素

mask

如果参数为空,则使用二维遮罩绘制词云。如果 mask 非空,设置的宽高值将被忽略,遮罩形状被 mask 取

min_font_size

显示的最小的字体大小

max_font_size

显示的最大的字体大小

max_words

要显示的词的最大个数,默认200

scale

按照比例进行放大画布,如设置为1.5,则长和宽都是原来画布的1.5

color_func

生成新颜色的函数,如果为空,则使用 self.color_fun

prefer_horizontal

词语水平方向排版出现的频率,默认 0.9 (所以词语垂直方向排版出现频率为 0.1 )

stopwords

设置需要屏蔽的词,如果为空,则使用内置的STOPWORDS

font_step

字体步长,如果步长大于1,会加快运算但是可能导致结果出现较大的误,默认1

background_color

背景颜色

relative_scaling

词频和字体大小的关联性,默认0.5

mode

当参数为“RGBA”并且background_color不为空时,背景为透,默认“RGB”

regexp

使用正则表达式分隔输入的文本

collocations

是否包括两个词的搭配,默认True

colormap

给每个单词随机分配颜色,若指定color_func,则忽略该方法

matplotlib

一个Python 2D绘图库。Matplotlib试图让简单易事的事情成为可能。只需几行代码即可生成绘图,直方图,功率谱,条形图,错误图,散点图等,该库最常用于Python数据分析的可视化。 官方文档

最小示例

代码语言:txt
复制
from wordcloud import WordCloud
import matplotlib.pyplot as plt

with open("野性的呼唤.txt", encoding="utf-8") as file:
    word_cloud = WordCloud().generate(file.read())
    plt.figure()      # 创建一个图形实例
    plt.imshow(word_cloud, interpolation='bilinear')
    plt.axis("off")  # 不显示坐标轴
    plt.show()

interpolation 参数的用法

中文词云

wordcloud 对中文分词支持不足,因此需要配合jieba分词库使用

代码语言:txt
复制
from wordcloud import WordCloud
import matplotlib.pyplot as plt

with open("fanrenxiuxian.txt", encoding="gbk") as file:
    word_cloud = WordCloud(font_path="c:\windows\Fonts\simhei.ttf",
                           background_color="white",
                           max_words=200,
                           max_font_size=100,
                           width=1000,
                           height=860).generate(file.read())


    plt.figure()      # 创建一个图形实例
    plt.imshow(word_cloud, interpolation='bilinear')
    plt.axis("off")  # 不显示坐标尺寸
    plt.show()

添加图片背景效果

代码语言:txt
复制
from wordcloud import WordCloud
from wordcloud import ImageColorGenerator
from matplotlib.image import imread
import matplotlib.pyplot as plt

back_img = imread("timg.jpg")
img_colors = ImageColorGenerator(back_img)

with open("fanrenxiuxian.txt", encoding="gbk") as file:
    word_cloud = WordCloud(font_path="c:\windows\Fonts\simhei.ttf",
                           background_color="white",
                           max_words=200,
                           max_font_size=100,
                           width=1920,
                           mask=back_img,
                           height=1080).generate(file.read())

    word_cloud.recolor(color_func=img_colors)  # 替换默认的字体颜色

    plt.figure()  # 创建一个图形实例
    plt.imshow(word_cloud, interpolation='bilinear')
    plt.axis("off")  # 不显示坐标尺寸
    plt.show()

扩展:将图片加载的几种方法

  • PIL.Image.open
  • scipy.misc.imread
  • skimage.io.imread
  • cv2.imread
  • matplotlib.image.imread

各方法性能对比

jieba

特点

  • 支持三种分词模式:
    • 精确模式,试图将句子最精确地切开,适合文本分析;
    • 全模式,把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;
    • 搜索引擎模式,在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词
  • 支持繁体分词
  • 支持自定义词典
  • MIT 授权协议

官方文档

简单示例

代码语言:txt
复制
import jieba

with open("fanrenxiuxian.txt", 'r', encoding="gbk") as file:
    # jieba.enable_parallel(4) 并行运算,类unix系统,Windows不支持
    seg_list = jieba.cut(file.read(), cut_all=False)
    print("/".join(seg_list))

提取关键词

代码语言:txt
复制
import jieba.analyse

# TF-IDF算法关键词抽取
with open("fanrenxiuxian.txt", 'r', encoding="gbk") as file:
    jieba.analyse.set_stop_words('stopwords.txt')
    tags = jieba.analyse.extract_tags(file.read(), 100)
    print(tags)

中文词云实例

网络上关于中文词云的博客资料99.9%是对wordcloud官网示例的翻译,我要说的是官方示例基本就是个大坑,不知道是不太放心上还是本身就是临时工lowB程序员写的。而国内的博主习惯了粘贴复制,已经丧失了独立思考的能力,不假思索的就照搬,反正我是被坑了,用官方示例将一部《凡人修仙传》在Windows上单线程生成词云花了300多秒,而我经过仔细阅读jieba库和wordcloud库的API后,发现根本就不是官网示例那么个写法,经过我重新改造后,只需要大概60秒就能生成《凡人修仙传》的词云。

首先我们进入wordcloud文档,找到 create wordcloud with chinese 这个示例,查看一下官方示例,代码我这里就不贴了,点击链接可直接跳转

  • 第一种写法 我们结合jieba库,修改词云代码。这里使用WordCloudstopwords参数加入停止词,而不是像官方示例那样去做遍历筛选停止词,特别是写出if not (myword.strip() in f_stop_seg_list) and len(myword.strip()) > 1:这种低性能的代码,就算是遍历, len(myword.strip()) > 1也应放在最前面去判断,而不是把停止词放在最前面去判断,这样大大的增加了时间复杂度。
代码语言:txt
复制
from wordcloud import WordCloud
from wordcloud import ImageColorGenerator
from matplotlib.image import imread
import matplotlib.pyplot as plt
import jieba, time


def get_stopwords():
    with open("stopwords.txt", encoding='utf-8') as f_stop:
        return f_stop.read().splitlines()


back_img = imread("timg.jpg")
img_colors = ImageColorGenerator(back_img)

with open("fanrenxiuxian.txt", encoding="gbk") as file:
    stop_words = get_stopwords()                       # 获取停止词列表
    seg_list = jieba.cut(file.read(), cut_all=False)  # 返回一个生成器

    cut_list = " ".join(seg_list)

    word_cloud = WordCloud(font_path="c:\windows\Fonts\simhei.ttf",
                           background_color="white",
                           max_words=1000,
                           max_font_size=100,
                           width=1920,
                           stopwords=stop_words,
                           mask=back_img,
                           height=1080).generate(cut_list)

    word_cloud.recolor(color_func=img_colors)  # 替换默认的字体颜色

    plt.figure()  # 创建一个图形实例
    plt.imshow(word_cloud, interpolation='bilinear')
    plt.axis("off")  # 不显示坐标尺寸
    plt.show()
  • 第二种写法 这里的第二种写法基本就官方示例的写法,只是略微调整了筛选停止词时的判断条件的顺序
代码语言:txt
复制
from wordcloud import WordCloud
from wordcloud import ImageColorGenerator
from matplotlib.image import imread
import matplotlib.pyplot as plt
import jieba, time


def get_stopwords():
    with open("stopwords.txt", encoding='utf-8') as f_stop:
        return f_stop.read().splitlines()


back_img = imread("timg.jpg")
img_colors = ImageColorGenerator(back_img)

with open("fanrenxiuxian.txt", encoding="gbk") as file:
    stop_words = get_stopwords()  # 获取停止词列表
    seg_list = jieba.cut(file.read(), cut_all=False)  # 返回一个生成器

    cut_list = "/".join(seg_list).split("/")
    content_list = []
    for word in cut_list:
        if len(word.strip()) > 1 and not (word.strip() in stop_words):
            content_list.append(word)

    word_cloud = WordCloud(font_path="c:\windows\Fonts\simhei.ttf",
                           background_color="white",
                           max_words=200,
                           max_font_size=100,
                           width=1920,
                           mask=back_img,
                           height=1080).generate(' '.join(content_list))

    word_cloud.recolor(color_func=img_colors)  # 替换默认的字体颜色

    plt.figure()  # 创建一个图形实例
    plt.imshow(word_cloud, interpolation='bilinear')
    plt.axis("off")  # 不显示坐标尺寸
    plt.show()
  • 第三种写法,最终版 这种是我推荐的做法。整个文本的分词包括关键词提取,我们都直接交给jieba库去做就行了,WordCloud库仅仅根据jieba库返回的关键词以及权重去生成词云图片就行。这里主要用到WordCloud库的generate_from_frequencies这个函数,API文档给出的说明是Create a word_cloud from words and frequencies.,有了这个API,不知道官方中文词云示例为什么还写成那样,难道是自己的API都不清楚吗?令人费解
代码语言:txt
复制
from wordcloud import WordCloud
from wordcloud import ImageColorGenerator
from matplotlib.image import imread
import matplotlib.pyplot as plt
import jieba.analyse

back_img = imread("timg.jpg")
img_colors = ImageColorGenerator(back_img)

with open("fanrenxiuxian.txt", encoding="gbk") as file:
    jieba.analyse.set_stop_words('stopwords.txt')  # 设置止词列表
    tags = jieba.analyse.extract_tags(file.read(), 1000, withWeight=True)
    data = {item[0]: item[1] for item in tags}

    word_cloud = WordCloud(font_path="c:\windows\Fonts\simhei.ttf",
                           background_color="white",
                           max_words=1000,
                           max_font_size=100,
                           width=1920,
                           mask=back_img,
                           height=1080).generate_from_frequencies(data)

    word_cloud.recolor(color_func=img_colors)  # 替换默认的字体颜色

    plt.figure()  # 创建一个图形实例
    plt.imshow(word_cloud, interpolation='bilinear')
    plt.axis("off")  # 不显示坐标尺寸
    plt.show()

简单说一下这里的stop_words停止词其实就是需要被过滤掉的词,比如一篇文章中肯定有无数个“的”、“了”之类的对于词频而言无意义词,根据具体需求,一些副词、逻辑连接词之类的也都要过滤掉,否则就会影响准确性。

由于我这里停止词没有单独去添加,而是用了一个通用的停止词表,导致最终生成的词云不是特别准确,这个就要大家自己去小心调试了

关注个人公众号:编程之路从0到1

编程之路从0到1
编程之路从0到1
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程之路从0到1 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 环境准备
    • wordclud
      • matplotlib
        • jieba
          • 中文词云实例
          • 关注个人公众号:编程之路从0到1
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档