目錄
1、TF-IDF算法介紹
(1)TF是詞頻(Term Frequency)
(2) IDF是逆向文件頻率(Inverse Document Frequency)
(3)TF-IDF實際上是:TF * IDF
2、TF-IDF應用
3、Python3實現TF-IDF算法
4、NLTK實現TF-IDF算法
5、Sklearn實現TF-IDF算法
1、TF-IDF算法介紹
TF-IDF(term frequency–inverse document frequency,詞頻-逆向文件頻率)是一種用於信息檢索(information retrieval)與文本挖掘(text mining)的常用加權技術。
TF-IDF是一種統計方法,用以評估一字詞對於一個文件集或一個語料庫中的其中一份文件的重要程度。字詞的重要性隨着它在文件中出現的次數成正比增加,但同時會隨着它在語料庫中出現的頻率成反比下降。
TF-IDF的主要思想是:如果某個單詞在一篇文章中出現的頻率TF高,並且在其他文章中很少出現,則認為此詞或者短語具有很好的類別區分能力,適合用來分類。
(1)TF是詞頻(Term Frequency)
詞頻(TF)表示詞條(關鍵字)在文本中出現的頻率。
這個數字通常會被歸一化(一般是詞頻除以文章總詞數), 以防止它偏向長的文件。
公式:
即:
其中 ni,j 是該詞在文件 dj 中出現的次數,分母則是文件 dj 中所有詞匯出現的次數總和;
(2) IDF是逆向文件頻率(Inverse Document Frequency)
逆向文件頻率 (IDF) :某一特定詞語的IDF,可以由總文件數目除以包含該詞語的文件的數目,再將得到的商取對數得到。
如果包含詞條t的文檔越少, IDF越大,則說明詞條具有很好的類別區分能力。
公式:
其中,|D| 是語料庫中的文件總數。 |{j:ti∈dj}| 表示包含詞語 ti 的文件數目(即 ni,j≠0 的文件數目)。如果該詞語不在語料庫中,就會導致分母為零,因此一般情況下使用 1+|{j:ti∈dj}|
即:
(3)TF-IDF實際上是:TF * IDF
某一特定文件內的高詞語頻率,以及該詞語在整個文件集合中的低文件頻率,可以產生出高權重的TF-IDF。因此,TF-IDF傾向於過濾掉常見的詞語,保留重要的詞語。
公式:
注: TF-IDF算法非常容易理解,並且很容易實現,但是其簡單結構並沒有考慮詞語的語義信息,無法處理一詞多義與一義多詞的情況。
2、TF-IDF應用
(1)搜索引擎;(2)關鍵詞提取;(3)文本相似性;(4)文本摘要
3、Python3實現TF-IDF算法
# -*- coding: utf-8 -*-
from collections import defaultdict
import math
import operator
"""
函數說明:創建數據樣本
Returns:
dataset - 實驗樣本切分的詞條
classVec - 類別標簽向量
"""
def loadDataSet():
dataset = [ ['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'], # 切分的詞條
['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
['stop', 'posting', 'stupid', 'worthless', 'garbage'],
['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
['quit', 'buying', 'worthless', 'dog', 'food', 'stupid'] ]
classVec = [0, 1, 0, 1, 0, 1] # 類別標簽向量,1代表好,0代表不好
return dataset, classVec
"""
函數說明:特征選擇TF-IDF算法
Parameters:
list_words:詞列表
Returns:
dict_feature_select:特征選擇詞字典
"""
def feature_select(list_words):
#總詞頻統計
doc_frequency=defaultdict(int)
for word_list in list_words:
for i in word_list:
doc_frequency[i]+=1
#計算每個詞的TF值
word_tf={} #存儲沒個詞的tf值
for i in doc_frequency:
word_tf[i]=doc_frequency[i]/sum(doc_frequency.values())
#計算每個詞的IDF值
doc_num=len(list_words)
word_idf={} #存儲每個詞的idf值
word_doc=defaultdict(int) #存儲包含該詞的文檔數
for i in doc_frequency:
for j in list_words:
if i in j:
word_doc[i]+=1
for i in doc_frequency:
word_idf[i]=math.log(doc_num/(word_doc[i]+1))
#計算每個詞的TF*IDF的值
word_tf_idf={}
for i in doc_frequency:
word_tf_idf[i]=word_tf[i]*word_idf[i]
# 對字典按值由大到小排序
dict_feature_select=sorted(word_tf_idf.items(),key=operator.itemgetter(1),reverse=True)
return dict_feature_select
if __name__=='__main__':
data_list,label_list=loadDataSet() #加載數據
features=feature_select(data_list) #所有詞的TF-IDF值
print(features)
print(len(features))
運行結果:
4、NLTK實現TF-IDF算法
from nltk.text import TextCollection
from nltk.tokenize import word_tokenize
#首先,構建語料庫corpus
sents=['this is sentence one','this is sentence two','this is sentence three']
sents=[word_tokenize(sent) for sent in sents] #對每個句子進行分詞
print(sents) #輸出分詞后的結果
corpus=TextCollection(sents) #構建語料庫
print(corpus) #輸出語料庫
#計算語料庫中"one"的tf值
tf=corpus.tf('one',corpus) # 1/12
print(tf)
#計算語料庫中"one"的idf值
idf=corpus.idf('one') #log(3/1)
print(idf)
#計算語料庫中"one"的tf-idf值
tf_idf=corpus.tf_idf('one',corpus)
print(tf_idf)
運行結果:
5、Sklearn實現TF-IDF算法
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
# 將語料轉化為詞袋向量,根據詞袋向量統計TF-IDF
vectorizer = CountVectorizer(max_features=5000)
tf_idf_transformer = TfidfTransformer()
tf_idf = tf_idf_transformer.fit_transform(vectorizer.fit_transform(x_train))
x_train_weight = tf_idf.toarray() # 訓練集TF-IDF權重矩陣
tf_idf = tf_idf_transformer.transform(vectorizer.transform(x_test))
x_test_weight = tf_idf.toarray() # 測試集TF-IDF權重矩陣