sklearn api与原生api
python下的xgboost有两套api,一套是原生api,一套是sklearn风格的api。两套api的逻辑还是区别较大的,但是考虑到使用习惯上的统一以及代码集成的统一管理,比较推荐sklearn api。
快速上手,以分类为例:
from xgboost import XGBClassifier as xgbc
alg=xgbc()
alg.fit(x_train,y_train)
y_pred=alg.predict(x_test)
参数解析
xgb的主要参数分为三类:常规参数、模型参数、学习任务参数,具体解析如下:
常规参数General Parameters
image.png
模型参数Booster Parameters
image.png
学习任务参数(Learning Task Parameters)
image.png
调参
gridsearch暴力搜索
这种方法很懒人,缺点就是直接所有参数排列组合会很多。效率非常低。
串行调参,一次只调一个或两个参数
调参顺序
n_estimators
min_child_weight、max_depth
gamma
subsample、colsample_bytree
reg_alpha、reg_lambda
learning_rate
调参策略
由粗到精
调好一个参数,立即更新基础参数
-
观察学习曲线、训练集与验证集表现
def search_best_params(cv_params,other_params): alg = xgbc(**other_params) optimized_alg = model_selection.GridSearchCV(estimator=alg, param_grid=cv_params, scoring='accuracy', cv=5, verbose=2, n_jobs=-1) optimized_alg.fit(X_train, y_train) # evalute_result = optimized_alg.grid_scores_ # print('每轮迭代运行结果:{0}'.format(evalute_result)) print('参数的最佳取值:{0}'.format(optimized_alg.best_params_)) print('最佳模型得分:{0}'.format(optimized_alg.best_score_)) other_params = {'learning_rate': 0.1, 'n_estimators': 500, 'max_depth': 3, 'min_child_weight': 5,'seed': 0,'subsample': 0.8, 'colsample_bytree': 0.8, 'gamma': 0, 'reg_alpha': 0, 'reg_lambda': 1} cv_params = {'n_estimators':[10,100,200,500,1000]} search_best_params(cv_params,other_params)
防止过拟合
增大min_child_weight、增大gamma
增加正则项reg_alpha、reg_lambda
减少max_depth、降低subsample、降低colsample_bytree
-
使用early stop
当验证集的auc20次迭代中均不发生变化或变差,则停止迭代。 alg.fit(x_train, y_train, eval_metric=‘auc’, eval_set=[(x_train, y_train), (x_eval, y_eval)],early_stopping_rounds=20)
自定义eval_metric
# sklearn api中自定义的eval_metric必须是越低越好的类型,故使用1-ks作为验证目标。
def my_ks(pred, y, n=1000):
data = {"y": np.array(y), "pred": np.array(pred)}
df = pd.DataFrame(data)
all_true = sum(y)
all_false = len(y) - all_true
ks = 0.0
for i in np.arange(0.0, 1.0, 1.0 / n):
tp = sum((df.y == 1) & (df.pred >= i)) # o_pre[i])
tpr = tp * 1.0 / all_true
fp = sum((df.y == 0) & (df.pred >= i)) # o_pre[i])
fpr = fp * 1.0 / all_false
if (tpr - fpr) > ks:
ks = tpr - fpr
return ks
def eval_ks(pred, y, n=1000):
labels = y.get_label()
return '1-ks_score', 1 - my_ks(pred, labels)
def evalue(alg, x_train, x_test, y_train, y_test):
x_train, x_eval, y_train, y_eval = model_selection.train_test_split(x_train, y_train, test_size=0.3, random_state=0)
alg.fit(x_train, y_train, eval_metric=eval_ks, eval_set=[(x_train, y_train), (x_eval, y_eval)],early_stopping_rounds=20)