如何在CARET中自定义模型来执行PLS-[Classifier]两步分类模型?

2024-03-29

这个问题是同一线程的延续here https://stats.stackexchange.com/questions/81727/what-is-the-best-strategy-to-train-and-validate-classification-using-pls-classi。下面是从本书中摘取的一个最小的工作示例:

Wehrens R. 化学计量学与 R 多变量数据分析 自然科学和生命科学。第一版。海德堡;纽约: 施普林格。 2011 年。(第 250 页)。

该示例取自本书及其包ChemometricsWithR。它强调了使用交叉验证技术建模时的一些陷阱。

The Aim:
使用同一组重复 CV 来执行已知策略的交叉验证方法PLS通常紧随其后的是LDA或者类似逻​​辑回归、SVM、C5.0、CART 的精神caret包裹。所以每次调用等待分类器之前都需要PLS来对PLS进行分类score空间而不是观察本身。插入符包中最近的方法是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

然而,混淆矩阵与书中的不匹配,无论如何,书中的代码确实被破坏了,但这里的这个对我有用!

Notes:
虽然这只是一份简历,但其目的是首先就这个方法论达成一致,sd and mean将训练集的数据应用于测试集,PLUS根据特定数量的PC转化为PLS分数ncomp。我希望这种情况在插入符号中的每一轮简历中都发生。如果代码方法在这里是正确的,那么它可以作为修改插入符包的代码时的最小工作示例的良好开端。

附注:
缩放和居中可能会非常混乱,我认为 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

如果我在本课程中遗漏了某些内容,请发表评论。谢谢。


如果您想将这些类型的模型与caret,您需要使用 CRAN 上的最新版本。创建最后一个更新是为了让人们可以使用非标型号 http://topepo.github.io/caret/custom_models.html他们认为合适的。

我下面的方法是联合拟合 PLS 和其他模型(我在下面的示例中使用随机森林)并同时调整它们。因此,对于每次折叠,都有一个 2D 网格ncomp and mtry用来。

“技巧”是将 PLS 载荷附加到随机森林对象,以便可以在预测期间使用它们。这是定义模型的代码(仅分类):

 modelInfo <- list(label = "PLS-RF",
              library = c("pls", "randomForest"),
              type = "Classification",
              parameters = data.frame(parameter = c('ncomp', 'mtry'),
                                      class = c("numeric", 'numeric'),
                                      label = c('#Components', 
                                                '#Randomly Selected Predictors')),
              grid = function(x, y, len = NULL) {
                grid <- expand.grid(ncomp = seq(1, min(ncol(x) - 1, len), by = 1),
                            mtry = 1:len)
                grid <- subset(grid, mtry <= ncomp)
                },
              loop = NULL,
              fit = function(x, y, wts, param, lev, last, classProbs, ...) { 
                     ## First fit the pls model, generate the training set scores,
                     ## then attach what is needed to the random forest object to 
                     ## be used later
                     pre <- plsda(x, y, ncomp = param$ncomp)
                     scores <- pls:::predict.mvr(pre, x, type = "scores")
                     mod <- randomForest(scores, y, mtry = param$mtry, ...)
                     mod$projection <- pre$projection
                     mod
                   },
                   predict = function(modelFit, newdata, submodels = NULL) {       
                     scores <- as.matrix(newdata)  %*% modelFit$projection
                     predict(modelFit, scores)
                   },
                   prob = NULL,
                   varImp = NULL,
                   predictors = function(x, ...) rownames(x$projection),
                   levels = function(x) x$obsLevels,
                   sort = function(x) x[order(x[,1]),])

这是调用train:

 library(ChemometricsWithR)
 data(prostate)

 set.seed(1)
 inTrain <- createDataPartition(prostate.type, p = .90)
 trainX <-prostate[inTrain[[1]], ]
 trainY <- prostate.type[inTrain[[1]]]
 testX <-prostate[-inTrain[[1]], ]
 testY <- prostate.type[-inTrain[[1]]]

 ## These will take a while for these data
 set.seed(2)
 plsrf <- train(trainX, trainY, method = modelInfo,
                preProc = c("center", "scale"),
                tuneLength = 10,
                trControl = trainControl(method = "repeatedcv",
                                         repeats = 5))

 ## How does random forest do on its own?
 set.seed(2)
 rfOnly <- train(trainX, trainY, method = "rf",
                tuneLength = 10,
                trControl = trainControl(method = "repeatedcv",
                                         repeats = 5))

只是为了好玩,我得到了:

 > getTrainPerf(plsrf)
   TrainAccuracy TrainKappa method
 1     0.7940423    0.65879 custom
 > getTrainPerf(rfOnly)
   TrainAccuracy TrainKappa method
 1     0.7794082  0.6205322     rf

and

 > postResample(predict(plsrf, testX), testY)
  Accuracy     Kappa 
 0.7741935 0.6226087 
 > postResample(predict(rfOnly, testX), testY)
  Accuracy     Kappa 
 0.9032258 0.8353982 

Max

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在CARET中自定义模型来执行PLS-[Classifier]两步分类模型? 的相关文章

随机推荐

  • 如何 git svn 仅获取具有特定模式的分支/标签?

    我想使用 git svn 查看 Boost 库 并且只想查看从版本 1 35 开始的主干和标签 即 tags release Boost 1 35 及更高版本 我的配置如下 svn remote svn ignore paths tags
  • MonoTouch.Dialog:UISearchBar 颜色

    在 3 月 31 日发布的 MonoTouch Dialog 中 我们无法设置UISearchBar现在不再这样了 因为有一个带有硬编码颜色的新容器对象 有没有更简单的方法来改变颜色UISearchBar 作为解决方法 我使用它 知道 UI
  • 无法更改样式:使用 getelementsbyclassname 显示

    document getElementByClassName xyz style display none 我无法隐藏课程内容 document getElementsByClassName返回一个类似数组的对象 您可以为此使用以下脚本 d
  • 如何减少Flutter的build_runner构建时间

    我的项目变得非常大 每次运行 build runner 都会花费太多时间来构建 我减少构建时间的想法是仅构建实际需要构建的文件 这些文件是我当前功能目录的文件 有没有办法只为单个文件夹或单个文件运行 build runner 您可以在 bu
  • Android 中的语音通话录音应用

    我想做一个录音通话的应用程序 可以吗 我期待 Android 领域经验丰富的人提供一些适当的指导 我在android中看到了android media MediaRecorder类 我需要使用那个类吗 感谢致敬 帕瓦蒂 卡玛隆 抱歉 开发人
  • 右值到左值转换 Visual Studio

    在 Visual Studio 2012RC 中存在一些非标准扩展 例如这段代码编译 include
  • Puppeteer:从使用延迟加载的页面中抓取整个 html

    我正在尝试获取使用延迟加载的网页上的整个 html 我尝试过的是一直滚动到底部 然后使用 page content 我还尝试在滚动到底部后滚动回页面顶部 然后使用 page content 两种方法都会抓取表格的一些行 但不是全部 这是我的
  • ActionBar.Tab 类型已弃用

    我正在尝试在 Eclipse 中创建滑动选项卡 但是当我导入时android app ActionBar Tab 它警告我导入 ActionBar Tab 类型已弃用 它使我的大部分代码成为警告并删除它 import android sup
  • 当浏览器忙于执行一些长时间运行的 JavaScript 时,WebDriver API 阻塞行为

    我在文档中的某个地方读到 WebDriver API 是非阻塞的 除了一些像 driver get 的 API 因此 执行 WebElement click 或 isDisplayed 通常应该是异步的 当然 假设启用了本机事件 我有一个简
  • Django:渲染快捷函数中的 context_instance 参数有什么用?

    有关 渲染 快捷方式的文档 https docs djangoproject com en 1 3 topics http shortcuts render 根据上面的链接 上下文实例参数定义为 用于渲染模板的上下文实例 默认情况下 模板将
  • 查找张量中沿轴的非零元素的数量

    我想找到沿特定轴的张量中非零元素的数量 有没有 PyTorch 函数可以做到这一点 我尝试使用非零 http pytorch org docs master torch html highlight nonzero torch nonzer
  • NSMutableArray 在 iPhone 应用程序中使用 NSLog 时不显示实际值

    我正在做一个数组的 NSLog 但它显示以下值而不是数据 我不知道如何解决这个问题并从数组中获取值 if surveyQuestions surveyQuestions NSMutableArray alloc init Total Sur
  • pandas 中没有“from_csv”方法

    当我尝试使用时from csvpython 3 7 中的方法 我收到归因错误 import pandas as pd pd DataFrame from csv adr AttributeError type object DataFram
  • 从javascript中的日期获取月份数

    我有一个 daterangepicker 函数 它以 2016 年 5 月 6 日的格式返回选定的日期 我想要做的是将月份提取为整数 因此从上面我应该能够返回数字 5 这是返回所选日期的代码行 getDateString new Date
  • 列表理解创建嵌套列表

    我想创建每月天数列表每年列表的嵌套列表 31 29 31 30 31 28 31 30 with mm 1 2 3 4 yy 2012 2013 但我的代码 result append calendar monthrange y m 1 f
  • 透明菜单/导航栏

    我无法解决 CSS 问题 我有一个应该是透明的导航栏 但由于不透明度属性以及它们是透明导航栏的子元素 其上的链接也会变得透明 你能帮我解决这个问题吗 如果您不希望链接文本受到影响 您应该修改以下规则 容器选择器看起来像这样 containe
  • 使用wireshark或其他工具绘制RTT直方图

    我有一个小型办公室网络 但我遇到了巨大的互联网链接延迟 我们有一个简单的网络拓扑 一台配置为运行 ubuntu 服务器 10 10 的路由器的计算机 2 个网卡 一个连接互联网 另一个连接办公室网络 和一个连接 20 台计算机的交换机 我在
  • 私有继承 VS 组合:什么时候使用哪个?

    私有继承VS组合 我有点困惑何时使用它们 由于私有继承在某种程度上密封了继承链 给出 class A private int z protected int y public int x class B private A B s data
  • QTreeView自定义各行的行高

    是否可以重新定义某个行中某些单独行的行高QTreeView 我有一个习惯QTreeView 风俗QAbstractItemModel和一个习惯QStyledItemDelegate 但似乎所有的sizeHint方法要么只调用一次 最初 要么
  • 如何在CARET中自定义模型来执行PLS-[Classifier]两步分类模型?

    这个问题是同一线程的延续here https stats stackexchange com questions 81727 what is the best strategy to train and validate classific