这个问题是这里同一线程的延续。以下是本书中的一个最小工作示例:
Wehrens R. Chemometrics 在自然科学和生命科学中使用 R 多元数据分析。第 1 版。海德堡;纽约:斯普林格。2011 年。(第 250 页)。
该示例取自这本书及其包ChemometricsWithR
。它突出了使用交叉验证技术建模时的一些缺陷。
目标:
一种交叉验证的方法,使用相同的重复 CV 集执行PLS
通常遵循的已知策略,LDA
或类似逻辑回归、SVM、C5.0、CART 的表亲,具有caret
打包的精神。因此,每次调用等待分类器之前都需要 PLS,以便对 PLS分数空间进行分类,而不是对观察结果本身进行分类。caret 包中最接近的方法是在PCA
使用任何分类器建模之前作为预处理步骤。下面是一个 PLS-LDA 程序,只有一个交叉验证来测试分类器的性能,没有 10 倍 CV 或任何重复。下面的代码取自上述书中,但进行了一些更正,否则会引发错误:
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
输出:
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
但是,混淆矩阵与书中的不匹配,无论如何书中的代码确实坏了,但是这里的这个对我有用!
注:
虽然这只是一份 CV,但目的是先就这个方法达成一致,sd
并将mean
训练集应用到测试集上,PLUS 转化为基于特定 PC 数量的 PLS 分数ncomp
。我希望这发生在插入符号中的每一轮简历中。如果作为代码的方法在这里是正确的,那么它可以作为一个最小工作示例的良好开端,同时修改 caret 包的代码。
旁注:
缩放和居中可能会非常混乱,我认为 R 中的一些 PLS 函数在内部进行缩放,有或没有居中,我不确定,所以在插入符号中构建自定义模型时应小心避免缺少或多个缩放或居中(我对这些东西保持警惕)。
多重居中/缩放的危险
下面的代码只是为了展示多重居中/缩放如何改变数据,这里只显示了居中,但同样的问题也适用于缩放。
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)
输出:
xNotCentered xCentered1 xCentered2 xCentered3
2.035540e+00 1.897798e-16 -5.603699e-18 -5.332377e-18
如果我在本课程的某个地方遗漏了什么,请发表评论。谢谢。