树模型与线性模型的融合模型(Python实现)

目录

一、树模型与线性模型的融合模型

二、Python sklearn实现GBDT+LR融合模型


一、树模型与线性模型的融合模型

树模型GBDT原理:https://blog.csdn.net/woniu201411/article/details/83114226

线性模型LR原理:https://blog.csdn.net/woniu201411/article/details/81335863

海量的离散特征+线性模型LR,因其较高的精度和较少的运算开销在业界广为使用。 线性模型LR无法捕捉到非线性特征对标签的影响,因而提升线性模型精度的有效方法是构造有效的交叉特征。比较成熟的构造交叉特征的方法包含:

  1. 结合业务,构造有效的交叉特征,这种方法对线性模型的精度提升是显著的,但要花费巨大的人力和时间,特别当特征达到上百维时,难以构造有效的交叉特征;
  2. 根据信息增益,分箱划分连续特征,将一个连续特征划分为多个类别特征,为线性模型增加了非线性表达,提高了模型的精度和健壮性。但这种方法构造的非线性特征包含的信息是很有限的;
  3. 离散特征通过笛卡尔积,获取所有的组合特征,但笛卡尔积获取的组合特征呈爆炸式增长,并且很多组合特征是无效的,为线性模型增加了很多噪音。

2014年faceBook提出了树模型GBDT与线性模型LR的融合模型(Practical Lessons from Predicting Clicks on Ads at Facebook),利用GBDT构造有效的交叉特征,从根节点到叶子节点的路径,代表部分特征组合的一个规则,提升树将连续特征转化为离散特征,可以明显提升线性模型的非线性表达能力,提高线性模型精度

以下图所示,GBDT构造两棵树,第一棵树有三个叶子节点,第二颗树有两个叶子节点,若训练样本落入第一棵树的第二个叶子节点,第二颗树的第一个叶子节点,GBDT构造的交叉离散特征输出为[0,1,0,1,0],其中前三个元素对应第一棵树的叶子节点,后两个元素对应第二颗树的叶子节点,输出的交叉离散特征作为LR的输入。

关于GBDT与LR融合模型的思考:

1、树模型采用集成决策树,而非单颗决策树

一棵树的表达能力很弱,不足以表达多个有区分性的特征组合,多棵树的表达能力更强一些。GBDT每棵树都在学习前面棵树尚存的不足,迭代多少次就会生成多少颗树。按paper的GBDT+LR融合方式,多棵树正好满足LR每条训练样本可以通过GBDT映射成多个特征的需求。

2建树采用GBDT而非RF

RF也是多棵树,但从效果上有实践证明不如GBDT。且GBDT前面的树,特征分裂主要体现对多数样本有区分度的特征;后面的树,主要体现的是经过前N颗树,残差仍然较大的少数样本。优先选用在整体上有区分度的特征,再选用针对少数样本有区分度的特征,思路更加合理,这应该也是用GBDT的原因。

二、Python sklearn实现GBDT+LR融合模型

引用包引入:

import numpy as np
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import (RandomTreesEmbedding,RandomForestClassifier,GradientBoostingClassifier)
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve,roc_auc_score,accuracy_score,auc

数据集划分(树模型和线性模型的训练分别用不同数据集,防止过拟合):

tmp = np.loadtxt("E:\\ensembleModelData.csv",dtype=np.str,delimiter=',')
data = tmp[1:,2:-1].astype(np.float)
label = tmp[1:,-1].astype(np.int)
#data,label = make_classification(n_samples=80000,n_features=30)
X_train,X_test,Y_train,Y_test = train_test_split(data,label,test_size=0.2)
X_train_tree,X_train_lr,Y_train_tree,Y_train_lr = train_test_split(X_train,Y_train,test_size=0.5)

利用网格搜索,获取最优参数:

for n_estimator in [80,100,150,200,250]:
    for depth in [1,2,3,5]:
        for maxiter in [300,400,500]: 
            GBDT = GradientBoostingClassifier(learning_rate=0.1,n_estimators=n_estimator,max_depth=depth)
            OHE = OneHotEncoder()
            LRGBDT = LogisticRegression(max_iter=maxiter)

            GBDT.fit(X_train_tree,Y_train_tree)
            OHE.fit(GBDT.apply(X_train_tree)[:,:,0])
            LRGBDT.fit(OHE.transform(GBDT.apply(X_train_lr)[:,:,0]),Y_train_lr)
            Y_pred_gbdt_lr = LRGBDT.predict_proba(OHE.transform(GBDT.apply(X_test)[:,:,0]))[:,1]
            auc_gbdt_lr = roc_auc_score(Y_test,Y_pred_gbdt_lr)
            print(n_estimator,depth,maxiter,auc_gbdt_lr)

最终结果为:100,5, 500, 0.9440185179246727

 

参考资料:

Practical Lesson from Predicting Clicks on Ads at Facebook

https://blog.csdn.net/u010352603/article/details/80681100

https://blog.csdn.net/asdfghjkl1993/article/details/78606268

https://blog.csdn.net/TwT520Ly/article/details/79769705

https://scikit-learn.org/stable/auto_examples/ensemble/plot_feature_transformation.html#sphx-glr-download-auto-examples-ensemble-plot-feature-transformation-py

 

猜你喜欢

转载自blog.csdn.net/woniu201411/article/details/84859022