入门数据挖掘-心电图信号预测datawhale组队学习笔记-task4 建模与调参

1. 学习模型

1.1 逻辑回归模型

  • 优点:可解释性好,适合二分类问题,训练速度快,计算量仅与特征数目有关。
  • 缺点:需要预先处理异常值和缺失值;对多重共线性数据较为敏感,很难处理数据不平衡问题,准确率不高。

1.2 决策树模型

  • 优点:可以可视化,数据不需要预处理,可处理离散值和连续值。
  • 缺点:易过拟合,泛化能力不强(可适当剪枝),采用贪心算法,容易得到局部最优解。

1.3 集成模型(ensemble method)

1.3.1 bagging 和 boosting

将若干个分类器整合为一个强分类器。

baggingboosting
样本选择训练集是从原始集有放回的选择,所以选出的各轮训练集之间独立。每一轮训练集不变,只是训练集中每个样本权重发生变化;权重是根据上一轮分类结果进行调整。
样例权重用均匀取样,所以每个样本的权重相等每个弱分类器都有相应的权重,对于分类误差小的分类器会有更大的权重
并行计算各个预测函数可以并行生成各个预测函数只能顺序生成,因为后一个模型参数需要前一轮模型的结果。
模型随机森林AdaBoost, GBDT, XgBoost, LightGBM

2 模型评估方法

2.1 数据集划分

  • 训练集和测试集是从样本真实分布中独立同分布采样而得(训练集和测试集要与样本真实分布一致);训练集和测试集要互斥。
  • 训练集上面的误差我们称之为训练误差或者经验误差,而在测试集上的误差称之为测试误差。

2.2 划分方法

1. 留出法:两个互斥集合。
数据集D -> 训练集S(大约2/3 ~ 4/5) + 测试集T (为保证数据分布的一致性,通常用**分层采样**的方式对数据采样。)
2. k折交叉验证法:分为k份,k-1份为训练集,剩余1份为测试集。
获得k组训练/测试集,k batches -> 结果为k个测试结果均值。数据集划分依然为**分层采样**。
k 常选10。 当 k=N 时,为留一法。
3. 自助法: 每次从数据集D中取一个样本作为训练集中的元素,然后把该样本放回,重复该行为m次,这样我们就可以得到大小为m的训练集,在这里面有的样本重复出现,有的样本则没有出现过,我们把那些没有出现过的样本作为测试集。**有放回重复采样**方式进行数据采样。

2.3 总结

1. 数据量充足 -> 留出法或者k折交叉验证法划分训练/测试集;
2. 数据集小且难以有效划分训练/测试集 -> 自助法;
3. 数据集小且可有效划分 -> 最好使用**留一法**,因为这种方法**最为准确**。

2.4 评价标准

自定义abs-sum。

3. 代码示例

3.1 导入工具包,读取数据

reduce_mem_usage 函数通过调整数据类型,减少数据占用内存。

3.2 简单建模

在这里插入图片描述在这里插入图片描述在这里插入图片描述

4. 模型调参

本次项目重点使用贝叶斯调参进行优化。

4.1 贪心调参

需要注意的是在树模型中参数调整的顺序,也就是各个参数对模型的影响程度,这里列举一下日常调参过程中常用的参数和调参顺序:

  1. max_depth、num_leaves
  2. min_data_in_leaf、min_child_weight
  3. bagging_fraction、 feature_fraction、bagging_freq
  4. reg_lambda、reg_alpha
  5. min_split_gain

4.2 网格搜索

sklearn 提供GridSearchCV用于进行网格搜索,只需要把模型的参数输进去,就能给出最优化的结果和参数。
相比起贪心调参,网格搜索的结果会更优,但是只适合于小数据集,一旦数据的量级上去了,很难得出结果。

4.3 贝叶斯调参

  • 在使用之前需要先安装包bayesian-optimization。
  • 给定优化的目标函数(广义的函数,只需指定输入和输出即可,无需知道内部结构以及数学性质),通过不断地添加样本点来更新目标函数的后验分布(高斯过程,直到后验分布基本贴合于真实分布)。简单的说,就是考虑了上一次参数的信息,从而更好的调整当前的参数。
from sklearn.model_selection import cross_val_score

"""定义优化函数"""
def rf_cv_lgb(num_leaves, max_depth, bagging_fraction, feature_fraction, bagging_freq, min_data_in_leaf, 
              min_child_weight, min_split_gain, reg_lambda, reg_alpha):
    # 建立模型
    model_lgb = lgb.LGBMClassifier(boosting_type='gbdt', objective='multiclass', num_class=4,
                                   learning_rate=0.1, n_estimators=5000,
                                   num_leaves=int(num_leaves), max_depth=int(max_depth), 
                                   bagging_fraction=round(bagging_fraction, 2), feature_fraction=round(feature_fraction, 2),
                                   bagging_freq=int(bagging_freq), min_data_in_leaf=int(min_data_in_leaf),
                                   min_child_weight=min_child_weight, min_split_gain=min_split_gain,
                                   reg_lambda=reg_lambda, reg_alpha=reg_alpha,
                                   n_jobs= 8
                                  )
    f1 = make_scorer(f1_score, average='micro')
    val = cross_val_score(model_lgb, X_train_split, y_train_split, cv=5, scoring=f1).mean()

    return val
from bayes_opt import BayesianOptimization
"""定义优化参数"""
bayes_lgb = BayesianOptimization(
    rf_cv_lgb, 
    {
        'num_leaves':(10, 200),
        'max_depth':(3, 20),
        'bagging_fraction':(0.5, 1.0),
        'feature_fraction':(0.5, 1.0),
        'bagging_freq':(0, 100),
        'min_data_in_leaf':(10,100),
        'min_child_weight':(0, 10),
        'min_split_gain':(0.0, 1.0),
        'reg_alpha':(0.0, 10),
        'reg_lambda':(0.0, 10),
    }
)

"""开始优化"""
bayes_lgb.maximize(n_iter=10)
"""显示优化结果"""
bayes_lgb.max
"""调整一个较小的学习率,并通过cv函数确定当前最优的迭代次数"""
base_params_lgb = {
                    'boosting_type': 'gbdt',
                    'objective': 'multiclass',
                    'num_class': 4,
                    'learning_rate': 0.01,
                    'num_leaves': 138,
                    'max_depth': 11,
                    'min_data_in_leaf': 43,
                    'min_child_weight':6.5,
                    'bagging_fraction': 0.64,
                    'feature_fraction': 0.93,
                    'bagging_freq': 49,
                    'reg_lambda': 7,
                    'reg_alpha': 0.21,
                    'min_split_gain': 0.288,
                    'nthread': 10,
                    'verbose': -1,
}

cv_result_lgb = lgb.cv(
    train_set=train_matrix,
    early_stopping_rounds=1000, 
    num_boost_round=20000,
    nfold=5,
    stratified=True,
    shuffle=True,
    params=base_params_lgb,
    feval=f1_score_vali,
    seed=0
)
print('迭代次数{}'.format(len(cv_result_lgb['f1_score-mean'])))
print('最终模型的f1为{}'.format(max(cv_result_lgb['f1_score-mean'])))
import lightgbm as lgb
"""使用lightgbm 5折交叉验证进行建模预测"""
cv_scores = []
for i, (train_index, valid_index) in enumerate(kf.split(X_train, y_train)):
    print('************************************ {} ************************************'.format(str(i+1)))
    X_train_split, y_train_split, X_val, y_val = X_train.iloc[train_index], y_train[train_index], X_train.iloc[valid_index], y_train[valid_index]

    train_matrix = lgb.Dataset(X_train_split, label=y_train_split)
    valid_matrix = lgb.Dataset(X_val, label=y_val)

    params = {
                'boosting_type': 'gbdt',
                'objective': 'multiclass',
                'num_class': 4,
                'learning_rate': 0.01,
                'num_leaves': 138,
                'max_depth': 11,
                'min_data_in_leaf': 43,
                'min_child_weight':6.5,
                'bagging_fraction': 0.64,
                'feature_fraction': 0.93,
                'bagging_freq': 49,
                'reg_lambda': 7,
                'reg_alpha': 0.21,
                'min_split_gain': 0.288,
                'nthread': 10,
                'verbose': -1,
    }

    model = lgb.train(params, train_set=train_matrix, num_boost_round=4833, valid_sets=valid_matrix, 
                      verbose_eval=1000, early_stopping_rounds=200, feval=f1_score_vali)
    val_pred = model.predict(X_val, num_iteration=model.best_iteration)
    val_pred = np.argmax(val_pred, axis=1)
    cv_scores.append(f1_score(y_true=y_val, y_pred=val_pred, average='macro'))
    print(cv_scores)

print("lgb_scotrainre_list:{}".format(cv_scores))
print("lgb_score_mean:{}".format(np.mean(cv_scores)))
print("lgb_score_std:{}".format(np.std(cv_scores)))
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值