11

私の目標は、次のテキスト ドキュメント間の KL 距離を計算することです。

1)The boy is having a lad relationship
2)The boy is having a boy relationship
3)It is a lovely day in NY

numpyを簡単に適用するために、まずドキュメントをベクトル化しました

1)[1,1,1,1,1,1,1]
2)[1,2,1,1,1,2,1]
3)[1,1,1,1,1,1,1]

次に、テキスト間の KL 距離を計算するために次のコードを適用しました。

import numpy as np
import math
from math import log

v=[[1,1,1,1,1,1,1],[1,2,1,1,1,2,1],[1,1,1,1,1,1,1]]
c=v[0]
def kl(p, q):
    p = np.asarray(p, dtype=np.float)
    q = np.asarray(q, dtype=np.float)
    return np.sum(np.where(p != 0,(p-q) * np.log10(p / q), 0))
for x in v:
    KL=kl(x,c)
    print KL

上記のコードの結果は次のとおりです[0.0, 0.602059991328, 0.0]。テキスト 1 とテキスト 3 はまったく別のものですが、距離は 0 ですが、関連性の高いテキスト 1 とテキスト 2 の距離は0.602059991328です。これは正確ではありません。

KLに関して私が正しくしていないことを知っている人はいますか? ご提案いただきありがとうございます。

4

3 に答える 3

30

別の回答を追加したくありませんが、ここには 2 つのポイントがあります。まず、ハイメがコメントで指摘したように、KL ダイバージェンス (または距離 - 次のドキュメントによると、それらは同じです) は、確率分布間の差を測定するように設計されています。これは基本的に、関数に渡すものは、それぞれの要素の合計が 1 になる 2 つの配列のようなものでなければならないことを意味します。

第二に、scipy は明らかにこれを実装しており、命名スキームは情報理論の分野により関連しています。関数は「エントロピー」です。

scipy.stats.entropy(pk, qk=None, base=None)

http://docs.scipy.org/doc/scipy-dev/reference/generated/scipy.stats.entropy.html

ドキュメントから:

qk が None でない場合、相対エントロピー (カルバック ライブラー ダイバージェンスまたはカルバック ライブラー距離とも呼ばれます) を計算します S = sum(pk * log(pk / qk), axis=0)。

この関数の利点は、渡したベクトルの合計が 1 にならない場合に、ベクトルを正規化することです (ただし、これは、渡す配列に注意する必要があることを意味します。つまり、配列がデータからどのように構築されるかということです)。

これが役に立てば幸いです。少なくともライブラリで提供されているので、独自にコーディングする必要はありません。

于 2014-07-08T19:17:16.407 に答える