嵌套交叉验证的一致特征(Consensus features nested cross-validation)

5.5 嵌套交叉验证的一致特征(Consensus features nested cross-validation)

参考:

  1. Parvandeh S, Yeh H W, Paulus M P, et al. Consensus features nested cross-validation[J]. Bioinformatics, 2020, 36(10): 3093-3098.
  2. 代码: https://github.com/insilico/cncv
  3. 浅谈关于特征选择算法与Relief的实现:https://cloud.tencent.com/developer/article/1087796

摘要

**总结:**特征选择可以提高机器学习模型的准确性,但必须采取适当的步骤以避免过拟合。**嵌套交叉验证(nested cross-validationn, CV)是一种常见的方法,它根据提供最大内褶精度的特征选择分类模型和特征来表示给定的外褶。差异隐私是一种避免过拟合的相关技术,它使用一种隐私保护噪声机制(rivacy-preserving noise mechanism)**来识别训练集和保留集之间稳定的特征。

我们开发了一致嵌套交叉验证(consensus nested cross-validation, cnCV),将差异隐私的特征稳定性的思想与nCV相结合。在每个内部折中应用特征选择,在折中使用最佳特征的一致性作为特征稳定性或可靠性的度量,而不是标准nCV中使用的分类精度。利用具有主效应、相关性和相互作用的模拟数据,比较了新型cnCV与交叉验证、**差异隐私(differential privacy)私有蒸发冷却(private evaporative cooling, pEC)**优化的标准nCV、Elastic Net的分类精度和特征选择性能。我们还使用来自重度抑郁症研究的真实RNA-seq数据来比较这些方法。

cnCV方法具有与nCV相似的训练和验证精度,但由于cnCV没有在内部折叠中构造分类器,因此运行时间要短得多。与nCV相比,cnCV方法选择了一组更精简的特征,具有更少的误报。cnCV方法具有与pEC相似的准确性,cnCV选择折叠之间的稳定特征,而不需要指定隐私阈值。结果表明,cnCV是一种将特征选择与分类相结合的有效方法。

5.5.1 方法简介

训练集、验证集和测试集之间的关系:https://zhuanlan.zhihu.com/p/377789735

名词解释:

  • 差异隐私(Differential privacy): 最初是为了在保护数据库中受试者的隐私的前提下,提供数据库中有用的统计信息(Dwork and Roth, 2013)。在查询统计数据中条件的人工干扰要足够高,以防止泄露个人信息,但又要足够低,以提供有用的组统计信息。差异隐私的概念已经被拓展到特征选择和分类中,其目标与嵌入交叉验证类似,提取关于结果(类)变量的信息,同时限制训练数据与holdout fold之间的信息泄露(Dwork,C. et al.2015)。对于这类机器学习问题中,噪声被添加到holdout统计量(准确性或特征重要性得分),使得当训练数据集和holdout数据集之间的平均统计量的差值保持在一个随机阈值内时, 来自holdout集合的信息不会被泄露。这个随机阈值过程保护holdout集合相对结果变量的隐私,被称之为”thresholdout(阈值holdout)“。对于更小的样本量,典型的生物信息学数据,差异隐私能够保护holdout数据集的隐私,但是忽视threshold的选择仍然有过拟合的风险。隐私蒸发冷却算法,基于统计物理和差异隐私的概念,被发展来解决偏差-方差权衡问题。
  • 一致嵌套交叉验证(consensus nested cross validataion, cnCV): 机器学习中解释隐私保护机制的一种有用的方式是该机制在训练数据集和holdout数据集上创建了一致的特征重要性打分和准确率。一致嵌套交叉验证使用了folds之间的一致性来选择特征,无需指定隐私噪声参数(不同于差异隐私) ,也不需要在inners folds中训练分类器(不同于标准的嵌套交叉验证)。特别是,cnCV选择的是内部训练数据集上常见的最佳特征。内部folds的使用防止了使用特征重要性排序信息时外部folds之间的信息泄露。**更进一步,**一致嵌套交叉验证相比在训练集和holdout集上使用差异隐私,将特征的一致性或稳定性(feature consistency/stability)拓展到了很多folds。一致嵌套交叉验证方法使用嵌套分割流程,首先在给定的inner folders上选择稳定的一致的特征,接着在外部folds上进行。一致嵌套交叉验证无需训练分类模型来选择特征,使得它比嵌套交叉验证计算效率更高。我们也展示了选择的一致特征比传统的嵌套交叉验证更简洁(不相关的特征更少)。
5.5.2 一致交叉验证(Consensus nested cross-validation)

**一致嵌套交叉验证(Consensus nested cross-validation)**跟嵌套交叉验证有类似的结构,但是一致嵌套交叉验证简化了特征,不需要在内部folds上训练分类器。嵌套交叉验证基于最好的inner-fold分类模型来选择的特征及其对应的模型,用于outer fold。相比较而言,一致嵌套交叉验证,只在inner-fold进行特征选择(但不进行分类)。具有阳性ReliefF打分的特征被在每个inner fold上组合,然后进行可选参数调整。调整可以在我们的实现中获取,我们使用标准的随机森林和ReliefF超参数,其中ReliefF的邻居数量随着每一折样本的数目而调整。所有inner folds中的公共的/一致的特征被用于外部折数据集。 一致的特征在outer fold上再次选择,来选择最终的特征用于训练最终的模型,并进行验证。

image-20220327165201180

一致嵌套交叉验证的流程如上图所示。

  • (A) 将数据划分为外部折(此处展示的为4折)。然后在每一个outer training fold上进行如下操作(图中A所示的红框展示了Training Fold 1的开始)。
  • (B) 将outer training fold划分为inner folds, 用于特征选择和网格化搜索调整优化超参数。
  • (C)寻找一致特征。对于每一折,阳性Relief打分的特征被收集(例如fold1中的‘QWZREFGTYU’ )。阴性Relief打分更有可能是跟分类无关的特征。该方法适用于不同的特征重要性方法和调整输入特征的数目。所有折中发现的一致特征被用作对应的outer fold中的最好特征。例如,特征’EFG’在三个inner folds中共享。该流程用于一致嵌套交叉验证的inner和outer folds。分类并不是选择一致特征所必须的。
  • (D) 最好的out-folder特征(由绿色的箭头和绿色的方块表示)能够在每一折中都发现【即,可以在所有折上重复(B)-(D)的步骤】。
  • (E)在所有outer folds上选择一致特征来在整个数据集上训练最终的模型。一致特征只是基于训练数据集来选择的。分类直到外部一致特征选择(A)-(D)完成后才进行。
  • (F)在独立数据集上验证最终的模型(本图的彩色版本可以在Bioinformatics的在线网站上获取)。
5.5.3 模拟数据集上的代码实现

参考:

  1. Consensus Nested Cross-Validation: https://github.com/insilico/cncv
  2. Differential privacy-based Evaporative Cooling包privateEC: https://github.com/insilico/privateEC

Consensus Nested Cross-Validation Vignette With Simulated Data

1. Install privateEC

私有蒸发冷却是一种随机的隐私保护机器学习算法,将Relief-F用于特征选择和随机森林来进行隐私保护分类,并避免过拟合。我们将隐私保护阈值机制和热力学麦克斯韦-玻尔兹曼分布联系起来,其中温度代表着隐私阈值。我们利用原子气体蒸发冷却的热统计物理概念来进行后向逐步的隐私保护特征选择。

  • Relief算法是一种特征权重算法(Feature weighting algorithms),根据各个特征和类别的相关性赋予特征不同的权重,权重小于某个阈值的特征将被移除。Relief算法中特征和类别的相关性是基于特征对近距离样本的区分能力。
  • 麦克斯韦-玻尔兹曼分布是一个描述一定温度下微观粒子运动速度的概率分布,在物理学和化学中有应用。最常见的应用是统计力学的领域。任何(宏观)物理系统的温度都是组成该系统的分子和原子的运动的结果。这些粒子有一个不同速度的范围,而任何单个粒子的速度都因与其它粒子的碰撞而不断变化。然而,对于大量粒子来说,处于一个特定的速度范围的粒子所占的比例却几乎不变,如果系统处于或接近处于平衡。麦克斯韦-玻尔兹曼分布具体说明了这个比例,对于任何速度范围,作为系统的温度的函数。它以詹姆斯·麦克斯韦和路德维希·玻尔兹曼命名。
  • 在精密测量、原子光谱等研究领域中,原子的热运动总会带来不利影响,因此得到相对“静止不动”的原子状态是研究人员的终极追求之一。经典的冷却方法,导致原子从相互作用较小的气体过渡到相互作用较强的液体或固体,偏离自由状态,不利于对原子的操控和测量。激光冷却和囚禁原子的特点是降低原子热运动速度的同时,保持原子处于相互作用很小的自由状态,开启了原子操控的新天地。
knitr::opts_chunk$set(echo = TRUE, warning=FALSE)
rm(list = ls())

if (!("devtools" %in% installed.packages()[,"Package"])){
  install.packages("devtools", repos = "http://cran.us.r-project.org", dependencies = TRUE)
}
library(devtools)

if (!("privateEC" %in% installed.packages()[,"Package"])){
  devtools::install_github("insilico/privateEC") # build_vignettes = TRUE)
}
if (!("cncv" %in% installed.packages()[,"Package"])){
  devtools::install_github("insilico/cncv", build_vignettes = TRUE)
}
library(privateEC)  # used to simulate data
library(cncv)
2. Simulate data with privateEC
letsSimulate <- T   # F to use previously simulated data
class.lab <- "class"
writeData <- F  # usually the same as letsSimulate
writeResults <- F

num.samp <- 300
num.attr <- 1000
pct.signals <- 0.1
bias <- 0.4
#sim.type <- "mainEffect"
sim.type <- "interactionErdos"
importance.algorithm = "ReliefFequalK"
num_tree = 500
verbose = T

pec_simFile <- paste("pec_simulated", sim.type, "bias", bias, 
                             "pct.signals", pct.signals,
                             "num.attr", num.attr, "num.samp", num.samp, sep = "_")
pec_simFile <- paste(pec_simFile,".csv",sep="")

if (letsSimulate == TRUE){
    sim.data <- createSimulation(num.samples = num.samp, num.variables = num.attr,
                                 pct.signals = pct.signals, pct.train = 1/3, pct.holdout = 1/3, 
                                 pct.validation = 1/3, bias = bias, sim.type = sim.type, verbose = FALSE)
  dat <- rbind(sim.data$train, sim.data$holdout)
  predictors.mat <- dat[, - which(colnames(dat) == class.lab)]
} else { # optional: use provided data
  dat <- read.csv(pec_simFile)
  dat <- dat[,-1] # written file has first X column with subject names
  predictors.mat <- dat[, - which(colnames(dat) == class.lab)]
}

dat[, class.lab] <- as.factor(dat[, class.lab]) 
pheno.class <- dat[, class.lab]
attr.names <- colnames(predictors.mat)
num.samp <- nrow(dat)

if (writeData == TRUE){
  write.csv(dat, file = pec_simFile)
}

检查数据:

> print(dim(dat))
[1]  200 1001
> print(dat[1:5, 1:5])
       simvar1  simvar2  simvar3  simvar4  simvar5
ctrl3 6.896783 6.736116 6.532103 6.914851 7.263744
ctrl5 7.264965 8.133793 7.620574 7.685788 6.925813
ctrl6 7.946881 8.262267 8.051022 7.917020 8.400325
ctrl7 4.535111 4.209302 3.872554 3.811386 4.257356
ctrl9 7.056017 6.643201 7.784639 5.968471 6.356104
> print(colnames(dat)[990:1001])
 [1] "var890" "var891" "var892" "var893" "var894" "var895" "var896" "var897" "var898" "var899" "var900" "class" 
> print(row.names(dat)[1:10])
 [1] "ctrl3"  "ctrl5"  "ctrl6"  "ctrl7"  "ctrl9"  "ctrl13" "ctrl19" "ctrl24" "ctrl28" "ctrl31"
> print(pec_simFile)
[1] "pec_simulated_interactionErdos_bias_0.4_pct.signals_0.1_num.attr_1000_num.samp_300.csv"

image-20220327230141027

3. Run Standard nested CV
rncv_result <- regular_nestedCV(train.ds = sim.data$train,
                                validation.ds =  sim.data$holdout,
                                label = sim.data$label,
                                method.model = "classification",
                                is.simulated = TRUE,
                                ncv_folds = c(10, 10),
                                param.tune = FALSE,
                                learning_method = "rf", 
                                importance.algorithm = importance.algorithm,
                                relief.k.method = "k_half_sigma",             # ReliefF knn
                                wrapper = "relief",
                                inner_selection_percent = 0.2,
                                inner_selection_positivescores = TRUE,
                                tuneGrid = NULL,
                                num_tree = num_tree,
                                verbose = verbose)

输出嵌套交叉验证的结果:

cat("\n Train Accuracy [",rncv_result$cv.acc,"]\n")
cat("\n Validation Accuracy [",rncv_result$Validation,"]\n")
cat("\n Selected Features \n [",rncv_result$Features,"]\n")
cat("\n Elapsed Time [",rncv_result$Elapsed,"]\n")

结果为(共选择了533个特征):

Validation Accuracy [ 0.68 ]
Validation Accuracy [ 0.68 ]
Selected Features
[ simvar2 simvar12 simvar1 simvar34 simvar32 simvar13 simvar10 simvar68 var618 ... var519 var581 var126 var629 ]
Elapsed Time [ 1658.17 ]
4. Run Consensus nested CV
cncv_result <- consensus_nestedCV(train.ds = rbind(sim.data$train,sim.data$holdout), 
                                  validation.ds =  sim.data$validation, 
                                  label = sim.data$label,
                                  method.model = "classification",
                                  is.simulated = TRUE,
                                  ncv_folds = c(10, 10),
                                  param.tune = FALSE,
                                  learning_method = "rf", 
                                  importance.algorithm = importance.algorithm,
                                  relief.k.method = "k_half_sigma",             # ReliefF knn
                                  wrapper = "relief",
                                  inner_selection_percent = 0.2,
                                  inner_selection_positivescores = TRUE,
                                  tune.k = FALSE,
                                  tuneGrid = NULL,
                                  num_tree = num_tree,
                                  verbose = verbose)

输出一致嵌套交叉验证的结果:

cat("\n Nested Cross-Validation Accuracy [",cncv_result$cv.acc,"]\n")
cat("\n Validation Accuracy [",cncv_result$Validation,"]\n")
cat("\n Selected Features \n [",cncv_result$Features,"]\n")
cat("\n Elapsed Time [",cncv_result$Elapsed,"]\n")

输出结果为(共127个特征):

Nested Cross-Validation Accuracy [ 0.93 ]
Validation Accuracy [ 0.94 ]
Selected Features
[ simvar2 simvar82 simvar12 simvar3 simvar1 simvar7 simvar61 simvar92 simvar95...]
Elapsed Time [ 76.59 ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值