天池热身赛——心跳信号建模与调参

根据Datawhale给的参考代码与自己的习惯,一般首先会选择合适的模型,接着调整数据集的划分方式,最后调整参数。

模型选择

随着近几年集成学习的发展,越来越多人在竞赛中会选择集成学习训练模型,而在实际中使用集成学习所得的结果也确实会优于传统的模型,对此我们可以使用模型进行验证。根据Datawhale所提供的课件,分别对逻辑回归模型、决策树模型和LightGBM模型进行验证。
为了较为准确的量化模型的泛化能力,首先将数据集拆分为训练集和测试集,测试集不参与所有的模型的训练。

逻辑回归模型

首先训练逻辑回归模型

from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
sc=StandardScaler()
sc.fit(X_train)
X_train_std=sc.transform(X)
X_test_std=sc.transform(x)
lr=LogisticRegression(C=1000.0,random_state=0)
starttime = datetime.datetime.now()
lr.fit(X_train_std,y_train)
endtime = datetime.datetime.now()
print((endtime - starttime).seconds)
y_pred=lr.predict_proba(X_test_std)
preds = np.argmax(y_pred, axis=1)
score = f1_score(y_true=y, y_pred=preds, average='macro')
print('逻辑回归模型的f1:{}'.format(score))

根据训练结果,得到模型训练时间为9s,f1_score为0.7685。

决策树模型

接着训练决策树模型

from sklearn import tree
from sklearn.metrics import classification_report
clf = tree.DecisionTreeClassifier(criterion='entropy')    
clf.fit(X, Y)
answer = clf.predict_proba(x)
preds = np.argmax(answer, axis=1)
score = f1_score(y_true=y, y_pred=preds, average='macro')
print('决策树模型的f1:{}'.format(score))

根据训练结果,得到模型训练时间为19s,f1_score为0.9185。

LightGBM

最后训练LightGBM模型(这里会想对训练集再做一次划分)

X_train_split, X_val, y_train_split, y_val = train_test_split(X, Y, test_size=0.2)
train_matrix = lgb.Dataset(X_train_split, label=y_train_split)
valid_matrix = lgb.Dataset(X_val, label=y_val)

params = {
    "learning_rate": 0.1,
    "boosting": 'gbdt',  
    "lambda_l2": 0.1,
    "max_depth": -1,
    "num_leaves": 128,
    "bagging_fraction": 0.8,
    "feature_fraction": 0.8,
    "metric": None,
    "objective": "multiclass",
    "num_class": 4,
    "nthread": 10,
    "verbose": -1,
}
starttime = datetime.datetime.now()  
model = lgb.train(params, 
                  train_set=train_matrix, 
                  valid_sets=valid_matrix, 
                  num_boost_round=2000, 
                  verbose_eval=50, 
                  early_stopping_rounds=200,
                  feval=f1_score_vali)
endtime = datetime.datetime.now()
print((endtime - starttime).seconds)
val_pre_lgb = model.predict(x, num_iteration=model.best_iteration)
preds = np.argmax(val_pre_lgb, axis=1)
score = f1_score(y_true=y, y_pred=preds, average='macro')
print('未调参前lightgbm单模型在验证集上的f1:{}'.format(score))

根据训练结果,得到模型训练时间为160s,f1_score为0.9575。
由此可以看出各类模型的优缺点。
逻辑回归模型虽然拟合速度快,但是其泛化能力一般,同时需要对数据做预处理。
决策树模型拟合速度较快,泛化能力也不错。
LightGBM模型虽然拟合速度最慢,但是其泛化效果最好。

数据集划分

对于数据集的划分方法有三种,留出法,交叉验证法和自助法。

留出法

留出法即直接将数据集进行拆分训练集和测试集,常见的比例为训练集:测试集=7:3。一般可以通过sklearn库实现。

from sklearn.model_selection import train_test_split
X_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

k折交叉验证法

通常将数据集D分为k份,其中k-1份作为训练集,剩余的一份作为测试集,这样就可以获得k组训练测试集,可以进行k次训练与测试,最终返回的是k个测试结果的均值。交叉验证中数据集的划分依然是依据分层采样的方式来进行。对于交叉验证法,其k值的选取往往决定了评估结果的稳定性和保真性,通常k值选取5或10。

自助法

没怎么接触过,所以参考Datawhale所提供的解释为:我们每次从数据集D中取一个样本作为训练集中的元素,然后把该样本放回,重复该行为m次,这样我们就可以得到大小为m的训练集,在这里面有的样本重复出现,有的样本则没有出现过,我们把那些没有出现过的样本作为测试集。 进行这样采样的原因是因为在D中约有36.8%的数据没有在训练集中出现过。留出法与交叉验证法都是使用分层采样的方式进行数据采样与划分,而自助法则是使用有放回重复采样的方式进行数据采样。

实际效果

为了检验数据集划分对泛化能力的影响,我们在前面LightGBM模型的基础上,进行五折交叉验证,之后再进行预测。

"""使用lightgbm 5折交叉验证进行建模预测"""
starttime = datetime.datetime.now()  
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 = {
                "learning_rate": 0.1,
                "boosting": 'gbdt',  
                "lambda_l2": 0.1,
                "max_depth": -1,
                "num_leaves": 128,
                "bagging_fraction": 0.8,
                "feature_fraction": 0.8,
                "metric": None,
                "objective": "multiclass",
                "num_class": 4,
                "nthread": 10,
                "verbose": -1,
            }
    
    model = lgb.train(params, 
                      train_set=train_matrix, 
                      valid_sets=valid_matrix, 
                      num_boost_round=2000, 
                      verbose_eval=100, 
                      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)
endtime = datetime.datetime.now()
print((endtime - starttime).seconds)
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)))
val_pre_lgb = model.predict(x, num_iteration=model.best_iteration)
preds = np.argmax(val_pre_lgb, axis=1)
score = f1_score(y_true=y, y_pred=preds, average='macro')
print('交叉验证后模型在验证集上的f1:{}'.format(score))

根据训练结果,得到模型训练时间为302s,f1_score为0.9615。可以看出,调整数据集的切割方式,是可以提升模型的泛化能力。

模型调参

这一部分代码运行失败,所以只能根据所提供的文档进行解释。
文档所提供的调参方法有三种,贪心调参、网格搜索和贝叶斯调参。

贪心调参

先使用当前对模型影响最大的参数进行调优,达到当前参数下的模型最优化,再使用对模型影响次之的参数进行调优,如此下去,直到所有的参数调整完毕。 这个方法的缺点就是可能会调到局部最优而不是全局最优,但是只需要一步一步的进行参数最优化调试即可,容易理解。 需要注意的是在树模型中参数调整的顺序,也就是各个参数对模型的影响程度,这里列举一下日常调参过程中常用的参数和调参顺序:
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

网格搜索

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

贝叶斯调参

贝叶斯调参的主要思想是:给定优化的目标函数(广义的函数,只需指定输入和输出即可,无需知道内部结构以及数学性质),通过不断地添加样本点来更新目标函数的后验分布(高斯过程,直到后验分布基本贴合于真实分布)。简单的说,就是考虑了上一次参数的信息,从而更好的调整当前的参数。
贝叶斯调参的步骤如下:
1、定义优化函数(rf_cv)
2、建立模型
3、定义待优化的参数
4、得到优化结果,并返回要优化的分数指标

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值