Todas las funciones que está utilizando son .Primitive
(por lo tanto, ya se llama código compilado directamente), por lo que será difícil encontrar ganancias de velocidad consistentes fuera de reconstruir R con un BLAS optimizado. Con eso dicho, aquí es una opción que podría ser más rápido para los vectores más grandes:
cosine_calc2 <- function(a,b,wts) {
a = a*wts
b = b*wts
crossprod(a,b)/sqrt(crossprod(a)*crossprod(b))
}
all.equal(cosine_calc1(a,b,w),cosine_calc2(a,b,w))
# [1] TRUE
# Check some timings
library(rbenchmark)
# cosine_calc2 is slower on my machine in this case
benchmark(
cosine_calc1(a,b,w),
cosine_calc2(a,b,w), replications=1e5, columns=1:4)
# test replications user.self sys.self
# 1 cosine_calc1(a, b, w) 100000 1.06 0.02
# 2 cosine_calc2(a, b, w) 100000 1.21 0.00
# but cosine_calc2 is faster for larger vectors
set.seed(21)
a <- rnorm(1000)
b <- rnorm(1000)
w <- runif(1000)
benchmark(
cosine_calc1(a,b,w),
cosine_calc2(a,b,w), replications=1e5, columns=1:4)
# test replications user.self sys.self
# 1 cosine_calc1(a, b, w) 100000 3.83 0
# 2 cosine_calc2(a, b, w) 100000 2.12 0
ACTUALIZACIÓN:
de perfiles revela que un poco de tiempo se dedica a multiplicar cada vector mediante el vector de pesos.
> Rprof(); for(i in 1:100000) cosine_calc2(a,b,w); Rprof(NULL); summaryRprof()
$by.self
self.time self.pct total.time total.pct
* 0.80 45.98 0.80 45.98
crossprod 0.56 32.18 0.56 32.18
cosine_calc2 0.32 18.39 1.74 100.00
sqrt 0.06 3.45 0.06 3.45
$by.total
total.time total.pct self.time self.pct
cosine_calc2 1.74 100.00 0.32 18.39
* 0.80 45.98 0.80 45.98
crossprod 0.56 32.18 0.56 32.18
sqrt 0.06 3.45 0.06 3.45
$sample.interval
[1] 0.02
$sampling.time
[1] 1.74
Si puede hacer la ponderación antes de tener que llamar a los millones de función de los tiempos, que le podría ahorrar un poco de tiempo. cosine_calc3
es marginalmente más rápido que tu función original con vectores pequeños. La compilación de bytes de la función debería darle otra aceleración marginal.
cosine_calc3 <- function(a,b) {
crossprod(a,b)/sqrt(crossprod(a)*crossprod(b))
}
A = a*w
B = b*w
# Run again on the 1000-element vectors
benchmark(
cosine_calc1(a,b,w),
cosine_calc2(a,b,w),
cosine_calc3(A,B), replications=1e5, columns=1:4)
# test replications user.self sys.self
# 1 cosine_calc1(a, b, w) 100000 3.85 0.00
# 2 cosine_calc2(a, b, w) 100000 2.13 0.02
# 3 cosine_calc3(A, B) 100000 1.31 0.00
sólo ser capaz de hacerlo un par a la vez va a ser un cuello de botella importante ... –
Odio decírtelo, pero en mi experiencia, no parece que se construirá R de rendimiento (hablando relativamente). Si estos datos provienen de una base de datos relacional, puede considerar calcular las similitudes allí y luego exportar a R. La mayoría de lo que uso R para el análisis a pequeña escala (es decir, en los conjuntos de datos después de haber hecho una cantidad significativa de agregación) y producción de gráficos. –
¿Por qué no avanzas y comparas los ejemplos enumerados en http://stackoverflow.com/questions/2535234/find-cosine-similarity-in-r/2536149#2536149 (es decir, la pregunta que vinculó; @JoshUlrich te muestra cómo en su respuesta) y ¿lo ves por ti mismo? –