Построение ROC для машины опорных векторов

#r #svm #roc

#r #svm #ОКР

Вопрос:

Я пытаюсь построить ROC для svm, следуя одному из примеровhttps://rpubs.com/JanpuHou/359286 , но я продолжаю получать ошибку в моей последней строке кода: вот заголовок моего набора данных head (данные)

 growth LogSales Age    LogTA CoAge CoAge2 Reg DigMkt
1     No 15.87283  45 15.32751     8     64   0      1
2    Yes 16.05044  44 15.27176     7     49   0      1
3    Yes 15.36307  32 15.20180     3      9   1      0
4    Yes 15.09644  31 14.97866     2      4   1      0
5    Yes 16.90655  59 16.58810    11    121   1      0
6    Yes 16.45457  58 15.95558    10    100   1      0
  

Мой код:

 split = sample.split(data, SplitRatio = 0.70)
training = subset(data, split==T)
testing = subset(data, split==F)

###Making growth last to allow for variable importnce


###Fitting model
svm_Lin = svm(growth~., data = training,
              kernel = "linear", cost =1, scale = T,
              probability = TRUE)

##Prediction
pred = predict(svm_Lin, testing)
table(predict = pred, truth = testing$growth)
confusionMatrix(table(pred, testing$growth))
###ROC Curve
library(ROCR)
p<- predict(svm_Lin,testing, type="decision")
pr<-prediction(p, testing$growth)
pref <- performance(pr, "tpr", "fpr")
plot(pref)
  

Когда я запускаю эту строку: pr<-prediction(p, testing$growth) я получаю следующее сообщение об ошибке

 Error: Format of predictions is invalid. It couldn't be coerced to a list.
  

Приветствуется любая помощь в решении этой проблемы.

Комментарии:

1. Проверьте ?ROCR::prediction , как должны быть отформатированы входные данные. Трудно сказать, что predict.svm отсюда вытекает, но, похоже, это в неправильном формате.

2. Спасибо, попытался отформатировать и, похоже, я все еще не выигрываю.

Ответ №1:

Я бы предложил следующий подход. Основная проблема, с которой вы столкнулись, заключается в том, что прогнозы из svm имели фактор типа, тогда ROCR функции не могут их сравнивать. Я внесу небольшую модификацию для вашей проблемы. У вас есть двоичные данные, поэтому вы можете работать с целевой переменной как с коэффициентом двух уровней. Затем в части ROCR вы должны преобразовать коэффициент в числовые значения. Таким образом, ваш код будет работать.

Кроме того, метод выборки из caTools пакета выдавал NA . Итак, я добавил аналогичный подход, используя rsample package. Вот код.

 library(ROCR)
library(e1071)
library(rsample)
#Data
data <- structure(list(growth = c("Yes", "Yes", "Yes", "Yes", "Yes", 
"Yes", "Yes", "Yes", "Yes", "Yes", "No", "No", "Yes", "Yes", 
"Yes", "Yes", "Yes", "Yes", "No", "No"), LogSales = c(15.36307, 
15.36307, 16.05044, 16.45457, 16.90655, 16.05044, 16.05044, 16.45457, 
16.05044, 16.90655, 15.87283, 15.87283, 16.90655, 16.45457, 16.90655, 
16.90655, 16.05044, 16.05044, 15.87283, 15.87283), Age = c(32L, 
32L, 44L, 58L, 59L, 44L, 44L, 58L, 44L, 59L, 45L, 45L, 59L, 58L, 
59L, 59L, 44L, 44L, 45L, 45L), LogTA = c(15.2018, 15.2018, 15.27176, 
15.95558, 16.5881, 15.27176, 15.27176, 15.95558, 15.27176, 16.5881, 
15.32751, 15.32751, 16.5881, 15.95558, 16.5881, 16.5881, 15.27176, 
15.27176, 15.32751, 15.32751), CoAge = c(3L, 3L, 7L, 10L, 11L, 
7L, 7L, 10L, 7L, 11L, 8L, 8L, 11L, 10L, 11L, 11L, 7L, 7L, 8L, 
8L), CoAge2 = c(9L, 9L, 49L, 100L, 121L, 49L, 49L, 100L, 49L, 
121L, 64L, 64L, 121L, 100L, 121L, 121L, 49L, 49L, 64L, 64L), 
    Reg = c(1L, 1L, 0L, 1L, 1L, 0L, 0L, 1L, 0L, 1L, 0L, 0L, 1L, 
    1L, 1L, 1L, 0L, 0L, 0L, 0L), DigMkt = c(0L, 0L, 1L, 0L, 0L, 
    1L, 1L, 0L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L
    )), row.names = c("3", "3.1", "2", "6", "5", "2.1", "2.2", 
"6.1", "2.3", "5.1", "1", "1.1", "5.2", "6.2", "5.3", "5.4", 
"2.4", "2.5", "1.2", "1.3"), class = "data.frame")
  

Теперь мы форматируем целевую переменную:

 #Format objective var to have a factor
data$growth[data$growth=='No']<-0
data$growth[data$growth=='Yes']<-1
data$growth <- factor(data$growth,levels = c(0,1),labels = c(0,1))
  

Метод разделения из rsample :

 #Split
split <- initial_split(data, prop = 0.7,
                       strata = 'growth')
#Create training and test set
training <- training(split)
testing <- testing(split)
  

Мы подходим к модели:

 ###Fitting model
svm_Lin = svm(growth~., data = training,
              kernel = "linear", cost =1, scale = T,
              probability = TRUE,type="C-classification")
  

Мы делаем прогнозы на тестовом наборе:

 ###Predict for ROC Curve
testing$p <- predict(svm_Lin,testing, type="response")
  

Теперь мы форматируем выходные переменные и готовимся к ROCR функциям:

Поскольку коэффициент начинается с 1, класс number 1 имеет значения 2, а класс number 0 имеет значения 1. Вы можете преобразовать в 0-1, сделав его числовым и вычитая 1.

 #Format variables
testing$growth <- as.numeric(testing$growth)-1
testing$p <- as.numeric(testing$p)-1
  

Наконец, мы строим ROC-кривую:

 #Build ROCR scheme
pr<-prediction(testing$p, testing$growth)
pref <- performance(pr, "tpr", "fpr")
plot(pref)
  

Вывод:

введите описание изображения здесь

Комментарии:

1. И это делает свое дело, большое спасибо. Теперь все отсортировано

2. @hzhou Отлично! Если вы считаете, что этот ответ был полезным, вы можете принять его, нажав на галочку в левой части этого ответа 🙂