上期我们讲过了Xgboost的原理和目标函数推导,今天我们来进行实战练习,首先简单回顾下Xgboost原理:
Xgboost是一个集成模型,将K个树的结果进行求和,作为最终的预测值,Xgboost的目的就是通过不断加入树模型来使得预测结果比之前的效果好,使目标函数最小,即预测值无限接近真实值。
接下来进行实战训练:
1. 首先引入
import xgboost as xgb
import pandas as pd
import numpy as np
import pickle
import sys
import matplotlib.pyplot as plt
from sklearn.metrics import mean_absolute_error, make_scorer
from sklearn.preprocessing import StandardScaler
from sklearn.grid_search import GridSearchCV
from scipy.sparse import csr_matrix, hstack
from sklearn.cross_validation import KFold, train_test_split
from xgboost import XGBRegressor
import warnings
warnings.filterwarnings('ignore')
2. 数据预处理和对数转换
train = pd.read_csv('train.csv')
train['log_loss'] = np.log(train['loss'])
3.数据分成连续和离散的特征
features = [x for x in train.columns if x not in ['id','loss', 'log_loss']]
cat_features = [x for x in train.select_dtypes(
include=['object']).columns if x not in ['id','loss', 'log_loss']] #选择dtype类型是object的且不在id/loss/log_loss的行
num_features = [x for x in train.select_dtypes(
exclude=['object']).columns if x not in ['id','loss', 'log_loss']]#选择dtype类型不是object的且不在id/loss/log_loss的行
4. 将离散数据转换为分类数据(即A/B/C类对应0/1/2,以此类推)
ntrain = train.shape[0]
train_x = train[features]
train_y = train['log_loss']
for c in range(len(cat_features)):
train_x[cat_features[c]]=train_x[cat_features[c]].astype('category').cat.codes
5. xgboost 自定义了一个数据矩阵类 DMatrix,会在训练开始时进行一遍预处理,从而提高之后每次迭代的效率
dtrain = xgb.DMatrix(train_x, train['log_loss'])
6. 接着我们需要对以下这些参数进行调节
- 'booster':'gbtree',
- 'objective': 'multi:softmax', 多分类的问题
- 'num_class':10, 类别数,与 multisoftmax 并用
- 'gamma':损失下降多少才进行分裂
- 'max_depth':12, 构建树的深度,越大越容易过拟合
- 'lambda':2, 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
- 'subsample':0.7, 随机采样训练样本
- 'colsample_bytree':0.7, 生成树时进行的列采样
- 'min_child_weight':3, 孩子节点中最小的样本权重和。如果一个叶子节点的样本权重和小于min_child_weight则拆分过程结束
- 'silent':0 ,设置成1则没有运行信息输出,最好是设置为0.
- 'eta': 0.007, 如同学习率
- 'seed':1000,
- 'nthread':7, cpu 线程数
xgb_params = {
'seed': 0,
'eta': 0.1,
'colsample_bytree': 0.5,
'silent': 1,
'subsample': 0.5,
'objective': 'reg:linear',
'max_depth': 5,
'min_child_weight': 3
}
7. 交叉验证(num_boost_round树模型个数;early_stopping_rounds若超过10次迭代没有优化则停止)
bst_cv1 = xgb.cv(xgb_params, dtrain, num_boost_round=50, nfold=3, seed=0,
feval=xg_eval_mae, maximize=False, early_stopping_rounds=10)
8. 参数调节
Step 1: 选择一组初始参数
Step 2: 改变 max_depth 和 min_child_weight.
max_depth: 树的最大深度。增加这个值会使模型更加复杂,也容易出现过拟合,深度3-10是合理的。
min_child_weight: 正则化参数. 如果树分区中的实例权重小于定义的总和,则停止树构建过程。
Step 3: 调节 gamma 降低模型过拟合风险.
我们选择使用偏小一些的 gamma.
Step 4: 调节 subsample 和 colsample_bytree 改变数据采样策略.
Step 5: 调节学习率 eta.
减小学习率并增大树个数
参数优化的最后一步是降低学习速度,同时增加更多的估计量
class XGBoostRegressor(object):
def __init__(self, **kwargs):
self.params = kwargs
if 'num_boost_round' in self.params:
self.num_boost_round = self.params['num_boost_round']
self.params.update({'silent': 1, 'objective': 'reg:linear', 'seed': 0})
def fit(self, x_train, y_train):
dtrain = xgb.DMatrix(x_train, y_train)
self.bst = xgb.train(params=self.params, dtrain=dtrain, num_boost_round=self.num_boost_round,
feval=xg_eval_mae, maximize=False)
def predict(self, x_pred):
dpred = xgb.DMatrix(x_pred)
return self.bst.predict(dpred)
def kfold(self, x_train, y_train, nfold=5):
dtrain = xgb.DMatrix(x_train, y_train)
cv_rounds = xgb.cv(params=self.params, dtrain=dtrain, num_boost_round=self.num_boost_round,
nfold=nfold, feval=xg_eval_mae, maximize=False, early_stopping_rounds=10)
return cv_rounds.iloc[-1,:]
def plot_feature_importances(self):
feat_imp = pd.Series(self.bst.get_fscore()).sort_values(ascending=False)
feat_imp.plot(title='Feature Importances')
plt.ylabel('Feature Importance Score')
def get_params(self, deep=True):
return self.params
def set_params(self, **params):
self.params.update(params)
return self
接下来就是不断调节,直到模型拥有最好的预测效果。后台回复集成可获得Xgboost数据集和代码,大家动手连起来呀~
喜欢的话点个关注哦~ 会每天分享人工智能机器学习内容,回复关键字可获取相关算法数据及代码~