程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python實現的《芳華》WordCloud詞雲+LDA主題模型

編輯:Python

WordCloud 詞雲 + LDA 主題模型

何小嫚&劉峰原圖.jpg

人物詞雲效果.jpg

電影《芳華》在春節重映了一波,加上之前的熱映,最終取得了 14 億票房的好成績。嚴歌苓的原著也因此被更多的人細細品讀。用文本分析的一些技術肢解小說向來是自然語言處理領域的一大噱頭,這次當然也不能放過,本篇達成的成就有:
1、提取兩大主角劉峰和何小嫚(萍)的關鍵詞並繪制好看的人物詞雲;
2、以章節為單位探索小說的主題分布並畫圖展示。

主要功能包:

jieba
lda
wordcloud
seaborn

安裝命令: pip install ***

需要的外部文件:

  • 小說全文, 芳華-嚴歌苓.txt
  • 中文停用詞,stopwords.txt
  • 小說人物名稱,person.txt,作為 jieba 的用戶自定義詞典
  • 兩個人物的 png 圖片
  • 你喜歡的中文字體的 ttf 文件,我用的楷體

人物名和停用詞文件示例.jpg

文本預處理

分詞,並過濾無意義詞

文本挖掘的必備步驟,畢竟理解中文的最小單位是詞匯。這裡沒有使用簡單的 jieba.cut 進行分詞,因為我們需要知道單詞的詞性,便於稍後根據詞性過濾不重要的詞。

采用 jieba.posseg.cut 分詞可以輸出詞性。我們並不能拍腦門決定是要動詞還是名詞等等,詞性有非常多個,我把全部分詞結果按照詞性分好類,看了一下每個詞性對應哪些詞,最後決定保留詞性為[“a”, “v”, “x”, “n”, “an”, “vn”, “nz”, “nt”, “nr”]的詞,例如圖中,m 代表量詞,這是對語義沒有幫助的詞,應該捨棄。

詞性示例.jpg

import jieba.posseg
jieba.load_userdict("data/person.txt")
STOP_WORDS = set([w.strip() for w in open("data/stopwords.txt").readlines()])
def cut_words_with_pos(text):
seg = jieba.posseg.cut(text)
res = []
for i in seg:
if i.flag in ["a", "v", "x", "n", "an", "vn", "nz", "nt", "nr"] and is_fine_word(i.word):
res.append(i.word)
return list(res)
# 過濾詞長,過濾停用詞,只保留中文
def is_fine_word(word, min_length=2):
rule = re.compile(r"^[\u4e00-\u9fa5]+$")
if len(word) >= min_length and word not in STOP_WORDS and re.search(rule, word):
return True
else:
return False

劃分章節

我們按照“第*章”這樣的字眼將小說的不同章節分割開來,作為獨立的文檔,用於之後的主題分析。定義了一個名為 MyChapters 的生成器,存儲每章分好的詞匯,是為了避免章節過多帶來的一些程序運行問題。其實《芳華》僅有 15 章,用一個簡單的列表也是可以的。

class MyChapters(object):
def __init__(self, chapter_list):
self.chapter_list = chapter_list
def __iter__(self):
for chapter in self.chapter_list:
yield cut_words_with_pos(chapter)
def split_by_chapter(filepath):
text = open(filepath).read()
chapter_list = re.split(r'第.{1,3}章\n', text)[1:]
return chapter_list

人物關鍵詞提取

要提取人物關鍵詞,首先要解決的問題是,在不借助外部的人物描述(比如百度百科和豆瓣電影上的角色介紹)的情況下,如何確定跟這個人物相關的內容。這裡采用的比較簡單的策略是,對小說文件中的每一行,如果該人物的名稱存在,則將該行加入到此人的相關語料中去。再以此為基礎統計詞頻,結果大致 ok,為了人物詞雲更精確的展示,我將詞頻輸出到了文件,手動刪除了一些詞,並簡單調整了一些詞的詞頻,下圖是調整過後的詞和詞頻,左為何小嫚,右為劉峰。

import pandas as pd
def person_word(name):
lines = open("data/芳華-嚴歌苓.txt", "r").readlines()
word_list = []
for line in lines:
if name in line:
words = cut_words_with_pos(line)
word_list += words
# 統計詞頻並按照詞頻由大到小排序,取top500
cnt = pd.Series(word_list).value_counts().head(500)
# 可以把結果輸出到文件,進行一些手動調整
# cnt.to_csv("data/cntliu.csv")
# 返回字典格式
return cnt.to_dict()

人物關鍵詞提取結果示例.jpg

詞雲繪制

python 有 wordcloud 包可以用於詞雲繪制,在使用過程中需要注意:

用於定義形狀的外部圖片必須是 png 格式,默認純白色部分為非圖像區域;

中文詞雲必須載入一個字體文件;

字的顏色可以自己定義,也可以使用圖片本身的底色。本例中何小嫚的圖片 底色很鮮艷明晰,可以用本身的底色(ImageColorGenerator);而劉峰的圖片是單色,且色淺,我使用了自定義顏色(my_color_func);

繪制詞雲需要用到的數據格式為 dict,key 為詞,value 為詞頻,詞頻越大,在圖片中的字體越大。

import matplotlib.pyplot as plt
from wordcloud import WordCloud, ImageColorGenerator
from scipy.misc import imread
from random import choice
# 定義顏色,方法很多,這裡用到的方法是在四個顏色中隨機抽取
def my_color_func(word, font_size, position, orientation, random_state=None, **kwargs):
return choice(["rgb(94,38,18)", "rgb(41,36,33)", "rgb(128,128,105)", "rgb(112,128,105)"])
def draw_cloud(mask_path, word_freq, save_path):
mask = imread(mask_path) #讀取圖片
wc = WordCloud(font_path='data/kaiti.TTF', # 設置字體
background_color="white", # 背景顏色
max_words=500, # 詞雲顯示的最大詞數
mask=mask, # 設置背景圖片
max_font_size=80, # 字體最大值
random_state=42,
)
# generate_from_frequencies方法,從詞頻產生詞雲輸入
wc.generate_from_frequencies(word_freq)
plt.figure()
# 劉峰, 采用自定義顏色
plt.imshow(wc.recolor(color_func=my_color_func), interpolation='bilinear')
# 何小嫚, 采用圖片底色
# image_colors = ImageColorGenerator(mask)
# plt.imshow(wc.recolor(color_func=image_colors), interpolation='bilinear')
plt.axis("off")
wc.to_file(save_path)
plt.show()
# 獲取關鍵詞及詞頻
input_freq = person_word("劉峰")
# 經過手動調整過的詞頻文件,供參考
# freq = pd.read_csv("data/cntliu.csv", header=None, index_col=0)
# input_freq = freq[1].to_dict()
draw_cloud("data/liu.png", input_freq, "output/liufeng.png")

對人物進行摳圖,背景設置為純白,存儲為 png 格式。
為了使形狀更鮮明,對小嫚的辮子還有腰的部分做了加白處理,可以對比文章開頭原圖感受一下。

何小嫚&劉峰用作生成詞雲的圖片.jpg

人物詞雲效果.jpg


  1. 上一篇文章:
  2. 下一篇文章:
相關文章
    没有相关文章
Copyright © 程式師世界 All Rights Reserved