图片说明
图片说明 图片说明
3.简单实现
3.1导入相关库

# -*- coding: utf-8 -*-
# @Author  : Hippo 
import numpy as np
import pandas as pd
import xgboost as xgb
from sklearn.datasets import load_svmlight_file
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve, auc, roc_auc_score
from sklearn.externals import joblib
from sklearn.preprocessing import  OneHotEncoder
import numpy as np
from scipy.sparse import hstack

3.2 数据输入

path = './data/train.csv'
data = pd.read_csv(path)

3.3 数据预处理

data = data.dropna()
data = data.drop(['id','color'],1)

3.4 训练/测试数据分割

column = data.columns
X = data[column[:-1]]
Y = data[column[-1]]
X_all, y_all = X,Y
X_train, X_test, y_train, y_test = train_test_split(X_all, y_all, test_size = 0.3, ranndom_state = 42)

3.5 用现有特征训练XGBoost模型

# 定义模型
model = xgb.XGBClassifier(nthread=4,     #含义:nthread=-1时,使用全部CPU进行并行运算(默认), nthread=1时,使用1个CPU进行运算。
                          learning_rate=0.08,    #含义:学习率,控制每次迭代更新权重时的步长,默认0.3。调参:值越小,训练越慢。典型值为0.01-0.2。
                          n_estimators=50,       #含义:总共迭代的次数,即决策树的个数
                          max_depth=5,           #含义:树的深度,默认值为6,典型值3-10。调参:值越大,越容易过拟合;值越小,越容易欠拟合
                          gamma=0,               #含义:惩罚项系数,指定节点分裂所需的最小损失函数下降值。
                          subsample=0.9,       #含义:训练每棵树时,使用的数据占全部训练集的比例。默认值为1,典型值为0.5-1。调参:防止overfitting。
                          colsample_bytree=0.5) #训练每棵树时,使用的特征占全部特征的比例。默认值为1,典型值为0.5-1。调参:防止overfitting。


model.fit(X_train.values, y_train.values)
# 预测及 AUC 评测
y_pred_test = model.predict_proba(X_test.values)
xgb_test_auc = roc_auc_score(pd.get_dummies(y_test), y_pred_test)
print('xgboost test auc: %.5f' % xgb_test_auc)

3.6 利用训练的XGBoost做特征转换

根据预测结果找到XGBoost的对应的叶节点的索引,然后对其进行one-hot编码

xgboost = model
# xgboost 编码原有特征
#apply()方法可以获得leaf indices(叶节点索引)
X_train_leaves = xgboost.apply(X_train.values)
#X_train_leaves.shape = (259, 150)
X_test_leaves = xgboost.apply(X_test.values)
#X_test.shape = (112, 4)
#X_test_leaves.shape = (112, 150)
#Return the predicted leaf every tree for each sample.


# 训练样本个数
train_rows = X_train_leaves.shape[0]
# 合并编码后的训练数据和测试数据
X_leaves = np.concatenate((X_train_leaves, X_test_leaves), axis=0)
X_leaves = X_leaves.astype(np.int32)
(rows, cols) = X_leaves.shape
# X_leaves.shape = (371, 150)


# 对所有特征进行ont-hot编码
xgbenc = OneHotEncoder()
X_trans = xgbenc.fit_transform(X_leaves)


#fit_transform()的作用就是先拟合数据,然后转化它将其转化为标准形式
#(train_rows, cols) = X_train_leaves.shape

#这里得到的X_trans即为得到的one-hot的新特征
# 定义LR模型
lr = LogisticRegression()
# lr对xgboost特征编码后的样本模型训练
lr.fit(X_trans[:train_rows, :], y_train)
y_pred_xgblr1 = lr.predict_proba(X_trans[train_rows:, :])
# 预测及AUC评测
#y_pred_xgblr1 = lr.predict_proba(X_trans[train_rows:, :])[:, 1]
# y_pred_xgblr1.shape  = (112,)
xgb_lr_auc1 = roc_auc_score(pd.get_dummies(y_test), y_pred_xgblr1)
print('基于Xgb特征编码后的LR AUC: %.5f' % xgb_lr_auc1)


将数据分为训练集和测试集进行,用新的特征输入LR进行预测
# 定义LR模型
lr = LogisticRegression(n_jobs=-1)
# 组合特征
X_train_ext = hstack([X_trans[:train_rows, :], X_train])
X_test_ext = hstack([X_trans[train_rows:, :], X_test])
# lr对组合特征的样本模型训练
lr.fit(X_train_ext, y_train)
# 预测及AUC评测
y_pred_xgblr2 = lr.predict_proba(X_test_ext)
xgb_lr_auc2 = roc_auc_score(pd.get_dummies(y_test), y_pred_xgblr2)
print('基于组合特征的LR AUC: %.5f' % xgb_lr_auc2)

这里在做one-hot的时候注意一下这个fit_transform操作。给个例子如下,代码来自官网

>> from sklearn.preprocessing import OneHotEncoder
>>> enc = OneHotEncoder()
>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])  
OneHotEncoder(categorical_features='all', dtype=<... 'numpy.float64'>,
       handle_unknown='error', n_values='auto', sparse=True)
>>> enc.n_values_
array([2, 3, 4])
>>> enc.feature_indices_
array([0, 2, 5, 9])
>>> enc.transform([[0, 1, 1]]).toarray()
array([[ 1.,  0.,  0.,  1.,  0.,  0.,  1.,  0.,  0.]])

首先确认一下输入样本[[0, 0, 3], [1, 1, 0], [0, 2, 1],[1, 0, 2]],

这个输入样本表示该input共有三个feature特征,也就是三列。这里我们观察可以发现对于第一个feature,对应第一列,它的取值有0,1两个属性值,第二列有0,1,2三个值,第三个有0,1,2,3四个取值。那么这里的enc.n_values_就是每个属性列不同属性值的个数,所以输出可以看到分别是2,3,4。而enc.feature_indices_是对enc.n_values_的一个累加。

enc.transform([[0, 1, 1]]).toarray()

这一句目标是将[0, 1, 1]这个样本转化为基于上面四个输入的one-hot编码。那么可以得到:

第一个属性值0,对应第一列:0->10

第二个属性值1,对应第二列:1->010

第三个属性值1,对应第三列:1->0100

所以[0, 1, 1]对应以上输入的one-hot编码为

[1,0,0,1,0,0,1,0,1]。

模型中的fit_transform对应的就是将XGBoost预测得到的特征进行one-hot编码,过程可以参考我上面给出的这个例子。

另外,关于为什么XGBoost的特征转换实质和为什么效果好,下次再做补充。

上班搬砖去啦,今天先写这么多!

大家觉得有用的话,记得点个赞哦,权当是对我这只匍匐前进的小 的鼓励。谢谢各位~~

有理解不到和错误之处欢迎各位交流讨论与批评指正!
史上最详细的XGBoost实战
XGboost数据比赛实战之调参篇(完整流程)