Если вы подумаете о том, как машина опорных векторов может "использовать" матрицу ядра, вы увидите, что на самом деле вы не можете сделать это так, как вы пытаетесь (как вы видели :-)
Я действительно немного боролся с этим, когда впервые использовал kernlab + матрицу ядра ... по совпадению, это было также для ядер графов!
В любом случае, давайте сначала поймем, что, поскольку SVM не знает, как вычислить вашу функцию ядра, ему необходимо, чтобы эти значения уже были рассчитаны между вашими новыми (тестовыми) примерами и примерами, которые он выбирает в качестве опорных векторов на этапе обучения. .
Итак, вам нужно вычислить матрицу ядра для всех ваших примеров вместе. Позже вы потренируетесь на некоторых и протестируете другие, удалив строки + столбцы из матрицы ядра, когда это необходимо. Позвольте показать вам код.
Мы можем использовать пример кода в ksvm
документации, чтобы загрузить в нашу рабочую область некоторые данные:
library(kernlab)
example(ksvm)
Вам нужно будет нажать return несколько (2) раз, чтобы графики отрисовывались и пример закончился, но теперь у вас должна быть матрица ядра в вашем рабочем пространстве с именем K
. Нам нужно будет восстановить вектор y
, который он должен использовать для своих меток (поскольку он был вытоптан другим кодом в примере):
y <- matrix(c(rep(1,60),rep(-1,60)))
Теперь выберите набор примеров для тестирования.
holdout <- sample(1:ncol(K), 10)
С этого момента я собираюсь:
- Создайте матрицу обучающего ядра с именем
trainK
из исходной матрицы ядра K
.
- Создайте модель SVM из моего обучающего набора
trainK
- Используйте векторы поддержки, найденные в модели, чтобы создать матрицу ядра тестирования
testK
... это странная часть. Если вы посмотрите на код в kernlab
, чтобы увидеть, как он использует индексы опорных векторов, вы поймете, почему это делается именно так. Возможно, можно было бы сделать это другим способом, но я не видел документации / примеров по прогнозированию с помощью матрицы ядра, поэтому я делаю это здесь «сложным путем».
- Используйте SVM для прогнозирования этих функций и точности отчетов
Вот код:
trainK <- as.kernelMatrix(K[-holdout,-holdout]) # 1
m <- ksvm(trainK, y[-holdout], kernel='matrix') # 2
testK <- as.kernelMatrix(K[holdout, -holdout][,SVindex(m), drop=F]) # 3
preds <- predict(m, testK) # 4
sum(sign(preds) == sign(y[holdout])) / length(holdout) # == 1 (perfect!)
Это должно было сделать это. Удачи!
Ответы на комментарий ниже
что означает K [-holdout, -holdout]? (что означает "-"?)
Представьте, что у вас есть вектор x
, и вы хотите извлечь из него элементы 1, 3 и 5, вы бы сделали:
x.sub <- x[c(1,3,5)]
Если вы хотите получить все из x
кроме элементов 1, 3 и 5, вы должны:
x.sub <- x[-c(1,3,5)]
Таким образом, K[-holdout,-holdout]
возвращает все строки и столбцы K
кроме строк, которые мы хотим удерживать.
Каковы аргументы вашего as.kernelMatrix - особенно аргумент [, SVindex (m), drop = F] (что особенно странно, потому что похоже, что вся скобка является матричным индексом K?)
Да, я объединил две команды в одну:
testK <- as.kernelMatrix(K[holdout, -holdout][,SVindex(m), drop=F])
Теперь, когда вы обучили модель, вы хотите дать ей новую матрицу ядра с примерами тестирования. K[holdout,]
предоставит вам только строки, соответствующие примерам обучения в K
, и все столбцы K
.
SVindex(m)
дает вам индексы ваших опорных векторов из вашей исходной обучающей матрицы - помните, что эти строки / столбцы были holdout
удалены. Итак, чтобы индексы этих столбцов были правильными (т.е. ссылались на правильный столбец sv), я должен сначала удалить holdout
столбцов.
Во всяком случае, возможно, это более ясно:
testK <- K[holdout, -holdout]
testK <- testK[,SVindex(m), drop=FALSE]
Теперь testK
имеет только строки наших примеров тестирования и столбцы, которые соответствуют векторам поддержки. testK[1,1]
будет иметь значение функции ядра, вычисленное между вашим первым тестовым примером и первым вектором поддержки. testK[1,2]
будет иметь значение функции ядра между вашим 1-м тестовым примером и вторым вектором поддержки и т. Д.
Обновление (30 января 2014 г.), чтобы ответить на комментарий от @wrahool
Прошло много времени с тех пор, как я играл с этим, поэтому подробные сведения о kernlab::ksvm
немного заржавели, но в принципе это должно быть правильно :-) ... вот:
в чем смысл testK <- K[holdout, -holdout]
- разве вы не удаляете столбцы, соответствующие набору тестов?
да. Короткий ответ заключается в том, что если вы хотите predict
использовать матрицу ядра, вы должны предоставить матрицу размером rows
на support vectors
. Для каждой строки матрицы (новый пример, который вы хотите спрогнозировать) значения в столбцах - это просто значение матрицы ядра, оцененное между этим примером и вектором поддержки.
Вызов SVindex(m)
возвращает индекс векторов поддержки, заданный в измерении исходных данных обучения.
Итак, сначала выполнение testK <- K[holdout, -holdout]
дает мне testK
матрицу со строками примеров, которые я хочу предсказать, а столбцы взяты из тех же примеров (измерения), на которых была обучена модель.
Далее я делю подгруппы столбцов testK
на SVindex(m)
, чтобы получить только те столбцы, которые (сейчас) соответствуют моим векторам поддержки. Если бы я не сделал первый [, -holdout]
выбор, индексы, возвращаемые SVindex(m)
, могут не соответствовать правильным примерам (если все N
ваших тестовых примеров не являются последними N
столбцами вашей матрицы).
Кроме того, что именно делает условие drop = FALSE?
Это немного защитное кодирование, чтобы гарантировать, что после выполнения операции индексирования возвращаемый объект будет того же типа, что и объект, который был проиндексирован.
В R, если вы индексируете только одно измерение 2D (или более высокого (?)) Объекта, вам возвращается объект более низкого измерения. Я не хочу передавать numeric
вектор в predict
, потому что он хочет иметь matrix
Например
x <- matrix(rnorm(50), nrow=10)
class(x)
[1] "matrix"
dim(x)
[1] 10 5
y <- x[, 1]
class(y)
[1] "numeric"
dim(y)
NULL
То же самое будет с data.frame
s и т. Д.
person
Steve Lianoglou
schedule
18.11.2009