Fork me on GitHub

WordCloud

概述

1. 词云图

相信大家在生活中也看过下面这样的图形吧?想必对于词云图也不是很陌生吧?词云图,顾名思义,就是一些具有关键意义的词,组成一些具有代表意义的形状,并按照重要程度、出现频率等进行排列组合得到一张精炼浓缩的信息图。是不是感觉十分高大上?其实,我们自己也可以做属于我们自己的词云图。
百度搜索词云图01
百度搜索词云图02

2. 准备素材

巧妇难为无米之炊,我们需要准备一下材料去烹饪我们这道视觉盛宴:

  • 主材料:文本
  • 辅料:图片
  • 工具:词云制作工具(WordArt 等) OR 编程语言(python 等)

3. 准备文本

这一章里面,我主要介绍的是如何把QQ聊天记录导出,并把整理成关键词,为后续可视化做准备的。

  • 导出聊天记录
    首先找到qq的消息管理器(小喇叭),然后找到你想要得到的聊天记录的那位,右键,导出消息记录就可以了。【注意】选择下拉菜单,将聊天记录导出为(* .txt)格式或者是(* .mht)格式。
    导出qq聊天记录.png

  • 处理文本
    在得到文本素材以后,我们需要将这些文本进行分割,得到一个个词语,经过过滤得到关键词。这里,我们选用的是 jieba 结巴中文分词。
    jieba 中文分词的 Github 项目地址:https://github.com/fxsjy/jieba

    • 通过 pip 安装jieba:pip install jieba
    • 通过 jieba 处理文本:

      1
      2
      3
      4
      5
      6
      7
      import jieba
      import jieba.analyse
      import re # 正则表达式清洗数据
      # 打开并读取文档
      file=open("wxb.txt",'r',encoding='UTF-8')
      obj=file.read()
      file.close()
      • 清洗聊天记录
        这里主要利用re 模块进行清洗,大家可以根据自己的聊天记录形式进行自定义的处理。
        re 模块介绍:http://www.runoob.com/python/python-reg-expressions.html

        1
        2
        3
        4
        5
        import re
        # 使用re.sub()函数进行清洗
        # 主要清洗对象为"=="、"YYYY-MM-DD"、"HH:MM:SS"、"QQ昵称"、"[图片]"
        # 下面以时间数据处理为例进行简单的演示,大家可以根据自己的需要,根据规则进行修改
        t_rm1= re.sub("\d\d:\d\d:\d\d",'',obj)
      • 分词

        1
        2
        3
        4
        5
        6
        # 将特定的词加入词典
        jieba.add_word("不安分的小王")
        # 分词
        word_list=jieba.cut(obj,cut_all=Flase,HMM=True)
        word_split="\".join(word_list)
        word_split` 便是你最终的分词结果
      • 提取关键词
        光得到分词结果我们还不能很好地展现文本内容,这一步,我们需要分词后的统计,提取关键词。为后面可视化做准备。

        1
        2
        3
        4
        5
        6
        # 提取关键词
        rank_K=300 #提取前300的关键词
        # 返回带有权重的词语的list
        tags = jieba.analyse.extract_tags(wrd_split, topK=rank_K, withWeight=True, allowPOS=())
        word_split="\".join(word_list)
        # 如果不想带权重的话,可以设置 withWeight=False
      • 保存最终关键词和结果

        1
        2
        3
        with open("keywords.txt",'w',encoding='UTF-8') as f:
        for i in range(0,rank_K):
        f.write(str(tags[i])+'\n')
      • 保存最终关键词和结果

        ![关键词提取结果(部分)](http://upload-images.jianshu.io/upload_images/10426271-6cc70c689fd46ef7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
        

到此,介绍完了文本准备的相关工作。后面会继续介绍如何制作词云

制作词云

1. 制作原料:

主料:文本(QQ聊天记录)
辅料:WordArt,jieba(python包)

  • jieba是进行中文分词的一个十分实用的软件包。项目在Github的地址为:https://github.com/fxsjy/jieba 。我们知道,一个文本的含义需要词语串联得到,利用jieba我们可以将中文字符串进行有效的分割,得到组成文本的各个词语。然后基于词语制作我们的词云图。

安装并使用 jieba 流程,具体参考前一篇博客
【传送门】:http://www.jianshu.com/p/dee4ff08df2a

  • 使用: pip install jieba 进行安装;
  • 使用 jieba.cut() 进行分词
    1
    2
    import jieba
    str_cut = jieba.cut(str)

2. 制作方法:

介绍制作词云的两种方法:

  • 基于WordArt 进行绘制
  • DIY编程实现

WordArt

WordArt 是一款十分好用的在线制作词云的软件。但是,需要付费得到更高清的结果。对于我们普通用户,在网站上申请自己的账号,做几张图娱乐一下就行了。没必要花很多钱去买会员。
下面是国外的网友的一些作品:
WordArt Trending - 《Rainbow Stitch》[1]
WordArt Trending - 《Emojiiiiiiiiiiiiiiiii...》[2]
WordArt Trending -《Mickey Mouse》[3]

[1] https://wordart.com/qhlv4vxrevtz/rainbow-stitch
[2] https://wordart.com/sajylyvwjx6u/emojiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
[3] https://wordart.com/s3zwaue4bw0s/mickey-mouse

想要制作自己的词云图,首先要准备好自己的文本材料(在这里,我以qq聊天记录为例子进行演示):有关 qq聊天记录的提取和分词,请翻看前篇BLOG(传送门)
注册登录账户,创建(CREATE NOW)自己的项目以后,WordA如图选项栏分为:文本、形状、字体、布局以及风格。
WordArt

  1. 导入自己的文本。再导入文本之前需要进行分词操作
    文本导入.png
  2. 导入合适的字体。这里需要注意的是WordArt本身没有支持中文的字体。需要我们手动进行导入。可以网上下载一些字体。导入(.ttf)字体文件。然后选择好形状以及布局
    选项面板
  3. 然后点击“Visualize”按钮。静静等待一会儿。就可以得到属于自己的词云图啦~
    Valentine 01
    Valentine 02
    valentine 03

DIY编程

前面介绍了文本材料的准备 以及 WordArt 可视化。这里我介绍如何自己动手DIY属于自己的词云。

  • 材料:

    • 文本数据
    • python (jieba,wordcloud)
      安装 jiebawordcloud
      1
      2
      pip install jieba
      pip install wordcloud

    wordcloud用于生成词云,Github地址:https://github.com/amueller/word_cloud
    wordcloud生成需要词语作为元素,由于wordcloud是国外的,对中文支持不好,所以我们需要提前对文本进行分词统计处理,得到关键词进行可视化。

  • 实现:

    • 方式一:
      直接将分词结果放入wordcloud.generate()函数中进行处理(wrd_dict是分词的结果)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      import matplotlib.pyplot as plt
      from wordcloud import WordCloud
      #可视化
      BKImg=np.array(Image.open("heart.jpg"))# 加入自定义背景图片
      my_wordcloud = WordCloud(
      background_color='white', # 设置背景颜色
      mask = BKImg, # 设置背景图片
      max_words = rank_K, # 设置最大现实的字数
      #stopwords = "小嫣嫣小星星", # 设置停用词
      font_path = 'FZLTHJW.TTF',# 设置字体格式,如不设置显示不了中文
      max_font_size = 80, # 设置字体最大值
      min_font_size = 10,
      # relative_scaling=0.5,
      random_state = 30, # 设置有多少种随机生成状态,即有多少种配色方案
      scale=1
      ).generate(wrd_dict)
      clr=ImageColorGenerator(BKImg) # 加入背景的配色方案
      plt.imshow(my_wordcloud.recolor(color_func=clr))`
      plt.imshow(my_wordcloud)
      plt.axis("off")
      plt.show() #显示
      my_wordcloud.to_file("result1.png") # 将结果写入png
    • 方式二:

      • 方式一中,将分好的词加入自定义词典,加入generate()函数,但是这样得到的结果却不是很理想,最终 wordcloud 整理出来的结果将人名和一些人所说的话并在一起,导致“小王 哈哈哈”,“小王”都被分进词云的词典,导致“小王”这个词重复出现。
      • 为了解决这个问题,查看WordCloud这个类(对象),找到generate_from_frequencies(wrd_dict)这个函数,送入的是自定义的字典{[对象]:[频率]}
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        # 制作词典
        wrd_dict={}
        for i in range(0,rank_K):
        wrd_dict[str(tags[i][0])]=round(math.log(tags[i][1]*len_txt,1.5))
        #可视化
        BKImg=np.array(Image.open("heart.jpg"))
        my_wordcloud = WordCloud(
        background_color='white', # 设置背景颜色
        mask = BKImg, # 设置背景图片
        max_words = rank_K, # 设置最大现实的字数
        #stopwords = "小嫣嫣小星星", # 设置停用词
        font_path = 'FZLTHJW.TTF',# 设置字体格式,如不设置显示不了中文
        max_font_size = 80, # 设置字体最大值
        min_font_size = 10,
        # relative_scaling=0.5,
        random_state = 30, # 设置有多少种随机生成状态,即有多少种配色方案
        scale=1
        ).generate_from_frequencies(wrd_dict)
        clr=ImageColorGenerator(BKImg)
        plt.imshow(my_wordcloud.recolor(color_func=clr))
        plt.imshow(my_wordcloud)
        plt.axis("off")
        plt.show()
        my_wordcloud.to_file("result2.png")
      • 这里 math.log() 是调整聊天记录中出现频率过度频繁的人的名字的权重,使得样 本权重比较平衡。
  • 成果:

    qq 聊天记录词云

    大家赶紧动手制作自己的词云吧~ 趁着情人节前给自己的女朋友一个惊喜(*\^▽\^*)

-------------The end Thanks-------------

Title:WordCloud

Author:Xingbo WANG

Datetime:2018-02-05 - 14:02

Latestupdate:2018-02-23 - 19:02

Originallink:http://yoursite.com/2018/02/05/WordCloud/

licence: The copyright of this article belongs to the author. Please quote this as reference upon reproduction of this article.

You donation will be huge motivation for me.