ClassifyR提供两个贡献。首先,有一个用于两类分类的结构化管道。分类分为四个阶段:数据转换、特征选择、分类器训练和预测。这些阶段可以按任何合理的顺序运行。每个步骤都可以提供遵循一些参数规则的函数。此外,驱动函数实现了普通的k-fold交叉验证,用替换重新采样,然后进行k-fold或x%测试集交叉验证,并省略k交叉验证。这个函数可以使用R中的并行处理功能,在多个cpu可用时加速交叉验证。为微阵列和RNA-seq数据提供了一些方便的函数接口,而其他函数则直接与框架一起工作,不需要接口。
其次,利用不同的特征类型实现了多种分类方法。大多数分类器处理的特征的均值是不同的。除了微分表达式,ClassifyR还考虑了差动偏差和差动分布。
驱动分类的函数是runTests.对于交叉验证,它重复调用小牛,它为单个数据分割运行分类。
中提供的函数ClassifyR将进行演示。但是,用户可以向分类框架提供任何功能,只要它满足一些最低限度的规则。关于这些的描述,请参阅最后一节“新函数规则”。
r中还有一些其他的分类框架,下表对它们提供的特性进行了比较。
包 | 运行用户定义的分类器 | 在任何操作系统上并行执行 | 参数调优 | 计算超过20个性能指标 | 排名和选择地块 | 班级分布图 | 错误的热图 |
---|---|---|---|---|---|---|---|
ClassifyR | 是的 | 是的 | 是的 | 是的 | 是的 | 是的 | 是的 |
脱字符号 | 是的 | 是的 | 是的 | 没有 | 没有 | 没有 | 没有 |
MLInterfaces | 是的 | 没有 | 没有 | 没有 | 没有 | 没有 | 没有 |
MCRestimate | 是的 | 没有 | 是的 | 没有 | 没有 | 没有 | 没有 |
CMA | 没有 | 没有 | 是的 | 没有 | 没有 | 没有 | 没有 |
对卵巢癌微阵列进行了生存研究,可从curatedOvarianDataBioconductor。将数据集加载到当前R会话中。只有1000个基因被用于说明。
library(ClassifyR) library(ggplot2) library(curatedOvarianData) data(GSE26712_eset) GSE26712_eset <- GSE26712_eset[1:1000,]
将死亡时间少于1年的患者定义为不良预后,将生存时间超过5年的患者定义为良好预后。
curatedClinical <- pData(GSE26712_eset) ovarPoor <- curatedClinical[, "vital_status"] == "deceased" & curatedClinical[, "days_to_death"] < 365 * 1 ovarGood <- curatedClinical[, "vital_status"] == "living" & curatedClinical[, "days_to_death"] > 365 * 5 sum(ovarPoor, na。rm = TRUE) sum(ovarGood, na。rm = TRUE)
## [1] 27 ## [1] 20
预后差27例,预后好20例。表达数据子集化,仅将患者分为差组或良组。
ovarexexpression <- exprs(GSE26712_eset)[, c(which(ovvarpoor), which(ovvargood))] ovarGroups <- factor(rep(c("Poor", "Good"), c(length(which(ovvarpoor)), length(which(ovvargood)))), levels = c("Poor", "Good")))
绘制箱线图是为了了解数据的分布情况。
plotData <- data.frame(expression = as.numeric(ovarExpression), sample = factor(rep(1:ncol(ovarExpression), each = nrow(ovarExpression)))) ggplot(plotData, aes(x = sample, y = expression)) + geom_boxplot() + scale_y_continuous(limits = c(0,15)) + xlab(" sample ") + ylab(" expression Value") + ggtitle(" expression for All Arrays"))
提供的所有功能ClassifyR使用矩阵向量或anExpressionSet对象。在这里,一个ExpressionSet对象。
groupsTable <- data.frame(class = ovaregroups) rownames(groupsTable) <- colnames(ovarExpression) ovarSet <- ExpressionSet(ovarExpression, AnnotatedDataFrame(groupsTable)) featureNames(ovarExpression) <- rownames(ovarExpression) dim(ovareset)
##功能示例
差分表达式分类器寻找组间均值的一致变化。这是最常见的分类形式。
针对这种类型的更改,现有特征选择和分类算法的接口包括:
limmaSelection适合微阵列数据和edgeRselection适用于RNA-seq数据,其中表达式值是原始计数。
在这里,基于limma的排名列表的特征选择,然后是DLDA分类器,将用于进行10次重采样和4次交叉验证。的dlda函数直接从sparsediscrim包装在ClassifyR框架,不需要任何接口。
library(sparsediscrim) DEresults <- runTests(卵巢集,"卵巢癌","差异表达",验证= "bootstrap", resamples = 5,折叠= 3,params = list(SelectParams(limmaSelection, resubstituteParams = resubstituteParams (nFeatures = c(25,50,75,100), performanceType = "balanced", better = "lower")), TrainParams(dlda, TRUE, doesTests = FALSE), PredictParams(predict, TRUE, getClasses = function(result) result[["class"]])), parallelParams = bpparam(), verbose = 1) DEresults
类ClassifyResult的对象。数据集名称:卵巢癌。分类名称:微分表达式。##特征选择名称:适度t检验。##特性:长度为5的行索引列表的列表长度为3。验证:5次重采样,3次折叠。预测:长度为5的数据帧列表。##性能度量:尚未计算。
对于超过1个CPU的计算机,可以指定使用的核数runTests通过使用论证parallelParams.
这个例子介绍了类SelectionParams,TrainParams,PredictParams.它们存储了用于选择、训练和预测的函数和参数的细节。构造函数的第一个参数总是一个函数,后面跟着其他参数。可以提供任何命名实参,只要指定给构造函数的函数知道如何使用该名称的实参。它们在列表中指定的顺序决定了阶段的运行顺序。
的limmaSelection指定给selectionParams基于p值对探测进行排序,并使用指定的分类器trainParams并计算顶部的再替换错误率nFeatures,选取错误率最低的值。
TrainParams有四个强制参数。第一个是训练分类器的函数。第二个是一个逻辑值,它指定表达式在传递给分类器函数之前是否应该转置。CRAN存储库中现有R包中的许多分类函数需要将特征作为列,将示例作为行。在ClassifyR,传递给runTest或runTest的表达式数据必须以特征为行,以示例为列。这在生物信息学中更为常见。在这个例子中,函数dlda期望列是特性,所以transposeExpression是真的。CRAN上的分类器之间的另一个常见区别是,其中一些分类器分别执行训练和测试,而在其他包中,一个函数执行训练和测试。在这种情况下dlda,它只做训练,所以doesTests,构造函数的第三个参数被设置为FALSE。
PredictParams有三个强制参数。第一个是一个函数,它采用一个构建的分类器,并对未见的数据进行预测。第二个是一个函数,它从函数返回的对象中提取预测类标签的向量。在这种情况下,预测方法返回一个对象,该对象将预测存储在名为类.此外,transposeExpression是强制性的。像TrainParams,它指定数值测量是否需要转置。
在特征选择步骤中选择的前5个探针可以直观地检查。DEresults是一个ClassifyResult返回的对象runTests.特性是允许访问为每次折叠选择的行索引的函数。
部署<- plotFeatureClasses(ovarSet, features(DEresults)[[1]][[2]][1:5])
这是在第一次重采样的第一次折叠中选择的两个生存类别的特征的微阵列强度分布。可以看到,探测器的方法并没有太大的不同。
分类错误率,以及许多其他预测性能措施,可以计算calcPerformance.接下来,计算所有10次重采样的平衡错误率。均衡错误率定义为每一类分类错误率的平均值。
DEresults <- calcPerformance(DEresults, "balanced") DEresults
类ClassifyResult的对象。数据集名称:卵巢癌。分类名称:微分表达式。##特征选择名称:适度t检验。##特性:长度为5的行索引列表的列表长度为3。验证:5次重采样,3次折叠。预测:长度为5的数据帧列表。性能度量:平衡错误率。
性能(DEresults)
## $ '平衡错误率' ## [1]0.3143939 0.2406250 0.3416667 0.4120879 0.3672727
错误率是合理的。任何绩效指标都可以计算出ROCR函数性能计算。例如,还可以计算马修斯相关系数。
DEresults <- calcPerformance(DEresults, "mat") DEresults
类ClassifyResult的对象。数据集名称:卵巢癌。分类名称:微分表达式。##特征选择名称:适度t检验。##特性:长度为5的行索引列表的列表长度为3。验证:5次重采样,3次折叠。预测:长度为5的数据帧列表。绩效衡量:平衡错误率,马修斯相关系数。
性能(DEresults)
##[1] 0.3143939 0.2406250 0.3416667 0.4120879 0.3672727 ## ## $ '马修斯相关系数' ## [1]0.4182081 0.4863875 0.3137747 0.1798207 0.2699080
有些疾病的典型特征不是组间特征表达方式的变化,而是表达变异性的变化。当基因表达的方差在健康细胞和癌细胞之间发生巨大变化时,就可以观察到这一点。
针对这种类型的更改,现有特征选择和分类算法的接口包括:
Fisher的LDA适用于表达式值从一个位置减去的绝对值,因为它不假设正态性,不像普通的LDA。Fisher的LDA应用于卵巢癌数据。只做了两次重采样。
DVresults <- runTests(卵巢集,"卵巢癌","差异变动性",验证= "bootstrap", resamples = 2,折叠= 4,params = list(SelectParams(leveneSelection, resubstituteParams = resubstituteParams (nFeatures = c(25,50,75,100), performanceType = "balanced", better = "lower")), TransformParams(subtractFromLocation, location = "median"), TrainParams(fishdiscriminant, FALSE, doesTests = TRUE), PredictParams(predictor = function(){}, FALSE, getClasses = function(result) result,returnType = "both")), verbose = 1) DVresults
类ClassifyResult的对象。数据集名称:卵巢癌。分类名称:差异变异性。特征选择名称:Levene测试。##特性:长度为2的行索引列表的长度为4。验证:2次重采样,4次折叠。预测:长度为2的数据帧列表。##性能度量:尚未计算。
为参数个数,SelectionParams对象首先指定。在此分析中,首先进行特征选择。一个TransformParams对象是列表中的下一个,因此在特征选择完成后,将应用数据转换。transformParams指定subtractFromLocation作为变换函数。这是因为预计从训练集的中位数中减去所有特征将是检测差分偏差的良好特征。trainParams指定fisherDiscriminant作为分类器函数。注意,这个函数同时进行训练和预测,因此第三个参数为TRUE。predictParams指定一个空函数作为预测函数,因为fisherDiscriminant执行两个步骤。fisherDiscriminant直接返回一个预测向量,因此第二个函数只是返回参数结果.
为第一次重采样和第一次折叠选择的前五个探针被可视化。
DVplots <- plotFeatureClasses(ovarSet, features(DVresults)[[1]][[2]][1:5])
计算差动偏差的平衡错误率。
DVresults <- calcPerformance(DVresults, "balanced") DVresults
类ClassifyResult的对象。数据集名称:卵巢癌。分类名称:差异变异性。特征选择名称:Levene测试。##特性:长度为2的行索引列表的长度为4。验证:2次重采样,4次折叠。预测:长度为2的数据帧列表。性能度量:平衡错误率。
性能(DVresults)
## $ '平衡错误率' ## [1]0.1245421 0.2445887
这些错误是合理的。
差异分布描述了基于分布的位置、规模或两个方面的差异进行的分类。
ClassifyR具有四个差分分布特征选择函数:
还包括两个分类器:*朴素贝叶斯。*法线的混合。
Kullback-Leibler散度将用于特征选择,朴素贝叶斯分类器将为每个类的基因表达值拟合密度。然后,预测是类之间的密度差异,对训练集中每个类的样本数量进行缩放,对所有选定的探针进行求和。
dParams < -列表(bw = " nrd0 ", n = 4096 =表达式(min (featureValues)) =表达式(max (featureValues))) DDresults < runTests (ovarSet,“卵巢癌”、“微分分布”,验证=“引导”,重新取样= 2,折叠= 2,params =列表(SelectParams (KullbackLeiblerSelection resubstituteParams = resubstituteParams (nFeatures = c(25、50、75、100),performanceType =“平衡”,更好的=“低”)),TrainParams (naiveBayesKernel,假,doesTests = TRUE),PredictParams(predictor = function(){}, FALSE, getClasses = function(result) result,加权= "加权",returnType = "both", densityParameters = dParams)), verbose = 1) dresults
类ClassifyResult的一个对象。数据集名称:卵巢癌。分类名称:差异分布。特征选择名称:Kullback-Leibler Divergence。##特性:行索引长度为2的列表的长度为2的列表。验证:2次重采样,2次折叠。预测:长度为2的数据帧列表。##性能度量:尚未计算。## ## $ '体重=身高差' ##类'ClassifyResult'的对象。数据集名称:卵巢癌。 ## Classification Name: Differential Distribution. ## Feature Selection Name: Kullback-Leibler Divergence. ## Features: List of length 2 of lists of length 2 of row indices. ## Validation: 2 Resamples, 2 Folds. ## Predictions: List of data frames of length 2. ## Performance Measures: None calculated yet. ## ## $`weight=sum differences` ## An object of class 'ClassifyResult'. ## Dataset Name: Ovarian Cancer. ## Classification Name: Differential Distribution. ## Feature Selection Name: Kullback-Leibler Divergence. ## Features: List of length 2 of lists of length 2 of row indices. ## Validation: 2 Resamples, 2 Folds. ## Predictions: List of data frames of length 2. ## Performance Measures: None calculated yet.
自naiveBayesKernel训练和测试时,是否都指定一个空函数作为预测函数PredictParams构造函数。
为第一次重采样和第一次折叠选择的前五个探针被可视化。
DDplots <- plotFeatureClasses(ovarSet, features(DDresults[[1]])[[1]][[1]][1:5])
使用交叉点距离类加权计算差分分布的平衡错误率。
DDresults[["weight=交叉距离"]]]<- calcPerformance(DDresults[["weight=交叉距离"]],"balanced") DDresults[["weight=交叉距离"]]]
类ClassifyResult的对象。数据集名称:卵巢癌。分类名称:差异分布。特征选择名称:Kullback-Leibler Divergence。##特性:行索引长度为2的列表的长度为2的列表。验证:2次重采样,2次折叠。预测:长度为2的数据帧列表。性能度量:平衡错误率。
性能(DDresults[[“重量=交叉距离”]])
## $ '平衡错误率' ## [1]0.3958333 0.2528736
错误率高于偏差或表达式。
的errorMap函数允许对不同样本的性能测量进行可视化比较ClassifyResult对象。
library(grid) resultsList <- list(Expression = DEresults, Variability = DVresults) errorPlot <- errorMap(resultsList)
的performancePlot函数允许对整体性能指标进行比较,例如精度和错误率。
errorBoxes <- performancePlot(list(DEresults, DVresults, dresulsults [["weight=交叉距离"]]),performanceName = "平衡错误率",boxfillcol着色= "None", boxlinecol着色= "None", title = "跨分类类型错误")
这张图将三种分类的平衡错误率画在一起。
有时,交叉验证是不必要的。这种情况发生在研究具有较大的样本量和精心设计的情况下,以便预先指定大量的样本来形成一个测试集。分类器只在训练样本集上进行训练,只在测试集上进行预测。
为了演示如何使用ClassifyR进行这种分析,我们模拟了一个训练数据集和一个测试数据集,每个数据集中有500个特征和50个样本。25个特征将在训练集中进行差异表达。25个特征将在测试集中被差异表达,其中15个特征将与训练集中相同。
trainingExpr <- matrix(rnorm(500 * 50,9,3), ncol = 50) trainingClasses <- factor(rep(c("健康","患病"),各= 25),levels = c("健康","患病"))trainingExpr[101:125, trainingClasses == "患病"]<- trainingExpr[101:125, trainingClasses == "患病"]- 2 testingExpr <- matrix(rnorm(500 * 50,9,3), ncol = 50) testingClasses <- factor(rep(c("健康","患病"),各= 25),levels = c("健康","患病"))testingExpr[111:135, "患病")testingClasses == "患病"]<- testingExpr[111:135, testingClasses == "患病"]-
有两个矩阵;一个是训练集,一个是测试集。自小牛除了单个表达式对象外,矩阵被组合,将列放在一起并连接类向量。训练和测试样本的规范通过提供每组样本的列号来实现。
allExpr <- cbind(trainingExpr, testingExpr) allClasses <- unlist(list(trainingClasses, testingClasses)) independentResult <- runTest(allExpr, allClasses, datasetName = "Simulation", classificationName = "DE", training = 1:50, testing = 51:100) independentResult
类ClassifyResult的对象。数据集名称:模拟。##分类名称:DE. ##特征选择名称:Limma缓和t检验。##特性:长度为1的行索引列表。##验证:独立集。预测:长度为1的数据帧列表。##性能度量:尚未计算。
一旦交叉验证分类完成,所选特征的有用性可以在另一个数据集中进行探索。previousSelection是一个函数,它接受一个现有的ClassifyResult对象,并返回在当前正在处理的等效迭代中选择的特征。这是必要的,因为在一个数据集上训练的模型不能直接转移到新的数据集上。分类器训练需要重新进行。
可以将一些分类器设置为输出分数或概率,表示样本来自某个类的可能性,而不是类标签。这允许尝试不同的分数阈值,以生成假阳性和假阴性率对。先前使用的朴素贝叶斯分类器和Fisher判别分析具有returnType变量设置为“两个”,所以标签和分数都存储在分类结果中。设置returnType来“分数”也是充分的。其他R包中的许多现有分类器也有一个选项,允许计算分数或概率。
ROCcurves <- ROCplot(list(DVresults, dresults [["weight=交叉距离"]]))
一些分类器允许设置一个调优参数,该参数控制模型学习的某些方面。给出了用线性支持向量机进行参数调整的一个例子。SVM只有一个调优参数,即成本。该参数值越高,错误分类越严重。
这是通过在ClassifyR中提供一个名为tuneParams到TrainParams容器构造函数。tuneParams是一个命名列表,其中名称是调优变量的名称,内容是要尝试的值的向量。如果tuneParams有多个元素,所有调优变量的值组合都要尝试。指定的性能标准resubstituteParams也被用作选择最佳调优参数的标准。这意味着任何性能衡量计算ROCR可以使用。
给出了一种线性支持向量机。它只有一个调优参数,即成本值。
library(e1071) #支持向量机函数。resubstituteParams = resubstituteParams (nFeatures = c(25,50,75, seq(100,1000,100)), performanceType = "balanced", better = "lower") SVMresults <- suppressWarnings(runTests(Ovarian set, "卵巢癌","Differential Expression", validation = "bootstrap", resamples = 5, folds = 3, params = list(SelectParams(limmaSelection, resubstituteParams = resubstituteParams), TrainParams(svm, TRUE, doeststs = FALSE, kernel = "linear", resubstituteParams = resubstituteParams,tuneParams = list(cost = c(0.01, 0.1, 1,10))), PredictParams(predict, TRUE, getClasses = function(result) result)), parallelParams = bpparam(), verbose = 1))
为每次验证存储所选参数的值,并可以使用tunedParameters函数。
长度(tunedParameters (SVMresults))
## [1]
tunedParameters (SVMresults) [[1]]
# # # #[[1]][[1]]美元成本# # 0.1 [1] ## ## ## [[ 2]] # # # #[[2]]美元成本0.1 [1] ## ## ## [[ 3]] # # # #[[3]]美元成本0.1 [1]
这些是为第一次重采样的三次折叠选择的代价值。在第一次折叠中,最佳值为0.1,而在第二次和第三次折叠中,最佳值为0.1。
当每个类有多个重复时,差异变异或分布分类可能比传统的差异表达分析具有更好的预测性能。从特征选择来看,因其差异分布而选择的探针比用于表达的探针具有更强的差异。
变换函数:第一个参数必须是anExpressionSet.其他的论点可能是任何东西。这个论点详细的是从小牛,所以它必须处理它。它返回一个ExpressionSet与输入的尺寸相同ExpressionSet.
选择功能:第一个参数必须是anExpressionSet.它返回一个SelectResult对象。培训功能:第一个参数必须是a矩阵.这是因为CRAN上大多数其他R分类器采用矩阵。这避免了必须为它们编写接口。其他的论点可能是任何东西。这个论点详细的是从小牛,所以它必须处理它。它返回一个分类器。
预测功能:第一个参数必须是由训练步骤生成的训练过的模型。第二个参数必须是a矩阵测试数据。其他的论点可能是任何东西。这个论点详细的是从小牛,所以它必须处理它。它返回一个包含预测的对象。
Strbenac D., Yang, J., Mann, G.J.和Ormerod, J. T. (2015)ClassifyR:用于转录组学分类性能评估的R包,生物信息学杨建军,杨建军。(2016).中国农业科学,31(11):1851-1853差异分布提高了基因选择的稳定性,并对患者生存具有竞争性分类性能,核酸研究, 44 (13): e119