MachineLearning 9. 癌症诊断机器学习之梯度提升算法(Gradient Boosting)

图片

点击关注,桓峰基因

桓峰基因

生物信息分析,SCI文章撰写及生物信息基础知识学习:R语言学习,perl基础编程,linux系统命令,Python遇见更好的你

97篇原创内容

公众号

桓峰基因的教程不但教您怎么使用,还会定期分析一些相关的文章,学会教程只是基础,但是如果把分析结果整合到文章里面才是目的,觉得我们这些教程还不错,并且您按照我们的教程分析出来不错的结果发了文章记得告知我们,并在文章中感谢一下我们哦!


公司英文名称:Kyoho Gene Technology (Beijing) Co.,Ltd.

如果您觉得这些确实没基础,需要专业的生信人员帮助分析,直接扫码加微信nihaoooo123,我们24小时在线!!

图片

前 言

梯度提升机是一个强大的机器学习技术家族,在广泛的实际应用中显示了相当大的成功。它们可以根据应用程序的特定需求进行高度定制,就像学习不同的损失函数一样。这篇文章提供了一个教程,介绍梯度提升方法的方法论,重点关注建模的机器学习方面。理论信息是补充描述性的例子和插图,涵盖梯度推进模型设计的所有阶段。讨论了处理模型复杂性的注意事项。给出了三个梯度助推应用实例,并进行了综合分析。

图片

基本原理

梯度提升法的主要思想是,先建立一个某种形式的初始模型(线性、样条、树或其他),称为基学习器;然后检查残差,在残差的基础上围绕损失函数拟合模型。损失函数测量模型和现实之间的差别,例如,在回归问题中可以用误差的平方。一直继续这个过程,直到满足某个特定的结束条件。这与下面的情形有点相似:一个学生进行模拟考试,100道题中错了30道,然后只研究那30道错题;在下次模考中,30道题中又错了10道,然后只研究那10道题,以此类推。

图片

实例解析

1. 软件安装

if (!require(xgboost)) install.packages("xgboost")

if (!require(caret)) install.packages("caret")

library(xgboost)
library(caret)

2. 数据读取

数据来源《机器学习与R语言》书中,具体来自UCI机器学习仓库。地址:http://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/ 下载wbdc.data和wbdc.names这两个数据集,数据经过整理,成为面板数据。查看数据结构,其中第一列为id列,无特征意义,需要删除。第二列diagnosis为响应变量(B,M),字符型,一般在R语言中分类任务都要求响应变量为因子类型,因此需要做数据类型转换。剩余的为预测变量,数值类型。查看数据维度,568个样本,32个特征(包括响应特征)。

BreastCancer <- read.csv("wisc_bc_data.csv", stringsAsFactors = FALSE)
dim(BreastCancer)
## [1] 568  32
table(BreastCancer$diagnosis)
## 
##   B   M 
## 357 211

3. 数据分布

比较恶性和良性之间的差距

library(reshape2)
bc <- BreastCancer[, -1]
bc.melt <- melt(bc, id.var = "diagnosis")
head(bc.melt)
##   diagnosis    variable value
## 1         M radius_mean 20.57
## 2         M radius_mean 19.69
## 3         M radius_mean 11.42
## 4         M radius_mean 20.29
## 5         M radius_mean 12.45
## 6         M radius_mean 18.25
ggplot(data = bc.melt, aes(x = diagnosis, y = log(value + 1), fill = diagnosis)) +
    geom_boxplot() + theme_bw() + facet_wrap(~variable, ncol = 8)

图片

比较变量之间的相关性,如下:

library(tidyverse)
data <- select(BreastCancer, -1) %>%
    mutate_at("diagnosis", as.factor)
data$diagnosis = ifelse(data$diagnosis == "B", "B", "M")
sum(is.na(data))
## [1] 0
corrplot::corrplot(cor(data[, -1]))

图片

4. 数据分割

当我们只有一套数据的时候,可以将数据分为训练集和测试集,具体怎么分割可以看公众号的专题:Topic 5. 样本量确定及分割我们将整个数据进行分割,分为训练集和测试集,并保证其正负样本的比例,如下:

# 数据分割 install.packages('sampling')
library(sampling)
set.seed(123)
# 每层抽取70%的数据
train_id <- strata(data, "diagnosis", size = rev(round(table(data$diagnosis) * 0.7)))$ID_unit
# 训练数据
train_data <- data[train_id, ]
# 测试数据
test_data <- data[-train_id, ]

# 查看训练、测试数据中正负样本比例
prop.table(table(train_data$diagnosis))
## 
##         B         M 
## 0.6281407 0.3718593

prop.table(table(test_data$diagnosis))
## 
##         B         M 
## 0.6294118 0.3705882

5. 模型构建

参数配置

在这一节要使用已经加载的xgboost包。因为这种方法的效果如雷贯耳,所以我们直接用它解决最有挑战性的乳腺癌诊断性问题。正如在提升算法简介中所说,我们要调整一些参数。(1) nrounds:最大迭代次数(最终模型中树的数量)。(2) colsample_bytree:建立树时随机抽取的特征数量,用一个比率表示,默认值为1(使用100%的特征)。(3) min_child_weight:对树进行提升时使用的最小权重,默认为1o(4) eta:学习率,每棵树在最终解中的贡献,默认为0.3。(5) gamma:在树中新增一个叶子分区时所需的最小减损。(6)subsample:子样本数据占整个观测的比例,默认值为1(100%)。(7) max_depth:单个树的最大深度。

使用expand.grid()函数可以建立实验网格,以运行caret包的训练过程。对于前面列出的参数,如果没有设定具体值,那么即使有默认值,运行函数时也会收到出错信息。下面的参数取值是基于我以前的一些训练迭代而设定的。建议各位亲自实验参数调整过程。使用以下命令建立网格:

###参数选择
grid = expand.grid(
  nrounds = c(75, 100),
  colsample_bytree = 1,
  min_child_weight = 1,
  eta = c(0.01, 0.1, 0.3), #0.3 is default,
  gamma = c(0.5, 0.25),
  subsample = 0.5,
  max_depth = c(2, 3)
)
grid
##    nrounds colsample_bytree min_child_weight  eta gamma subsample max_depth
## 1       75                1                1 0.01  0.50       0.5         2
## 2      100                1                1 0.01  0.50       0.5         2
## 3       75                1                1 0.10  0.50       0.5         2
## 4      100                1                1 0.10  0.50       0.5         2
## 5       75                1                1 0.30  0.50       0.5         2
## 6      100                1                1 0.30  0.50       0.5         2
## 7       75                1                1 0.01  0.25       0.5         2
## 8      100                1                1 0.01  0.25       0.5         2
## 9       75                1                1 0.10  0.25       0.5         2
## 10     100                1                1 0.10  0.25       0.5         2
## 11      75                1                1 0.30  0.25       0.5         2
## 12     100                1                1 0.30  0.25       0.5         2
## 13      75                1                1 0.01  0.50       0.5         3
## 14     100                1                1 0.01  0.50       0.5         3
## 15      75                1                1 0.10  0.50       0.5         3
## 16     100                1                1 0.10  0.50       0.5         3
## 17      75                1                1 0.30  0.50       0.5         3
## 18     100                1                1 0.30  0.50       0.5         3
## 19      75                1                1 0.01  0.25       0.5         3
## 20     100                1                1 0.01  0.25       0.5         3
## 21      75                1                1 0.10  0.25       0.5         3
## 22     100                1                1 0.10  0.25       0.5         3
## 23      75                1                1 0.30  0.25       0.5         3
## 24     100                1                1 0.30  0.25       0.5         3

交叉验证

使用car包的train()函数之前,我要创建一个名为cntrl的对象,来设定trainControl的参数。这个对象会保存我们要使用的方法,以训练调优参数。我们使用10折交叉验证,代码如下所示:

cntrl = trainControl(method = "cv", number = 10, verboseIter = FALSE, returnData = FALSE,
    returnResamp = "final")

根据配置好的参数,进行建模

set.seed(123)train.xgb = train(x = train_data[, -1], y = train_data[, 1], trControl = cntrl, tuneGrid = grid,    method = "xgbTree")
train.xgb
## eXtreme Gradient Boosting ## ## No pre-processing## Resampling: Cross-Validated (10 fold) ## Summary of sample sizes: 359, 358, 358, 358, 358, 359, ... ## Resampling results across tuning parameters:## ##   eta   max_depth  gamma  nrounds  Accuracy   Kappa    ##   0.01  2          0.25    75      0.9448077  0.8815793##   0.01  2          0.25   100      0.9448718  0.8825558##   0.01  2          0.50    75      0.9448077  0.8811347##   0.01  2          0.50   100      0.9448077  0.8814371##   0.01  3          0.25    75      0.9498718  0.8926807##   0.01  3          0.25   100      0.9473077  0.8868425##   0.01  3          0.50    75      0.9448077  0.8815793##   0.01  3          0.50   100      0.9473077  0.8868425##   0.10  2          0.25    75      0.9623718  0.9187054##   0.10  2          0.25   100      0.9598718  0.9133019##   0.10  2          0.50    75      0.9548077  0.9022024##   0.10  2          0.50   100      0.9623718  0.9192980##   0.10  3          0.25    75      0.9648718  0.9247034##   0.10  3          0.25   100      0.9673718  0.9298262##   0.10  3          0.50    75      0.9548077  0.9022182##   0.10  3          0.50   100      0.9598718  0.9128120##   0.30  2          0.25    75      0.9623718  0.9190002##   0.30  2          0.25   100      0.9648718  0.9241266##   0.30  2          0.50    75      0.9623077  0.9184364##   0.30  2          0.50   100      0.9598077  0.9133136##   0.30  3          0.25    75      0.9649359  0.9247785##   0.30  3          0.25   100      0.9699359  0.9357355##   0.30  3          0.50    75      0.9748718  0.9457522##   0.30  3          0.50   100      0.9748718  0.9457522## ## Tuning parameter 'colsample_bytree' was held constant at a value of 1## ## Tuning parameter 'min_child_weight' was held constant at a value of 1## ## Tuning parameter 'subsample' was held constant at a value of 0.5## Accuracy was used to select the optimal model using the largest value.## The final values used for the model were nrounds = 75, max_depth = 3, eta##  = 0.3, gamma = 0.5, colsample_bytree = 1, min_child_weight = 1 and subsample##  = 0.5.

最优参数设置

由此可以得到最优的参数组合来建立模型。模型在训练数据上的正确率是0.975, Kappa值是0.946。下面要做的事情有点复杂,但我认为这才是最佳实践。首先创建一个参数列表,供xgboost包的训练函数xgb.train()使用。然后将数据框转换为一个输入特征矩阵,以及一个带标号的数值型结果列表(其中的值是0和1)。接着,将特征矩阵和标号列表组合成符合要求的输入,即一个xgb.Dmatrix对象。代码如下:

param <- list(objective = "binary:logistic", booster = "gbtree", eval_metric = "error",
    eta = 0.1, max_depth = 2, subsample = 0.5, colsample_bytree = 1, gamma = 0.5)

x <- as.matrix(train_data[, -1])
y <- ifelse(train_data$diagnosis == "B", 0, 1)
train.mat <- xgb.DMatrix(data = x, label = y)

优化模型

set.seed(123)
xgb.fit <- xgb.train(params = param, data = train.mat, nrounds = 100)
xgb.fit
## ##### xgb.Booster
## raw: 87 Kb 
## call:
##   xgb.train(params = param, data = train.mat, nrounds = 100)
## params (as set within xgb.train):
##   objective = "binary:logistic", booster = "gbtree", eval_metric = "error", eta = "0.1", max_depth = "2", subsample = "0.5", colsample_bytree = "1", gamma = "0.5", validate_parameters = "TRUE"
## xgb.attributes:
##   niter
## callbacks:
##   cb.print.evaluation(period = print_every_n)
## # of features: 30 
## niter: 100
## nfeatures : 30

可视化变量

从图上我们可以出前几个重要的变量占比几乎达到0.3,这个阈值是在之前grid网格中设置:eta = c(0.01, 0.1, 0.3), #0.3 is default。

impMatrix <- xgb.importance(feature_names = dimnames(x)[[2]], model = xgb.fit)
impMatrix
##                     Feature         Gain       Cover   Frequency
##  1:    concave_points_worst 0.2967527144 0.147574780 0.074766355
##  2:     concave_points_mean 0.2341084307 0.144084708 0.079439252
##  3:            radius_worst 0.0776151887 0.075881804 0.056074766
##  4:         perimeter_worst 0.0742989918 0.080783308 0.065420561
##  5:                 area_se 0.0707442192 0.075966262 0.065420561
##  6:           texture_worst 0.0431688078 0.084473059 0.107476636
##  7:              area_worst 0.0349753102 0.054806620 0.056074766
##  8:         concavity_worst 0.0274044659 0.045700578 0.060747664
##  9:            texture_mean 0.0242682068 0.042618830 0.056074766
## 10:        smoothness_worst 0.0180421347 0.030139745 0.046728972
## 11:               area_mean 0.0137108659 0.022756702 0.018691589
## 12:          compactne_mean 0.0105402518 0.012610045 0.028037383
## 13:             symmetry_se 0.0104209161 0.020799297 0.042056075
## 14:         smoothness_mean 0.0090815731 0.020561037 0.032710280
## 15:               radius_se 0.0084606195 0.029712377 0.018691589
## 16:            compactne_se 0.0080685708 0.014326525 0.032710280
## 17:          symmetry_worst 0.0076659203 0.027927952 0.037383178
## 18:  fractal_dimension_mean 0.0057942369 0.008967406 0.014018692
## 19:           smoothness_se 0.0050382309 0.018076694 0.023364486
## 20:    fractal_dimension_se 0.0043507637 0.007250846 0.018691589
## 21: fractal_dimension_worst 0.0029493268 0.006075975 0.009345794
## 22:           symmetry_mean 0.0026459958 0.006109480 0.014018692
## 23:          concavity_mean 0.0023260374 0.003932079 0.009345794
## 24:          perimeter_mean 0.0022726213 0.003359381 0.004672897
## 25:         compactne_worst 0.0019021532 0.003878213 0.009345794
## 26:       concave_points_se 0.0011308883 0.002550426 0.004672897
## 27:             radius_mean 0.0010039937 0.002045465 0.004672897
## 28:            perimeter_se 0.0008485220 0.002095077 0.004672897
## 29:              texture_se 0.0004100425 0.004935332 0.004672897
##                     Feature         Gain       Cover   Frequency
xgb.plot.importance(impMatrix, main = "Gain by Feature")

图片

模型性能评估

library(InformationValue)
pred <- predict(xgb.fit, x)
optimalCutoff(y, pred)
## [1] 0.2692855

测试集验证

testMat <- as.matrix(test_data[, -1])
xgb.test <- predict(xgb.fit, testMat)
y.test <- ifelse(test_data$diagnosis == "B", 0, 1)
optimalCutoff(y.test, xgb.test)
## [1] 0.1793153

混淆矩阵计算假阳和假阴个数,如下:

confusionMatrix(y.test, xgb.test, threshold = 0.29)
##     0  1
## 0 103  0
## 1   4 63
1 - misClassError(y.test, xgb.test, threshold = 0.29)
## [1] 0.9765

绘制ROC曲线

最后就是模型的准确性评估,这里我们使用的是InformationValue软件包中的plotROC,绘制ROC曲线,如下:

###
library(InformationValue)
plotROC(y.test, xgb.test)

图片

结果解读

我们再回忆一下对乳腺癌数据我们都用过哪些机器学习方法。

基于乳腺癌的数据我们已经做过四种类型的机器学习算法,如下:

K-邻近算法(KNN)准确率为0.9471

支持向量机(SVM)准确率为 0.9765

分类随机森林RT准确率为0.969

这期使用梯度提升准确率为0.997,准确率嗖的一下就上去了,这模型应该是让老板十万分满意。

其实这说明做模型时,不应单一只是用一种算法,需要多种算法比较,找到最优的选择!

还有就是注意绘制ROC的方法,在做分类随机森林时我们使用的是ROSE软件包,而在做回归随机森林时我们使用的是ROCR,需要注意使用时方法的选择。在这里我们使用InformationValue软件包里面的plotROC

References:
  1. Frontiers in Neurorobotics, Gradient boosting machines,a tutorial,Natekin A., Knoll A.(2013)
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值