2020-03-08 | 技术 Python | 4 min read

此文章发表于 678 天前,请注意文章时效

上一篇中完成了对歌词的下载及存储就等着这次的歌词分词、清洗处理。

简易过程

  1. 读入歌词
  2. 分词、清洗去掉停用词
  3. 绘制词云

读入歌词、分词

读入歌词非常简单,在这一步骤时使用了codecs防止出现编码问题。得到了歌词之后就进行分词处理,采用结巴分词,并且读入停用词表。

    lyrc_from_file = text
    word_split = jieba.cut(lyrc_from_file, cut_all=False)
    # 分词的结果不是列表
    jdr = '/'.join(word_split)
    stop_words_file = 'stopwords.txt'
    stop_words = codecs.open(stop_words_file, "r", encoding='utf-8').read()
    stop_words_list = stop_words.split("\n")

但是很快就发现了另一个问题,那是就网上下载的停用词表不能将歌词中无意义的词给一网打尽,比如“编曲”、“作词”、“混音”之类的。所以采用自定义停用词,但是在这里我却遇到了一个问题:自己创建的停用词文件读入之后,不能去除歌词中的停用词。

    my_stop_words =codecs.open('mystopwords.txt','r',encoding='utf-8').read()
    my_stop_words_list=my_stop_words.split('\n')

考虑了好久,一直也没有发现问题在哪里。在这个问题上,搞了很长时间,最后才发现问题所在:自己创建的txt文件中的手动换行并不是\n而是\r\n 完整的代码是这样的:

def split_text(text):
    lyrc_from_file = text
    word_split = jieba.cut(lyrc_from_file, cut_all=False)
    # 分词的结果不是列表
    jdr = '/'.join(word_split)
    stop_words_file = 'stopwords.txt'
    stop_words = codecs.open(stop_words_file, "r", encoding='utf-8').read()
    stop_words_list = stop_words.split("\n")
    my_stop_words =codecs.open('mystopwords.txt','r',encoding='utf-8').read()
    my_stop_words_list=my_stop_words.split('\r\n')
    #注意自己写的中回车处理不同
    stop_words_list.extend(my_stop_words_list)
    lyrc_list = []
    for abt in jdr.split('/'):
        if not (abt.strip() in stop_words_list):
            lyrc_list.append(abt)
    return lyrc_list

绘词云

在绘制词云的时候也遇到一个很奇怪的问题:在给词云上色的时候使用recolor函数,如果在参数中不声明color_func参数名,则会报错。所以在使用这个函数的时候,一定要指明color_func。
另外还有一个有意思的问题,那就是使用generate from text 不会包含单个字母,对应到中文中则不包含一个字。这其实是因为wordcloud是为了英文设计的,所以会有这个问题。为了防止词云绘制失真,可以使用generate from frequencies。 在使用这个函数的时候,需要注意一点,虽然wordcloud说明中generate from frequencies的参数是turtle,但是使用turtle则会报错,实际上的参数类型是dict(真是坑呀!!)
词云部分的代码如下:

def draw_word_cloud(text, pic):
    font = "HYJiaGuoSongW.ttf" #When drawing chinese wordcloud, the font must be used, otherwise, it will not display chinese characters.
    mask_image_path = pic
    mask_image = np.array(Image.open(mask_image_path))
    word_cloud_color1 = ImageColorGenerator(mask_image)
    wcp = WordCloud(
        font_path=font,
        background_color="white",
        max_words=600,
        mask=mask_image,  # 设置背景图片
        max_font_size=100,  # 字体最大值
        random_state=42,
        width=1200,
        height=900,
        margin=2,
    )
    # wcp.generate(text)
    wcp.generate_from_frequencies(text)
    #fre required dit not turtle
    #and default generate(text) will not include single word(one chinese word or one english letter)
    wcr = wcp.recolor(color_func=word_cloud_color1)
    # 此外如果不是这样就会报错
    plt.rcParams['savefig.dpi'] = 300
    plt.imshow(wcr)
    plt.axis('off')
    plt.savefig('word_cloud_result.png')
    plt.show()

既然需要使用词频来绘制词云,那如何得到词频呢? 使用counter对象,可以方便的得到词频。代码如下:

def get_word_fre(wordlist):
    seg_list = wordlist
    c = Counter()
    for x in seg_list:
        c[x] += 1
    word_fre={}
    for(k,v)in c.most_common(600):
        word_fre[k]=int(v)
    return word_fre

结果


其实从词频中我们看到一个很有意思的现象:
唱情歌的人,更喜欢说,而不是唱。哈哈哈哈哈哈

本文链接:https://willisfusu.github.io/post/python-wordcloud-2/

此文章由李二先生采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可,转载请注明出处。

🎉🎉🎉 我开通了Newsletter,欢迎订阅! 🎉🎉🎉