15

TF-IDFを使用してドキュメントをカテゴリに分類しようとしています。いくつかのドキュメントの tf_idf を計算しましたが、これらのドキュメントの 2 つの間のコサイン類似度を計算しようとすると、次のようなトレースバックが表示されます。

#len(u)==201, len(v)==246

cosine_distance(u, v)
ValueError: objects are not aligned

#this works though:
cosine_distance(u[:200], v[:200])
>> 0.52230249969265641

len(u)==len(v) が正しいアプローチになるようにベクトルをスライスしていますか? コサインの類似性は、異なる長さのベクトルで機能すると思います。

私はこの機能を使用しています:

def cosine_distance(u, v):
    """
    Returns the cosine of the angle between vectors v and u. This is equal to
    u.v / |u||v|.
    """
    return numpy.dot(u, v) / (math.sqrt(numpy.dot(u, u)) * math.sqrt(numpy.dot(v, v))) 

また、ベクトル内の tf_idf 値の順序は重要ですか? それらをソートする必要がありますか?それとも、この計算では重要ではありませんか?

4

3 に答える 3

10

ベクトル内の対応する単語のエントリを乗算する必要があるため、単語にはグローバルな順序が必要です。これは、理論的にはベクトルが同じ長さであることを意味します。

実際には、ある文書が他の文書より前に表示された場合、最初の文書が表示された後に 2 番目の文書の単語が全体的な順序に追加された可能性があるため、ベクトルが同じ順序であっても、最初の文書の方が短い可能性があります。そのベクトルにない単語のエントリはありません。

文書1:素早い茶色のキツネが怠け者の犬を飛び越えた.

Global order:     The quick brown fox jumped over the lazy dog
Vector for Doc 1:  1    1     1    1     1     1    1   1   1

資料2:走者は速かった。

Global order:     The quick brown fox jumped over the lazy dog runner was
Vector for Doc 1:  1    1     1    1     1     1    1   1   1
Vector for Doc 2:  1    1     0    0     0     0    0   0   0    1     1

この場合、理論上は Document 1 ベクトルの最後にゼロを埋め込む必要があります。実際には、内積を計算するときは、ベクトル 1 の最後までの要素を乗算するだけで済みます (ベクトル 2 の余分な要素を省略してゼロを掛けることはまったく同じですが、余分な要素にアクセスする方が遅くなるためです)。

次に、各ベクトルの大きさを個別に計算できます。そのために、ベクトルは同じ長さである必要はありません。

于 2010-06-30T01:00:22.093 に答える
6

項ベクトルの余弦類似度を計算していますか? 項ベクトルは同じ長さでなければなりません。ドキュメントに単語が存在しない場合、その用語の値は 0 になります。

コサイン類似度を適用しているベクトルは正確にはわかりませんが、コサイン類似度を実行する場合、ベクトルは常に同じ長さである必要があり、順序は非常に重要です。

例:

Term | Doc1 | Doc2
Foo     .3     .7
Bar  |  0   |  8
Baz  |  1   |  1

ここでは、2 つのベクトル (.3,0,1) と (.7,8,1) があり、それらの間のコサイン類似度を計算できます。(.3,1) と (.7,8) を比較すると、Baz の Doc1 スコアと Bar の Doc2 スコアを比較することになり、意味がありません。

于 2010-06-25T20:40:32.113 に答える
4

Try building the vectors before feeding them to the cosine_distance function:

import math
from collections import Counter
from nltk import cluster

def buildVector(iterable1, iterable2):
    counter1 = Counter(iterable1)
    counter2= Counter(iterable2)
    all_items = set(counter1.keys()).union( set(counter2.keys()) )
    vector1 = [counter1[k] for k in all_items]
    vector2 = [counter2[k] for k in all_items]
    return vector1, vector2


l1 = "Julie loves me more than Linda loves me".split()
l2 = "Jane likes me more than Julie loves me or".split()


v1,v2= buildVector(l1, l2)
print(cluster.util.cosine_distance(v1,v2))
于 2013-02-19T06:36:12.447 に答える