文档章节

利用豆瓣短评数据生成词云

PLart
 PLart
发布于 2017/08/18 18:03
字数 2378
阅读 8
收藏 0

在之前的文章中,我们获得了豆瓣爬取的短评内容,汇总到了一个文件中,但是,没有被利用起来的数据是没有意义的。

前文提到,有一篇微信推文的关于词云制作的一个实践记录,准备照此试验一下。

思路分析

读文件

利用with open() as...将文件读进来。这里需要注意文件内容的大小。

分词

由于获取的是大量的短评文字,而制作词云需要的是各种词语,有了词,才能谈词云,所以目前第一步需求的就是讲短评内容拆分成一个个的中文词汇。

这里就用到了我所听过的一个库jieba,可以将中文语句拆解成一个个的词汇。这里是用的是lcut()方法,能将中文字符串拆解成一个列表,每项都是一个词。

清洗非中文

但是,我们在分析中,需要的就是中文文字,所以需要将非中文字符彻底清理,这里使用了正则表达式。短小精悍的一个模式[\u4e00-\u9fa5]+即可匹配。

使用正则表达式,我的习惯是现在网上的一些在线正则表达式工具上直接测试。其中oschina的不错,还给提供了一些例子。

在线正则表达式测试

这里是oschina的工具网站,做的很好。

工具分类索引

处理停词

由于这些词汇中,有很多词是没有实际分析价值的,所以我们需要利用一个停词文件来将不必要的词处理掉。

参考文章中,是利用pandas库汇总的方法read_csv()来处理停词文件。,利用一个isin()方法实现了停词。

聚合

词分开了,基本也处理干净了。接下来应该考虑制作词云的问题。

我们这里想要重点突出在所有评论中的重要的核心观点,为了实现这样的目的,我们使用了分词。

这似乎是一种有些“断章取义”的思路。借助词频的分布实现重点突出高词频内容的方式,来展现我们的词云。

所以现在我们需要做的事,就是处理词汇的聚合问题,统计词频而已。

参考文种中利用了类DataFrame的分组方法group()和聚合方法agg()

关于这里,参考文章中在agg()中使用了一个显式的字典(可见文末参考文章),调用了numpy.size,但是似乎是这种用法将来会被移除,查了一些文章,说是可以这样用,就是不能自己定制字典了。

FutureWarning: using a dict on a Series for aggregation is deprecated and will be removed in a future version

词云

这里使用了第三方库wordcloud。这个库在安装的时候,直接pip install wordcloud时,我出了问题,提示微软开发工具的问题,折腾了半天,最后还是直接在一个极为丰富的第三方库的集合站点上下载使用pip insatll了它的whl文件。

这下可以正常使用了。

同时,这里为了能够显示处理图片,使用了matplotlib.pyplot&numpy来进行处理。

掩膜设置

wordcloud项目主页README 了解,可以使用二值图像来设定掩膜(mask)。

出于提升数据的表现力,也出于学习的目的,这里使用了直接编写的rgb2gray()&gray2bw()函数来实现真彩图像转换为二值图像的过程。获得了最终的二值图像掩膜。

这里开始我并不知道需要怎样的图像,看了给的示例代码,用的图片的是二值图像,才明白,白白浪费了好多时间。

而且,我的理解,由彩色转为二值图像,是必要经过灰度图像这个过程的。

关于matplotlib.pyplot的使用,网上都说,和matlab的语法很类似,以前了解过一点,所以看着例子中的imshow(),很自然的就想出了imread(),实现了图片的读取。

在查阅文档的过程中发现了一个有意思的地方。

文档

Return value is a numpy.array. For grayscale images, the return array is MxN. For RGB images, the return value is MxNx3. For RGBA images the return value is MxNx4. matplotlib can only read PNGs natively, but if PIL is installed, it will use it to load the image and return an array (if possible) which can be used with imshow(). Note, URL strings may not be compatible with PIL. Check the PIL documentation for more information.

我文中使用的是JPG图像,可见是调用了PIL处理。

而这里对于二值图像的获取,开始经历了一个误区。由于在网上搜索的时候,搜到的大多是利用PIL库的Image模块的open()&convert()方法的处理,附加参数1,可以实现二值图像的转化,但是在这里使用,后面在使用词云的时候,会提示缺少属性,可见这里不适合这样处理。

词云设定

词云支持自定义字体,背景颜色,掩膜设置等等,可以直接在IDE中跳至源文件中查看。都有相关的介绍。

文末代码是一些参数的摘录。

词频选择

这里使用了刚才聚合排序好的数据,选择了前1000个词进行展示,并组合成字典,传入了词云的实例对象的方法fit_words()生成了词云。

词云展示

这里使用了matplotlib.pyplot的的几个函数,实现了图像的保存,显示,以及坐标轴的隐藏。

这里倒是有个小异或,有点分不清楚imshow()show()了。两者从文档我也没看出个所以然来。不过他们有个最明显的区别就是后者依赖图形窗口,但是前者似乎不需要。

要是有明白的,还请大家留言或者发邮件给我。

完整代码

# -*- coding: utf-8 -*-
"""
Created on Thu Aug 17 16:31:35 2017

@note: 为了便于阅读,将模块的引用就近安置了
@author: lart
"""

# 读取事先爬取好的文件,由于文件较小,直接一次性读入。若文件较大,则最好分体积读入。
with open('秘密森林的短评.txt', 'r', encoding='utf-8') as file:
    comments = file.readlines()
    comment = ''.join(comments)


# 摘取中文字符,没有在下载时处理,正好保留原始数据。
import re

pattern = re.compile(r'[\u4e00-\u9fa5]+')
data = pattern.findall(comment)
filted_comment = ''.join(data)

# 分词
import jieba

word = jieba.lcut(filted_comment)


# 整理
import pandas as pd

words_df = pd.DataFrame({'words': word})

#停词相关设置。参数 quoting=3 全不引用
stopwords = pd.read_csv(
        "stopwords.txt",
        index_col=False,
        quoting=3,
        sep="\t",
        names=['stopword'],
        encoding='utf-8'
        )
words_df = words_df[~words_df.words.isin(stopwords.stopword)]

# 聚合
words_stat = words_df.groupby('words')['words'].agg({'size'})
words_stat = words_stat.reset_index().sort_values("size", ascending=False)


# 词云设置
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import numpy as np

def rgb2gray(rgb):
    return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])

def gray2bw(gray):
    for raw in range(len(gray)):
        for col in range(len(gray[raw])):
            gray[raw][col] = (0 if gray[raw][col]>50 else 255)
    return gray

img = plt.imread('4.jpg')
mask = rgb2gray(img)
bw = gray2bw(mask)

wordcloud = WordCloud(
                font_path="YaHei Consolas Hybrid.ttf",
                background_color="white",
                mask=bw,
                max_font_size=80
                )
# word_frequence 为字典类型,可以直接传入wordcloud.fit_words()
word_frequence = {
        x[0]:x[1] for x in words_stat.head(1000).values
        }
wordcloud = wordcloud.fit_words(word_frequence)

# 存储显示
plt.imsave('img.jpg', wordcloud)

plt.subplot(131)
plt.imshow(img)
plt.axis("off")
plt.subplot(132)
plt.imshow(bw)
plt.axis("off")
plt.subplot(133)
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis("off")

结果文件

使用的掩膜原图片:

秘密森林剧照

秘密森林剧照

输出图片

输出图片

IDE输出结果

这里写图片描述

停词文件

stopwords.txt


参考文章

Parameters
----------
font_path : string
    Font path to the font that will be used (OTF or TTF).
    Defaults to DroidSansMono path on a Linux machine. If you are on
    another OS or don't have this font, you need to adjust this path.

width : int (default=400)
    Width of the canvas.

height : int (default=200)
    Height of the canvas.

prefer_horizontal : float (default=0.90)
    The ratio of times to try horizontal fitting as opposed to vertical.
    If prefer_horizontal < 1, the algorithm will try rotating the word
    if it doesn't fit. (There is currently no built-in way to get only
    vertical words.)

mask : nd-array or None (default=None)
    If not None, gives a binary mask on where to draw words. If mask is not
    None, width and height will be ignored and the shape of mask will be
    used instead. All white (#FF or #FFFFFF) entries will be considerd
    "masked out" while other entries will be free to draw on. [This
    changed in the most recent version!]

scale : float (default=1)
    Scaling between computation and drawing. For large word-cloud images,
    using scale instead of larger canvas size is significantly faster, but
    might lead to a coarser fit for the words.

min_font_size : int (default=4)
    Smallest font size to use. Will stop when there is no more room in this
    size.

font_step : int (default=1)
    Step size for the font. font_step > 1 might speed up computation but
    give a worse fit.

max_words : number (default=200)
    The maximum number of words.

stopwords : set of strings or None
    The words that will be eliminated. If None, the build-in STOPWORDS
    list will be used.

background_color : color value (default="black")
    Background color for the word cloud image.

max_font_size : int or None (default=None)
    Maximum font size for the largest word. If None, height of the image is
    used.

mode : string (default="RGB")
    Transparent background will be generated when mode is "RGBA" and
    background_color is None.

relative_scaling : float (default=.5)
    Importance of relative word frequencies for font-size.  With
    relative_scaling=0, only word-ranks are considered.  With
    relative_scaling=1, a word that is twice as frequent will have twice
    the size.  If you want to consider the word frequencies and not only
    their rank, relative_scaling around .5 often looks good.

    .. versionchanged: 2.0
        Default is now 0.5.

color_func : callable, default=None
    Callable with parameters word, font_size, position, orientation,
    font_path, random_state that returns a PIL color for each word.
    Overwrites "colormap".
    See colormap for specifying a matplotlib colormap instead.

regexp : string or None (optional)
    Regular expression to split the input text into tokens in process_text.
    If None is specified, ``r"\w[\w']+"`` is used.

collocations : bool, default=True
    Whether to include collocations (bigrams) of two words.

    .. versionadded: 2.0

colormap : string or matplotlib colormap, default="viridis"
    Matplotlib colormap to randomly draw colors from for each word.
    Ignored if "color_func" is specified.

    .. versionadded: 2.0

normalize_plurals : bool, default=True
    Whether to remove trailing 's' from words. If True and a word
    appears with and without a trailing 's', the one with trailing 's'
    is removed and its counts are added to the version without
    trailing 's' -- unless the word ends with 'ss'.

© 著作权归作者所有

PLart
粉丝 0
博文 2
码字总数 4422
作品 0
大连
程序员
私信 提问
用 Python 分析胡歌的《猎场》到底值不值得看?

已经授权 CSDN公众号、CSDN网站、51CTO、Python开发者、Python中文社区、Python中文专栏等进行发布。获取授权,请联系作者,谢谢! 11月6日,湖南卫视已经开播被称作年度压轴的大戏“猎场”,...

布道
2017/11/18
0
0
分析豆瓣电影短评《我不是药神》关键词

小爬怡情,中爬伤身,强爬灰灰。爬虫有风险,使用请谨慎,可能是这两天爬豆瓣电影爬多了,今天早上登录的时候提示号被封了(我用自己帐号爬的,是找死呢还是在找死呢 ...),好在后面发完短信...

一别丶经年
2018/07/13
0
0
用 Python分析胡歌的《猎场》到底值不值得看?

專 欄 ❈作者:布道,互联网运维负责人。负责公司和电商平台运维技术工作,带领团队在公司推行DevOps,践行“自动化、平台化、可视化”运维理念。目前主要关注几个方面:1.平台开发,作出更好...

bf02jgtrs00xktcx
2017/11/22
0
0
“蚁”小见大,数据告诉你《蚁人2》是否值得一看

并没有成功爬到所有的短评,一波三折,最终只爬到了500条,当然这也是豆瓣目前可见的最大数量,本文将细致分析爬虫的整个过程,并对爬到的数据加以分析,蚁小见大。 整篇文章共包含爬和文本分...

Mr_zebra
2018/09/14
5
0
使用Python分析《我不是药神》豆瓣电影短评

小爬怡情,中爬伤身,强爬灰灰。爬虫有风险,使用请谨慎,可能是这两天爬豆瓣电影爬多了,今天早上登录的时候提示号被封了(我用自己帐号爬的,是找死呢还是在找死呢 ...),好在后面发完短信...

一别丶经年
2018/07/13
4K
9

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
今天
815
11
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
今天
15
0
计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
昨天
6
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
昨天
7
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部