Py学习  »  机器学习算法

Stata中的堆栈泛化和机器学习-pystacked

连享会 • 1 年前 • 444 次点击  

👇 连享会 · 推文导航 | www.lianxh.cn

连享会课程 · 2024 Stata 寒假班

温馨提示: 文中链接在微信中无法生效。请点击底部「阅读原文」。或直接长按/扫描如下二维码,直达原文:

作者:冯乔 (中山大学)
邮箱:fengq33@mail2.sysu.edu.cn

编者按:本文主要整理自下文,特此致谢!
Source:Ahrens A, Hansen C B, Schaffer M E. pystacked: Stacking generalization and machine learning in Stata[J]. arXiv preprint arXiv:2208.10896, 2022. -PDF-

1. 理论基础

1.1 引入

当前,存在很多为人熟知的机器学习算法,例如支持向量机、神经网络、随机森林等等。应用这些算法,能够解决很多回归或分类问题,得到比一般线性模型拟合效果更好的结果。但是,这些机器学习模型之间存在着差异,那么,当它们输出的回归或分类结果不同的时候,我们应该选择哪一个?

堆叠 (Stacking,又叫做 Meta ensembling) 就是集成多个模型的解决之道。通过堆叠,我们能够对多个模型的输出结果进行加权,得到较于单一模型来说,稳定性更好的集成模型,同时也能够兼顾准确性 (比如,可以对表现好的模型赋予更高的权重) 。

pystacked 能够帮助使用者,在 Stata 中调用 Python 的 Scikit-learn 包,实现堆叠回归 (Wolpert,1992),支持使用线性回归、逻辑回归 (Logit)、套索算法 (Lasso)、岭回归 (Ridge)、弹性网络 (Elastic net)、线性支持向量机 (Linear SVM)、梯度提升 (Gradient boosting)、神经网络 (其中的 MLP)。

pystacked 至少需要 Stata 16 (或更高),安装 Python 和 Scikit-learn (0.24 或更高)。

1.2 堆叠的数学原理

本节主要介绍对于回归与二分类问题的堆叠方法,分成堆叠回归与堆叠分类两部分介绍。

1.2.1 堆叠回归

对于一个多变量的回归问题,堆叠的思路是用一个最终评估器 (即最终的集成模型) 来结合数个基分类器 (即集成模型中所使用的多个机器学习分类算法) 进行预测。当模型纳入较多且差别较大的基分类器,这种方法更能捕捉数据中的特征。

第一步,对于每个基分类器 ,我们得到交叉验证的预测值 。如果不使用交叉验证,堆叠会给过拟合的基分类器更高权重,因此交叉验证是必要的。

交叉验证即为,把数据随机地分成大小相等的 组 (即 折),每次取一组作为测试集,用其他 组做训练集,对测试集进行预测。

第二步,用实际值 作为输出值,交叉验证中预测的 ,……, 作为预测值,拟合出最终评估器。拟合最终评估器时,默认使用非负最小二乘法 (NNLS)。

堆叠回归的预测值为

1.2.2 堆叠分类

pystacked 支持用于二分类问题, 取 0 或 1,除了基分类器输出的是分类的概率,其他部分与堆叠回归相同。

1.3 基分类器

接下来介绍基分类器可以使用的的算法,这些基分类器可以用于堆叠,也可以单独使用。线性回归、逻辑回归与回归树不做赘述,以下是其他的算法。

正则化回归对系数的大小施加惩罚来控制过度拟合。套索 (Lasso) 惩罚系数的绝对大小,而岭回归 (Ridge) 惩罚系数的平方和。两种方法都将系数往 0 进行缩小。弹性网结合了套索和岭回归惩罚。对于套索算法,pystacked 还支持选择 AIC 或 BIC 惩罚。使用 AIC 或 BIC 的优点是计算强度低于交叉验证。

随机森林依赖于大量的回归或决策树。随机森林的预测是单个树的平均。随机森林的重要参数是:树的数量 (n_estimators()),单一树的最大深度 (max_depth()),每片叶子的最小观测数 (min_samples_leaf() ),每次分组时考虑的特征数量 (max_features()) 和 bootstrap 样本的数量 (max_samples())。

梯度提升树同样依赖于大量的树。不同于随机森林,这些树根据当前模型的残差有顺序地进行拟合。除了树的数量 (n_estimators()) 是重要参数外,学习率 (learning_rate()) 决定了最新的树对与整体模型有多大影响。

支持向量机 (SVM) 通过一个超平面对观测值进行分类。超平面是基于最大距离 (使得观测值离平面距离最大) 来选择的,同时允许一定程度的分类错误。C 参数 (C()) 控制着分类错误的频率和程度。超平面可以是线性的或者用核函数 (kernel) 拟合的。SVM 同样可以用于回归。

前馈神经网络由输入层-隐含层-输出层组成,每一个隐含层包含多个节点,通过激活函数将信号传输到下一层。重要参数是激活函数的选择 (activation()),隐含层的大小和数量 (hidden_layer_sizes())。以下为全部可使用的基分类器:

method()type()description
olsregressLinear regression
logitclassLogistic regression
lassoicregressLasso with AIC/BIC penalty
lassocvregressLasso with CV penalty

classLogistic lasso with CV penalty
ridgecvregressRidge with CV penalty

classLogistic ridge with CV penalty
elasticcvregressElastic net with CV penalty

classLogistic elastic net with CV
svmregressSupport vector regression

classSupport vector classification
gradboostregress Gradient boosting regression

classGradient boosting classification
rfregressRandom forest regression

classRandom forest classification
linsvmclassLinear SVC
nnetregressNeural net regression

classNeural net classification

2. 命令介绍

2.1 命令安装

ssc install pystacked, replace

2.2 命令语法

第一个语法,使用 methods(string) 来选择基分类器,string 是基分类器的列表。最多可以选择 10 个基分类器,pipe*(string) 用于预测器的预处理。xvars(predictors) 允许对分类器指定采用的变量列表。

pystacked depvar predictors [if] [in], [,methods(string) cmdopt1(string)
cmdopt2(string) ... cmdopt10(string) pipe1(string) pipe2(string) ...
pipe10(string) xvars1(predictors) xvars2(predictors) ...
xvars10(predictors) general options ]

第二个语法更加灵活,对于基分类器的数量没有限制 (虽然还要考虑计算的复杂程度),基分类器通过 method(string) 添加,之后是对特定的分类器进行设置,用 || 分隔。

pystacked depvar [indepvars] || method(string) opt(string) 
pipe(string) xvars(predictors)
[|| method(string) opt(string) pipe(string) xvars(predictors) ... || ]
[if][in][, general options]

2.3 预测结果输出

获得预测值:

predict type newname [if][in][, pr xb ]

获得每一个基分类器的拟合值:




    
predict type stub [if][in][, transform ]

输出表格 (如果是回归问题,报告预测的均方预测误差 MSPE,如果是分类问题,输出混淆矩阵):

pystacked [, table holdout[(varname)] ]

输出图片展示模型性能:

pystacked [, graph[(options)] lgraph[(options)] histogram
holdout[(varname)] ]

2.4 数据预处理

Sklearn 使用 pipelines 来对输入数据进行预处理,可以填充缺失值、创建交互项、进行标准化。下表为可用的 pipelines。

pipe*()Description
stdscalerStandardize to mean zero and unit variance (default for regularized regression)
nostdscalerOverwrites default standardization for regularized regression
stdscaler0Standardize to unit variance
sparseTransform to sparse matrix
onehotCreate dummies from categorical variables
minmaxscalerScale to 0-1 range
medianimputerMedian imputation
knnimputerKNN imputation
poly2Add 2nd-order polynomials
poly3Add 3rd-order polynomials
interactAdd interactions

3. 应用

3.1 单一基分类器

这里采用了加州房屋价格数据,以 75/25 的比例将数据随机划分为训练集和测试集。任务是通过一系列房价特征数据预测房屋价格。首先准备数据:

. clear all
. use https://statalasso.github.io/dta/cal_housing.dta, clear
. set seed 42
. gen train=runiform()
. replace train=train<.75>. replace medh = medh/10e3
. label var medh

采用 pystacked 的梯度提升回归树,并且保存样本外预测值:设置 type(reg)method(gradboost)

. pystacked medh longi-medi if train, type(reg) methods(gradboost)
. predict double yhat_gb1 if !train

由于是单一基回归器,可见权重为 1。

|Method|Weight|
|----------|:-----:|
|gradboost| 1.0000000|

3.2 堆叠回归

还以同样的数据为例,采用多个基分类器:

  • 线性回归
  • 套索+交叉验证惩罚
  • 套索+二阶多项式+交互作用
  • 默认参数的随机森林
  • 梯度提升,学习率=0.01,树的数量=1000
. pystacked medh longi-medi if train,       ///
> type(regress) ///
> methods(ols lassocv lassocv rf gradboost) ///
> pipe3(poly2) cmdopt5(learning_rate(0.01) ///
> n_estimators(1000))

输出堆叠权重如下:

MethodWeight
ols0.0000000
lassocv0.0000000
lassocv0.4692388
rf0.2505079
gradboost0.2802533

使用第二种句法规则,实现相同的功能:

. set seed 42
. pystacked medh longi-medi || ///
> m(ols) || ///
> m(lassocv) || ///
> m(lassocv) pipe(poly2) || ///
> m(rf) || ///
> m(gradboost) opt(learning_rate(0.01) n_estimators(1000)) ///
> if train, type(regress)

输出堆叠权重相同。

输出堆叠预测值与每个基分类器的预测值 (使用 transf 选项):

. predict double yhat, xb
. predict double ytrans, transf
. list yhat ytrans* if _n <= 5

绘图 (横轴为观测值,纵轴为预测值,绘制散点图,红线为 45 度线):

. pystacked, graph holdout

3.3 堆叠分类

pystack 可用于二元的分类问题。这里采用了 UCI 机器学习库的垃圾邮件识别数据。首先,载入数据并且分成训练集和测试集。

. insheet using ///
> https://archive.ics.uci.edu/ml/machine-learning-databases/spambase/spambase.data, ///
> clear comma
. set seed 42
. gen train=runiform()
. replace train=train<.75>

采用五个基分类器:

  • 逻辑回归 + 二次项 + 交互项
  • 梯度提升,600个分类树
  • 梯度提升,1000个分类树
  • 神经网络,两个隐含层,每层五个节点
  • 神经网络,一个隐含层,五个节点
. pystacked v58 v1-v57 || ///
> m(logit) pipe(poly2) || ///
> m(gradboost) opt(n_estimators(600)) || ///
> m(gradboost) opt(n_estimators(1000)) || ///
> m(nnet) opt(hidden_layer_sizes(5 5)) || ///
> m(nnet) opt(hidden_layer_sizes(5)) || ///
> if train, type(class) njobs(8)

输出混淆矩阵:

. pystacked, table holdout

绘制 ROC 曲线(受试者工作特征曲线),y 轴为灵敏性,x 轴为特异性。曲线下方的面积 (AUC) 是衡量分类效果的重要指标。面积为 0.5 为随机分类,识别能力为 0,面积越接近于 1 识别能力越强,面积等于 1 为完全识别。

. pystacked, graph(subtitle(Spam data)) ///
> lgraph(plotopts(msymbol(i) ///
> ylabel(0 1, format(%3.1f)))) ///
> holdout

4. 总结

pystacked 在 Stata 中调用 Python 第三方包 Sklearn 实现机器学习回归与分类。既可以实现单个分类器,也可实现堆叠回归与分类,并且也实现了模型相关评价指标的输出与可视化,使得解决机器学习问题更加方便快捷。

5. 相关推文

Note:产生如下推文列表的 Stata 命令为:
lianxh 机器学习, m
安装最新版 lianxh 命令:
ssc install lianxh, replace

  • 专题:机器学习
    • Drukker, 刘迪, 2020, Stata Blogs - An introduction to the lasso in Stata (拉索回归简介), 连享会 No.117.
    • 仵荣鑫, 2022, 知乎热议:如何学习机器学习, 连享会 No.983.
    • 全禹澄, 2021, 机器学习如何用?金融+能源经济学文献综述, 连享会 No.670.
    • 关欣, 2022, 机器学习在经济学领域的应用前景, 连享会 No.905.
  • 专题:Python-R-Matlab
    • 吕卓阳, 2021, MLRtime:如何在 Stata 调用 R 的机器学习包?, 连享会 No.85.
    • 吴小齐, 2023, R语言:L2 Boosting 在经济学中的应用, 连享会 No.1288.
    • 张瑞钰, 2021, 知乎热议:纠结-计量经济、时间序列和机器学习, 连享会 No.585.
  • 专题:论文写作
    • 李占领, 2020, Semantic scholar:一款基于机器学习的学术搜索引擎, 连享会 No.177.
  • 专题:内生性-因果推断
    • 李金桐, 2023, 因果推断:双重机器学习-ddml, 连享会 No.1221.
    • 樊嘉诚, 2021, Stata:机器学习分类器大全, 连享会 No.505.
    • 王卓, 2023, Python:从随机实验到双重机器学习, 连享会 No.1204.
  • 专题:Stata命令
    • 董洁妙, 2022, Stata:双重机器学习-多维聚类标准误的估计方法-crhdreg, 连享会 No.1036.
  • 专题:其它
    • 赵莹, 2022, 知乎热议:机器学习在经济学的应用前景, 连享会 No.938.
  • 专题:Stata教程
    • 连享会, 2021, Stata-Python交互-7:在Stata中实现机器学习-支持向量机, 连享会 No.557.
  • 专题:专题课程
    • 连享会, 2023, 基于机器学习的因果推断方法-司继春主讲, 连享会 No.1162.
    • 连享会, 2023, 文本分析:从文本到论文, 连享会 No.1259.
  • 专题:Stata资源
    • 连享会, 2022, 连享会主页-推文列表-按时间, 连享会 No.449.
    • 连享会, 2022, 连享会主页-推文列表-按类别, 连享会 No.448.
    • 马丁, 刘梦真, 2021, 机器学习:随机森林算法的Stata实现, 连享会 No.568.

🍏 关于我们

  • 连享会 ( www.lianxh.cn,推文列表) 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 直通车: 👉【百度一下: 连享会】即可直达连享会主页。亦可进一步添加 「知乎」,「b 站」,「面板数据」,「公开课」 等关键词细化搜索。


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/165402
 
444 次点击