我一直在使用逻辑回归(LR与start_params作为前一个(训练)数据集获得的参数&L1正则化)来建模我们的用例(使用一些复杂的特征转换)。我在部分相同的数据上尝试了梯度增强分类器,它似乎给出了更好的拟合。传统上,我一直在使用梯度增强分类器的特征重要性,并将其用作LR特征工程的反馈。
我认为完全采用梯度增强(GB)的典型障碍是,我不太理解如何将"学习树"表述为其数学结构。到目前为止,我主要使用SKLearn文档中的这些分类和回归示例来玩&比较预测。
问题:我知道梯度增强是一个非参数模型。这是否意味着我永远都无法恢复数学结构。抱歉,如果这听起来很原始,但我没有将这些推向生产的经验。也就是说,除非我真的学会了。实时预测类别,我如何将标签"分类"到一个类别或另一个类别?如何在生产中使用该模型?
# Fit regression model
params = {'n_estimators': 500, 'max_depth': 4, 'min_samples_split': 1,
'learn_rate': 0.01, 'loss': 'ls'}
clf = ensemble.GradientBoostingRegressor(**params)
pred_object=clf.fit(X_train, y_train)
pred_object
GradientBoostingRegressor(alpha=0.9, init=None, learning_rate=0.01, loss='ls',
max_depth=4, max_features=None, min_samples_leaf=1,
min_samples_split=1, n_estimators=500, random_state=None,
subsample=1.0, verbose=0)
# Next, I get the feature importances,
pred_object.feature_importances_
array([ 3.08111834e-02, 1.44739767e-04, 1.31885157e-02,
2.68202997e-05, 3.01134511e-02, 2.82639689e-01,
7.67647932e-02, 5.90503853e-02, 7.86688625e-03,
2.48124873e-02, 8.52094429e-02, 3.93616279e-02,
3.50009978e-01])
我深入研究了dir(pred_object)
,但找不到我能立即理解的东西。在给定特征重要性数组,损失函数='ls', alpha &其他参数吗?或者,因为它是一个树,所以在尝试预测新数据点的类别时,它将总是尝试"重新平衡"更多的数据点(测试集)?
有两种方法可以将GBM "投入生产"。
- 将数据拉入python、R或用于拟合模型的任何语言。对其进行评分,并将其写回数据库(或任何您的生产数据存储)。这实际上可以很好地扩展:如果你可以将需要评分的"事件"放到队列中,你可以有20、100或1000台机器运行你的python模型的副本,独立地对每个"事件"进行评分。
- 将模型编码为SQL语句,并在您选择的数据库上运行。(如果你正在使用nosql数据库或其他数据存储,希望你有一些方法运行If -then-else语句)。
1是不言自明的。将生产数据分解为可管理的块,并在运行模型的不同机器上对每个块进行评分。这需要一些工作来构建基础结构,但是您不需要更改任何建模代码。
2更难理解:基于树的模型的核心是if-else语句的集合:
if var1>10 and var2<3 then outcome = 0
else if var1<10 and var2<3 then outcome = 1
else if var2<10 and var2<1 then outcome = 0
等。
这样的语句很容易在基于sql的数据库中编码,并且在大多数编程语言中也很容易编码。如果您可以在python中循环遍历GBM中的每个树并将其转换为SQL语句,则可以通过运行每个SQL语句并将其乘以GBM的正确权重来在生产中对模型进行评分。这需要您将模型转换为另一种语言,但它允许您在不将数据从数据存储中取出的情况下对数据进行评分。
梯度增强,以及经典的决策树和随机森林,都属于所谓的树建模或树方法。这意味着他们的得分逻辑通常只是"if then, else if…"其他"。不确定这是否符合"数学结构"的要求。我想没有。
根据需要数学构造的目的,我可以在以后进行扩展。我怀疑也许观察或行明智的贡献计算建立的GB模型可能是问题背后的动机。
SKompiler库可以通过将训练好的模型翻译成SQL(或各种其他语言)中的表达式来提供帮助。
from skompiler import skompile
import sys
sys.setrecursionlimit(10000) # Necessary for models with many estimators
expr = skompile(gbr.predict)
现在可以获得模型的SQL形式:
sql_code = expr.to('sqlalchemy/sqlite')
或将其翻译为C代码(至少在GradientBoostingRegressor的情况下,与其他类C语言兼容,如c++/c#/Java/Javascript)
c_code = expr.to('sympy/c')
或to Rust:
rust_code = expr.to('sympy/rust')
或R:
r_code = expr.to('sympy/r')
或甚至到Excel公式:
excel_code = expr.to('excel')
(使用n_estimators=500
时,您将无法将其粘贴到Excel单元格中,因为公式将比Excel允许的最大8196个字符长)
最后,从SKompiler expr
对象编写一个编译器到您可能需要的部署类型的表示或代码并不太复杂。