Приятной особенностью 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
гораздо эффективнее, чем создание эквивалентной операции вручную).
As @В ответе Джека Мани говорится, что скалярное произведение двух векторов (это длина (a) * длина (b) * cos (a, b)) может быть отрицательным ...
Для чего это стоит, я подозреваючто функция cosine
в lsa
может быть более легко / эффективно реализована для аргументов матрицы как as.dist(crossprod(x))
...
edit : в комментариях к удаленному ответу нижеЯ предположил, что квадрат гоМера косинус-расстояния может быть подходящей, если кто-то хочет меру подобия на [0,1] - это было бы аналогично использованию коэффициента детерминации (r ^ 2), а не коэффициента корреляции (r) - но этоможет также стоить вернуться и более тщательно обдумать назначение / значение мер сходства, которые будут использоваться ...