Я создал SVM в R с использованием пакета kernlab, однако он работает невероятно медленно (20 000 прогнозов занимают ~ 45 секунд при распространении win64 R).Процессор работает на 25%, а использование оперативной памяти составляет всего 17% ... это не узкое место оборудования.Аналогичные вычисления с использованием алгоритмов интеллектуального анализа данных в службах анализа SQL Server выполняются примерно в 40 раз быстрее.
Методом проб и ошибок мы обнаружили, что ядро лапласедота дает нам лучшие результаты с большим отрывом.Rbfdot примерно на 15% менее точен, но в два раза быстрее (но все еще слишком медленный).Лучшее выступление - ваниль.Он запускается более или менее мгновенно, но точность слишком низкая, чтобы его использовать.
В идеале мы хотели бы использовать ядро лапласедот, но для этого нам нужно значительное ускорение.У кого-нибудь есть идеи как это сделать?
Вот некоторая информация о профилировании, которую я сгенерировал с помощью rprof.Похоже, что большую часть времени проводят в математических вызовах низкого уровня (остальная часть профиля состоит из данных, подобных строкам 16-40).Это должно выполняться очень быстро, но похоже, что код просто не оптимизирован (и я не знаю, с чего начать).
http://pastebin.com/yVPC66Be
Редактировать : пример кода для воспроизведения:
dummy.length = 20000;
source.data = as.matrix(cbind(sample(1:dummy.length)/1300, sample(1:dummy.length)/1900))
colnames(source.data) <- c("column1", "column2")
y.value = as.matrix((sample(1:dummy.length) + 9) / 923)
model <- ksvm(source.data[,], y.value, type="eps-svr", kernel="laplacedot",C=1, kpar=list(sigma=3));
Исходные данные имеют 7 числовых столбцов (с плавающей запятой) и 20 000строк.Это займет около 2-3 минут, чтобы тренироваться.Следующий вызов генерирует прогнозы и последовательно занимает 40 секунд:
predictions <- predict(model, source.data)
Edit 2: Ядро Laplacedot вычисляет точечное произведение двух векторов, используя следующую формулу.Это довольно близко соответствует профр продукции.Как ни странно, отрицательный символ (непосредственно перед функцией округления) потребляет около 50% времени выполнения.
return(exp(-sigma * sqrt(-(round(2 * crossprod(x, y) - crossprod(x,x) - crossprod(y,y), 9)))))
Редактировать 3: Добавлен пример кода для воспроизведения - это дает мне примерно то же время выполнения, что и мойфактические данные.