Векторная модель пространства: косинусное сходство против евклидова расстояния
У меня есть корпус секретного текста. Из них я создаю векторы. Каждый вектор соответствует одному документу. Векторные компоненты-это веса слов в этом документе, вычисляемые как значения TFIDF. Затем я создаю модель, в которой каждый класс представлен одним вектором. Модель имеет столько векторов, сколько есть классов в корпусах. Компонент вектора модели вычисляется как среднее всех значений компонента, взятых из векторов в этом классе. Для неклассифицированных векторов я определяю сходство с моделью вектор путем вычисления Косинуса между этими векторами.
вопросы:
1) могу ли я использовать Евклидово расстояние между неклассифицированным и модельным вектором для вычисления их сходства?
2) Почему евклидово расстояние нельзя использовать в качестве меры подобия вместо косинуса угла между двумя векторами и наоборот?
спасибо!
3 ответов
один неформальный, но довольно интуитивный способ подумать об этом-рассмотреть 2 компонента вектора:направление и величины.
направление является "предпочтением" / "стилем" / "настроением" / "скрытой переменной" вектора, в то время как величины насколько он силен в этом направлении.
при классификации документов мы хотели бы классифицировать их по их общему мнению, поэтому мы используем угловые расстояние.
евклидово расстояние восприимчиво к документам, кластеризованным по их L2-норме (величине, в двумерном случае) вместо направления. Т. е. векторы с совершенно разными направлениями будут кластеризованы, потому что их расстояния от начала координат одинаковы.
Я отвечу на вопросы в обратном порядке. Для вашего второго вопроса косинусное сходство и Евклидово расстояние-два разных способа измерения векторного сходства. Первый измеряет сходство векторов относительно начала координат, а второй измеряет расстояние между конкретными точками интереса вдоль вектора. Вы можете использовать либо изолированно, комбинировать их и использовать оба, либо посмотреть на один из многих других способов определения сходства. См.эти слайды из лекции Майкла Коллинза для получения дополнительной информации.
ваш первый вопрос не очень ясен, но вы должны иметь возможность использовать любую меру, чтобы найти расстояние между двумя векторами независимо от того, сравниваете ли вы документы или ваши "модели" (которые традиционно описываются как кластеры, где модель является суммой всех кластеров).
вычислительная времени (в 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
--------------------------------------------------------