Zum Hauptinhalt springen

Caret: ein Blumenstrauß an Funktionen für die prädiktive Modellbildung in R

R ist eine der populärsten Open-Source-Programmiersprachen für Predictive Analytics. Ihr großer Vorteil ist das Comprehensive R Archive Network (CRAN) mit über 10.000 Paketen für verschiedenste Modelllösungen. Ein Hindernis ihrer Anwendung besteht jedoch in der häufig paketspezifischen Syntax (im Gegensatz zu z. B. Python). Das Paket Caret versucht, durch ein einheitliches Interface auf verschiedene Trainings- und Vorhersagefunktionen den Modellierungsprozess zu vereinfachen. Durch seine Datenvorbereitungs-, Merkmalsselektions- und Modell-Tuning-Funktionalität erleichtert Caret die Bildung und Evaluierung von prädiktiven Modellen. Dieser Blogeintrag zeigt auf, wie wir mit Caret verschiedenen Herausforderungen des Modellierungsprozesses begegnen können, insbesondere bei der Selektion und dem Tuning von Modellen.

Selektion zwischen Modellen und innerhalb von Modellklassen

Es gibt keinen Goldstandard: Kein Modell ist jedem anderen Modell in jeder Situation überlegen. Aus diesem Grund müssen wir als Data Scientists unsere Modellwahl rechtfertigen. Wir selektieren zwischen verschiedenen Modellen, indem wir sie prüfen und ihre Performance miteinander vergleichen. Bei Parametern, die nicht durch den Optimierungsprozess bestimmt werden, verhält es sich analog: Wir entscheiden uns für ein Modell einer Klasse, indem wir die Prognosefähigkeit der Modelle für verschiedene Parameterwerte gegenüberstellen.

Mit Carets train-Funktion können wir schnell und einfach verschiedene Modelle prüfen. Dies zeigen wir exemplarisch anhand der Entwicklung eines prädiktiven Modells zur Schätzung des Zahlungsausfalls von Kreditkartenbesitzern, basierend auf persönlichen Informationen und ihrer Transaktionshistorie.[1]

Zur Selektion des geeigneten Verfahrens erstellen wir einen kleinen Trainingsdatensatz, prüfen unterschiedliche Modelle für verschiedene Resamples, vergleichen ihre Performance und verwenden das beste Modell für Vorhersagen.

Datenvorbereitung

Caret stellt einfache Funktionen zur Erstellung von ausgewogenen Stichproben zur Verfügung, wodurch die Verteilung der abhängigen Variable erhalten bleibt. Dieses Vorgehen ist ratsam, wenn seltene Ereignisse wie Ausfallwahrscheinlichkeiten modelliert werden.

library(caret)

set.seed(11)

# reading data and preparation
customer_data <- read.csv("credit_default_prepared.csv", sep = ";",stringsAsFactors = TRUE)

# data partition
rows_train <- createDataPartition(y = customer_data$DEFAULT, 
                                  p = 0.3, list = FALSE)
training <- customer_data[rows_train,  ]

Ein einfaches, aber bewährtes Modell für binäre Variablen ist die logistische Regression, die wir mit den beiden Ensemblemethoden Random Forest und Boosting vergleichen. Random Forests bewerten und aggregieren eine Reihe von Entscheidungsbäumen, die durch das zufällige Ziehen der Prädiktoren dekorreliert werden. Der ursprüngliche Boosting-Algorithmus aggregiert ebenfalls Klassifikationsbäume, bewertet sie jedoch sequentiell:

Zu Beginn erhält jede Beobachtung das gleiche Gewicht. Mit jeder Iteration steigt die Gewichtung der fehlklassifizierten Beobachtungen. In der folgenden Iteration wird diese Gewichtung verwendet, um die korrekte Prognose der fehlerhaften Vorhersagen zu forcieren. Die finale Aggregation gewichtet die einzelnen Entscheidungsbäume gemäß ihrer Genauigkeit.

Für beide Ensemblemethoden können wir Tuningparameter optimieren. Im Random-Forest-Modell betrachten wir lediglich die Anzahl der zu ziehenden Prädiktoren als Tuningparameter und erwägen Werte von 4 bis 14. Tabelle 1 beschreibt die Tuningparameter für unser Boosting-Modell:

 

Tuningparameter Boosting

Beschreibung

Betrachtete Werte

Interaction.depth

Anzahl
der Entscheidungsknoten

1, 2, 3

n.trees

Anzahl der Bäume

80, 100

shrinkage

Lernrate (Wie schnell
passen sich die Gewich-
tungen an?)

0,01, 0,1

n.minobsinnode

Minimale Anzahl der Be-
obachtungen im Blatt

10

 

Bestimmung des Suchrasters

Per Default verwendet train() ein minimales Suchraster aus drei Werten für jeden Tuningparameter. Mit Carets expand.grid-Funktion kann das kartesische Produkt der gewünschten Parameterwerte an die train-Funktion übergeben werden:

# parameter grid random forest
grid_rf <- expand.grid(mtry = 4:14)

# parameter grid boosting
grid_bo <- expand.grid(interaction.depth = 1:3,
                    n.trees = seq(80, 100, by = 20),
                    shrinkage = c(0.01, 0.1),
                    n.minobsinnode = 10)

Resampling-Techniken und Performancemaße

Ein Ansatz des Modelltunings beinhaltet das Bewerten der Modelle für unterschiedliche Parameterkonfigurationen auf vielen verschiedenen Resamples und die Modellauswahl auf Basis eines Performancemaßes.

Die Resample-Technik und das Performancemaß können mit der trainControl-Funktion festgelegt werden. Für unser Beispiel verwenden wir eine 5-fache Kreuzvalidierung und messen die Prognosegüte mit der Fläche unter der ROC-Kurve (die Default-Einstellung beinhaltet das Bootstrap-Verfahren und die Treffergenauigkeit):

ctrl <- trainControl(
  method = "cv",
  number = 5,
  summaryFunction = twoClassSummary,
  classProbs = TRUE
)

Modellbewertung

Der unten abgebildete Code zeigt, wie durch das Anpassen der Methode und des Rasters verschiedene Modelle mit train() bewerten werden können. Caret automatisiert die finale Parameterselektion und stellt mit „print(objekt_name)“ eine Übersicht der Bewertungsergebnisse zusammen, wobei „objekt_name“ der Rückgabewert der train-Funktion ist:

# random forest
set.seed(11)
fit_rf <- train(y ~.,
                data = training,
                method = "rf",
                ntrees = 5,
                metric = "ROC",
                trControl = ctrl,
                tuneGrid = grid_rf)

# boosting
set.seed(11)
fit_bo <- train(y ~.,
                data = training,
                method = "gbm",
                metric = "ROC",
                verbose = FALSE,
                trControl = ctrl,
                tuneGrid = grid_bo)

# performance plot random forest
plot(fit_rf, main = "Random forest ROC for several mtry values")

Die Plotfunktion veranschaulicht das Performanceprofil der Tuningparameter. Als Beispiel zeigt Abbildung 1 das Performanceprofil des Random Forests in Abhängigkeit der Anzahl der zu ziehenden Prädiktoren. Die zufällige Auswahl von 6 Prädiktoren an jedem Knoten führt zu dem Modell mit der höchsten ROC.

 

performance-profil-des-random-forests

 

Die Entwicklung eines guten logistischen Regressionsmodells benötigt viel Aufwand bei der Merkmalsextraktion und -selektion. An dieser Stelle verkürzen wir diesen Prozess, indem wir einfach die jeweils fünf wichtigsten Prädiktoren der Ensemblemethode verwenden:

# logistic regression: variable selection

top_n <- function(x, n = 5){

  x <- varImp(x)

  row.names(x$importance)[order(x$importance, decreasing = TRUE)][1:n]

}

lg_par <- unique(as.vector(unique(sapply(list(fit_bo,fit_rf), top_n))))

mt <- model.matrix(~.,data = training)[,lg_par]

# logistic regression
set.seed(11)
fit_lr <- train(mt, training$DEFAULT,
                method = "glm",
                family = binomial,
                metric = "ROC",
                trControl = ctrl)

Modellvergleich

Durch diese wenigen Zeilen Code haben wir insgesamt 120 Modelle bewertet und können jetzt die Performanceverteilung vergleichen. Zu diesem Zweck verwenden wir die resamples-Funktion, mit der wir die Resampling-Ergebnisse sammeln, analysieren und visualisieren können. Abbildung 2 fasst die Performanceverteilung der optimalen Modelle für die Testmengen der Kreuzvalidierung zusammen. Boosting und Random Forest übertreffen dabei das logistische Regressionsmodell. Beide Ensemblemethoden schneiden vergleichbar ab, die Varianz des Boosting-Modells erscheint jedoch geringer. Für unser Beispiel übertrifft der Performancedurchschnitt des Boosting-Modells (ROC: 0,7807) den Durchschnitt des Random-Forest-Modells knapp (ROC:  0,7802).

 

performanceverteilung-fuer-die-kreuzvalidierung

# Model comparison
comp <- resamples(list(Logistic = fit_lr, RandomForest = fit_rf, Boosting = fit_bo))
summary(comp)

# plot performance comparison
bwplot(comp, metric="ROC", main = "Model Comparison: RF vs Boosting vs LR")

Gefahren bei automatisierten Auswertungen

Ein starkes Argument für die Verwendung von Caret ist, dass es den Modellierungsprozess automatisiert und optimiert, wodurch man sich auf wichtigere Modellierungsfragen konzentrieren kann: Welche Modelle sind für die Problemstellung geeignet? Was ist das passende Performancemaß? Welcher Parameterraum sollte im Tuningprozess berücksichtigt werden? Caret vereinfacht die Modellbildung und -selektion signifikant, entbindet aber nicht vom weiteren Nachdenken:

  • Es sollten nicht einfach irgendwelche Modelle und Parameterräume betrachtet werden, sondern die richtigen.
  • Und vor allem: Das Feature-Engineering ist wesentliche Voraussetzung der Modellbildung und muss an die jeweiligen Modelle angepasst werden.

[1] Der Datensatz stammt aus Yeh, I. C., & Lien, C. H. (2009). The comparisons of data mining techniques for the predictive accuracy of probability of default of credit card clients. Expert Systems with Applications, 36(2), 2473-2480ll. (http://archive.ics.uci.edu/ml/datasets/default+of+credit+card+clients). Für die präparierte Version des Datensatzes kontaktieren Sie bitte christoph.hoffmann@btelligent.com.

Dr. Sebastian Petry
Dein Ansprechpartner
Dr. Sebastian Petry
Competence Center Leiter
Sebastian erobert als Datanaut mit Data Science und AI unentdeckte Potentiale in den unendlichen Weiten der Datenuniversen - ein Mission lautet „Use Case First - AI Second“. Er identifiziert Use Cases in unterschiedlichen Themenfeldern, entwirft nachhaltige Konzepte und Strategien und unterstützt bei der Umsetzung. Er ist davon überzeugt, das Data Science und KI für jedes Unternehmen Innovationstreiber ist und umsetzbar ist.
#KI #UseCaseFirstAISecond #Datanautic