Como personalizar um modelo no CARET para executar o modelo de classificação em duas etapas PLS- [Classifer]?

Esta pergunta é uma continuação do mesmo threadaqui. Abaixo está um exemplo de trabalho mínimo retirado deste livro:

Wehrens R. Chemometrics com análise de dados multivariada R nas ciências naturais e ciências da vida. 1ª edição. Heidelberg; Nova York: Springer. 2011. (página 250).

O exemplo foi retirado deste livro e seu pacoteChemometricsWithR. Ele destacou algumas armadilhas ao modelar usando técnicas de validação cruzada.

O objetivo:
Uma metodologia validada cruzada usando o mesmo conjunto de CV repetido para executar uma estratégia conhecida dePLS seguido tipicamente porLDA primos como regressão logística, SVM, C5.0, CART, com o espírito decaret pacote. Portanto, o PLS seria necessário todas as vezes antes de chamar o classificador em espera para classificar o PLSPonto espaço em vez das próprias observações. A abordagem mais próxima no pacote de intercalação está fazendoPCA como uma etapa de pré-processamento antes da modelagem com qualquer classificador. Abaixo está um procedimento PLS-LDA com apenas uma validação cruzada para testar o desempenho do classificador, não houve CV 10 vezes ou qualquer repetição. O código abaixo foi retirado do livro mencionado, mas com algumas correções gera erro:

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

Resultado:

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

No entanto, a matriz de confusão não coincidiu com a do livro, de qualquer maneira o código do livro quebrou, mas este aqui funcionou comigo!

Notas:
Embora este fosse apenas um CV, mas a intenção é concordar com essa metodologia primeiro,sd emean do conjunto de trens foram aplicados no conjunto de testes, PLUS transformado em escores PLS com base em um número específico de PCncomp. Eu quero que isso ocorra a cada rodada do CV no cursor. Se a metodologia como código estiver correta aqui, ela poderá servir, como um bom começo para um exemplo de trabalho mínimo, enquanto modifica o código do pacote de interpolação.

Notas laterais:
Pode ser muito complicado com a escala e a centralização, acho que algumas das funções do PLS no R fazem a escala internamente, com ou sem centralização, não tenho certeza, portanto, a construção de um modelo personalizado em caret deve ser manuseada com cuidado para evitar a falta ou várias escalas ou centralizações (estou de guarda com essas coisas).

Perigos de várias centralizações / redimensionamentos
O código abaixo é apenas para mostrar como a centralização / escalonamento múltiplo pode alterar os dados, apenas a centralização é mostrada aqui, mas o mesmo problema com a escalabilidade também se aplica.

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)

Resultado:

xNotCentered    xCentered1    xCentered2    xCentered3 
 2.035540e+00  1.897798e-16 -5.603699e-18 -5.332377e-18

Deixe um comentário se estiver faltando algo em algum lugar deste curso. Obrigado.

questionAnswers(4)

yourAnswerToTheQuestion