Как выполнить обнаружение новизны с помощью 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, что вы можете видеть.

Другие вопросы по тегам