Python詞頻分析
在亳州等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場(chǎng)前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作 網(wǎng)站設(shè)計(jì)制作按需設(shè)計(jì)網(wǎng)站,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),全網(wǎng)營(yíng)銷推廣,外貿(mào)網(wǎng)站制作,亳州網(wǎng)站建設(shè)費(fèi)用合理。
在日常工作或者生活中,有時(shí)候會(huì)遇到詞頻分析的場(chǎng)景。如果是要進(jìn)行詞頻分析,那么首先需要對(duì)句子進(jìn)行分詞,將句子中的單詞進(jìn)行切割并按照詞性進(jìn)行歸類。
在Python中有個(gè)第三方庫叫jieba(結(jié)巴),可以對(duì)文章或者語句進(jìn)行分詞。不得不佩服這個(gè)庫的作者,真是個(gè)取名鬼才:)
jieba庫github地址
jieba庫官方給出了3中安裝庫的方式,分別如下:
全自動(dòng)安裝:
easy_install jieba 或者 pip install jieba / pip3 install jieba
半自動(dòng)安裝:
先下載 http://pypi.python.org/pypi/jieba/ ,解壓后運(yùn)行 python setup.py install
手動(dòng)安裝:
將 jieba 目錄放置于當(dāng)前目錄或者 site-packages 目錄
方法接受四個(gè)輸入?yún)?shù):
1、需要分詞的字符串;
2、cut_all 參數(shù)用來控制是否采用全模式;
3、HMM 參數(shù)用來控制是否使用 HMM 模型;
4、use_paddle 參數(shù)用來控制是否使用paddle模式下的分詞模式,paddle模式采用延遲加載方式,通過enable_paddle接口安裝paddlepaddle-tiny,并且import相關(guān)代碼;
注意:
1、實(shí)測(cè)paddle模式無法開啟(jieba.enable_paddle()),會(huì)報(bào)錯(cuò)。
2、該方法返回的是generator,如果需要返回list,則可以通過list轉(zhuǎn)換結(jié)果或者使用jieba.lcut方法
3、待分詞的字符串可以是 unicode 或 UTF-8 字符串、GBK 字符串。不建議直接輸入 GBK 字符串,可能無法預(yù)料地錯(cuò)誤解碼成 UTF-8。
方法接受兩個(gè)參數(shù):
1、需要分詞的字符串;
2、是否使用 HMM 模型。
注意:
1、該方法適合用于搜索引擎構(gòu)建倒排索引的分詞,粒度比較細(xì)。
2、該方法返回的是generator,如果需要返回list,則可以通過list轉(zhuǎn)換結(jié)果或者使用jieba.lcut_for_search方法。
該方法用于新建自定義分詞器,可用于同時(shí)使用不同詞典。jieba.dt 為默認(rèn)分詞器,所有全局分詞相關(guān)函數(shù)都是該分詞器的映射。
# encoding=utf-8
import jieba
strs = ["我來到北京清華大學(xué)", "乒乓球拍賣完了", "中國(guó)科學(xué)技術(shù)大學(xué)"]
for s in strs:
seg_list = jieba.cut(s, use_paddle=False) # 使用paddle模式
print("Paddle Mode: " + '/'.join(list(seg_list)))
seg_list = jieba.cut("我來到北京清華大學(xué)", cut_all=True)
print("Full Mode: " + "/ ".join(seg_list)) # 全模式
seg_list = jieba.cut("我來到北京清華大學(xué)", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list)) # 精確模式
seg_list = jieba.cut("他來到了網(wǎng)易杭研大廈") # 默認(rèn)是精確模式
print(", ".join(seg_list))
seg_list = jieba.cut_for_search("小明碩士畢業(yè)于中國(guó)科學(xué)院計(jì)算所,后在日本京都大學(xué)深造") # 搜索引擎模式
print(", ".join(seg_list))
運(yùn)行結(jié)果:
Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\FURONG~1\AppData\Local\Temp\jieba.cache
Loading model cost 0.705 seconds.
Prefix dict has been built successfully.
Paddle Mode: 我/來到/北京/清華大學(xué)
Paddle Mode: 乒乓球/拍賣/完/了
Paddle Mode: 中國(guó)/科學(xué)技術(shù)/大學(xué)
Full Mode: 我/ 來到/ 北京/ 清華/ 清華大學(xué)/ 華大/ 大學(xué)
Default Mode: 我/ 來到/ 北京/ 清華大學(xué)
他, 來到, 了, 網(wǎng)易, 杭研, 大廈
小明, 碩士, 畢業(yè), 于, 中國(guó), 科學(xué), 學(xué)院, 科學(xué)院, 中國(guó)科學(xué)院, 計(jì)算, 計(jì)算所, ,, 后, 在, 日本, 京都, 大學(xué), 日本京都大學(xué), 深造
開發(fā)者可以指定自己自定義的詞典,以便包含 jieba 詞庫里沒有的詞。雖然 jieba 有新詞識(shí)別能力,但是自行添加新詞可以保證更高的正確率。
用法:jieba.load_userdict(file_name) # file_name 為文件類對(duì)象或自定義詞典的路徑。
詞典格式和 dict.txt 一樣(dict.txt為安裝jieba庫時(shí)自帶的詞典,路徑為:Python安裝路徑\Lib\site-packages\jieba\dict.txt),一個(gè)詞占一行;每一行分三部分:
創(chuàng)新辦 3 i
云計(jì)算 5
凱特琳 nz
臺(tái)中
更改分詞器(默認(rèn)為 jieba.dt)的 tmp_dir 和 cache_file 屬性,可分別指定緩存文件所在的文件夾及其文件名,用于受限的文件系統(tǒng)。
范例:
自定義詞典:https://github.com/fxsjy/jieba/blob/master/test/userdict.txt
用法示例:https://github.com/fxsjy/jieba/blob/master/test/test_userdict.py
加載自定義詞庫前: 李小福 / 是 / 創(chuàng)新 / 辦 / 主任 / 也 / 是 / 云 / 計(jì)算 / 方面 / 的 / 專家 /
加載自定義詞庫后: 李小福 / 是 / 創(chuàng)新辦 / 主任 / 也 / 是 / 云計(jì)算 / 方面 / 的 / 專家 /
調(diào)整詞典
使用 add_word(word, freq=None, tag=None) 和 del_word(word) 可在程序中動(dòng)態(tài)修改詞典。
使用 suggest_freq(segment, tune=True) 可調(diào)節(jié)單個(gè)詞語的詞頻,使其能(或不能)被分出來。
注意:自動(dòng)計(jì)算的詞頻在使用 HMM 新詞發(fā)現(xiàn)功能時(shí)可能無效。
print('/'.join(jieba.cut('如果放到post中將出錯(cuò)。', HMM=False)))
如果/放到/post/中將/出錯(cuò)/。
jieba.suggest_freq(('中', '將'), True)
494
print('/'.join(jieba.cut('如果放到post中將出錯(cuò)。', HMM=False)))
如果/放到/post/中/將/出錯(cuò)/。
print('/'.join(jieba.cut('「臺(tái)中」正確應(yīng)該不會(huì)被切開', HMM=False)))
「/臺(tái)/中/」/正確/應(yīng)該/不會(huì)/被/切開
jieba.suggest_freq('臺(tái)中', True)
69
print('/'.join(jieba.cut('「臺(tái)中」正確應(yīng)該不會(huì)被切開', HMM=False)))
「/臺(tái)中/」/正確/應(yīng)該/不會(huì)/被/切開
jieba.posseg.POSTokenizer(tokenizer=None) 新建自定義分詞器,tokenizer 參數(shù)可指定內(nèi)部使用的 jieba.Tokenizer 分詞器。jieba.posseg.dt 為默認(rèn)詞性標(biāo)注分詞器。
標(biāo)注句子分詞后每個(gè)詞的詞性,采用和 ictclas 兼容的標(biāo)記法。
import jieba.posseg as pseg
words = pseg.cut("我愛北京天安門")
for word, flag in words:
print('%s %s' % (word, flag))
我 r
愛 v
北京 ns
天安門 ns
詞性和專名類別標(biāo)簽集合如下表,其中詞性標(biāo)簽 24 個(gè)(小寫字母),專名類別標(biāo)簽 4 個(gè)(大寫字母):
這里就拿筆者最近看的一本小說判官.txt來進(jìn)行實(shí)例詞頻分析吧。目的是想要分析這本小說的人物、名詞、地名,從而對(duì)這本小說有個(gè)大概的認(rèn)識(shí)。
分詞代碼如下:
def m_get_content(self):
"""
獲取給定txt或str中的內(nèi)容
@return: {str:獲取到的內(nèi)容}
"""
if self.f_input.endswith('.txt'):
with open(self.f_input, 'r', encoding='utf-8') as f:
content = f.read()
else:
content = self.f_input
return content
def m_get_target_words_from_content(self, p_content):
"""
從目標(biāo)內(nèi)容中獲取到指定詞性的詞語
@param p_content: 需要分詞的內(nèi)容
@return: {list:分詞后的詞語}
"""
return [
_.word
for _ in psg.cut(p_content)
if len(_.word) > 1 and _.flag in self.f_wordclass
]
def words_frequency(p_list, p_reverse=True):
"""
返回給定的list中的所有元素按照頻率和指定的順序組成的list
@param p_list: 給定的list
@param p_reverse: 指定的排序順序(倒序?yàn)門rue,正序?yàn)镕alse)
@return: {list[tuple]:經(jīng)過排序后的內(nèi)容}
"""
result = {}
for word in p_list:
result.setdefault(word, 0)
result[word] += 1
return sorted(result.items(), key=lambda x: x[1], reverse=p_reverse)
def m_words_sort(self, p_words: list):
"""
對(duì)獲取到的分詞的內(nèi)容進(jìn)行按照頻率排序
@param p_words: 需要進(jìn)行按頻率排序的內(nèi)容
@return: {list[tuple]:經(jīng)過排序后的內(nèi)容}
"""
return words_frequency(p_list=p_words, p_reverse=self.f_reverse)
def m_show_words_frequency(self, p_words_sort: list):
"""
將p_words_sort中的內(nèi)容提取前p_ranknum項(xiàng)使用"-"符號(hào)展示柱圖。
@param p_words_sort: 要用來展示柱圖的dict內(nèi)容
@return: {str:柱圖}
"""
max_frequency = max(p_words_sort[0][1], p_words_sort[-1][1])
ratio = max_frequency / self.f_shownum
print('%-5s\t%-5s\t%-5s\t%-15s' % ('序號(hào)', '詞性', '詞頻', '柱圖'))
for i in range(self.f_ranknum):
print(f'{i + 1:<5}\t{p_words_sort[i][0]:<5}\t{p_words_sort[i][1]:<5}\t{"-" * int(p_words_sort[i][1] / ratio):<15}')
用Python制作詞云圖需要安裝wordcloud第三方庫。參照如下:
python詞云制作(最全最詳細(xì)的教程)
from wordcloud import WordCloud
words_cloud = ' '.join([_[0] for _ in words_sort[:10]])
wordcloud = WordCloud(font_path="msyh.ttc").generate(words_cloud)
wordcloud.to_file(self.f_wordcloud_fn)
人名部分
序號(hào) 詞性 詞頻 柱圖
1 聞時(shí) 1405 ------------------------------
2 謝問 1092 -----------------------
3 周煦 762 ----------------
4 卜寧 513 ----------
5 張嵐 466 ---------
6 張雅臨 332 -------
7 張碧靈 219 ----
8 沈曼怡 216 ----
9 張正初 185 ---
10 李先生 164 ---
名詞部分
序號(hào) 詞性 詞頻 柱圖
1 時(shí)候 777 ------------------------------
2 有點(diǎn) 449 -----------------
3 傀線 376 --------------
4 手指 345 -------------
5 聲音 324 ------------
6 地方 316 ------------
7 感覺 293 -----------
8 眼睛 255 ---------
9 老毛 209 --------
10 對(duì)方 208 --------
地名部分
序號(hào) 詞性 詞頻 柱圖
1 夏樵 803 ------------------------------
2 東西 550 --------------------
3 大東 231 --------
4 沈家 184 ------
5 云山 140 -----
6 沈橋 80 --
7 寧州 51 -
8 下山 45 -
9 天津 35 -
10 西屏園 32 -
import jieba.posseg as psg
def words_frequency(p_list, p_reverse=True):
"""
返回給定的list中的所有元素按照頻率和指定的順序組成的list
@param p_list: 給定的list
@param p_reverse: 指定的排序順序(倒序?yàn)門rue,正序?yàn)镕alse)
@return: {list[tuple]:經(jīng)過排序后的內(nèi)容}
"""
result = {}
for word in p_list:
result.setdefault(word, 0)
result[word] += 1
return sorted(result.items(), key=lambda x: x[1], reverse=p_reverse)
class WordsFrequency:
def __init__(self, p_input: str, p_wordclass: list[str], p_ranknum=10, p_reverse=True, p_shownum=30, p_wordcloud_fn='人名.jpg'):
"""
@param p_input: 要分析的文件名或字符串,文件必須為txt格式,編碼為utf-8.
@param p_wordclass: 要獲取的詞性。常見的類型有:普通名詞n、人名nr、地名ns
@param p_ranknum: 要獲取前多少個(gè)目標(biāo)詞性的詞語。
@param p_reverse: 目標(biāo)詞語通過頻率指定的排序方向。(倒序?yàn)門rue,正序?yàn)镕alse)
@param p_shownum: 頻率最多的元素使用的柱圖標(biāo)識(shí)"-"的個(gè)數(shù)。
@param p_wordcloud_fn: 生成詞云圖的圖片文件名
"""
self.f_input = p_input
self.f_wordclass = p_wordclass
self.f_ranknum = p_ranknum
self.f_reverse = p_reverse
self.f_shownum = p_shownum
self.f_wordcloud_fn = p_wordcloud_fn
def m_get_content(self):
"""
獲取給定txt或str中的內(nèi)容
@return: {str:獲取到的內(nèi)容}
"""
if self.f_input.endswith('.txt'):
with open(self.f_input, 'r', encoding='utf-8') as f:
content = f.read()
else:
content = self.f_input
return content
def m_get_target_words_from_content(self, p_content):
"""
從目標(biāo)內(nèi)容中獲取到指定詞性的詞語
@param p_content: 需要分詞的內(nèi)容
@return: {list:分詞后的詞語}
"""
return [
_.word
for _ in psg.cut(p_content)
if len(_.word) > 1 and _.flag in self.f_wordclass
]
def m_words_sort(self, p_words: list):
"""
對(duì)獲取到的分詞的內(nèi)容進(jìn)行按照頻率排序
@param p_words: 需要進(jìn)行按頻率排序的內(nèi)容
@return: {list[tuple]:經(jīng)過排序后的內(nèi)容}
"""
return words_frequency(p_list=p_words, p_reverse=self.f_reverse)
def m_show_words_frequency(self, p_words_sort: list):
"""
將p_words_sort中的內(nèi)容提取前p_ranknum項(xiàng)使用"-"符號(hào)展示柱圖。
@param p_words_sort: 要用來展示柱圖的dict內(nèi)容
@return: {str:柱圖}
"""
max_frequency = max(p_words_sort[0][1], p_words_sort[-1][1])
ratio = max_frequency / self.f_shownum
print('%-5s\t%-5s\t%-5s\t%-15s' % ('序號(hào)', '詞性', '詞頻', '柱圖'))
for i in range(self.f_ranknum):
print(f'{i + 1:<5}\t{p_words_sort[i][0]:<5}\t{p_words_sort[i][1]:<5}\t{"-" * int(p_words_sort[i][1] / ratio):<15}')
def main(self):
content = self.m_get_content()
words = self.m_get_target_words_from_content(content)
words_sort = self.m_words_sort(words)
# 柱圖部分
self.m_show_words_frequency(words_sort)
# 生成詞云圖
from wordcloud import WordCloud
words_cloud = ' '.join([_[0] for _ in words_sort[:10]])
wordcloud = WordCloud(font_path="msyh.ttc").generate(words_cloud)
wordcloud.to_file(self.f_wordcloud_fn)
if __name__ == '__main__':
wf = WordsFrequency(p_input='判官.txt', p_wordclass=['ns'], p_wordcloud_fn='地名.jpg')
wf.main()