用vs2010做網(wǎng)站如何推廣普通話
一.TF-IDF算法概述
什么是TF-IDF?
詞頻-逆文檔頻率(Term Frequency-Inverse Document Frequency,TF-IDF)是一種常用于文本處理的統(tǒng)計方法,可以評估一個單詞在一份文檔中的重要程度。簡單來說就是可以用于文檔關鍵詞的提取。
TF-IDF的基本思想:
看到下面這段文本,我們應該很容易就能看出“梅西”應該是一個關鍵詞,但是我們?nèi)绾瓮ㄟ^算法的形式讓計算機也能夠辨別呢?
五屆世界最佳球員萊昂內(nèi)爾·梅西與阿根廷一起遭遇了更多的心碎——在世界杯1/8淘汰賽上,阿根廷3-4輸給了法國隊。 梅西在俄羅斯只進了一球,在世界杯淘汰賽階段還沒有進球。盡管被廣泛認為是史上最偉大的球員之一,巴塞羅那球星在他的祖國阿根廷卻仍然受到許多人的質(zhì)疑,特別是與1986年奪得世界杯的球王馬拉多納相比。曾經(jīng)的 “球王接班人”如今已年滿31歲,他可能已經(jīng)失去了為祖國爭奪榮譽的最后機會。
腦海中想到的第一個方法就是對單詞出現(xiàn)的次數(shù)進行統(tǒng)計,也就是詞頻。如果一個單詞在文中出現(xiàn)的頻率很高,那我們是否可以認為這個單詞就是文章的關鍵詞呢?
其實不一定,詞頻很高的單詞往往更有可能是一些沒有意義的停用詞(stopword),例如“我”,“的”,“了”等等。
與此同時,在文章中出現(xiàn)次數(shù)很少的單詞也不一定是不重要的單詞。因此,TF-IDF的基本思想是:如果某個單詞在一篇文章的出現(xiàn)的頻率很高,同時在其他文章中很少出現(xiàn),則認為該單詞大概率是一個關鍵詞。
詞頻統(tǒng)計的思路:單詞w在文檔d中出現(xiàn)的頻率。
逆文檔頻率(Inverse Document Frequency,IDF):
逆文檔頻率的思路:如果一個單詞在很多的文檔中出現(xiàn),則意味著該單詞的的重要性不高;反之則意味著該單詞的重要性很高。主要是考慮了單詞的重要性。
文檔數(shù)量越大,同時單詞出現(xiàn)在越少的文檔中,IDF值就越大,則說明單詞越重要。
上面IDF公式已經(jīng)可以使用了,但是在一些特殊情況下可能會有一些小問題,比如某一個生僻詞在我們的語料庫中沒有出現(xiàn)過,那么分母N(w)=0,IDF就沒有意義了。
所以常用的IDF需要做平滑處理,使得沒有在語料庫中出現(xiàn)的單詞也可以得到一個合適的IDF值。
二.代碼實現(xiàn)
# 0. 引入依賴
import numpy as np
import pandas as pd# 1. 定義數(shù)據(jù)和預處理
docA = "The cat sat on my bed"
docB = "The dog sat on my knees"bowA = docA.split(" ")
bowB = docB.split(" ")# 構建詞庫
wordSet = set(bowA).union(set(bowB))
# print(wordSet)# 2. 進行詞數(shù)統(tǒng)計
# 用統(tǒng)計字典來保存詞出現(xiàn)的次數(shù)
wordDictA = dict.fromkeys(wordSet, 0)
wordDictB = dict.fromkeys(wordSet, 0)# 遍歷文檔,統(tǒng)計詞數(shù)
for word in bowA:wordDictA[word] += 1
for word in bowB:wordDictB[word] += 1# pd.DataFrame([wordDictA, wordDictB])
# print(wordDictA)
# print(wordDictB)# 3. 計算詞頻TF
def computeTF(wordDict, bow):# 用一個字典對象記錄tf,把所有的詞對應在bow文檔里的tf都算出來tfDict = {}nbowCount = len(bow)# 取出key與valuefor word, count in wordDict.items():tfDict[word] = count / nbowCountreturn tfDicttfA = computeTF(wordDictA, bowA)
tfB = computeTF(wordDictB, bowB)
# print(tfA)
# print(tfB)# 4. 計算逆文檔頻率idf
def computeIDF(wordDictList):# 用一個字典對象保存idf結果,每個詞作為key,初始值為0idfDict = dict.fromkeys(wordDictList[0], 0)N = len(wordDictList)import math# 遍歷字典序列中的每一本字典for wordDict in wordDictList:# 遍歷字典中的每個詞匯,統(tǒng)計Nifor word, count in wordDict.items():if count > 0:# 先把Ni增加1,存入到idfDictidfDict[word] += 1# 已經(jīng)得到所有詞匯i對應的Ni,現(xiàn)在根據(jù)公式把它替換成為idf值。Ni:表示文檔集中包含了詞匯i的文檔數(shù)for word, Ni in idfDict.items():# 若一個詞匯每個文檔均出現(xiàn)則Ni=N,則log10(1)=0idfDict[word] = math.log10((N + 1) / (Ni + 1))return idfDictidfs = computeIDF([wordDictA, wordDictB])
# print(idfs)# 5. 計算TF-IDF
def computeTFIDF( tf, idfs ):tfidf = {}for word, tfval in tf.items():tfidf[word] = tfval * idfs[word]return tfidftfidfA = computeTFIDF( tfA, idfs )
tfidfB = computeTFIDF( tfB, idfs )# pd.DataFrame( [tfidfA, tfidfB] )
# print(tfidfA)
# print(tfidfB)