4  類似度を定義してみる

自分で類似度計算式を定義して libae に組みこんでみます.

4.1 類似度定義ファイルを修正する(IDFの導入)

前の章で説明した WT_TF を変更してみましょう. 名前は WT_MINE とします. まずは,類似度定義ファイルディレクトリへ移動して, 元となる定義ファイル wt_tf.f を wt_mine.f にコピーします.

        % cd $GETASRC/lib/ae/wt
        % cp wt_tf.f wt_mine.f

定義式の変更方針は以下のとおりです.

WT_TF では単語の頻度をそのまま単語の重みとしていました. 実はこれはあまり良い方法ではありません. たくさん現れる単語が必ずしも重要だとは限らないからです. 例えば,新聞記事では, 「記者」とか「事件」といった単語が頻繁に出てきますが, かといってこれらはあまり重要だとは思えません.

そこで,IDF(Inverted Document Frequency)という尺度がよく用いられます. これは, コーパス中のたくさんの文書にあらわれる単語ほど一般的な単語であり重要ではないとする方法です. 式で書くと以下のようになります.

        idf(t) = log (N / DF(t))
N はコーパス中の総文書数,DF(t) は単語 t があらわれる文書数です. なぜ対数をとるかは,とりあえず無視してください.idf(t) と頻度を組みあわせたのが最終的な重みになります.

まずは変更前の WT_TF の式を書いておきます.

        sim(d|q) = (1 / TF(.|d)) * \sum_t { TF(t|q) * TF(t|d) }
WT_MINE では idf(t) を導入して以下のようにします.
        sim(d|q) = (1 / TF(.|d)) * \sum_t { log(N / DF(t)) * TF(t|q) * TF(t|d) }
定義ファイルではパート 2 を修正することになります.
        2:
                wq(t|q) = TF(t|q) * log (N / DF(t));
DF(t) は単語 t があらわれる文書数(の変数)に自動的に展開されます.N はコーパス中の総文書数(の変数)に自動的に展開されます, と言いたいところですが,そうはいかず「さて困った」ということにしましょう. 実は N_wam_d というそのものズバリの変数があるのですが, 今回はそれを使わず自分で計算してみます.

コーパス中の総文書数のような大域的な値は, パート 0 でそれ用の変数を宣言して, パート 1 で値を設定します. まず,パート 0 で,この値を格納する変数を宣言しましょう.

        0:
                int N;
次にパート 1 で実際に変数に値を代入します.
        1:
                N = wam_size(wam, WAM_ROW);
パート 0 と 1 で定義した変数は以下のパート 2, 3, 4, 5 で参照できるようになります.

これでおわりです.

実は,IDFは良く使うスコアですのであらかじめ定義してあります.

        2:
                wq(t|q) = TF(t|q) * idf(t);
と書くだけでも ok だったのでした.

最後に名前パートを修正しておくのも忘れずに!

        name: WT_MINE
              ^^^^^^^

4.2 ライブラリに組みこむ

今作った wt_mine.f を libae に組みこんで wsh が WT_MINE を認識できるようにします.$GETASRC/lib/ae で make install を実行すれば自動的に定義ファイルの変換を行い, libae の再構成も行います.

        % cd $GETASRC/lib/ae
        % make install
make は拡張子が f のファイルを類似度定義ファイルとみなしますから, 自分で新しく定義ファイルを作るときは必ず拡張子を f として, 定義ファイルディレクトリ($GETASRC/lib/ae/wt)に置いてください. なお,定義ファイルディレクトリには, 定義ファイルがいくつあっても構いません(*?).

4.3 wsh で指定する

最後に msearch2.c を修正します.

        r = wsh(q, *qlen, w, WAM_COL, WT_MINE, &rlen, NULL, NULL, NULL);
                                      ^^^^^^^
と変更するだけです. コンパイルして実行してみましょう.どうでしょうか. 自分で作った式をいろいろ差しかえてみるとおもしろいかもしれません.


*1: ただし,以下の名前は予約語ですので, これらの名前を持つ定義ファイルは作れません.WT_DEFAULT, WT_NONE


5: 複雑な類似度を定義する」に進む
3: 類似度定義ファイルの基礎」に戻る
1: はじめに」に戻る