2016-04-19 3 views
1

Ich möchte mit R-Caret (cf. this example) die Subjekt-out-Kreuzvalidierung durchführen, aber nur eine Teilmenge der Daten im Training verwenden, um CV-Modelle zu erstellen. Dennoch sollte die ausgelassene CV-Partition als Ganzes verwendet werden, da ich alle Daten eines ausgeschlossenen Subjekts testen muss (egal, ob es Millionen von Samples gibt, die aufgrund von Berechnungseinschränkungen nicht im Training verwendet werden können).R caret: Lassen Sie das Subjekt aus der Kreuzvalidierung mit der Datenuntermenge für das Training aus?

Ich habe ein minimal 2 Klasse Klassifizierung Beispiel erstellt die subset und index Parameter von caret::train und caret::trainControl dies zu erreichen, verwenden. Aus meiner Beobachtung sollte dies das Problem lösen, aber ich habe es wirklich schwer sicherzustellen, dass die Auswertung immer noch in einem Leave-Subject-Out-Weg erfolgt. Vielleicht hat jemand mit Erfahrung in dieser Aufgabe auf das etwas Licht könnte:

library(plyr) 
library(caret) 
library(pROC) 
library(ggplot2) 

# with diamonds we want to predict cut and look at results for different colors = subjects 
d <- diamonds 
d <- d[d$cut %in% c('Premium', 'Ideal'),] # make a 2 class problem 
d$cut <- factor(d$cut) 
indexes_data <- c(1,5,6,8:10) 
indexes_labels <- 2 

# population independent CV indexes for trainControl 
index <- llply(unique(d[,3]), function(cls) c(which(d[,3]!=cls))) 
names(index) <- paste0('sub_', unique(d[,3])) 
str(index) # indexes used for training models with CV = OK 

m3 <- train(x = d[,indexes_data], 
      y = d[,indexes_labels], 
      method = 'glm', 
      metric = 'ROC', 
      subset = sample(nrow(d), 5000), # does this subset the data used for training and obtaining models, but not the left out partition used for estimating CV performance? 
      trControl = trainControl(returnResamp = 'final', 
            savePredictions = T, 
            classProbs = T, 
            summaryFunction = twoClassSummary, 
            index = index)) 
str(m3$resample) # all samples used once = OK 

# performance over all subjects 
myRoc <- roc(predictor = m3$pred[,3], response = m3$pred$obs) 

Grundstück (myRoc, main = 'all')

Leistung für einzelne Fächer

l_ply (unique (m3 $ pred $ Resample), .fun = Funktion (cls) { pred_sub < - m3 $ pred [m3 $ pred $ Resample == cls,] myRoc < - roc (Vorhersage = pred_sub [, 3], Antwort = pred_sub $ obs) Grundstück (myRoc, Haupt = cls) })

Danke für Ihre Zeit!

Antwort

1

Verwendung sowohl die index und indexOut Parameter in caret::trainControl zugleich scheinen (für den Hinweis in this question dank Max) den Trick zu tun. Hier ist der aktualisierte Code:

library(plyr) 
library(caret) 
library(pROC) 
library(ggplot2) 
str(diamonds) 

# with diamonds we want to predict cut and look at results for different colors = subjects 
d <- diamonds 
d <- d[d$cut %in% c('Premium', 'Ideal'),] # make a 2 class problem 
d$cut <- factor(d$cut) 
indexes_data <- c(1,5,6,8:10) 
indexes_labels <- 2 

# population independent CV partitions for training and left out partitions for evaluation 
indexes_populationIndependence_subjects <- 3 
index <- llply(unique(d[,indexes_populationIndependence_subjects]), function(cls) c(which(d[,indexes_populationIndependence_subjects]!=cls))) 
names(index) <- paste0('sub_', unique(d[,indexes_populationIndependence_subjects])) 
indexOut <- llply(index, function(part) (1:nrow(d))[-part]) 
names(indexOut) <- paste0('sub_', unique(d[,indexes_populationIndependence_subjects])) 
# subsample partitions for training 
index <- llply(index, function(i) sample(i, 1000)) 

m3 <- train(x = d[,indexes_data], 
      y = d[,indexes_labels], 
      method = 'glm', 
      metric = 'ROC', 
      trControl = trainControl(returnResamp = 'final', 
            savePredictions = T, 
            classProbs = T, 
            summaryFunction = twoClassSummary, 
            index = index, 
            indexOut = indexOut)) 
m3$resample # seems OK 
str(m3$pred) # seems OK 
myRoc <- roc(predictor = m3$pred[,3], response = m3$pred$obs) 
plot(myRoc, main = 'all') 
# analyze results per subject 
l_ply(unique(m3$pred$Resample), .fun = function(cls) { 
    pred_sub <- m3$pred[m3$pred$Resample==cls,] 
    myRoc <- roc(predictor = pred_sub[,3], response = pred_sub$obs) 
    plot(myRoc, main = cls) 
}) 

Trotzdem bin ich nicht absolut sicher, ob dies tatsächlich tut die Schätzung in einer Population unabhängige Art und Weise, also wenn jemand Wissen über die Details hat bitte teilen Sie Ihre Meinung!

Verwandte Themen