美文网首页消除零零发文本分析
用Py做文本分析3:制作词云图

用Py做文本分析3:制作词云图

作者: 凡有言说 | 来源:发表于2020-02-06 09:40 被阅读0次

    1.词频统计

    在词频统计之前,需要先完成分词工作。因为词频统计是基于分词后所构建的list进行的。

    import jieba
    
    #对小说文本第一回分词
    word_list = jieba.lcut(chapter.txt[1])
    word_list[:10]
    
    ['第一回', ' ', '风雪', '惊变', '钱塘江', '浩浩', '江水', ',', '日日夜夜', '无穷']
    

    1.1使用Pandas统计

    #使用pandas统计
    #将数据放入DataFrame
    import pandas as pd
    df = pd.DataFrame(word_list, columns = ['word'])
    df.head(10)
    
    word
    0   第一回
    1   
    2   风雪
    3   惊变
    4   钱塘江
    5   浩浩
    6   江水
    7   ,
    8   日日夜夜
    9   无穷
    
    #统计并降序排列
    result = df.groupby(['word']).size()
    print(type(result))
    freqlist = result.sort_values(ascending=False)
    freqlist[:10]
    
    <class 'pandas.core.series.Series'>
    word
    ,    2034
    。     714
    了     400
    “     344
    :     343
    ”     342
    的     291
    道     210
    他     187
    是     167
    dtype: int6
    

    1.2 使用NLTK统计

    NLTK的生成结果为频数字典,可以被一些程序包直接调用

    import nltk
    
    #生成完整的词条频数字典
    fdist = nltk.FreqDist(word_list)
    fdist
    
    #查看某词出现的次数
    fdist['颜烈']
    
    37
    
    #列出词条列表
    fdist.keys()
    
    
    #频率分布表
    fdist.tabulate(10)
    
       ,    。    了    “    :    ”    的    道    他    是 
    2034  714  400  344  343  342  291  210  187  167 
    
    #高频词汇Top10
    fdist.most_common(10)
    
    [(',', 2034),
     ('。', 714),
     ('了', 400),
     ('“', 344),
     (':', 343),
     ('”', 342),
     ('的', 291),
     ('道', 210),
     ('他', 187),
     ('是', 167)]
    

    2.词云图

    词云实际上是对分词结果频数表的图形化展示,使得浏览者能快速发现文本的核心内容。

    常见的词云工具有:

    • Python

      • 生成比较标准的词云
      • 可以对背景图片进行修饰
    • R

      • 可以展示不同类别间的词云比较
      • 可以实现彩色动态效果的词云
      • 可以对背景图片进行修饰
    • Tableau

      • 可以实现词云结果的动态监测和展示

    2.1wordcloud包安装

    wordcloud包不太好安装,这里给一些攻略:
    Anaconda 3.6安装wordcloud 词云出现问题
    Anaconda安装jieba、wordcloud等第三方库

    对于wordcloud,我们需要指定中文字体支持
    WordCloud(font_path='xxx')
    以上需要写字体文件所在的完整路径

    2.2 wordcloud包用法

    class 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=0.5, 
            regexp=None, 
            collocations=True,
            colormap=None, 
            normalize_plurals=True)
    

    常用功能:

    • font_path = None:字体路径,默认使用系统字体
    • width = 400 :宽度
    • height = 200:高度
    • max_words = 200:需要绘制的词条最大数目
    • stopwords = None:停用词列表

    字体设定:

    • min_font_size=4 / max_font_size=None:字符大小范围
    • font_step=1:字号增加的步长
    • relative_scaling=0.5:词频和字号的换算关系
    • prefer_horizontal=0.9:词条水平显示的比例

    颜色设定:

    • background_color='black':图形背景色
    • mode='RGB':图形颜色编码,如果指定为“RGBA”且背景色为None时,背景色为透明
    • color_func=None:生成新颜色的函数,使用matplotlib的colormap

    背景掩模:

    • mask=None:词云使用过的背景图

    用wordcloud绘制特定文本的词云时,需要用空格或标点符号对文本进行分隔,以便后续对文本进行分词处理

    #对原始文本直接分词并绘制
    import wordcloud
    myfont = 'C:/Windows/Fonts/simkai.ttf'
    text = 'this is hangzhou, 郭靖, 和, 哀牢山 三十六剑'
    cloudobj = wordcloud.WordCloud(font_path = myfont).generate(text)
    print(cloudobj)
    
    <wordcloud.wordcloud.WordCloud object at 0x00000289345D7908>
    
    #显示词云
    import matplotlib.pyplot as plt
    plt.imshow(cloudobj)
    plt.axis('off')
    plt.show()
    
    image.png

    说明:上图中没有‘this’,'is',‘和’是因为默认的停用表中包含上述词。

    #优化词云
    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()
    
    image.png

    最后我们保存一下词云

    #保存词云
    cloudobj.to_file('词云test.png')
    

    接下来制作射雕英雄传第一章的词云

    #射雕英雄传第一章词云
    import pandas as pd
    import jieba
    
    stoplist_path = 'D:/Files/program data/nlp/PythonData/停用词.txt'
    stoplist = list(pd.read_csv(stoplist_path, names = ['w'], sep = 'aaa',
                               encoding = 'utf-8', engine = 'python').w)
    
    cloudobj = wordcloud.WordCloud(font_path = myfont,
                                  width = 1200, height = 800,
                                  mode = 'RGBA', background_color = None,
                                  stopwords = stoplist).generate(' '.join(jieba.lcut(chapter.txt[1])))
    
    plt.imshow(cloudobj)
    plt.axis('off')
    plt.show()
    
    #保存图片
    cloudobj.to_file('词云test2.png')
    
    image.png

    generate()操作背后实际上执行了两个函数

    • 调用分词函数process_text()
    • 调用基于频数的绘制函数fit_words()

    fit_words(dict)

    • dict:由词条和频数构成的字典
    #基于分词频数绘制词云
    def m_cut(intext):
        return [w for w in jieba.cut(intext) if w not in stoplist]
    
    import nltk
    from nltk import FreqDist
    
    tokens = m_cut(chapter.txt[1])
    fdist = FreqDist(tokens)
    
    cloudobj = wordcloud.WordCloud(font_path = myfont).fit_words(fdist)
    
    plt.imshow(cloudobj)
    plt.axis('off')
    plt.show()
    
    image.png

    2.3词云美化

    (1)设置背景图片
    Mask 掩模/遮罩

    • 用于控制词云的整体形状
    • 设定Mask后,设定的高度和宽度值将被忽略,遮罩形状被指定图形的形状取代。除全白的部分仍然保留外,其余部分会用于绘制词云。因此背景图片的画布一定要设置为白色(#FFFFFF)
    • 字的大小,布局和颜色也会基于Mask生成
    • 必要时可以调整颜色来增强可视化效果
    from scipy.misc import imread
    
    def m_cut(intext):
        return [w for w in jieba.cut(intext) if w not in stoplist and len(w) >1]
    
    cloudobj = wordcloud.WordCloud(font_path = myfont,
                                  mask = imread('D:/Files/program data/nlp/PythonData/射雕背景1.png'),
                                  mode = 'RGBA', background_color =None
                                  ).generate(' '.join(m_cut(chapter.txt[1])))
    
    plt.imshow(cloudobj)
    plt.axis('off')
    plt.show()
    
    image.png

    更换背景图片

    from scipy.misc import imread
    
    def m_cut(intext):
        return [w for w in jieba.cut(intext) if w not in stoplist and len(w) >1]
    
    cloudobj = wordcloud.WordCloud(font_path = myfont,
                                  mask = imread('D:/Files/program data/nlp/PythonData/射雕背景2.png'),
                                  mode = 'RGBA', background_color =None
                                  ).generate(' '.join(m_cut(chapter.txt[1])))
    
    plt.imshow(cloudobj)
    plt.axis('off')
    plt.show()
    
    image.png

    对比下原图,出现不同的原因在于弓箭的弓背很细,词条和图不能很好的适配。因此在选择图片时要注意。


    射雕背景2.png

    (2)指定图片的色系
    我们可以选择合适图片,将其色系运用在词云中。

    import numpy as np
    
    imgobj = imread('D:/Files/program data/nlp/PythonData/射雕背景2.png')
    image_colors = wordcloud.ImageColorGenerator(np.array(imgobj))
    cloudobj.recolor(color_func = image_colors)
    
    plt.imshow(cloudobj)
    plt.axis('off')
    plt.show()
    
    image.png

    (3)指定单词组上色
    理想的情况是分组比较词频,在两组中都高频的词条在图形中相互抵消。Python目前只能实现词条分组上色。

    from wordcloud import get_single_color_func
    
    class GroupedColorFunc(object):
        
        def __init__(self, color_to_words, default_color):
            self.color_func_to_words = [
                (get_single_color_func(color), set(words))
                for (color, words) in color_to_words.items()
            ]
            
            self.default_color_func = get_single_color_func(default_color)
            
        def get_color_func(self, word):
            try:
                color_func = next(
                    color_func for (color_func, words) in self.color_func_to_words
                    if word in words
                )
            except StopIteration:
                color_func = self.default_color_func
            
            return color_func
        
        def __call__(self, word, **kwargs):
            return self.get_color_func(word)(word, **kwargs)
    
    color_to_words = {
        '#00ff00': ['颜烈', '武官', '金兵', '官兵'],
        'red': ['包惜弱', '郭啸天', '杨铁心', '丘处机']
    }
    
    default_color = 'grey'
    
    grouped_color_func = GroupedColorFunc(color_to_words, default_color)
    cloudobj.recolor(color_func = grouped_color_func)
    plt.imshow(cloudobj)
    plt.axis('off')
    plt.show()
    
    image.png

    参考资料:
    Python数据分析--玩转文本挖掘
    自然语言处理NLTK之入门
    wordCloud的基本使用

    相关文章

      网友评论

        本文标题:用Py做文本分析3:制作词云图

        本文链接:https://www.haomeiwen.com/subject/atsyxhtx.html