2 min read

"集成学习:Stacking 原理与实现

{r setup, include=FALSE} knitr::opts_chunk$set(eval = FALSE) {r message=FALSE, warning=FALSE, include=FALSE} library(tidyverse) library(knitr) write_bib(x = "SuperLearner",file = "auto.bib",prefix="")

stacking主要分为两类:

  • 用历史结果stacking
  • 用模型结果stacking

这是大方向,具体的迭代方法,之后介绍。

@stack 的文章是英文的,网上找到的中文翻译可以参考 @stackchi 。

用历史结果stacking

@stack 提到最简单的一种方式是,每次打比赛的时候,不要把历史的.csv文件删除,而是保存好,然后用for循环,批量导入后,直接stacking。

用模型结果stacking

我们可以发现每种模型都有自己的优点,以下列举、不穷举:

  • 逻辑回归、线性回归可以预测训练集中不存在$y$
  • 树模型可以处理非线性问题、缺失值,但是线性问题做的不好,往往需要特征工程
  • 支持向量机使用好的Kernel,可以处理非线性模型,而且快,但是缺失值问题处理不好。
  • 聚类,跑得快,但是一定要标准化数据,否则受到高量级数据影响大

具体stacking的方式

  • Voting ensembles
  • Ave. nsembles
  • Modeling emsembeles

Voting ensembles

stacking的好处

这里引用@stack的例子,假设我们有一组测试集,每个样本可能为$0,1$。

1111111111

我们用了三个模型 $f_1,f_2,f_3$, 准确率分别为 $\alpha_1=\alpha_2=\alpha_3=0.7$。

按照众数投票后,

一共有以下几种情况,

  • 三个全对:$p_1=0.7\times0.7\times0.7=$ r 0.7^3
  • 三个全错:$p_2=0.3\times0.3\times0.3=$ r 0.3^3
  • 有两个对:$p_3=\binom{2}{3}0.7^2\cdot0.3^1=$ r 3*0.7^2*0.3^1
  • 有一个对:$p_4=\binom{1}{3}0.7^1\cdot0.3^2=$ r 3*0.7^1*0.3^2

一次按照众数投票,第一种和第二种,我们都会最后选择$\hat y =1$,概率加总为 $p1+p2=$ r 0.7^3+3*0.7^2*0.3^1。 因此模型显然得到了提升。

这里假设了每个模型之间是独立的,因此可以概率直接相乘。 每个模型估计出来的$\hat y$之间的相关性,也影响之后$\hat y_{stack}$的准确性。 理论上,越小$\hat y_{stack}$的准确性越高。

对于 __Voting__一词,可以联想到对每个投票者给予不同的权重,这个权重在真实世界中就是每个投票者的地位,那么在stacking中,可以利用每个模型在公开比赛的准确率来作为weight。准确率越高的,weight越高。

举个例子

{r echo=FALSE} tibble::tribble( ~MODEL, ~PUBLIC.ACCURACY.SCORE, "GradientBoostingMachine", 0.65057, "RandomForest Gini", 0.75107, "RandomForest Entropy", 0.75222, "ExtraTrees Entropy", 0.75524, "ExtraTrees Gini (Best)", 0.75571 )

Ave. emsembles

$$\hat y_{stack} = \frac{\sum_{i=1}^n \hat f_i}{n}$$

$$\hat y_{stack} = \frac{\sum_{i=1}^n w_i\hat f_i}{\sum_{i=1}^n w_i}$$

$w_i$是每个模型权重。

Modeling emsembeles

根据 @stack 的解释, 我们在第二步,不是Voting也不是Ave.,而是用原来的特征向量,加上所有的$\hat y$来fit$f_{stack}$。

… where the outputs of the first-level learners are regarded as input features while the original labels are still regarded as labels of the new training data. [@Zhou2012, pp. 83-85]

因此这个$f_{stack}$就可以套用很多模型了,

  • 逻辑回归、线性回归可以预测训练集中不存在$y$。 这里可以引入 交叉项目
  • 树模型可以处理非线性问题、缺失值,但是线性问题做的不好,往往需要特征工程
  • 支持向量机使用好的Kernel,可以处理非线性模型,而且快,但是缺失值问题处理不好。
  • 聚类,跑得快,但是一定要标准化数据,否则受到高量级数据影响大

这里可以做聚类

单纯的聚类我们不能做是是因为没有监督一个$y$,但是这里对于$f_{stack}$,可以做聚类了,因为在第一步的所有$f_i$都进行了监督了,$f_{stack}$相当于把相似$\hat f_i$分在一起,从可视化角度,考虑t-SNE吧。

Automation stacking

这里可以类似于神经网络的完成,看图,但是已经没有什么sense,完全在丢模型。

{r automation-stacking-fig, echo=FALSE, out.width='80%', fig.align='center', fig.cap='自动化Stacking示意图'} knitr::include_graphics('autometicstacking.png')

stacking中,第二层使用LM的依据

如果第一个模型不好,存在$\hat \mu$,可能大部分的$y$是偏高于$\hat y$的,这个时候可以乘上一个一个系数扩大$\hat y$,这个系数就是LM里面的$\hat \beta$。 # 总结

其实idea理解起来还是非常简单的,基本上了解了随机森林和神经网络部分,这部分很好理解。 R中已经有ensembles的包了,那么SuperLearner,我估计里面的底层逻辑就是$f_{stack}$就是线性回归或者逻辑回归,所以还是比较简单。 而且这个除了Automation那一版本比较复杂点,其它的都可以自己手动来。

参考文献与扩展阅读

<!-- 
以下是一些关于集成学习:的参考书籍,供进一步学习:

## 推荐阅读

### 核心参考
- **Zhi-Hua Zhou. - Ensemble methods: foundations and algorithms**
  - 全书234页,第98页专门介绍Stacking
  - 链接:http://gen.lib.rus.ec/book/index.php?md5=4A4B90E0737BB707BAED5FCD99C99DD6

### 其他相关书籍
- Robi Polikar (auth.), Cha Zhang, Yunqian Ma (eds.) - Ensemble Machine Learning: Methods and Applications
- Lior Rokach - Pattern Classification Using Ensemble Methods
- Giovanni Seni, John Elder - Ensemble Methods in Data Mining: Improving Accuracy Through Combining Predictions

## 注意事项
- 部分书籍可能难以找到或下载链接已失效
- 建议优先阅读Zhi-Hua Zhou的著作,内容最为全面
- 实际应用中,SuperLearner包已经提供了很好的实现
-->
<!-- 注释:原计划添加参考文献列表,但考虑到文章已经引用了关键文献,且SuperLearner包文档足够详细,故保留此部分作为扩展阅读建议 -->