我一直在使用Sklearn中的Boostings功能,我注意到sklearn.ensemble.GradientBoostingRegressor
和sklearn.ensemble.AdaBoostRegressor
之间的关键区别。虽然后者允许用户指定基础学习者,但前者不允许。具体来说,sklearn.ensemble.GradientBoostingRegressor
仅使用树。这有点烦人,因为在Gradient Boosting中使用OLS和Spline基础学习者会很不错。我错过了什么吗? Sklearn库中的另一个函数或不同的python库是否提供此功能?
答案 0 :(得分:3)
这是实现目标的一种方式。
将sklearn/ensemble/gradient_boosting.py
替换为this script。
然后,您就可以将base_estimator
传递给GradientBoostingRegressor
。
如果您满意,请尽情享受。如果没有,请参阅下面的讨论。
在开始之前,我想提一些事情。此帖中的所有图都可以从the scripts available in my repo复制到此项目中。只需将restore.sh
和run.sh
的内容替换为本地安装Sklearn的相应目录即可。请记住,两个bash脚本将永久覆盖现有的Sklearn文件(gradient_boosting.py
)。您只需从Sklearn仓库复制文件即可恢复该文件。我并不是说在这篇文章中展示的任何内容都是开发Sklearn新功能的好方法。我不隶属于Sklearn,也不是一位经验丰富的软件开发人员。所有脚本都在Sklearn 18.2上进行了测试。
现在,使用新的gradient_boosting.py
脚本,我们可以指定线性基础学习器(通常用于AdaBoostRegressor
)。作为一个完整性检查,我们可以将线性基础GBR放在单个变量上,并确保在针对该变量绘制时产生线性视觉。这是波士顿住房数据集中四个(任意)变量的结果。
作为另一个健全性检查,我们可以确保通过将树base_estimat传递给新的GBR来再现原始的基于树的GBR的结果。下图是关于增强迭代的MSE 10倍交叉验证配置文件。也就是说,对于每次增强迭代次数,我交叉验证以获得10个MSE分数的向量并计算该向量的平均值/分钟。左图是原始GBR,而右图是使用新gradient_boosting.py
的图。
我们可以use any diffchecker将原始gradient_boosting.py
与新版_fit_stage()
进行比较。这将显示我为创建此新脚本所采取的所有步骤,但主要步骤是修改_decision_function()
和_fit_stage()
方法。在tree
内,负责在每次提升迭代时拟合学习者,我们注意到基础学习者(名为DecisionTreeRegressor
)用base_estimator
实例化,所以我们只需要添加以下内容条件,以便此方法使用if (self.base_estimator is None or
isinstance(self.base_estimator,
(BaseDecisionTree, BaseForest))):
# Original code for decision trees will go here.
else:
base_learner = self.base_estimator
if X_csc is not None:
base_learner.fit(X_csc, residual, sample_weight=sample_weight)
else:
base_learner.fit(X, residual, sample_weight=sample_weight)
if X_csr is not None:
y_pred[:, k] += self.learning_rate * base_learner.predict(X_csr).ravel()
else:
y_pred[:, k] += self.learning_rate * base_learner.predict(X).ravel()
self.estimators_[i, k] = base_learner
参数指定的自定义学习器:
_decision_function()
接下来,我们可能会检查predict()
,它负责在从GradientBoostingRegressor
调用顶级predict_stages()
函数时计算增强结果。这里,计算的核心在于一个名为.pyx
的函数,它是仅用于基于树的集合的增强步骤的相当低级的Cython(predict_stages()
)实现。为了为任意基础学习者计算此步骤,我们绕过整个def _decision_function(self, X):
score = self._init_decision_function(X)
score += self.learning_rate*sum(estimator[0].predict(X) for estimator in self.estimators_).reshape((-1, 1))
# predict_stages(self.estimators_, X, self.learning_rate, score)
return score
计算并在Python级别手动输入:
BaseGradientBoosting
以上两个变化是我认为需要做出的主要变化。其余的都是次要的技术细节,包括:
GradientBoostingRegressor
和sample_weights
的类定义中包含超文本)您选择的基础学习者必须能够支持'ls'
参数。出于这个原因,我无法插入类似样条的回归量(如PyEarth)。如果您或任何人设法实现此目的,请告诉我。
另请注意,使用非树基础学习者时,您仍可以无错误地传递与树相关的参数,但当然,它们将被完全忽略。
以下是我的脚本无法做到的事情:
base_estimator
之外的其他损失。 (也许它可以,但我还没试过。)GradientBoostingClassifier
传递给{{1}} 总的来说,这只是真正定制基础学习者的一个温和的开端。希望它有所帮助。