87-预测分析-R语言实现-集成模型

> library(pacman)
> p_load(dplyr, caret)

集成模型方法:
1、装袋-使用同一个数据集的不同样本(可通过有放回的抽样创建)来训练同一个模型的多个版本,然后这些模型会对新的观测数据进行投票,并根据问题的类型作出平均或多数的决策。
对非线性模型装袋才有意义,因为装袋过程就是对产生的模型进行一次取平均值(线性运算)的处理,从而在线性回归里就不会看到任何改善,因为没有增加模型的表达力。
ipred包包含了为通过rpart()构建的树构建一个装袋预测器的工具,可以通过bagging()函数实现。
2、增强-训练一序列模型,并给没有正确分类或远离其预测值的观测数据分配权重,以便增强后续训练的模型把它们放在优先地位。
增强在默认情况下会用到所有的训练数据,并在没有任何惩罚或收缩准则的情况下逐步尝试纠正它犯的错误(虽然要训练的单个模型本身可以是正则化的),因此,增强有时候也会过拟合。另外,很多增强算法在分类过程中对产生的假阳性分类误差和假阴性分类误差是没有差别的处理其权值,即具有一个对称的损失函数,也是其局限性。
fastAdaboost包和gbm包可以实现集成模型中的增强算法。

任务:分析望远镜照相机拍下的辐射中出现的模式,预测某个模式是来源于泄露到大气中的伽马射线还是常规的背景辐射。

1、数据准备

> magic <- readr::read_csv("data_set/magic04.data", col_names = F)
> names(magic) <- c("flength", "fwidth", "fsize", "fconc", "fconc1", "fasym",
+                   "fm3long", "fm3trans", "falpha", "fdisk", "class")
> 
> str(magic)
## tibble [19,020 × 11] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ flength : num [1:19020] 28.8 31.6 162.1 23.8 75.1 ...
##  $ fwidth  : num [1:19020] 16 11.72 136.03 9.57 30.92 ...
##  $ fsize   : num [1:19020] 2.64 2.52 4.06 2.34 3.16 ...
##  $ fconc   : num [1:19020] 0.3918 0.5303 0.0374 0.6147 0.3168 ...
##  $ fconc1  : num [1:19020] 0.1982 0.3773 0.0187 0.3922 0.1832 ...
##  $ fasym   : num [1:19020] 27.7 26.27 116.74 27.21 -5.53 ...
##  $ fm3long : num [1:19020] 22.01 23.82 -64.86 -6.46 28.55 ...
##  $ fm3trans: num [1:19020] -8.2 -9.96 -45.22 -7.15 21.84 ...
##  $ falpha  : num [1:19020] 40.09 6.36 76.96 10.45 4.65 ...
##  $ fdisk   : num [1:19020] 81.9 205.3 256.8 116.7 356.5 ...
##  $ class   : chr [1:19020] "g" "g" "g" "g" ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   X1 = col_double(),
##   ..   X2 = col_double(),
##   ..   X3 = col_double(),
##   ..   X4 = col_double(),
##   ..   X5 = col_double(),
##   ..   X6 = col_double(),
##   ..   X7 = col_double(),
##   ..   X8 = col_double(),
##   ..   X9 = col_double(),
##   ..   X10 = col_double(),
##   ..   X11 = col_character()
##   .. )
> DataExplorer::profile_missing(magic)
## # A tibble: 11 x 3
##    feature  num_missing pct_missing
##    <fct>          <int>       <dbl>
##  1 flength            0           0
##  2 fwidth             0           0
##  3 fsize              0           0
##  4 fconc              0           0
##  5 fconc1             0           0
##  6 fasym              0           0
##  7 fm3long            0           0
##  8 fm3trans           0           0
##  9 falpha             0           0
## 10 fdisk              0           0
## 11 class              0           0

不存在缺失值。

> table(magic$class)
## 
##     g     h 
## 12332  6688

g表示伽马射线,h表示背景辐射,重新编码为1和-1。

> magic$class <- as.factor(ifelse(magic$class == "g", 1, -1))

2、标准化和中心化

> pre <- preProcess(magic[, -11], method = c("center", "scale"))
> magic.new <- predict(pre, magic[, -11]) %>% 
+   bind_cols(class = magic$class)
> str(magic.new)
## tibble [19,020 × 11] (S3: tbl_df/tbl/data.frame)
##  $ flength : num [1:19020] -0.577 -0.511 2.568 -0.695 0.517 ...
##  $ fwidth  : num [1:19020] -0.337 -0.57 6.206 -0.687 0.476 ...
##  $ fsize   : num [1:19020] -0.381 -0.649 2.616 -1.029 0.711 ...
##  $ fconc   : num [1:19020] 0.0628 0.8204 -1.8758 1.282 -0.3475 ...
##  $ fconc1  : num [1:19020] -0.149 1.472 -1.773 1.607 -0.285 ...
##  $ fasym   : num [1:19020] 0.541 0.5169 2.0449 0.5328 -0.0202 ...
##  $ fm3long : num [1:19020] 0.225 0.26 -1.478 -0.334 0.353 ...
##  $ fm3trans: num [1:19020] -0.406 -0.49 -2.183 -0.355 1.037 ...
##  $ falpha  : num [1:19020] 0.477 -0.815 1.889 -0.659 -0.881 ...
##  $ fdisk   : num [1:19020] -1.498 0.153 0.843 -1.031 2.176 ...
##  $ class   : Factor w/ 2 levels "-1","1": 2 2 2 2 2 2 2 2 2 2 ...

3、拆分训练集和测试集

> ind <- createDataPartition(magic.new$class, p = 0.8, list = F)
> dtrain <- magic.new[ind, ]
> dtest <- magic.new[-ind, ]

4、逻辑回归

使用基本的逻辑回归模型,其结果作为基准对比。

> fit.glm <- glm(class ~ ., data = dtrain, family = binomial(link = "logit"))
> hat.train <- ifelse(fit.glm$fitted.values >= 0.5, 1, -1) %>% 
+   as.factor()
> hat.test <- predict(fit.glm, newdata = dtest, type = "response")
> hat.test <- ifelse(hat.test >= 0.5, 1, -1) %>% 
+   as.factor()
> res <- tibble(model = "glm",
+               train_acc = mean(hat.train == dtrain$class),
+               test_acc = mean(hat.test == dtest$class))
> res
## # A tibble: 1 x 3
##   model train_acc test_acc
##   <chr>     <dbl>    <dbl>
## 1 glm       0.789    0.796

5、装袋算法

> ctrl <- trainControl(method = "cv", number = 3L)
> 
> set.seed(123)
> fit.bag <- train(class ~ ., method = "treebag", data = dtrain, trControl = ctrl)
> fit.bag$finalModel
## 
## Bagging classification trees with 25 bootstrap replications
> train_acc <- mean(predict(fit.bag, newdata = dtrain, type = "raw") == dtrain$class)
> test_acc <- mean(predict(fit.bag, newdata = dtest, type = "raw") == dtest$class)
> res <- res %>% 
+   bind_rows(tibble(model = "bag",
+                    train_acc = train_acc,
+                    test_acc = test_acc))
> res
## # A tibble: 2 x 3
##   model train_acc test_acc
##   <chr>     <dbl>    <dbl>
## 1 glm       0.789    0.796
## 2 bag       0.997    0.879

6、增强 - AdaBoost自适应增强

> set.seed(123)
> fit.adaboost <- train(class ~ ., method = "adaboost", data = dtrain, trControl = ctrl)
> res <- res %>% 
+   bind_rows(tibble(model = "adaboost",
+                    train_acc = mean(predict(fit.adaboost, newdata = dtrain, 
+                                             type = "raw") == dtrain$class),
+                    test_acc = mean(predict(fit.adaboost, newdata = dtest, 
+                                            type = "raw") == dtest$class)))
> res
## # A tibble: 3 x 3
##   model    train_acc test_acc
##   <chr>        <dbl>    <dbl>
## 1 glm          0.789    0.796
## 2 bag          0.997    0.879
## 3 adaboost     1        0.888

7、增强 - gbm随机梯度增强

> set.seed(123)
> fit.gbm <- train(class ~ ., method = "gbm", data = dtrain, trControl = ctrl)
> res <- res %>% 
+   bind_rows(tibble(model = "gbm",
+                    train_acc = mean(predict(fit.gbm, newdata = dtrain, 
+                                             type = "raw") == dtrain$class),
+                    test_acc = mean(predict(fit.gbm, newdata = dtest, 
+                                            type = "raw") == dtest$class)))
> res
## # A tibble: 4 x 3
##   model    train_acc test_acc
##   <chr>        <dbl>    <dbl>
## 1 glm          0.789    0.796
## 2 bag          0.997    0.879
## 3 adaboost     1        0.888
## 4 gbm          0.876    0.874

8、随机森林

随机森林是一种基于装袋决策树的非常流行和强大的算法。

> set.seed(123)
> fit.rf <- train(class ~ ., method = "rf", data = dtrain, trControl = ctrl)
> res <- res %>% 
+   bind_rows(tibble(model = "rf",
+                    train_acc = mean(predict(fit.rf, newdata = dtrain, 
+                                             type = "raw") == dtrain$class),
+                    test_acc = mean(predict(fit.rf, newdata = dtest, 
+                                            type = "raw") == dtest$class)))
> res
## # A tibble: 5 x 3
##   model    train_acc test_acc
##   <chr>        <dbl>    <dbl>
## 1 glm          0.789    0.796
## 2 bag          0.997    0.879
## 3 adaboost     1        0.888
## 4 gbm          0.876    0.874
## 5 rf           1        0.885

可以看到,所有集成模型的性能都优于单纯的逻辑回归模型。
而本实例中,随机梯度增强模型(gbm)在训练集和测试集上的准确度最接近,拟合效果较好,所以应该选择使用该模型。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355