自然語言處理:詞頻-逆文檔頻率

介紹

大家好,博主又來給大家分享知識了。本來博主計劃完成稠密向量表示的內容分享后,就開啟自然語言處理中文本表示的講解。可在整理分享資料的時候,博主發現還有個知識點,必須得單獨拎出來好好說道說道。

這就是TF-IDF,也就是詞頻-逆文檔頻率。它在自然語言處理里堪稱“幕后功臣”,在文本表示、文本分類、信息檢索等諸多關鍵任務中,發揮著超乎想象的作用。那么,我們直接進入正題。

TF-IDF

自然語言處理(NLP)領域,理解文本數據的含義并從中提取有價值的信息是核心任務。TF-IDF(Term Frequency-Inverse Document Frequency)作為一種重要的統計方法,在文本表示、文本分類、信息檢索、關鍵詞提取等眾多任務中發揮著關鍵作用。

基礎概念

詞頻

Term Frequency, TF。詞頻衡量的是一個詞在一篇文檔中出現的頻率。直觀地說,一個詞在文檔中出現的次數越多,它對該文檔的重要性可能越高。例如,在文檔“我喜歡蘋果,蘋果很美味”中,“蘋果”這個詞出現了兩次,相對其他詞出現的頻率較高,可能在該文檔中具有一定重要性。

其計算公式為:TF_{t,d} = \frac{n_{t,d}}{\sum_{k} n_{k,d}}

其中,TF_{t,d}表示詞t在文檔d中的詞頻,n_{t,d}是詞t在文檔d中出現的次數,\sum_{k} n_{k,d}是文檔d中所有詞的出現次數總和。

逆文檔頻率

Inverse Document Frequency, IDF。逆文檔頻率反映了一個詞在整個文檔集合中的普遍重要性。如果一個詞在大量文檔中都出現,那么它對于區分不同文檔的作用就較小。相反,一個只在少數文檔中出現的詞,對于識別這些特定文檔更為關鍵。

例如,“的”,“是”等常用詞在幾乎所有文檔中都會頻繁出現,它們的區分能力較弱。而專業術語如“量子糾纏”,只在特定領域的文檔中出現,其區分能力較強。

其計算公式為:IDF_{t} = \log \frac{N}{n_{t}}

其中,IDF_{t}表示詞t的逆文檔頻率,N是文檔集合中的文檔總數,n_{t}是包含詞t的文檔數量。

TF-IDF加權

TF-IDF加權綜合了詞頻和逆文檔頻率,通過將兩者相乘得到每個詞在文檔中的TF-IDF值。

公式為:TF-IDF_{t,d} = TF_{t,d} \times IDF_{t}

TF-IDF值越高,說明該詞對當前文檔越重要,同時在整個文檔集中相對不常見,具有較強的區分性。

代碼實現

計算詞頻(TF)

完整代碼
# 從collections模塊導入Counter類,用于統計元素出現的次數
from collections import Counter# 定義一個名為NLPTextRepresentation的類,用于處理文本表示相關任務
class NLPTextRepresentation:# 類的初始化方法,此處不做任何初始化操作def __init__(self):# pass 語句占位,不進行實際操作pass# 定義一個方法,用于計算文檔中每個單詞的詞頻(TF)def compute_tf(self, document):# 將輸入的文檔按空格分割成單詞列表words = document.split()# 使用Counter統計每個單詞在文檔中出現的次數word_count = Counter(words)# 計算文檔中單詞的總數total_words = len(words)# 初始化一個空字典,用于存儲每個單詞的詞頻tf_dict = {}# 遍歷統計結果中的每個單詞及其出現次數for word, count in word_count.items():# 計算該單詞的詞頻并存儲到字典中tf_dict[word] = count / total_words# 返回存儲詞頻的字典return tf_dict# 當腳本作為主程序運行時執行以下代碼
if __name__ == "__main__":# 創建NLPTextRepresentation類的一個實例nlp_text_representation = NLPTextRepresentation()# 定義一個示例文檔document = "我喜歡蘋果 蘋果很美味"# 調用compute_tf方法計算文檔中單詞的詞頻tf_result = nlp_text_representation.compute_tf(document)# 打印計算得到的詞頻結果print(tf_result)
運行結果
{'我喜歡蘋果': 0.5, '蘋果很美味': 0.5}進程已結束,退出代碼為 0

在這段代碼中,首先使用split()方法將輸入的文檔字符串分割成單詞列表。然后,利用Counter類統計每個單詞在文檔中出現的次數。

接著,計算文檔的總詞數,通過遍歷每個單詞及其出現次數,將每個單詞的出現次數除以總詞數,得到該單詞在文檔中的詞頻,并存儲在字典tf_dict中。

最后返回這個字典,其中鍵為單詞,值為對應的詞頻。

計算逆文檔頻率(IDF)

完整代碼
# 導入math模塊,用于使用數學函數,這里主要是為了計算對數
import math# 定義一個名為NLPTextRepresentation的類,用于處理自然語言處理中的文本表示相關任務
class NLPTextRepresentation:# 類的初始化方法,目前不做任何初始化操作def __init__(self):# 占位語句,不執行任何實際邏輯pass# 定義一個方法,用于計算語料庫中每個單詞的逆文檔頻率(IDF)def compute_idf(self, corpus):# 計算語料庫中文檔的總數total_docs = len(corpus)# 初始化一個空字典,用于存儲每個單詞在多少個文檔中出現過word_in_doc_count = {}# 遍歷語料庫中的每一個文檔for doc in corpus:# 將當前文檔按空格分割成單詞,并使用 set 去重words = set(doc.split())# 遍歷當前文檔中出現的每個唯一單詞for word in words:# 如果該單詞還未在word_in_doc_count字典中if word not in word_in_doc_count:# 則將該單詞添加到字典中,并將其出現文檔數初始化為 1word_in_doc_count[word] = 1else:# 否則,將該單詞出現的文檔數加 1word_in_doc_count[word] += 1# 初始化一個空字典,用于存儲每個單詞的逆文檔頻率idf_dict = {}# 遍歷word_in_doc_count字典中的每個單詞及其出現文檔數for word, count in word_in_doc_count.items():# 計算該單詞的逆文檔頻率(使用自然對數),并存儲到idf_dict中idf_dict[word] = math.log(total_docs / count)# 返回存儲逆文檔頻率的字典return idf_dict# 當腳本作為主程序運行時執行以下代碼
if __name__ == "__main__":# 創建NLPTextRepresentation類的一個實例nlp_text_representation = NLPTextRepresentation()# 定義一個語料庫,包含多個文檔corpus = ["我喜歡蘋果 蘋果很美味", "我喜歡香蕉 香蕉很甜", "蘋果和香蕉都是水果"]# 調用compute_idf方法計算語料庫中每個單詞的逆文檔頻率idf_result = nlp_text_representation.compute_idf(corpus)# 打印計算得到的逆文檔頻率結果print(idf_result)
運行結果
{'我喜歡蘋果': 1.0986122886681098, '蘋果很美味': 1.0986122886681098, '我喜歡香蕉': 1.0986122886681098, '香蕉很甜': 1.0986122886681098, '蘋果和香蕉都是水果': 1.0986122886681098}進程已結束,退出代碼為 0

在這段代碼中,首先計算語料庫中總的文檔數量。然后,遍歷語料庫中的每一篇文檔,將文檔中的單詞通過set()方法去重,以確保每個單詞只被統計一次。

對于每個單詞,如果它不在word_in_doc_count字典中,則將其初始值設為 1;如果已經存在,則將其對應的值加 1,這樣word_in_doc_count字典記錄了每個單詞在多少篇文檔中出現過。

接下來,通過遍歷word_in_doc_count字典,根據逆文檔頻率的計算公式,計算每個單詞的逆文檔頻率,并存儲在idf_dict字典中返回。

計算詞頻-逆文檔頻率(TF-IDF)

完整代碼
# 從collections模塊導入Counter類,用于統計元素出現的次數
from collections import Counter
# 導入math模塊,用于使用數學函數,這里主要是為了計算對數
import math# 定義一個名為NLPTextRepresentation的類,用于處理自然語言處理中的文本表示相關任務
class NLPTextRepresentation:# 類的初始化方法,目前不做任何初始化操作def __init__(self):# 占位語句,不執行任何實際邏輯pass# 定義一個方法,用于計算文檔中每個單詞的詞頻(TF)def compute_tf(self, document):# 將輸入的文檔按空格分割成單詞列表words = document.split()# 使用Counter統計每個單詞在文檔中出現的次數word_count = Counter(words)# 計算文檔中單詞的總數total_words = len(words)# 初始化一個空字典,用于存儲每個單詞的詞頻tf_dict = {}# 遍歷統計結果中的每個單詞及其出現次數for word, count in word_count.items():# 計算該單詞的詞頻并存儲到字典中tf_dict[word] = count / total_words# 返回存儲詞頻的字典return tf_dict# 定義一個方法,用于計算語料庫中每個單詞的逆文檔頻率(IDF)def compute_idf(self, corpus):# 計算語料庫中文檔的總數total_docs = len(corpus)# 初始化一個空字典,用于存儲每個單詞在多少個文檔中出現過word_in_doc_count = {}# 遍歷語料庫中的每一個文檔for doc in corpus:# 將當前文檔按空格分割成單詞,并使用set去重words = set(doc.split())# 遍歷當前文檔中出現的每個唯一單詞for word in words:# 如果該單詞還未在word_in_doc_count字典中if word not in word_in_doc_count:# 則將該單詞添加到字典中,并將其出現文檔數初始化為1word_in_doc_count[word] = 1else:# 否則,將該單詞出現的文檔數加1word_in_doc_count[word] += 1# 初始化一個空字典,用于存儲每個單詞的逆文檔頻率idf_dict = {}# 遍歷word_in_doc_count字典中的每個單詞及其出現文檔數for word, count in word_in_doc_count.items():# 計算該單詞的逆文檔頻率(使用自然對數),并存儲到idf_dict中idf_dict[word] = math.log(total_docs / count)# 返回存儲逆文檔頻率的字典return idf_dict# 定義一個方法,用于計算語料庫中每個文檔里單詞的TF-IDF值def compute_tfidf(self, corpus):# 初始化一個空列表,用于存儲每個文檔的TF-IDF結果tfidf_corpus = []# 調用compute_idf方法計算語料庫中所有單詞的逆文檔頻率idf = self.compute_idf(corpus)# 遍歷語料庫中的每一個文檔for doc in corpus:# 調用compute_tf方法計算當前文檔中每個單詞的詞頻tf = self.compute_tf(doc)# 初始化一個空字典,用于存儲當前文檔中每個單詞的TF-IDF值tfidf_doc = {}# 遍歷當前文檔詞頻字典中的每個單詞for word in tf:# 計算該單詞的TF-IDF值并存儲到字典中tfidf_doc[word] = tf[word] * idf[word]# 將當前文檔的TF-IDF結果添加到tfidf_corpus列表中tfidf_corpus.append(tfidf_doc)# 返回存儲所有文檔TF-IDF結果的列表return tfidf_corpus# 當腳本作為主程序運行時執行以下代碼
if __name__ == "__main__":# 創建NLPTextRepresentation類的一個實例nlp_text_representation = NLPTextRepresentation()# 定義一個包含多個文檔的語料庫corpus = ["我喜歡蘋果 蘋果很美味", "我喜歡香蕉 香蕉很甜", "蘋果和香蕉都是水果"]# 調用compute_tfidf方法計算語料庫中每個文檔里單詞的TF-IDF值tfidf_result = nlp_text_representation.compute_tfidf(corpus)# 遍歷計算得到的TF-IDF結果列表for i, doc in enumerate(tfidf_result):# 打印每個文檔的TF-IDF計算結果print(f"文檔{i + 1}的TF-IDF結果: {doc}")
運行結果
文檔1的TF-IDF結果: {'我喜歡蘋果': 0.5493061443340549, '蘋果很美味': 0.5493061443340549}
文檔2的TF-IDF結果: {'我喜歡香蕉': 0.5493061443340549, '香蕉很甜': 0.5493061443340549}
文檔3的TF-IDF結果: {'蘋果和香蕉都是水果': 1.0986122886681098}進程已結束,退出代碼為 0

這段代碼首先調用前面定義的compute_idf函數計算整個語料庫的逆文檔頻率。然后,遍歷語料庫中的每一篇文檔,對每篇文檔調用compute_tf函數計算詞頻。

接著,對于每個詞,將其在當前文檔中的詞頻乘以其在整個語料庫中的逆文檔頻率,得到該詞在當前文檔中的TF-IDF值,并存儲在tfidf_doc字典中。

最后,將每篇文檔的TF-IDF字典結果添加到tfidf_corpus列表中并返回。這段代碼的目的是將前面計算得到的詞頻和逆文檔頻率進行綜合計算,得到每篇文檔中每個詞的TF-IDF值,從而完成TF-IDF加權的計算過程。?

TF-IDF的優點

  • 簡單有效:TF-IDF的計算原理直觀易懂,實現相對簡單,不需要復雜的模型訓練過程,卻能在很多實際應用中取得較好的效果,如文本分類、信息檢索等。
  • 突出關鍵信息:通過加權計算,能夠突出那些在特定文檔中頻繁出現且在整個文檔集中相對不常見的詞,這些詞往往與文檔的主題緊密相關,有助于快速定位文檔的核心內容。
  • 可擴展性好:無論是小規模還是大規模的文檔集合,TF-IDF都能適用,并且計算資源消耗相對可控。在處理大規模文本數據時,可以通過分布式計算等方式進一步優化計算效率。

TF-IDF的缺點

  • 忽略語義信息:TF-IDF只考慮了詞的出現頻率和文檔分布,完全沒有涉及詞與詞之間的語義關系。例如,“汽車”“轎車”在語義上相近,但TF-IDF無法體現這種關系,可能會導致在一些需要語義理解的任務中效果不佳。
  • 依賴文檔集合:逆文檔頻率的計算依賴于整個文檔集合,當文檔集合發生變化時,需要重新計算IDF值,這在實時性要求較高的應用場景中可能會帶來不便。
  • 無法處理多義詞:對于具有多種含義的詞,TF-IDF不能區分其在不同上下文中的語義差異,會將其視為同一個詞進行計算,可能影響對文本的準確理解。

結論賦能

TF-IDF作為自然語言處理中的經典方法,在文本分析的眾多領域有著廣泛應用。通過對詞頻和逆文檔頻率的巧妙結合,能夠有效地提取文本中的關鍵信息,為后續的文本處理任務提供有力支持。

然而,其固有的局限性也為研究人員提供了改進和創新的方向。在實際應用中,需要根據具體任務的需求和數據特點,合理選擇是否使用TF-IDF,并結合其他技術(如詞向量模型等)來彌補其不足,以更好地實現自然語言處理的目標。

結束

好了,以上就是本次分享的全部內容了。不知道大家是否對TF-IDF有了更深入的理解,以及對其在實際應用中的潛力有了新的認識呢?希望本次分享能為大家在自然語言處理的學習和實踐中帶來啟發和幫助。

隨著自然語言處理技術的不斷發展,我們期待看到更多能夠克服TF-IDF局限性的創新方法涌現。無論是在文本分類、信息檢索,還是在文本摘要等領域,TF-IDF都已經奠定了堅實的基礎,激勵著研究者們不斷探索更高效、更精準的文本處理策略。

那么本次分享就到這里了。最后,博主還是那句話:請大家多去大膽的嘗試和使用,成功總是在不斷的失敗中試驗出來的,敢于嘗試就已經成功了一半。如果大家對博主分享的內容感興趣或有幫助,請點贊和關注。大家的點贊和關注是博主持續分享的動力🤭,博主也希望讓更多的人學習到新的知識。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72055.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72055.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72055.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

架構思維:架構的演進之路

文章目錄 引言為什么架構思維如此重要架構師的特點軟件架構的知識體系如何提升架構思維大型互聯網系統架構的演進之路一、大型互聯網系統的特點二、系統處理能力提升的兩種途徑三、大型互聯網系統架構演化過程四、總結 引言 在軟件開發行業中,有很多技術人可能會問…

DeepSeek-R1-Zero:基于基礎模型的強化學習

注:此文章內容均節選自充電了么創始人,CEO兼CTO陳敬雷老師的新書《自然語言處理原理與實戰》(人工智能科學與技術叢書)【陳敬雷編著】【清華大學出版社】 文章目錄 DeepSeek大模型技術系列四DeepSeek大模型技術系列四》DeepSeek-…

Metal學習筆記八:紋理

到目前為止,您已經學習了如何使用片段函數和著色器為模型添加顏色和細節。另一種選擇是使用圖像紋理,您將在本章中學習如何操作。更具體地說,您將了解: ? UV 坐標:如何展開網格,以便可以對其應用紋理。 ?…

Dify使用和入門

第一步:了解 Dify 在開始之前,先簡單了解一下 Dify 是什么: Dify 是一個開源的 LLM 應用開發平臺,專注于幫助開發者快速構建生產級的生成式 AI 應用。它支持知識庫集成、RAG(檢索增強生成)技術、復雜工作…

threeJS——安裝以及三要素

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 前言一、安裝二、三要素1.場景1.1創建場景1.2向場景添加元素1.3場景屬性 2.相機2.1相機特點2.2正交相機2.3空間布局2.4小姐操作 3.渲染器 總結 前言 本章簡單介紹前…

畢業項目推薦:基于yolov8/yolo11的野生菌菇檢測識別系統(python+卷積神經網絡)

文章目錄 概要一、整體資源介紹技術要點功能展示:功能1 支持單張圖片識別功能2 支持遍歷文件夾識別功能3 支持識別視頻文件功能4 支持攝像頭識別功能5 支持結果文件導出(xls格式)功能6 支持切換檢測到的目標查看 二、數據集三、算法介紹1. YO…

【精華】為什么class在前端開發中不常用?

為什么class在前端開發中不常用? js是一種基于原型的語言。它的對象繼承是通過 原型鏈(prototype chain)實現的,每個對象都有一個 proto 屬性指向它的原型。(大多數傳統面向對象語言(如 Java、C、Python、…

【六祎 - Note】SQL備忘錄;DDL,DML,DQL,DCL

SQL備忘錄 from to : 點擊訪問源地址

阿里云物聯網獲取設備屬性api接口:QueryDevicePropertyData

阿里云物聯網接口:QueryDevicePropertyData 說明:調用該接口查詢指定設備或數字孿生節點,在指定時間段內,單個屬性的數據 比如提取上傳到物聯網的溫度數據 api文檔:QueryDevicePropertyData_物聯網平臺_API文檔-阿里…

需求和開發模型

文章目錄 什么是需求?用戶需求軟件需求用戶需求和軟件需求的不同 開發模型什么是“模型”?軟件的生命周期常見的開發模型瀑布模型(Waterfall Model)螺旋模型增量模型、迭代模型敏捷模型 測試模型V 模型W 模型(雙 V 模型…

21-發糖果

n 個孩子站成一排。給你一個整數數組 ratings 表示每個孩子的評分。 你需要按照以下要求,給這些孩子分發糖果: 每個孩子至少分配到 1 個糖果。 相鄰兩個孩子評分更高的孩子會獲得更多的糖果。 請你給每個孩子分發糖果,計算并返回需要準備的 最…

sql深入學習

文章目錄 前言知識學習注釋的兩種形式字符型注入萬能密碼 布爾盲注報錯注入堆疊注入時間盲注二次注入 小技巧 前言 這次學習建立在對數據庫有基本的認識,了解基礎的增刪改查語句,數字型注入和字符型注入的基礎上,進一步深入學習知識&#xf…

利用three.js在Vue項目中展示重構的stl模型文件

一、目的 為了在前端頁面展示3d打印機打印過程 二、前期準備 完整模型的stl文件和模型切割成的n個stl文件 models文件夾下的文件就是切割后的stl文件 三、代碼 <template><div ref"threeContainer" class"three-container"></div><…

【Eureka 緩存機制】

今天簡單介紹一下Eureka server 的緩存機制吧?????? 一、先來個小劇場&#xff1a;服務發現的"拖延癥" 想象你是個外賣小哥&#xff08;客戶端&#xff09;&#xff0c;每次接單都要打電話問調度中心&#xff08;Eureka Server&#xff09;&#xff1a;“現在…

Python--內置模塊和開發規范(下)

2. 開發規范 2.1 單文件應用 文件結構示例 # 文件注釋 import os import jsonDB_PATH "data.json" # 常量放頂部def load_data():"""函數注釋&#xff1a;加載數據"""if os.path.exists(DB_PATH):with open(DB_PATH, "r"…

go設計模式

劉&#xff1a;https://www.bilibili.com/video/BV1kG411g7h4 https://www.bilibili.com/video/BV1jyreYKE8z 1. 單例模式 2. 簡單工廠模式 代碼邏輯&#xff1a; 原始&#xff1a;業務邏輯層 —> 基礎類模塊工廠&#xff1a;業務邏輯層 —> 工廠模塊 —> 基礎類模塊…

搭建數字化生態平臺公司:痛點與蚓鏈解決方案

在數字技術突飛猛進的當下&#xff0c;數字化生態平臺成為眾多企業實現創新發展、拓展業務版圖的 “秘密工具”。今天&#xff0c;咱們就一起來聊聊搭建這類平臺的公司&#xff0c;看看它們有啥獨特之處&#xff0c;又面臨哪些難題。 一、面臨的痛點 &#xff08;一&#xff0…

標記符號“<”和“>”符號被稱為“尖括號”或“角括號”

你提到的“<”和“>”符號被稱為“尖括號”或“角括號”。它們常用于編程語言中表示類型參數&#xff08;如泛型&#xff09;、HTML標簽&#xff08;如<div>&#xff09;、數學中的不等式&#xff08;如< 5&#xff09;等。 好的&#xff0c;我來用通俗的方式解…

云平臺DeepSeek滿血版:引領AI推理革新,開啟智慧新時代

引言&#xff1a;人工智能的未來——云平臺的卓越突破 在當今科技飛速發展的時代&#xff0c;人工智能&#xff08;AI&#xff09;技術正深刻地改變著我們生活與工作方式的方方面面。作為AI領域的創新者與領航者&#xff0c;云平臺始終走在技術前沿&#xff0c;憑借無窮的熱情…

自然語言處理:文本規范化

介紹 大家好&#xff01;很高興又能在這兒和大家分享自然語言處理相關的知識了。在上一篇發布于自然語言處理&#xff1a;初識自然語言處理-CSDN博客為大家初步介紹了自然語言處理的基本概念。而這次&#xff0c;我將進一步深入這個領域&#xff0c;和大家聊聊自然語言處理中一…