Wie kann ein Modell in CARET angepasst werden, um ein zweistufiges PLS- [Classifer] -Klassifikationsmodell durchzuführen?
Diese Frage ist eine Fortsetzung des gleichen ThemasHier. Nachfolgend finden Sie ein minimales Arbeitsbeispiel aus diesem Buch:
Wehrens R. Chemometrics mit R multivariate Datenanalyse in den Naturwissenschaften und Life Sciences. 1. Auflage. Heidelberg; New York: Springer. 2011. (Seite 250).
Das Beispiel stammt aus diesem Buch und seiner VerpackungChemometricsWithR
. Es wurden einige Fallstricke bei der Modellierung mit Kreuzvalidierungstechniken aufgezeigt.
Das Ziel:
Eine kreuzvalidierte Methodik, die denselben Satz von wiederholten Lebensläufen verwendet, um eine bekannte Strategie von durchzuführenPLS
gefolgt vonLDA
oder Cousins wie logistische Regression, SVM, C5.0, CART, mit dem Geist voncaret
Paket. Daher würde PLS jedes Mal benötigt, bevor der wartende Klassifizierer aufgerufen wird, um PLS zu klassifizierenErgebnis Raum statt der Beobachtungen selbst. Der nächstgelegene Ansatz im Caret-Paket ist dabeiPCA
als Vorverarbeitungsschritt vor der Modellierung mit einem Klassifikator. Nachfolgend finden Sie eine PLS-LDA-Prozedur mit nur einer Kreuzvalidierung, um die Leistung des Klassifikators zu testen. Es gab keinen 10-fachen Lebenslauf oder eine Wiederholung. Der folgende Code wurde aus dem erwähnten Buch entnommen, aber mit einigen Korrekturen wird sonst ein Fehler ausgegeben:
library(ChemometricsWithR)
data(prostate)
prostate.clmat <- classvec2classmat(prostate.type) # convert Y to a dummy var
odd <- seq(1, length(prostate.type), by = 2) # training
even <- seq(2, length(prostate.type), by = 2) # holdout test
prostate.pls <- plsr(prostate.clmat ~ prostate, ncomp = 16, validation = "CV", subset=odd)
Xtst <- scale(prostate[even,], center = colMeans(prostate[odd,]), scale = apply(prostate[odd,],2,sd))
tst.scores <- Xtst %*% prostate.pls$projection # scores for the waiting trained LDA to test
prostate.ldapls <- lda(scores(prostate.pls)[,1:16],prostate.type[odd]) # LDA for scores
table(predict(prostate.ldapls, new = tst.scores[,1:16])$class, prostate.type[even])
predictionTest <- predict(prostate.ldapls, new = tst.scores[,1:16])$class)
library(caret)
confusionMatrix(data = predictionTest, reference= prostate.type[even]) # from caret
Ausgabe:
Confusion Matrix and Statistics
Reference
Prediction bph control pca
bph 4 1 9
control 1 35 7
pca 34 4 68
Overall Statistics
Accuracy : 0.6564
95% CI : (0.5781, 0.7289)
No Information Rate : 0.5153
P-Value [Acc > NIR] : 0.0001874
Kappa : 0.4072
Mcnemar's Test P-Value : 0.0015385
Statistics by Class:
Class: bph Class: control Class: pca
Sensitivity 0.10256 0.8750 0.8095
Specificity 0.91935 0.9350 0.5190
Pos Pred Value 0.28571 0.8140 0.6415
Neg Pred Value 0.76510 0.9583 0.7193
Prevalence 0.23926 0.2454 0.5153
Detection Rate 0.02454 0.2147 0.4172
Detection Prevalence 0.08589 0.2638 0.6503
Balanced Accuracy 0.51096 0.9050 0.6643
Die Verwirrungsmatrix stimmte jedoch nicht mit der im Buch überein, der Code im Buch brach jedoch, aber dieser hier funktionierte mit mir!
Anmerkungen:
Dies war zwar nur ein Lebenslauf, aber die Absicht ist, zunächst auf diese Methodik zu einigen,sd
undmean
der Zuggarnitur wurden auf die Testgarnitur angewendet, PLUS transformiert in PLS-Scores basierend auf einer bestimmten Anzahl von PCsncomp
. Ich möchte, dass dies in jeder Runde des Lebenslaufs im Caret geschieht. Wenn die Methodik als Code hier korrekt ist, kann sie als guter Anfang für ein minimales Arbeitsbeispiel dienen, während der Code des Caret-Pakets geändert wird.
Randnotizen:
Das Skalieren und Zentrieren kann sehr chaotisch sein. Ich denke, einige der PLS-Funktionen in R führen eine interne Skalierung mit oder ohne Zentrierung durch. Ich bin mir nicht sicher. Daher sollte beim Erstellen eines benutzerdefinierten Modells in Caret vorsichtig vorgegangen werden, um sowohl einen Mangel als auch eine Beeinträchtigung zu vermeiden mehrfache Skalierungen oder Zentrierungen (ich bin bei diesen Dingen auf der Hut).
Gefahren mehrfacher Zentrierung / Skalierung
Der folgende Code soll nur zeigen, wie die mehrfache Zentrierung / Skalierung die Daten ändern kann. Hier wird nur die Zentrierung gezeigt, aber das gleiche Problem mit der Skalierung gilt auch.
set.seed(1)
x <- rnorm(200, 2, 1)
xCentered1 <- scale(x, center=TRUE, scale=FALSE)
xCentered2 <- scale(xCentered1, center=TRUE, scale=FALSE)
xCentered3 <- scale(xCentered2, center=TRUE, scale=FALSE)
sapply (list(xNotCentered= x, xCentered1 = xCentered1, xCentered2 = xCentered2, xCentered3 = xCentered3), mean)
Ausgabe:
xNotCentered xCentered1 xCentered2 xCentered3
2.035540e+00 1.897798e-16 -5.603699e-18 -5.332377e-18
Bitte hinterlassen Sie einen Kommentar, wenn ich irgendwo in diesem Kurs etwas vermisse. Vielen Dank.