基於Python的tf-idf演算法實現:以《笑傲江湖》為例

Jason Wu發表於2018-09-15

連結

github.com/Jasonnor/tf…

簡介

tf-idf(term frequency-inverse document frequency)是一種用於資訊檢索與文字探勘的常用加權技術,為一種統計方法,評估字詞對於「檔案集合」或「語料庫中的一份檔案」的重要程度。詳細方法和公式可參見Wikipedia,不再贅述。

preview

Figure 1: 輸入「笑傲江湖」檔案集合,每份檔案為小說中的一個章回,輸出每章前 K 高的字詞和其權重。

本專案為實作 tf-idf ,輸入給定「一組有特定集合關係的檔案」(例如某本小說),輸出為每份檔案的 tf-idf 權重值結果,具體為顯示前 k 高的「字詞」和其權重值,如 Figure 1 所示。另外也可以輸入某個字詞,輸出該字詞在所有檔案中的權重值。

其中因為中文不同於英文可以藉由空白區隔字詞,我們採用了 jieba 結巴中文分詞,將檔案集合先進行分詞獲得語料庫,之後使用 tf-idf 演演算法取得字詞加權值。

預設測試資料位於 data 資料夾底下,每組檔案以 01 ~ 99.txt 格式命名,並放置到各別所屬集合的資料夾,例如 data/笑傲江湖/01.txt 。測試資料包含笑傲江湖丶創世紀丶出埃及記。

jieba 其實也內建了「基於 TF-IDF 演算法的關鍵詞抽取」,不過根據它的檔案和 Source Code 所述, jieba 其實只讀取一個檔案來計算TF,而IDF部分則是讀取他們自定的語料庫,因此結果不準確(不是基於相關檔案集合來計算逆頻率)。具體可以試試目錄下的src/tf-idf-jieba.py,我有寫了簡單的 jieba 版本 Demo。

預覽

preview

簡易GUI

preview

「笑傲江湖」資料集的各章字詞權重列表,可以看到各章節的重要關鍵字排名

preview

字詞「任我行」在各章節的權重排名,可以看到他在第28章出場最多,而數值為0的部分就能得知他沒有出現

結論

tf-idf 這個統計方法可以應用在許多場合,處理小說只是其中一種。不過 tf-idf 儘管簡單有效,卻存在部分重大缺陷。以我個人發現的例子來說,笑傲江湖資料集裡每章基本上都一定會出現主角的名字「令狐沖」這個字詞,然而對 tf-idf 來說,每章都出現的東西代表它是常用字詞,逆頻率的存在使「令狐沖」的權重反而變為 0,這真是很諷刺的結果。

可以見得 idf 的簡單架構不能有效反映常見字詞和重要字詞的比重,精確度並不是很高。另外位置資訊也是其缺陷一環,不過在小說中這種缺點並不明顯,因此不多做討論。

相關文章