Jak dostosować model w CARET do wykonania dwuetapowego modelu klasy PLS- [Classifer]?
To pytanie jest kontynuacją tego samego wątkututaj. Poniżej znajduje się minimalny przykład pracy zaczerpnięty z tej książki:
Wehrens R. Chemometrics z R wielowymiarową analizą danych w naukach przyrodniczych i naukach przyrodniczych. Pierwsza edycja. Heidelberg; Nowy Jork: Springer. 2011. (strona 250).
Przykład pochodzi z tej książki i jej pakietuChemometricsWithR
. Podkreślił pewne pułapki podczas modelowania za pomocą technik walidacji krzyżowej.
Cel:
Sprawdzona krzyżowo metodologia wykorzystująca ten sam zestaw powtarzających się CV do realizacji znanej strategiiPLS
zwykle poLDA
lub kuzynów, takich jak regresja logistyczna, SVM, C5.0, CART, z duchemcaret
pakiet. Zatem PLS byłby potrzebny za każdym razem przed wywołaniem oczekującego klasyfikatora w celu sklasyfikowania PLSwynik przestrzeń zamiast samych obserwacji. Najbliższe podejście w pakiecie karetki robiPCA
jako etap wstępnego przetwarzania przed modelowaniem za pomocą dowolnego klasyfikatora. Poniżej znajduje się procedura PLS-LDA z tylko jedną walidacją krzyżową do testowania wydajności klasyfikatora, nie było 10-krotnego CV ani żadnego powtórzenia. Poniższy kod pochodzi ze wspomnianej książki, ale z pewnymi poprawkami w przeciwnym razie pojawia się błąd:
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
Wydajność:
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
Jednak matryca zamieszania nie pasowała do tej w książce, zresztą kod w książce się zepsuł, ale ten tutaj działał ze mną!
Uwagi:
Chociaż było to tylko jedno CV, ale intencją jest najpierw uzgodnienie tej metodologii,sd
imean
zestawu pociągów zastosowano na zestawie testowym, PLUS przekształcono w wyniki PLS na podstawie określonej liczby komputerówncomp
. Chcę, aby miało to miejsce w każdej rundzie CV w karierze. Jeśli metodologia jako kod jest tutaj poprawna, może służyć, może być dobrym początkiem minimalnego przykładu pracy podczas modyfikowania kodu pakietu opieki.
Uwagi dodatkowe:
Skalowanie i centrowanie może być bardzo chaotyczne, myślę, że niektóre funkcje PLS w R wykonują skalowanie wewnętrzne, z centrowaniem lub bez, nie jestem pewien, więc budowanie niestandardowego modelu w karcie powinno być traktowane ostrożnie, aby uniknąć zarówno braku, jak i wiele skalowań lub centrowania (jestem z tymi strażnikami na moich strażnikach).
Niebezpieczeństwa wielokrotnego centrowania / skalowania
Poniższy kod służy jedynie do pokazania, jak wielowarstwowe centrowanie / skalowanie może zmienić dane, pokazane jest tu tylko centrowanie, ale również ten sam problem ze skalowaniem.
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)
Wydajność:
xNotCentered xCentered1 xCentered2 xCentered3
2.035540e+00 1.897798e-16 -5.603699e-18 -5.332377e-18
Upuść komentarz, jeśli czegoś brakuje mi na tym kursie. Dzięki.