Как выполнить обнаружение новизны с помощью ksvm в R?
Я пытаюсь реализовать детектор новизны, используя библиотеку kernlab (функция ksvm) в R. Вот простой пример того, что я пытаюсь сделать:
# Training data
xxTrain <- matrix(rnorm(2000), nrow=1000, ncol=2, byrow=TRUE)
y <- rep(1,1000)
classifier <- ksvm(xxTrain, y, type="one-svc", kernel="rbfdot", kpar="automatic")
# Test data
x1 <- rnorm(1000)
scale <- c(rep(1,500), rep(10,100), rep(1,400))
x2 <- rnorm(1000)*scale
xxTest <- matrix(c(x1,x2), nrow=1000, ncol=2, byrow=TRUE)
# Prediction
p <- predict(classifier, xxTest, type="response")
# Visualization
plot(x2, type='l')
lines(x1, col="red")
points(5*as.integer(p), type='l', col="blue")
Рисунок выше - результат, который я получаю. Синяя кривая - это предсказание, и она четко показывает период, когда ее значение равняется 0. Но она не совпадает по времени или ширине с выбросом в черной трассе. Есть 100 точек (черная линия), которые имеют большую амплитуду, и вывод, который я получаю синим цветом, не совпадает с черной линией.
Что я делаю неправильно?
1 ответ
Вот что вы делаете неправильно:
xxTest <- matrix(c(x1,x2), nrow=1000, ncol=2, byrow=TRUE)
это должно быть
xxTest <- matrix(c(x1,x2), nrow=1000, ncol=2, byrow=F )
или лучше
xxTest <- cbind( x1, x2 )
или просто
p <- predict( classifier, cbind( x1, x2 ), type= "response" )
Результат (я использовал серый для x2):
Пояснение: по спецификации byrow=T
сначала вы брали элементы x1, чтобы заполнить первые 500 строк (альтернативно, столбцы 1 и 2), а затем x2, чтобы заполнить оставшиеся 500 строк xxTest
, Так как сингулярность была в пределах ~ 500 - 600 в x2, то она оказалась в обеих колонках xxTest
около (500+500)/2 - (500+600)/2, что составляет 750-800, что вы можете видеть.