NGBoost

背景介绍

从DT到GBT,Xgboost,lightgbm,算法的稳定性和泛化能力在进一步的增加,之前的迭代方面主要集中在梯度提升和学习维度,以及降低模型的过拟合增加正则化,或者提升精度增加求导阶数。这些机器学习工具用于预测,且达到相当高的精确度,但也有些场景并没有特别大的把握能做出准确预测,如天气预测及寿命预测;另外自动决策系统尤其需要对不确定性的估计,以便提前做好备选方案应对;还有若在得到预测值的同时看到置信区间,如果真实值偏离预测值较远,但还落在该样本对应的置信区间内(只是置信区间也很大),则说明问题未必出现在模型上。(方便在跨部门/企业合作中撕的时候提供证据

仅仅是把标签值换成概率分布(的参数)并不能简单解决问题,于是为了做到“预测分布”这件事,作者引入更多相关数学概念对底层一番改造:
适当得分法则(Proper Scoring Rules)

NGBoost(Natural Gradient Boosting)是一种概率预测模型,它结合了梯度提升树和自然梯度下降的思想。NGBoost 的主要目标是通过预测目标变量的分布来提高预测精度,而不仅仅是预测一个点估计值(这里更多是针对回归问题,分类问题其他模型也可以支持)。

NGBoost 使用自然梯度下降来更新模型参数,可以减少训练过程中的振荡和收敛时间。自然梯度下降是梯度下降的变体,它使用 Fisher 信息矩阵来归一化梯度方向,以便在不同参数空间中进行更准确的更新。这种方法可以使得 NGBoost 更加鲁棒,并且具有更好的收敛性能。

1. 梯度提升(Gradient Boosting)

梯度提升是一种集成学习方法,它通过构建一系列的弱学习器(通常是决策树),并将它们以加权方式组合起来,来提高模型的预测性能。在每一步迭代中,新的弱学习器被添加到模型中,以最小化损失函数的梯度。

2. 自然梯度

自然梯度是一种在优化中使用的梯度,它考虑了参数空间中的度量结构。在传统的梯度下降中,使用的是欧几里得度量(即L2范数),而自然梯度则使用Fisher信息矩阵(或其逆)作为度量矩阵,从而考虑了参数间的依赖关系。这种方法可以使得优化过程更加高效,尤其是在参数空间具有复杂结构时。

3. NGBoost算法原理

NGBoost结合了上述两种思想:
模型构建:NGBoost使用一系列的弱学习器(通常是决策树),这些树在每一步迭代中根据当前模型的预测误差来构建。
自然梯度优化:在每一步迭代中,使用自然梯度而不是标准的梯度来更新模型的参数。自然梯度通过考虑Fisher信息矩阵(FIM)来调整梯度方向,使得优化过程更加高效和稳定。FIM是对参数的二阶导数进行估计,反映了参数间的相关性。
贝叶斯推断:NGBoost在内部使用贝叶斯推断框架来估计模型的参数和不确定性。这有助于生成预测的不确定性度量,例如预测的置信区间。

4. 优点

高效性:使用自然梯度可以减少在参数空间中的震荡,提高优化效率。
不确定性估计:通过贝叶斯方法,NGBoost能够提供模型预测的不确定性估计。
泛化能力:通过考虑参数间的依赖关系,NGBoost有助于提高模型的泛化能力。

5. 应用场景

NGBoost特别适用于需要高精度预测和不确定性估计的场景,如金融市场预测、医学诊断等。

ngboost建模

注意点:
(1)不支持类别型变量入模,需要自行编码
(2)不支持缺失数据入模,需要自行填充
(3)由于模型复杂度高,训练、推理速度减慢,不过通用参数效果依然很好

1、回归方面

 from ngboost import NGBRegressor
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split

# 生成数据
X, y = make_regression(n_samples=1000, n_features=20, noise=0.1, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
 
# 创建模型并训练
model = NGBRegressor(n_estimators=100, learning_rate=0.01)
model.fit(X_train, y_train)
 
# 评估模型
y_pred = model.predict(X_test)

2、分类方向

ngb_params={
    'Dist':k_categorical(2), # 预测值y的分布,取值k_categorical, Bernoulli,Normal,Exponential等
    'Score':LogScore, # 损失函数,取值LogScore, CRPScore
    'Base':default_tree_learner, # 基学习器、类似于子树,取值default_tree_learner、DecisionTreeRegressor(criterion='friedman_mse', max_depth=4)
    'natural_gradient':True,   # 自然梯度 or 常规梯度
    'n_estimators':1000,  # 迭代次数
    'learning_rate':0.01,  # 学习速率
    'minibatch_frac':1.0,  # 行采样
    'col_sample':1.0,  # 列采样
    'verbose':True,
    'verbose_eval':100,
    'tol':0.0001,   # 迭代过程中损失函数阈值,当损失函数的变化小于tol时,训练过程将停止
    'random_state':1,
}
 
def ngboost_model(df,y_name,fea_list,params):
    x_train,x_test, y_train, y_test =train_test_split(df[fea_list],df[y_name],test_size=0.2, random_state=123)
    
    model = NGBClassifier(**params)
    model.fit(x_train, y_train)
    
    train_pred = model.predict_proba(x_train)[:,1]
    train_auc= roc_auc_score(list(y_train),train_pred)
    
    test_pred = model.predict_proba(x_test)[:,1]
    test_auc= roc_auc_score(list(y_test),test_pred)
    
    result={
        'train_auc':train_auc,
        'test_auc':test_auc,
    }
    return model,result
 
ngboost_model,model_result=ngboost_model(df_copy.fillna(-1),'isDefault',float_col,ngb_params)
model_result
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容