The answer is really right there in your linked articles. From the first, here are the formulae for cosine and correlation (lightly edited for brevity and clarity):
\begin{align}
{\rm CosSim}(x,y) &= \frac{\sum_i x_i y_i}{ \sqrt{ \sum_i x_i^2} \sqrt{ \sum_i y_i^2 } } \\
\ \\
\ \\
{\rm Corr}(x,y) &= \frac{ \sum_i (x_i-\bar{x}) (y_i-\bar{y}) }{
\sqrt{\sum (x_i-\bar{x})^2} \sqrt{ \sum (y_i-\bar{y})^2 } } \\
\ \\
{\rm Corr}(x,y) &= {\rm CosSim}(x-\bar{x},\ y-\bar{y})
\end{align}
So the simplest adaptation is just to subtract the means from your input vectors:
library(MASS) # we need this package to generate correlated data below
set.seed(2641) # this makes the example exactly reproducible
# now I generate correlated data:
X <- mvrnorm(1000, mu=c(100, 150), Sigma=rbind(c(30, 17),
c(17, 50) ) )
# I adapted the function somewhat, as the original was keyed to its context
cos.sim <- function(X, corr=FALSE){
if(corr){
A = X[,1] - mean(X[,1])
B = X[,2] - mean(X[,2])
} else {
A = X[,1]
B = X[,2]
}
return( t(A)%*%B / sqrt(sum(A^2)*sum(B^2)) )
}
cos.sim(X)
# [,1]
# [1,] 0.9985756
cos.sim(X, corr=TRUE)
# [,1]
# [1,] 0.4604822
cor(X)
# [,1] [,2]
# [1,] 1.0000000 0.4604822
# [2,] 0.4604822 1.0000000
Here is a matrix version:
set.seed(6616)
X3 <- mvrnorm(1000, mu=c(100, 150, 175), Sigma=rbind(c(30, 17, 12),
c(17, 50, 29),
c(12, 29, 46) ))
cos.sim.mat <- function(X, corr=FALSE){
if(corr){ X = apply(X, 2, function(x){ x-mean(x) }) }
denom = solve(diag(sqrt(diag(t(X)%*%X))))
return( denom%*%(t(X)%*%X)%*%denom )
}
cos.sim.mat(X3)
# [,1] [,2] [,3]
# [1,] 1.0000000 0.9984552 0.9983700
# [2,] 0.9984552 1.0000000 0.9992154
# [3,] 0.9983700 0.9992154 1.0000000
cos.sim.mat(X3, corr=TRUE)
# [,1] [,2] [,3]
# [1,] 1.0000000 0.3990872 0.2584569
# [2,] 0.3990872 1.0000000 0.5900067
# [3,] 0.2584569 0.5900067 1.0000000
cor(X3)
# [,1] [,2] [,3]
# [1,] 1.0000000 0.3990872 0.2584569
# [2,] 0.3990872 1.0000000 0.5900067
# [3,] 0.2584569 0.5900067 1.0000000
R
because I'm not its user. But correlation is cosine for centered data. So, if you need cosine between data columns, do as if you are computing $r$, only do not center columns (or, equivalently, do not compute sum-of-squares of deviations, compute just sum-of-squares). $\endgroup$