原創轉載請注明出處:https://www.cnblogs.com/agilestyle/p/12828493.html
什么是 TF-IDF 值
在多項式朴素貝葉斯中提到了“詞的 TF-IDF 值”,TF-IDF 是一個統計方法,用來評估某個詞語對於一個文件集或文檔庫中的其中一份文件的重要程度。
TF-IDF 實際上是兩個詞組 Term Frequency 和 Inverse Document Frequency 的總稱,兩者縮寫為 TF 和 IDF,分別代表了詞頻和逆向文檔頻率。
詞頻 TF 計算了一個單詞在文檔中出現的次數,它認為一個單詞的重要性和它在文檔中出現的次數呈正比。
逆向文檔頻率 IDF,是指一個單詞在文檔中的區分度。它認為一個單詞出現在的文檔數越少,就越能通過這個單詞把該文檔和其他文檔區分開。IDF 越大就代表該單詞的區分度越大。
所以 TF-IDF 實際上是詞頻 TF 和逆向文檔頻率 IDF 的乘積。這樣我們傾向於找到 TF 和 IDF 取值都高的單詞作為區分,即這個單詞在一個文檔中出現的次數多,同時又很少出現在其他文檔中。這樣的單詞適合用於分類。
TF-IDF 如何計算
首先看下詞頻 TF 和逆向文檔概率 IDF 的公式。
IDF 的分母中,單詞出現的文檔數要加 1,是因為有些單詞可能不會存在文檔中,為了避免分母為 0,統一給單詞出現的文檔數都加 1。
TF-IDF=TF*IDF
TF-IDF 值就是 TF 與 IDF 的乘積,這樣可以更准確地對文檔進行分類。比如“我”這樣的高頻單詞,雖然 TF 詞頻高,但是 IDF 值很低,整體的 TF-IDF 也不高。
舉個具體的例子
假設一個文件夾里一共有 10 篇文檔,其中一篇文檔有 1000 個單詞,“this”這個單詞出現 20 次,“bayes”出現了 5 次。“this”在所有文檔中均出現過,而“bayes”只在 2 篇文檔中出現過。計算一下這兩個詞語的 TF-IDF 值。
針對“this”,計算 TF-IDF 值:
所以 TF-IDF=0.02*(-0.0414)=-8.28e-4。
針對“bayes”,計算 TF-IDF 值:
所以 TF-IDF=0.005*0.5229=2.61e-3。
很明顯“bayes”的 TF-IDF 值要大於“this”的 TF-IDF 值。這就說明用“bayes”這個單詞做區分比單詞“this”要好。
如何求 TF-IDF
在 sklearn 中直接使用 TfidfVectorizer 類,它可以計算單詞 TF-IDF 向量的值。在這個類中,取 sklearn 計算的對數 log 時,底數是 e,不是 10。
from sklearn.feature_extraction.text import TfidfVectorizer stop_words = ['is', 'the', 'and'] tfidf_vec = TfidfVectorizer(stop_words=stop_words) # TfidfVectorizer(analyzer='word', binary=False, decode_error='strict', # dtype=<class 'numpy.float64'>, encoding='utf-8', # input='content', lowercase=True, max_df=1.0, max_features=None, # min_df=1, ngram_range=(1, 1), norm='l2', preprocessor=None, # smooth_idf=True, stop_words=['is', 'the', 'and'], # strip_accents=None, sublinear_tf=False, # token_pattern='(?u)\\b\\w\\w+\\b', tokenizer=None, use_idf=True, # vocabulary=None) print(tfidf_vec) documents = [ 'this is the bayes document', 'this is the second second document', 'and the third one', 'is this the document' ] # 使用 fit_transform 計算,返回文本矩陣,該矩陣表示了每個單詞在每個文檔中的 TF-IDF 值 tfidf_matrix = tfidf_vec.fit_transform(documents) # 不重復的詞: ['bayes', 'document', 'one', 'second', 'third', 'this'] print('不重復的詞:', tfidf_vec.get_feature_names()) # 停用詞表: frozenset({'and', 'the', 'is'}) print('停用詞表:', tfidf_vec.get_stop_words()) # 每個單詞的ID: {'this': 5, 'bayes': 0, 'document': 1, 'second': 3, 'third': 4, 'one': 2} print('每個單詞的ID:', tfidf_vec.vocabulary_) # 每個單詞的tfidf值: # [[0.74230628 0.47380449 0. 0. 0. 0.47380449] # [0. 0.29088811 0. 0.91146487 0. 0.29088811] # [0. 0. 0.70710678 0. 0.70710678 0. ] # [0. 0.70710678 0. 0. 0. 0.70710678]] print('每個單詞的tfidf值:\n', tfidf_matrix.toarray())
Note:
停用詞就是在分類中沒有用的詞,這些詞一般詞頻 TF 高,但是 IDF 很低,起不到分類的作用。為了節省空間和計算時間,把這些詞作為停用詞 stop words,告訴機器這些詞不需要計算。停用詞 stop_words 是一個列表 List 類型。
Reference
https://time.geekbang.org/column/article/79762