您的位置:首页 > 编程语言 > Python开发

Python实现:利用GBDT产生新特征(GBDT+Linear Regression)

2017-08-15 14:11 483 查看
Python实现:利用GBDT产生新特征(GBDT+Linear Regression)



最近实习接了个任务,利用GBDT产生新特征,加入到已有特征中,再训练线性模型,预测价格。

算法思想:

训练集上,用已有特征训练GBDT模型,然后利用GBDT模型学习到的树来构造新特征,最后把这些新特征加入原有特征一起训练模型。构造的新特征向量是取值0/1的,向量的每个元素对应于GBDT模型中树的叶子结点。当一个样本点通过某棵树最终落在这棵树的一个叶子结点上,那么在新特征向量中这个叶子结点对应的元素值为1,而这棵树的其他叶子结点对应的元素值为0。新特征向量的长度等于GBDT模型里所有树包含的叶子结点数之和。

画图说明一下:

 


虚线区域为x经过GBDT模型输出的新特征。

Python实现:

算法的难点在于如何获得GBDT模型每个叶子节点的输出状况,而这可以通过sklearn包中GradientBoostingRegressor的apply函数实现,其原理如下:

 


上面为GBDT模型下的三棵树,红色部分为某一样本x经过GBDT模型apply函数后的输出,为一个数组(4,7,6),但是(4,7,6)这样的数字是不能直接作为特征作为线性模型的输入的,因为这些数字只是一个位置的信息,并没有量的含义,所以需要用sklearn中的onehot编码(pandas中是dummy数据)将其转化为01

代码:

import numpy as np
import pandas as pd
from sklearn import linear_model
from sklearn.preprocessing import OneHotEncoder
from sklearn.ensemble import GradientBoostingRegressor
gbr=GradientBoostingRegressor()#x[i0]为训练样本输入,y[i0]为训练样本输出
gbr.fit(x[i0], y[i0])#训练GBDT模型
enc = OneHotEncoder()
enc.fit(gbr.apply(x[i0]))#将位置码转化为01码
new_feature_train=enc.transform(gbr.apply(x[i0]))
new_feature_train=new_feature_train.toarray()#将转化后的新特征转化为np数组形式
new_train=np.concatenate([x[i0],new_feature_train],axis=1)#与原特征拼接
#x[i1]和y[i1]为测试的输入和输出
new_feature_test=enc.transform(gbr.apply(x[i1]))#产生测试集对应的新特征
new_feature_test=new_feature_test.toarray()
new_test=np.concatenate([x[i1],new_feature_test],axis=1)

lr = linear_model.Ridge(alpha=1.5)
lr.fit(new_train, y[i0])#训练线性模型
print (abs(lr.predict(new_train) - y[i0])/y[i0]).mean()#计算mae
print (abs(lr.predict(new_test) - y[i1])/y[i1]).mean()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: