xgboost + hyperopt 调参套路

本文介绍了两种常见的机器学习调参方法:手动设置超参数和使用Hyperopt工具包自动调参。手动调参通常将数据分为70%训练、10%验证和20%测试,而使用Hyperopt则可在控制调参时间的同时,通过交叉验证避免过拟合,找到最优模型。

1. 手动设置超参数:

有时候为了节省时间快速验证不用工具进行调参,手动设定超参数,此时一般设置成70%的train, 10%的validation, 20%的test。

由于fit的过程是不断增加tree,所以在train上fit的时候,设置validation set,当在validation上loss不再下降的时候,就停止fit,这样可以避免在train上过拟合。

 

2. 利用工具包调参

相比gridsearch,hyperopt调参可以设置调参次数max_evals_num,控制调参时间。不至于调起来没完没了让人等得心焦。

一个基本的套路总结如下:

1. 拆分训练集和测试集,例如80%的训练,20%的测试集。

2. 利用hyperopt + 80%的训练集,针对决策树的相关超参数进行调参。

调参时要提供一个评价函数:hyperopt_eval_func()。

例如用train做五折交叉验证:cross_val_score()代表目前这批超参数的效果,避免调参时在tarin上过拟合。

所以这种情况下其实没必要再设置外部的validation集了。

利用hyperopt调参的代码如下:

def hyperopt_eval_func(params, X, y):
    '''利用params里定义的模型和超参数,对X进行fit,并返回cv socre。
    Args:
        @params: 模型和超参数
        @X:输入参数
        @y:真值
    Return:
        @score: 交叉验证的损失值
    '''   
    
    int_feat = ['n_estimators', 'max_depth', 'min_child_weight']
    for p in int_feat:
        params[p] = int(params[p])    
    
    clf = XGBClassifier(**params)        

    #用cv结果来作为评价函数
    from sklearn.model_selection import KFold
    shuffle = KFold(n_splits=5, shuffle=True)
    score = -1 * cross_val_score(clf, X, y, scoring='f1', cv=shuffle).mean()
    
    return score

def hyperopt_binary_model(params):
    '''hyperopt评价函数,在hyperopt_eval_func外面包围了一层,增加一些信息输出
    Args:
        @params:用hyperopt调参优化得到的超参数
    Return:
        @loss_status: loss and status
        
    '''    
    global best_loss, count, binary_X, binary_y   
    count += 1 
    
    clf_type = params['type']   
    del params['type']
    loss = hyperopt_eval_func(params, binary_X, binary_y)
    print(count, loss)
    if loss < best_loss:
        ss = 'count:%d  new best loss: %4.3f , using %s'%(count, loss, clf_type)        
        print(ss)         
        best_loss = loss

    loss_status = {'loss': loss, 'status': STATUS_OK}
    return loss_status

def get_best_model(best):
    '''根据hyperopt搜索的参数,返回对应最优score的模型
    Args:
        @best:最优超参数
    Return:
        @clf: xgb model
    '''     
    int_feat = ['n_estimators', 'max_depth', 'min_child_weight']
    for p in int_feat:
        best[p] = int(best[p])
        
    #fix the random state
    best['seed'] = 2018    
    clf = XGBClassifier(**best)
    
    return clf


def get_best_model(X_train, y_train, predictors, max_evals_num=10):
    '''利用hyperopt得到最优的xgb model
    Args:
        @X_train: 训练样本X 数据
        @y_train: 训练样本y target
        @predictors: 用于预测的特征
        @max_evals_num: hyperopt调参时的次数,次数越多,模型越优,但是也越耗费时间
    Return:
        @clf: 最优model
    '''
    space = {     
        'type': 'xgb',
        'n_estimators': hp.quniform('n_estimators', 50,400,50),
        'max_depth': hp.quniform('max_depth', 2, 8, 1),            
        'learning_rate': hp.uniform('learning_rate', 0.01, 0.1),
        'min_child_weight': hp.quniform('min_child_weight', 2, 8, 1),
        'gamma': hp.uniform('gamma', 0, 0.2),
        'subsample': hp.uniform('subsample', 0.7, 1.0),
        'colsample_bytree': hp.uniform('colsample_bytree', 0.7, 1.0) 
    }   
    
    #hyperopt train
    global count, best_loss, binary_X, binary_y
    count = 0
    best_loss = 1000000
    binary_X = X_train
    binary_y = y_train
    trials = Trials()
    best = fmin(hyperopt_binary_model, space, algo=tpe.suggest, max_evals=max_evals_num, trials=trials)
    print( 'best param:{}'.format(best))
    print('best trans cv mse on train:{}'.format(best_loss)) 
    
    
    clf = get_best_model(best)
    
    return clf

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值