有一篇中文文章,或者一本小說。想要根據詞頻來生成詞雲圖。
![](http://image.uc.cn/s/wemedia/s/upload/2024/ea5ea79fc13f3eca5add2fcaa39470e4.jpg)
中文分詞是理解和處理中文文本的關鍵步驟,它直接影響到後續的文本分析和信息提取的准確性和有效性。
無明顯單詞分隔:中文文本不像英文那樣使用空格來分隔單詞,中文字符通常連續書寫,沒有明顯的單詞邊界。語言單位:中文的基本語言單位是字,但單獨的字往往不能表達完整的意思。中文的表達往往需要由多個字組成的詞語來實現。語境依賴性:中文詞語的意義很大程度上依賴于語境,相同的字在不同的詞語中可能有不同的意義。詞義豐富性:中文中的詞語往往比單個的字具有更豐富的語義信息,分詞有助于更准確地理解文本內容。語法複雜性:中文的語法結構相對複雜,詞語的順序、搭配和使用習慣對句子意義的影響很大。自然語言處理:在自然語言處理領域,分詞是中文文本分析的基礎步驟,無論是進行詞性標注、命名實體識別還是句法分析,都需要先進行分詞。信息檢索和文本挖掘:分詞可以提高中文信息檢索和文本挖掘的准確性,有助于提取關鍵詞和短語,從而更好地理解文本內容。文本預處理最終目的是,生成句子數組。
在進行中文文本分析前,必須執行數據預處理步驟,以提升後續處理的准確性和效率。這包括:
移除文本中的特殊符號,因爲它們通常不攜帶有用信息,且可能幹擾分詞算法。統一替換空格、換行符、制表符等空白字符爲中文逗號,以保持句子的連貫性。刪除無意義的英文字母,因爲它們對于中文文本分析不是必要的。清除文本中的網址、圖片鏈接、日期等信息,這些通常與文本的主題無關,可能會影響分析結果。數據處理函數
處理文本,過濾不需要無意義的字符。
import re def data_process(str_data): # 定義正則表達式模式 # 去除換行、空格 str_data = re.sub(r'[\n\s]+', '', str_data) # 匹配網址 url_pattern = r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+' # 匹配日期格式如 YYYY/MM/DD, YYYY-MM-DD, YYYY年MM月DD日 date_pattern = r'\d{4}[/\-]?\d{1,2}[/\-]?\d{1,2}' # 匹配郵箱地址 email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Z|a-z]{2,}\b' # 匹配數字 number_pattern = r'\d+' # 匹配英文字母 english_letter_pattern = r'[a-zA-Z]' # 替換空白字符爲空格 str_data = re.sub(r'\s', ',', str_data) # 刪除特殊符號、網址、日期、郵箱、數字和英文字母 str_data = re.sub(url_pattern, '', str_data) str_data = re.sub(date_pattern, '', str_data) str_data = re.sub(email_pattern, '', str_data) str_data = re.sub(number_pattern, '', str_data) str_data = re.sub(english_letter_pattern, '', str_data) # 刪除標點符號 punctuation = r""""!!??#$%&'()()*+-/:;▪³/<=>@[\]^_`●{|}~⦅⦆「」、、〃》「」『』【】[]〔〕〖〗〘〙{}〚〛*°▽〜〝〞〟〰〾〿–—‘'‛“”„‟…‧﹏""" str_data = re.sub(f"[{re.escape(punctuation)}]+", '', str_data) return str_data.strip() sample_text = "這是一個例子。\n包含網址 http://example.com,參考文獻[1]{,日期2024-06-18。" processed_text = data_process(sample_text) print(processed_text)句子數組函數封裝
讀取txt文件生成句子數組
![](http://image.uc.cn/s/wemedia/s/upload/2024/b8f4d35ea8db13f4e03dc1146549a2b0.jpg)
輸出結果
![](http://image.uc.cn/s/wemedia/s/upload/2024/573b002577ab483d6ff8a8c078083240.jpg)
jieba分詞
Jieba分詞是一個流行的中文分詞Python庫,它的主要特點和作用可以簡單概括爲:
什麽是Jieba分詞:一個用于中文文本分詞的庫。做了什麽:識別中文文本中的單詞邊界,將連續的文本切分成單獨的詞語。得到什麽:提供分詞後的結果,即文本中各個詞語的列表。![](http://image.uc.cn/s/wemedia/s/upload/2024/65f625d376e0a3749c5ff6a4fb669250.jpg)
Jieba 分詞器屬于概率語言模型分詞,基于前綴詞典實現高效的詞圖掃描,生成句子中漢字所有可能成詞情況構建成有向無環圖,然後采用動態規劃尋找最大概率路徑,找出基于詞頻的最大切分組合。對于不存在與前綴詞典中的詞,采用了漢字成詞能力的 HMM 模型,使用了 Viterbi 算法。Jieba 的切分模式有全模式、精確模式、搜索引擎模式,更多詳細信息可以查看 github 倉庫。
以下是 Jieba 分詞器中一些常用函數的:
函數名
描述
jieba.cut
對輸入文本進行分詞,返回一個可叠代的分詞結果
jieba.cut_for_search
在搜索引擎模式下對輸入文本進行分詞,返回一個可叠代的分詞結果
jieba.lcut
對輸入文本進行分詞,返回一個列表形式的分詞結果
jieba.lcut_for_search
在搜索引擎模式下對輸入文本進行分詞,返回一個列表形式的分詞結果
jieba.add_word
向分詞詞典中添加新詞
jieba.del_word
從分詞詞典中刪除指定詞
jieba.load_userdict
加載用戶自定義詞典
jieba.analyse.extract_tags
提取文本中的關鍵詞,返回一個列表形式的關鍵詞結果
詞頻函數封裝
統計句子列表中名詞('n', 'nr', 'nz')的詞頻, 返回一個字典
import jieba.posseg as psg def getWordFrequency(sentences): """ 統計句子列表中名詞('n', 'nr', 'nz')的詞頻 :param sentences: 包含多個句子的列表 :return: 包含名詞詞頻的字典 """ words_dict = {} # 用于存儲詞頻的字典 for text in sentences: # 去掉標點符號 text = re.sub("[\s+.!/_,$%^*(+"']+|[+——!,。?、~@#¥%……&*()]+", "", text) # 使用結巴分詞進行詞性標注 wordGen = psg.cut(text) # 遍曆分詞結果,統計名詞詞頻 for word, attr in wordGen: if attr in ['n', 'nr', 'nz']: # 判斷詞性是否爲名詞 if word in words_dict.keys(): words_dict[word] += 1 else: words_dict[word] = 1 return words_dict if __name__ == "__main__": sentences = getText("../百度百科-黃河.txt") # pprint(sentences) words_dict = getWordFrequency(sentences) pprint(words_dict)輸出結果
![](http://image.uc.cn/s/wemedia/s/upload/2024/becf3a84b980882d7fc6920f87df572e.jpg)
完整代碼
import re from pprint import pprint import jieba.posseg as psg from wordcloud import WordCloud import matplotlib.pyplot as plt def data_process(str_data): # 定義正則表達式模式 # 去除換行、空格 str_data = re.sub(r'[\n\s]+', '', str_data) # 匹配網址 url_pattern = r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+' # 匹配日期格式如 YYYY/MM/DD, YYYY-MM-DD, YYYY年MM月DD日 date_pattern = r'\d{4}[/\-]?\d{1,2}[/\-]?\d{1,2}' # 匹配郵箱地址 email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Z|a-z]{2,}\b' # 匹配數字 number_pattern = r'\d+' # 匹配英文字母 english_letter_pattern = r'[a-zA-Z]' # 替換空白字符爲空格 str_data = re.sub(r'\s', ',', str_data) # 刪除特殊符號、網址、日期、郵箱、數字和英文字母 str_data = re.sub(url_pattern, '', str_data) str_data = re.sub(date_pattern, '', str_data) str_data = re.sub(email_pattern, '', str_data) str_data = re.sub(number_pattern, '', str_data) str_data = re.sub(english_letter_pattern, '', str_data) # 刪除標點符號 punctuation = r""""!!??#$%&'()()*+-/:;▪³/<=>@[\]^_`●{|}~⦅⦆「」、、〃》「」『』【】[]〔〕〖〗〘〙{}〚〛*°▽〜〝〞〟〰〾〿–—‘'‛“”„‟…‧﹏""" str_data = re.sub(f"[{re.escape(punctuation)}]+", '', str_data) return str_data.strip() def getText(filename): sentences = [] with open(filename, 'r', encoding='utf-8') as fp: for line in fp: processed_line = data_process(line) if processed_line: # 檢查處理後的句子是否爲空或只包含空白字符 sentences.extend(re.split(r'[。!?]', processed_line)) # 使用更複雜的句子劃分規則 # 去除列表中的空字符串 sentences = [sentence for sentence in sentences if sentence.strip()] return sentences def getWordFrequency(sentences): """ 統計句子列表中名詞('n', 'nr', 'nz')的詞頻 :param sentences: 包含多個句子的列表 :return: 包含名詞詞頻的字典 """ words_dict = {} # 用于存儲詞頻的字典 for text in sentences: # 去掉標點符號 text = re.sub("[\s+.!/_,$%^*(+"']+|[+——!,。?、~@#¥%……&*()]+", "", text) # 使用結巴分詞進行詞性標注 wordGen = psg.cut(text) # 遍曆分詞結果,統計名詞詞頻 for word, attr in wordGen: if attr in ['n', 'nr', 'nz']: # 判斷詞性是否爲名詞 if word in words_dict.keys(): words_dict[word] += 1 else: words_dict[word] = 1 return words_dict if __name__ == "__main__": sentences = getText("../百度百科-黃河.txt") # pprint(sentences) words_dict = getWordFrequency(sentences) # 創建 wordcloud 對象,背景圖片爲 graph,背景色爲白色 wc = WordCloud(font_path='../Hiragino.ttf', width=800, height=600, mode='RGBA', background_color=None) # 生成詞雲 wc.generate_from_frequencies(words_dict) # 顯示詞雲 plt.imshow(wc, interpolation='bilinear') plt.axis('off') plt.show()詞雲結果
![](http://image.uc.cn/s/wemedia/s/upload/2024/cabdfc4d47341167c329e0ef23611701.jpg)
作者:Wusp1994鏈接:https://juejin.cn/post/7381423581018243112