応用編として,更に複雑な類似度計算に挑戦してみます.
sim(d|q) = 1 / norm(d) * \sum_t { wq(t|q) * wd(t|d) }ここで,
wq(t|q) = tf_n(t|q) * idf(t) wd(t|d) = tf_n(t|d)とします.idf(t)は前の章で説明しました.tf_n(t|q), tf_n(t|d)は少し工夫してあります. まず,tf_n(t|q)ですが,
1 + log(TF(t|q)) tf_n(t|q) = --------------------- 1 + log(ave(TF(.|q)))と定義します. 今までは,単純に頻度 TF(t|q) を使っていましたが, 高頻度語の影響をおさえるために対数を使います. さらに,検索要求q中の TF(t|q) の平均 ave(TF(.|q)) で正規化しています.tf_n(t|d) も同様です.
1 + log(TF(t|d)) tf_n(t|d) = --------------------- 1 + log(ave(TF(.|d)))最後に norm(d) を以下のように定義します.
norm(d) = ave(len(.)) + slope * (len(d) - ave(len(.)))ここで,len(d)はd中の異なり単語数です.ave(len(.)) はコーパス中での len(d) の平均です.slope は適当な定数です. この式は ave(len(.)) を基準にして文書長の調整をしています. 詳しくは文献[1]を参照してください.
以上で使った記号をまとめておきましょう.
--------------------------------------------- 記号 意味 --------------------------------------------- TF(t|q) q における単語 t の頻度 TF(t|d) d における単語 t の頻度 ave(TF(.|q)) q における TF(t|q) の平均 ave(TF(.|d)) d における TF(t|d) の平均 len(d) d における異り単語数 ave(len(.)) コーパスにおける len(d) の平均 slope 傾きの定数(0.2) --------------------------------------------定義ファイルで自動的に展開してくれるのはTF(t|q), TF(t|d)のみで, 後は自分で計算しなければなりません.それぞれについて,
-------------------- 記号 変数名 -------------------- ave(TF(.|q)) aveTFq ave(TF(.|d)) aveTFd len(d) lend ave(len(.)) avelen slope Slope --------------------という変数を宣言することにします.
以下にこの計算式の定義ファイルをリストしておきます. なおここでは, 効率化のためtf_n(t|d)の分母をくくりだしてnorm(d)に入れこんでいます.
name: WT_SMART 0: globals double aveTFq = 0.0; double avelen = 0.0; double Slope = 0.0; 1: loop constants { int i; for (aveTFq = 0.0, i = 0; i < qlen; i++) { aveTFq += q[i].TF_d; } aveTFq /= qlen; avelen = wam_total_elem_num(wam, dir_d) / (double)N_wam_d; Slope = 0.2; } 2: wq(t|q) = ((1.0 + log(TF(t|q))) / (1.0 + log(aveTFq))) * idf(t); 3: wd(t|d) = (1.0 + log(TF(t|d))); 4: norm(d) = (avelen + Slope * (DF(.|d) - avelen)) * (1.0 + log(TF(.|d)/DF(.|d))); 5:
「6: 関連文書検索,適合性フィードバックを実装する」に進む
「4: 類似度を定義してみる」に戻る
「1: はじめに」に戻る