数据挖掘面试题之GBDT构建新特征

GBDT构建新的特征思想
特征决定模型性能上界,例如深度学习方法也是将数据如何更好的表达为特征。如果能够将数据表达成为线性可分的数据,那么使用简单的线性模型就可以取得很好的效果。GBDT构建新的特征也是使特征更好地表达数据。

主要思想:GBDT每棵树的路径所代表的特征组合直接作为LR的输入特征使用。

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

 

GBDT的叶子节点就代表有效的特征组合。我们需要求的就是w1、w2、w3、w4。这个可以用lr或者fm求解。

GBDT与LR融合案例

所以这个过程我们一般需要将数据划分为3个。gbdt特征组合提取数据集,lr特征组合有效性系数训练数据集,测试集。

import numpy as np # 快速操作结构数组的工具
import matplotlib.pyplot as plt  # 可视化绘制
from sklearn.linear_model import LinearRegression  # 线性回归
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier,RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score,roc_curve,auc
from sklearn.preprocessing import OneHotEncoder


# 弱分类器的数目
n_estimator = 10
# 随机生成分类数据。
X, y = make_classification(n_samples=80000,n_features=20,n_classes=2)

# 切分为测试集和训练集,比例0.5
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5)
# 将训练集切分为两部分,一部分用于训练GBDT模型,另一部分输入到训练好的GBDT模型生成GBDT特征,然后作为LR的特征。这样分成两部分是为了防止过拟合。
X_train_gbdt, X_train_lr, y_train_gbdt, y_train_lr = train_test_split(X_train, y_train, test_size=0.5)
# 调用GBDT分类模型。
grd = GradientBoostingClassifier(n_estimators=n_estimator)
# 调用one-hot编码。
one_hot = OneHotEncoder()
# 调用LR分类模型。
lr = LogisticRegression()


'''使用X_train训练GBDT模型,后面用此模型构造特征'''
grd.fit(X_train_gbdt, y_train_gbdt)

X_leaf_index = grd.apply(X_train_gbdt)[:, :, 0]  # apply返回每个样本在每科树中所属的叶子节点索引。行数为样本数,列数为树数目。值为在每棵树的叶子索引
X_lr_leaf_index = grd.apply(X_train_lr)[:, :, 0] # apply返回每个样本在每科树中所属的叶子节点索引。行数为样本数,列数为树数目。值为在每棵树的叶子索引
print('每个样本在每个树中所属的叶子索引\n',X_leaf_index)
# fit one-hot编码器
one_hot.fit(X_leaf_index)  # 训练one-hot编码,就是识别每列有多少可取值
X_lr_one_hot = one_hot.transform(X_lr_leaf_index)  # 将训练数据,通过gbdt树,形成的叶子节点(每个叶子代表了原始特征的一种组合)索引,编码成one0-hot特征。
# 编码后的每个特征代表原来的一批特征的组合。

''' 
使用训练好的GBDT模型构建特征,然后将特征经过one-hot编码作为新的特征输入到LR模型训练。
'''

# 使用lr训练gbdt的特征组合
print('使用逻辑回归训练GBDT组合特征的结果')
lr.fit(X_lr_one_hot, y_train_lr)
# 用训练好的LR模型多X_test做预测
y_pred_grd_lm = lr.predict_proba(one_hot.transform(gbdt.apply(X_test)[:, :, 0]))[:, 1]  # 获取测试集正样本的概率
# 根据预测结果输出
fpr, tpr, thresholds = roc_curve(y_test, y_pred_grd_lm)  # 获取真正率和假正率
roc_auc = auc(fpr, tpr)
print('auc值为\n',roc_auc)
#画图,只需要plt.plot(fpr,tpr),变量roc_auc只是记录auc的值,通过auc()函数能计算出来
plt.plot(fpr, tpr, lw=1, label='area = %0.2f' %  roc_auc)
plt.show()



# 使用lr直接训练原始数据
print('使用逻辑回归训练原始数据集的结果')
lr.fit(X_train_lr, y_train_lr)
# 用训练好的LR模型多X_test做预测
y_pred_grd_lm = lr.predict_proba(X_test)[:, 1]  # 获取测试集正样本的概率
# 根据预测结果输出
fpr, tpr, thresholds = roc_curve(y_test, y_pred_grd_lm)  
roc_auc = auc(fpr, tpr)
print('auc值为\n',roc_auc)
#画图,只需要plt.plot(fpr,tpr),变量roc_auc只是记录auc的值,通过auc()函数能计算出来
plt.plot(fpr, tpr, lw=1, label='area = %0.2f' %  roc_auc)
plt.show()

结果:新构建的特征对模型结果有提高

参考:python机器学习案例系列教程——GBDT构建新特征  https://blog.csdn.net/luanpeng825485697/article/details/80150594?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

发布了86 篇原创文章 · 获赞 1 · 访问量 8203

猜你喜欢

转载自blog.csdn.net/a1272899331/article/details/104765839