先說一下什么是td-idf:簡單說,tf代表詞頻,也就是詞匯出現的次數;idf為逆文檔頻率。換句話說,tf代表該詞的普遍性,idf代表該詞的重要性。
我要做的是:采集n多相關文章,對文章分段,每一段提取核心詞作為搜索組合條件;然后,寫內容的時候,只需要輸入標題,根據標題詞匯查找搜索相關段落進行拼接。
1、采集內容并分段保存
這個就不用多說了吧,主要分段,我是按嘆號和句號劃分的。
2、每一段提取三個核心詞、人名詞匯和代詞。
問題來了,我有一段測試文字:
學校的升旗臺一般都是使用一根旗桿以懸掛國旗的,三根旗桿的比較少見,應該是中學以上的學校吧。
用scws提取核心詞的時候發現其權值是這樣的:三根>旗桿>升旗臺。
這不是我要的,所以他的tf-idf不適合我,于是自己整理計算tf-idf。
1、導出scws所有詞匯存入數據庫。
2、根據我的語料數據計算tf-idf。
網上通用的計算是這樣的:tf=該詞出現次數/總記錄數,idf=log(總記錄數/(該詞出現次數+1))。結果得到的數據大概是這樣,比如:
詞 | tf | idf | td-idf |
雕塑 |
0.2615 |
1.3414391736273468 |
|
學校 |
0.0054 |
5.221846917501328 |
|
升旗臺 |
0.0004 |
7.9021657054993115 |
|
旗桿 |
0.0000 |
8.837371884366199 |
|
由上表可見,不論旗桿出現多少次,其權值都為0;于是想著把tf統一乘以n倍,如此排查為0的情況,但同樣,這個詞需要有權值,需要出現的次數是雕塑的無數倍才可以……這同樣不是我想要的!
看了看scws官方文檔,他是這樣計算的td-idf的:
if ($count < 1000) $count = 21000 - $count * 18; $tf = log($count); $tf = pow($tf, 5) * log(strlen($word)); $tf = log($tf); $idf = log(5000000000/$count);
沒看明白,尤其是$count的處理,感覺好不科學……還是自己來改。目前主要的問題是:熱門詞與稀有詞tf懸殊太大。所以,降低他們之間的差值即可,想了很多辦法,最終確定用方根來實現。
php有平方根,sqrt(),但是沒有n次方根,不過可以通過pow(數,1/n)來實現。最終得到的還不錯。
© 致遠 2020-05-09,原創內容,轉載請注明出錯:td-idf進行偽原創實操