web-dev-qa-db-ja.com

ベクトル空間モデル:コサイン類似度とユークリッド距離

分類されたテキストのコーパスがあります。これらからベクトルを作成します。各ベクトルは1つのドキュメントに対応します。ベクトルコンポーネントは、TFIDF値として計算されたこのドキュメントのワードの重みです。次に、すべてのクラスが単一のベクトルで表されるモデルを構築します。モデルには、コーパス内のクラスと同じ数のベクトルがあります。モデルベクトルのコンポーネントは、このクラスのベクトルから取得したすべてのコンポーネント値の平均として計算されます。未分類のベクトルの場合、これらのベクトル間のコサインを計算することにより、モデルベクトルとの類似性を判断します。

質問:

1)分類されていないベクトルとモデルベクトル間のユークリッド距離を使用してそれらの類似性を計算できますか?

2)2つのベクトル間の角度のコサインの代わりにユークリッド距離を類似性尺度として使用できないのはなぜですか?

ありがとう!

39
Anton Ashanin

これについての非公式だがかなり直感的な1つの方法は、ベクトルの2つのコンポーネント、方向および大きさを考慮することです。

方向は、ベクトルの「好み」/「スタイル」/「センチメント」/「潜在変数」であり、一方、大きさは、その方向に対する強さです。

文書を分類するときは、全体的な感情によって分類したいので、angular distanceを使用します。

ユークリッド距離は、方向ではなくL2ノルム(大きさ、2次元の場合は大きさ)によってクラスター化されたドキュメントの影響を受けやすくなります。つまりOriginからの距離が類似しているため、方向がまったく異なるベクトルはクラスター化されます。

39
kizzx2

質問には逆の順序で答えます。 2番目の質問では、コサイン類似度とユークリッド距離は、ベクトルの類似度を測定する2つの異なる方法です。前者は、原点に対するベクトルの類似性を測定し、後者は、ベクトルに沿った特定の関心点間の距離を測定します。単独で使用するか、それらを組み合わせて両方を使用するか、類似性を判断するために他の多くの方法のいずれかを見ることができます。詳細については、Michael Collins講義の これら スライドを参照してください。

最初の質問はあまり明確ではありませんが、ドキュメントまたは「モデル」を比較するかどうかに関係なく、どちらかの尺度を使用して2つのベクトル間の距離を見つけることができます。モデルはすべてのクラスターの合計です)。

23
Tyson

時間に関する計算(python単位):

import time
import numpy as np

for i in range(10):
    start = time.time() 
    for i in range(10000):
        a, b = np.random.Rand(100), np.random.Rand(100) 
        np.dot(a, b) / ( np.linalg.norm(a) * np.linalg.norm(b))
    print 'Cosine similarity took', time.time() - start

    start = time.time() 
    for i in range(10000):
        a, b = np.random.Rand(100), np.random.Rand(100) 
        2 * (1 - np.dot(a, b) / ( np.linalg.norm(a) * np.linalg.norm(b)))
    print 'Euclidean from 2*(1 - cosine_similarity) took', time.time() - start


    start = time.time() 
    for i in range(10000):
        a, b = np.random.Rand(100), np.random.Rand(100) 
        np.linalg.norm(a-b)
    print 'Euclidean Distance using np.linalg.norm() took', time.time() - start


    start = time.time() 
    for i in range(10000):
        a, b = np.random.Rand(100), np.random.Rand(100) 
        np.sqrt(np.sum((a-b)**2))
    print 'Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took', time.time() - start
    print '--------------------------------------------------------'

[でる]:

Cosine similarity took 0.15826010704
Euclidean from 2*(1 - cosine_similarity) took 0.179041862488
Euclidean Distance using np.linalg.norm() took 0.10684299469
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.113723039627
--------------------------------------------------------
Cosine similarity took 0.161732912064
Euclidean from 2*(1 - cosine_similarity) took 0.178358793259
Euclidean Distance using np.linalg.norm() took 0.107393980026
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.111194849014
--------------------------------------------------------
Cosine similarity took 0.16274189949
Euclidean from 2*(1 - cosine_similarity) took 0.178978919983
Euclidean Distance using np.linalg.norm() took 0.106336116791
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.111373186111
--------------------------------------------------------
Cosine similarity took 0.161939144135
Euclidean from 2*(1 - cosine_similarity) took 0.177414178848
Euclidean Distance using np.linalg.norm() took 0.106301784515
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.11181807518
--------------------------------------------------------
Cosine similarity took 0.162333965302
Euclidean from 2*(1 - cosine_similarity) took 0.177582979202
Euclidean Distance using np.linalg.norm() took 0.105742931366
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.111120939255
--------------------------------------------------------
Cosine similarity took 0.16153883934
Euclidean from 2*(1 - cosine_similarity) took 0.176836967468
Euclidean Distance using np.linalg.norm() took 0.106392860413
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.110891103745
--------------------------------------------------------
Cosine similarity took 0.16018986702
Euclidean from 2*(1 - cosine_similarity) took 0.177738189697
Euclidean Distance using np.linalg.norm() took 0.105060100555
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.110497951508
--------------------------------------------------------
Cosine similarity took 0.159607887268
Euclidean from 2*(1 - cosine_similarity) took 0.178565979004
Euclidean Distance using np.linalg.norm() took 0.106383085251
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.11084485054
--------------------------------------------------------
Cosine similarity took 0.161075115204
Euclidean from 2*(1 - cosine_similarity) took 0.177822828293
Euclidean Distance using np.linalg.norm() took 0.106630086899
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.110257148743
--------------------------------------------------------
Cosine similarity took 0.161051988602
Euclidean from 2*(1 - cosine_similarity) took 0.181928873062
Euclidean Distance using np.linalg.norm() took 0.106360197067
Euclidean Distance using np.sqrt(np.sum((a-b)**2)) took 0.111301898956
--------------------------------------------------------
5
alvas

特定のアプリケーションでどちらの距離尺度が優れているかを判断する唯一の確実な方法は、両方を試して、どちらがより満足のいく結果をもたらすかを確認することです。ほとんどの場合、有効性の差はそれほど大きくないと思いますが、特定のアプリケーションではそうではないかもしれません。

0
Ralph Dratman