5  複雑な類似度を定義する

応用編として,更に複雑な類似度計算に挑戦してみます.

        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:


文献[1]: Singhal, A. and Buckley, C. and Mitra, M., "Pivoted Document Length Normalization", Proc. of SIGIR, 1996, pp.21-29.


6: 関連文書検索,適合性フィードバックを実装する」に進む
4: 類似度を定義してみる」に戻る
1: はじめに」に戻る