Я пытаюсь взять скалярное произведение из матрицы 331x23152 и 23152x23152.
В Python и Octave это тривиальная операция, но в R она кажется невероятно медленной.
N <- 331
M <- 23152
mat_1 = matrix( rnorm(N*M,mean=0,sd=1), N, M)
mat_2 = matrix( rnorm(N*M,mean=0,sd=1), M, M)
tm3 <- system.time({
mat_3 = mat_1%*%mat_2
})
print(tm3)
Выход
user system elapsed
101.95 0.04 101.99
Другими словами, для выполнения этого скалярного произведения требуется более 100 секунд.
Я использую 64-разрядную версию R-3.4.0 с RStudio v1.0.143 на i7-4790 с 16 ГБ ОЗУ. Поэтому я не ожидал, что эта операция займет так много времени.
Я что-то упускаю из виду? Я начал изучать пакеты bigmemory и bigалгебра, но я не могу не думать, что есть решение, не прибегая к пакетам.
ИЗМЕНИТЬ
Чтобы дать вам представление о разнице во времени, вот скрипт для Octave:
n = 331;
m = 23152;
mat_1 = rand(n,m);
mat_2 = rand(m,m);
tic
mat_3 = mat_1*mat_2;
toc
Выход
Elapsed time is 3.81038 seconds.
И в Питоне:
import numpy as np
import time
n = 331
m = 23152
mat_1 = np.random.random((n,m))
mat_2 = np.random.random((m,m))
tm_1 = time.time()
mat_3 = np.dot(mat_1,mat_2)
tm_2 = time.time()
tm_3 = tm_2 - tm_1
print(tm_3)
Выход
2.781277894973755
Как видите, эти цифры даже не совпадают.
ИЗМЕНИТЬ 2
По просьбе Чжэюань Ли, вот игрушечные примеры для точечных произведений.
In R:
mat_1 = matrix(c(1,2,1,2,1,2), nrow = 2, ncol = 3)
mat_2 = matrix(c(1,1,1,2,2,2,3,3,3), nrow = 3, ncol = 3)
mat_3 = mat_1 %*% mat_2
print(mat_3)
Результат:
[,1] [,2] [,3]
[1,] 3 6 9
[2,] 6 12 18
В Октаве:
mat_1 = [1,1,1;2,2,2];
mat_2 = [1,2,3;1,2,3;1,2,3];
mat_3 = mat_1*mat_2
Результат:
mat_3 =
3 6 9
6 12 18
В Питоне:
import numpy as np
mat_1 = np.array([[1,1,1],[2,2,2]])
mat_2 = np.array([[1,2,3],[1,2,3],[1,2,3]])
mat_3 = np.dot(mat_1, mat_2)
print(mat_3)
Результат:
[[ 3 6 9]
[ 6 12 18]]
Для получения дополнительной информации о матричных точечных произведениях: https://en.wikipedia.org/wiki/Matrix_multiplication
ИЗМЕНИТЬ 3
Вывод для sessionInfo()
:
> sessionInfo()
R version 3.4.0 (2017-04-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1
Matrix products: default
locale:
[1] LC_COLLATE=Dutch_Netherlands.1252 LC_CTYPE=Dutch_Netherlands.1252 LC_MONETARY=Dutch_Netherlands.1252
[4] LC_NUMERIC=C LC_TIME=Dutch_Netherlands.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] compiler_3.4.0 tools_3.4.0
ИЗМЕНИТЬ 4
Я попробовал пакет bigalgebra
, но это, похоже, не ускорило процесс:
library('bigalgebra')
N <- 331
M <- 23152
mat_1 = matrix( rnorm(N*M,mean=0,sd=1), N, M)
mat_1 <- as.big.matrix(mat_1)
mat_2 = matrix( rnorm(N*M,mean=0,sd=1), M, M)
tm3 <- system.time({
mat_3 = mat_1%*%mat_2
})
print(tm3)
Результат:
user system elapsed
101.79 0.00 101.81
ИЗМЕНИТЬ 5
Джеймс предложил изменить мою случайно сгенерированную матрицу:
N <- 331
M <- 23152
mat_1 = matrix( runif(N*M), N, M)
mat_2 = matrix( runif(M*M), M, M)
tm3 <- system.time({
mat_3 = mat_1%*%mat_2
})
print(tm3)
Результат:
user system elapsed
102.46 0.05 103.00
rand
и numpyrandom
производят значения в ограниченном диапазоне: (0,1) и [0,1) соответственно. Вы используетеrnorm
в R, который опирается на нормальное распределение (имеющее бесконечную поддержку), а неrunif
, что эквивалентно тому, с чем вы сравниваете. Когда значения матрицы неотрицательны и ограничены, могут быть оптимизации, которые может выполнить BLAS. - person James   schedule 09.05.2017