Преимущество R в том, что вы часто можете копаться в функциях и сами видеть, что происходит. Если вы введете cosine
(без каких-либо скобок, аргументов и т. д.), то R распечатает тело функции. Поковырявшись в ней (что требует некоторой практики), можно увидеть, что есть куча машин для вычисления попарного сходства столбцов матрицы (т.е. бит, завернутый в условие if (is.matrix(x) && is.null(y))
, но ключевая строка функции
crossprod(x, y)/sqrt(crossprod(x) * crossprod(y))
Давайте вытащим это и применим к вашему примеру:
> crossprod(a,b)/sqrt(crossprod(a)*crossprod(b))
[,1]
[1,] -0.05397935
> crossprod(a)
[,1]
[1,] 1
> crossprod(b)
[,1]
[1,] 1
Итак, вы используете уже нормализованные векторы, так что у вас есть только crossprod
для просмотра. В вашем случае это эквивалентно
> sum(a*b)
[1] -0.05397935
(для реальных матричных операций crossprod
намного эффективнее, чем построение эквивалентной операции вручную).
Как говорится в ответе @Jack Maney, скалярное произведение двух векторов (длина (a) * длина (b) * cos (a, b)) может быть отрицательным...
Для чего бы это ни стоило, я подозреваю, что функция cosine
в lsa
может быть более легко/эффективно реализована для аргументов матрицы как as.dist(crossprod(x))
...
редактировать: в комментариях к уже удаленному ответу ниже я предположил, что квадрат меры косинусного расстояния может быть подходящим, если кто-то хочет получить меру сходства на [0, 1] -- это было бы аналогично использованию коэффициента детерминации (r^2), а не коэффициента корреляции (r) -- но, возможно, стоит вернуться и более тщательно обдумать цель/значение подобия меры, которые следует использовать...
person
Ben Bolker
schedule
06.07.2011