Re0誰是真女主?讓詞雲來告訴你
1.前言
關於Re0誰是女主角一直是個爭論不休的話題,作為一個堅定的艾米莉亞黨,為了支援自己買的股票,我決定交給Re0原著小說(1-19章)來判斷。根據原著中誰的出場頻率最高,來看看誰才是真正的女主角。
2.最簡單的詞雲
首先讓我們有請我們的工具人1號——WordCloud庫。它可以統計文字中各個詞語的頻率,並且將它們通過不同大小的詞雲來展示。話不多說,上程式碼。
import matplotlib.pyplot as plt
from wordcloud import WordCloud
txt = open('Re0.txt', encoding='ANSI').read()
#讀入Re0小說,注意小說的格式,儲存在字串txt中
wc = WordCloud(font_path='Hiragino.ttf',width=800,
height=600,mode='RGBA',background_color=None).generate(txt)
#WordCloud新建的是一個wordcloud物件,裡面的引數可以自行控制,
#width和heigth分別是寬度和高度
#font_path代指字型路徑,中文字型不設定路徑就會出現亂碼
#而mode代表讀入的模式,這裡採用RBGA格式,表示在RGB的基礎上加了一
#個alpha,也就是透明度backgroud_color為背景顏色,預設是黑色,
#這裡設定為None和RGBA模式配合可以得到無背景的透明詞雲
plt.imshow(wc)
plt.axis('off')
#去除座標軸
plt.show()
wc.to_file('Re0_untokenized.png')
#輸出圖片,注意在RGBA模式下只能輸出為png格式的圖片
|
import matplotlib.pyplot as plt
from wordcloud import WordCloud
import jieba
txt = open('Re0.txt', encoding='ANSI').read()
txt = ' '.join(jieba.cut(txt))
#用jieba進行分詞,再將分詞用空格連線起來。這裡分詞會消耗很長的時間
stop_words = open('stopwords/baidu_stopwords.txt',
encoding='utf8').read().split()
#開啟停頓詞庫,將其用空白符分割成列表
wc = WordCloud(font_path='Hiragino.ttf',width=800, height=600,
stopwords=stop_words,mode='RGBA',
background_color=None).generate(txt)
#把停頓詞列表輸入wordcloud物件中,這樣wordcloud計數時便會忽略這些詞
plt.imshow(wc)
plt.axis('off')
plt.show()
wc.to_file('Re0_tokenized_stopwords.png')
|
看到艾米莉亞這幾個大字沒有,這是EMT黨的大勝利!!!但是我有覺得好像和雷姆差不多。那麼讓我們用數來說話吧。下面我們選取幾個比較大的名字將他們在詞雲統計中的頻率畫出來。
#接續上一節程式碼
print(wc.words_)
# wc.words_是詞雲物件的一個成員,它是由詞語:頻率組成的字典,
# 我們將它列印觀察一下
plt.rcParams['font.sans-serif']=['KaiTi'] #用來正常顯示中文標籤
plt.rcParams['font.serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號
#這一段是用來處理中文亂碼的程式碼,原本是打算按照網上改成SimHei字型,
#發現還是亂碼結果改成KaiTi才解決了這個問題。
new_keys = [u'愛蜜 莉雅', u'雷姆', u'拉姆', u'羅茲 瓦爾',
u'威爾 海姆', u'嘉飛爾', u'碧翠絲', u'裡烏斯']
#這裡每個中文詞前面加u表示採用unicode編碼
dic1 = {key : wc.words_[key] for key in new_keys}
# 這裡我們根據選擇的keys形成新的詞典
plt.bar(*zip(*dic1.items()))
#用dic1.items()獲得字典裡面的全部內容,得到用二元組組成的列表
#zip(*)將其解壓,得到一堆二元組。bar(*)將二元組一個個畫出來
plt.show()
|
#列印的結果
{'愛蜜 莉雅': 1.0, '雷姆': 0.5444051387078757, '拉姆':
0.41817166263265687, '羅茲 瓦爾': 0.39136101284676966, '威爾 海姆':
0.3528207037795569, '嘉飛爾': 0.31297709923664124, '碧翠絲':
0.28542170917892384, '聲音': 0.2619623906162726, '少女':
0.26084528020852726, '魔女': 0.25991435486873954, '就算':
0.25544591323775834, '身體': 0.23589648110221562, '世界':
0.23422081549059764, '真的': 0.2329175200148948, '感覺':
0.23273133494693726, '一個': 0.22938000372370135, '裡烏斯':
0.2280767082479985,
我們可以看到艾米莉亞詞頻最高,EMT的大勝利。而雷姆從第二卷登場,第十卷沉睡,只在一半的章節登場,相對出場頻率卻佔了艾米莉亞的一半還多,tql。而從詞頻上看,486根本沒有上榜,可能是分詞後‘菜月昴’無了,所以我們的男主是’羅茲瓦爾’,不接受反駁,謝謝。牛頭人黨的大勝利。另外,讓人感到意外的是,Re0裡面妹子這麼多,沒想到威爾海姆老爺子,加菲貓,尤里烏斯這幾個大老爺們也上榜了。真就是無論男的女的我全都要唄。
3.將詞雲變成艾米莉亞的形狀
這樣就完事也太無聊了,為了慶祝EMT黨的大勝利,不如我們把詞雲改成艾米莉亞的形狀。這裡就要介紹我們的第3個工具人了——cv2庫。它能夠按照多維陣列格式讀入圖片。wordcloud物件有一個mask引數,讀入多維陣列。然後wordcloud會將白色的畫素視為背景刪去,在剩餘的畫素點上繪圖。因此要求我們選作蒙版的圖片要麼是白色背景的jpg,要麼是無背景的PNG,並且儘量大一點且前景集中在一塊,否則會出現字看不清和字分佈得很離散的情況。
這裡由於艾米莉亞穿的是白色的衣服,所以經常被剔除,得到殘破不全的詞雲。無奈之下博主只能用PS P了一張黑白的。這是原圖和P圖
|
|
import matplotlib.pyplot as plt
import jieba
import cv2
from wordcloud import WordCloud
txt = open('Re0.txt', encoding='ANSI').read()
txt = ' '.join(jieba.cut(txt))
stop_words = open('stopwords/baidu_stopwords.txt',
encoding='utf8').read().split()
img = cv2.imread('aimi4.png', cv2.IMREAD_GRAYSCALE)
#用cv2庫讀入圖影像,並且採用灰度方式讀入。
#這裡推薦使用600x800以上的圖片,而且背景和角色最好分開,角色最好比較大,
#圖片背景必須是透明或者全白,不能有其它雜色
wc = WordCloud(mask=img, font_path='Hiragino.ttf',
stopwords=stop_words,contour_width=1,contour_color='black',
background_color='white').generate(txt)
#設定Img為mask蒙版,控制詞雲形狀
#為了將圖片的輪廓畫出來,所以指定contour_width就是輪廓寬度,預設等於
#0,就#是不畫輪廓,contour_color指的是輪廓顏色。
#注意這裡不能用RGBA模式否則報錯
#operands could not be broadcast together
#with shapes (868,726,4) (868,726,3)猜測是因為RGBA是4維度的
#而畫輪廓用的卻是三維顏色
plt.imshow(wc)
plt.axis('off')
plt.show()
wc.to_file('Re0_black_shape.png')
|
4.給詞雲染上艾米莉亞的顏色
這還不夠,博主希望控制雲圖的文字安裝艾米莉亞的顏色來上色。也就是說根據原圖中艾米莉亞的顏色分佈控制雲圖文字顏色分佈。這裡我們可以借用WordCloud中的ImageColorGenerator函式得到原圖的顏色分佈,在利用wordcloud物件的recolor函式給雲圖重新上色。
# -*- coding: utf-8 -*-
from wordcloud import WordCloud, ImageColorGenerator
import cv2
import matplotlib.pyplot as plt
import jieba
txt = open('Re0.txt', encoding='ANSI').read()
txt = ' '.join(jieba.cut(txt))
stop_words = open('stopwords/baidu_stopwords.txt',
encoding='utf8').read().split()
mask = cv2.imread('aimi4.png', cv2.IMREAD_UNCHANGED)
#這裡假如後面的詞雲要採用RGBA模式的話,讀入png格式需要指定讀入格式為
#cv2.IMREAD_UNCHANGED,否則alpha元素資訊丟失,後面會報錯。
wc = WordCloud(mask=mask, font_path='Hiragino.ttf',
stopwords=stop_words,
contour_width=1,contour_color='black',
background_color='gray').generate(txt)
#這裡為了便於觀看將背景色設為灰色
color = cv2.imread('aimi3.png', cv2.IMREAD_UNCHANGED)
img_color = ImageColorGenerator(color)
#從圖片中獲得原圖的顏色分佈
wc.recolor(color_func=img_color)
#根據圖片顏色分佈給詞雲上色
plt.imshow(wc)
plt.axis('off')
plt.show()
wc.to_file('Re0_color_mask.png')
|
|
5.用雷姆藍給詞雲上色
但是博主作為一個博愛的人,對於雷姆也特別喜歡,所以我希望將詞雲染上雷姆色。並且希望將詞雲用雷姆色表示。(希望各位EMT黨放下你們手裡的刀)。這裡就要說到wordcloud物件的又一個引數了——color_func。它讀入一個返回顏色的函式名,形參為word, font_size, position, orientation, font_path, random_state。例如random_color(word, font_size, position, orientation, font_path, random_state)。這裡為了控制詞雲的顏色。根據官網的說法,可以這麼寫color_func=lambda *args, **kwargs: (255,0,0)便可以將字型顏色設定為紅色。
# -*- coding: utf-8 -*-
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import cv2
import jieba
# 開啟文字
text = open('Re0.txt', encoding='ANSI').read()
# 中文分詞
text = ' '.join(jieba.cut(text))
#print(text[:100])
# 生成物件
mask = cv2.imread('aimi4.png', cv2.IMREAD_UNCHANGED)
stop_words = open('stopwords/baidu_stopwords.txt',
encoding='utf8').read().split()
wc = WordCloud(color_func=lambda *args, **kwargs: (0,0,255),
mask=mask, font_path='Hiragino.ttf',stopwords=stop_words,
contour_width=1,contour_color='black',
background_color='white').generate(text)
#這裡設定詞雲的顏色為藍色
# 顯示詞雲
plt.imshow(wc, interpolation='bilinear')
plt.axis("off")
plt.show()
# 儲存到檔案
wc.to_file('RE0_color_blue.png')
|
6.用頻率說話
這裡詞雲可以通過wordcloud物件的generate(文字字串)生成,實際上,也可以用wordcloud物件的generate_from_frequencies(頻率字典)函式形成。也就是說,該函式可以讀入一個形如{詞:詞頻}的字典,然後輸出雲圖。我們看看利用這個函式會不會有什麼區別。
# -*- coding: utf-8 -*-
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import cv2
import jieba.analyse
# In[1]:
# 開啟文字
text = open('Re0.txt', encoding='ANSI').read()
# 提取關鍵詞和權重
#freq = jieba.analyse.extract_tags(text, topK=200,
# withWeight=True, allowPOS=('ns','n'))
#這裡allowPos是指允許提取的詞性,這裡選取的是ns--地名,n--名詞,
#但是耗時長達2min,並且人名無法分析出來,很奇怪,於是果斷放棄
freq = jieba.analyse.extract_tags(text, topK=200, withWeight=True)
print(freq[:20])
#這裡由於jieba分析後得到的結果返回的是二元組構成的列表,
#因此需要將其修改為字典
freq = {i[0]: i[1] for i in freq}
mask = cv2.imread('aimi4.png')
stop_words = open('stopwords/baidu_stopwords.txt',
encoding='utf8').read().split()
wc = WordCloud(color_func=lambda *args, **kwargs: (0,0,255),
mask=mask, font_path='Hiragino.ttf', stopwords=stop_words,
contour_width=1,contour_color='black',
background_color='white').generate_from_frequencies(freq)
# 顯示詞雲
plt.imshow(wc, interpolation='bilinear')
plt.axis("off")
plt.show()
wc.to_file('RE0_Freq.png')
|
|
我們可以看到還是有些區別的,艾米莉亞被分成了兩個詞艾米和莉亞。羅茲瓦爾也是類似。而且還有不少的停頓詞如‘只是’,‘只有’,‘什麼’等等。看樣子還是老老實實用generate吧。
圖片均來自於百度,如若侵權請通知博主刪除。剛剛入門wordcloud。如果有錯誤希望各位大佬不吝指教。
參考資料:
相關文章
- 讓我來告訴你為什麼做女程式媛很好
- 程式猿,讓我來告訴你怎麼追女生!!!
- NLP(十五)讓模型來告訴你文字中的時間模型
- 誰告訴你 Flutter 會幹掉原生開發?Flutter
- 面試完總是讓你回去等通知?不,告訴你怎麼搶救下!面試
- A的女兒是B的女兒的媽媽,A是B的誰?
- NuoDB:告訴你未來的資料庫是什麼樣VU資料庫
- 過來人告訴你,去工作前最好還是學學GitGit
- 為什麼需要銀行卡文字識別API?讓我來告訴你!API
- 龍象之爭:資料告訴你真實的差距
- 告訴你什麼是Pixelmator Pro for Mac!Mac
- 什麼是雲資料庫?這篇文章詳細告訴你!資料庫
- 什麼是「小島秀夫遊戲」?讓監督親自告訴你遊戲
- 洩露!Apple Intelligence提示詞原來是這樣,還告訴大模型:別幻覺APPIntel大模型
- 讓機器學習告訴你,你的siri在想什麼!機器學習
- 遊戲是如何告訴"你快要死了”?遊戲
- 一篇告訴你什麼是SpringSpring
- 一張圖告訴你什麼是GraphQL?
- 【轉】kafka-告訴你什麼是kafkaKafka
- 告訴你 Redis 是一個牛逼貨Redis
- java面試官:程式設計師,請你告訴我是誰把公司面試題洩露給你的?Java程式設計師面試題
- 讓 APISpace 告訴你什麼場景使用什麼APIAPI
- 讓 CPU 告訴你硬碟和網路到底有多慢硬碟
- 【揭祕】紅樓夢後四十回到底是誰寫的?機器學習告訴你機器學習
- 用大白話告訴你什麼是Event LoopOOP
- 告訴你什麼是TestOps測試運維運維
- 一座島告訴你,什麼是智慧!
- 盜版雲遊戲,誰來為你買單?遊戲
- 2021年國慶你的朋友去哪浪了?讓Python告訴你!Python
- 雲圖說|一圖告訴你主機安全的運維效率如何提升超出預期運維
- 萬兆網路卡該如何選擇?我來告訴你!
- 告訴你MySQL主鍵查詢為什麼這麼快MySql
- Java,你告訴我 fail-fast 是什麼鬼?JavaAIAST
- MQTT 協議是個啥?這篇文章告訴你!MQQT協議
- 用大白話告訴你,Java到底是什麼Java
- 一張圖告訴你學JAVA還是學Python!JavaPython
- 以極致實力扛起手遊電競大旗:紅魔3告訴你什麼是真電競
- python和Java學哪個?過來人告訴你答案!PythonJava