python【包含數據預處理】基于詞頻生成詞雲圖

互聯架構唠唠嗑 2024-06-20 07:53:59
背景目的

有一篇中文文章,或者一本小說。想要根據詞頻來生成詞雲圖。

爲什麽中文需要分詞

中文分詞是理解和處理中文文本的關鍵步驟,它直接影響到後續的文本分析和信息提取的准確性和有效性。

無明顯單詞分隔:中文文本不像英文那樣使用空格來分隔單詞,中文字符通常連續書寫,沒有明顯的單詞邊界。語言單位:中文的基本語言單位是字,但單獨的字往往不能表達完整的意思。中文的表達往往需要由多個字組成的詞語來實現。語境依賴性:中文詞語的意義很大程度上依賴于語境,相同的字在不同的詞語中可能有不同的意義。詞義豐富性:中文中的詞語往往比單個的字具有更豐富的語義信息,分詞有助于更准確地理解文本內容。語法複雜性:中文的語法結構相對複雜,詞語的順序、搭配和使用習慣對句子意義的影響很大。自然語言處理:在自然語言處理領域,分詞是中文文本分析的基礎步驟,無論是進行詞性標注、命名實體識別還是句法分析,都需要先進行分詞。信息檢索和文本挖掘:分詞可以提高中文信息檢索和文本挖掘的准確性,有助于提取關鍵詞和短語,從而更好地理解文本內容。文本預處理

最終目的是,生成句子數組。

在進行中文文本分析前,必須執行數據預處理步驟,以提升後續處理的准確性和效率。這包括:

移除文本中的特殊符號,因爲它們通常不攜帶有用信息,且可能幹擾分詞算法。統一替換空格、換行符、制表符等空白字符爲中文逗號,以保持句子的連貫性。刪除無意義的英文字母,因爲它們對于中文文本分析不是必要的。清除文本中的網址、圖片鏈接、日期等信息,這些通常與文本的主題無關,可能會影響分析結果。

數據處理函數

處理文本,過濾不需要無意義的字符。

 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文件生成句子數組

 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

輸出結果

分詞和詞頻統計

jieba分詞

Jieba分詞是一個流行的中文分詞Python庫,它的主要特點和作用可以簡單概括爲:

什麽是Jieba分詞:一個用于中文文本分詞的庫。做了什麽:識別中文文本中的單詞邊界,將連續的文本切分成單獨的詞語。得到什麽:提供分詞後的結果,即文本中各個詞語的列表。

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)

輸出結果

由詞頻生成詞雲

完整代碼

 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()

詞雲結果

作者:Wusp1994鏈接:https://juejin.cn/post/7381423581018243112

0 阅读:1

互聯架構唠唠嗑

簡介:感謝大家的關注