R Support Vector Machine с радиальным ядром классифицирует все изображения в одном классе
Я не смог найти ничего об этой ошибке, поэтому решил спросить:
Я обучаю SVM (векторную машину ужина) на наборе данных mnist, содержащем значения пикселей рукописных изображений в оттенках серого (1 значение на пиксель). Для этого я использую библиотеку e1071 в R. Существует три основных способа обучения SVM с использованием библиотеки e1071: "линейный", "радиальный" и "полиномиальный". Когда я попробовал "линейный", настроив функцию стоимости, я получил разумные результаты, на самом деле отличные результаты, я был очень им доволен. Но когда я пробую "радиальный" и прогнозирую на своем тестовом наборе данных, я получаю следующую матрицу путаницы:
Reference
Prediction 0 1 2 3 4 5 6 7 8 9
0 0 3621 0 0 0 0 0 0 0 0
1 0 4149 0 0 0 0 0 0 0 0
2 0 3666 0 0 0 0 0 0 0 0
3 0 3833 0 0 0 0 0 0 0 0
4 0 3593 0 0 0 0 0 0 0 0
5 0 3352 0 0 0 0 0 0 0 0
6 0 3648 0 0 0 0 0 0 0 0
7 0 3905 0 0 0 0 0 0 0 0
8 0 3568 0 0 0 0 0 0 0 0
9 0 3665 0 0 0 0 0 0 0 0
Я пытался повозиться с ним, и я пытался настроить его, но я не могу заставить его классифицировать любое изображение как что-либо, кроме 1, с использованием радиального ядра. Есть идеи, почему?
- Другие библиотеки там, потому что я работал над другими методами машинного обучения в то же время, я новичок в этой области и прохожу курс в университете, где используются все эти библиотеки, поэтому я не совсем уверен, какой из них можно выключить.
- Сокращенный набор данных - это просто исходный набор данных mnist, преобразованный в размер 14 на 14 пикселей вместо исходных 28 на 28 пикселей, чтобы я мог завершить задание до крайнего срока (завтра:P).
- Я прошу не заканчивать курс с проходной оценкой (я легко получаю это, используя линейную модель), а потому, что я не понимаю, что может вызвать эту странную ошибку.
Это мой код для линейной модели:
library(nnet)
library(caret)
library(plyr)
library(dplyr)
library(e1071)
library(OpenImageR)
library(glmnet)
set.seed(200)
mnist.dat <- read.csv("reduced.csv")
# Data preparation --------------------------------------------------------
#set minimum contrast by filtering pixels that average below a pre determined value
mnist.dat <- mnist.dat[, colSums(mnist.dat != 0) > 0]
#sample dataset into training, testing and validation datasets
index <- sample(nrow(mnist.dat), 5000)
samples <- mnist.dat[index, ]
last_test <- mnist.dat[-index, ]
samples$label <- as.factor(samples$label)
last_test$label <- as.factor(last_test$label)
label.index <- which(names(mnist.dat)=="label")
# svm, cost tuning, 5 folds -----------------------------------------------
mnist.svm.tune <- tune(
svm,
samples[,-label.index],
samples$label,
kernel = "linear",
ranges = list(cost=c(
1*10^-6:9
)
)
)
mnist.svm <- svm(
samples[,-label.index],
samples$label,
kernel = "linear",
scale = FALSE,
cross = 5,
cost = mnist.svm.tune[["best.parameters"]][["cost"]]
)
mnist.svm.cm <- confusionMatrix(
last_test[,label.index],
predict(
mnist.svm,
last_test[,-label.index]
)
)
Что дает гораздо более разумную матрицу путаницы:
Reference
Prediction 0 1 2 3 4 5 6 7 8 9
0 3514 0 13 1 12 25 20 3 26 7
1 0 4066 20 16 5 5 4 4 22 7
2 30 22 3264 40 67 15 57 65 87 19
3 18 22 83 3321 8 180 20 35 110 36
4 6 14 17 0 3334 4 33 15 11 159
5 30 43 26 112 43 2890 66 16 96 30
6 31 10 29 1 37 43 3481 0 16 0
7 13 39 52 6 55 18 2 3573 23 124
8 8 75 36 68 18 99 39 18 3142 65
9 15 24 15 46 171 21 0 116 40 3217
И это код, который я использовал для генерации SVM с радиальным ядром, которое создало матрицу путаницы в верхней части этого сообщения:
test.svm <- svm(samples$label ~ ., data = samples[,-174], kernel = "radial", gamma = 0.1, cost = 1)
Попробовал настроить:
test.svm.tune <- tune.svm(samples$label ~ ., data = samples[,-174], gamma = 10^(-5:-1), cost = 10^(-3:1))
Это привело к следующей ошибке:
Error in model.frame.default(formula, data) :
variable lengths differ (found for 'V7')
Это явно не тот случай, проверял вручную, V7 такой же длины, как и все остальные. Мне это кажется очевидным, поскольку линейная модель не вызвала такой ошибки.
Я попробовал еще раз, подумав, может, мне стоит указать радиальный:
test.svm.tune <- tune.svm(samples$label ~ ., data = samples[,-174], kernel = "radial", gamma = 10^(-5:-1), cost = 10^(-3:1))
Но я получаю ту же ошибку, логичную, потому что "радиальный" является настройкой по умолчанию. Если кто-нибудь сможет указать на то, что я делаю не так, это было бы огромной тяжестью, которую я не мог себе представить, так что заранее спасибо!