zoukankan      html  css  js  c++  java
  • 模型优化

     

    解决过拟合和欠拟合的思路
    过拟合
    • 获取更多的数据量

    有时数据量大并没有帮助

    通常数据量越大,学习模型训练得越好,但是即使这样,也应该做一些初步实验(使用学习曲线)来确保数据量越大,训练越好。(如果一开始就用大量的数据来训练模型,将会耗费大量的时间:收集数据,训练模型)

    • 增大正则化系数
    • 减少特征量(不太推荐)

    细心的从已有的特征量中选出一个子集

    可以手工选择,也可以用一些降维( dimensionality reduction)技术,但降维也不一定缓解过拟合

    欠拟合
    • 增加额外的特征量

    有时并不起作用

    仔细考虑数据集,是否遗漏了一些重要的特征量(可能花费较多的时间)

    添加的特征量可能只是训练集的特征,不适合全体数据集,可能会过拟合

    • 添加多项式的特征量
    • 减少正则化参数
    线性模型的权重分析

    线性模型:

    Linear Regression ,Logistic Regression , LinearSVM

    线性模型得到的是一系列的权重,我们可以将权重提取出来,观察哪些特征的权重系数是比较大的

    考虑将这些权重大的特征和其他特征做一个组合,如房屋面积和几居室,作为新的特征加入到训练数据中,

    也可以将这些特征进行分拆,如房屋面积分拆成客厅面积、厨房面积、卧室面积,或者是分拆部分面积和总面积的比值,作为新的特征加入到训练数据中。

    bad-case分析

    我们可以查看哪些训练样本分错了,这些被分错的样本是由哪部分特征所决定的,

    然后我们可以查看这些被分错的样本的决定性特征是不是很相似的,

    思考哪些特征值的我们去重点关注。

    模型融合
    stacking

     

    stacking 原理:

    • 假设我们使用N个模型进行融合
    • 使用一个模型进行如下操作:

    将训练集划分为k份,使用k-1份的数据作为训练集,另外一份数据作为验证集,使用训练集进行模型训练,将训练的模型对验证集和测试集进行预测,我们使用k折交叉验证,得到k个模型,这k个模型是不同的,因为训练集是不同的,这k个模型对验证集的预测堆叠起来,其维度是(训练集样本数,1),对测试集的预测结果做一个平均,维度变为(测试集样本数,1)

    • 然后对另外N-1个模型使用上面同样的处理方法。
    • 将每一个模型得到的验证集的预测结果合起来作为新的训练集,器维度是(训练集样本数,N),输入到模型进行训练。将每一个模型得到的测试机的预测结果合并起来,其维度是(测试集的样本数,N),作为新的测试集。

    代码实现:

    stack_model = [svm,lr,nn,xgb,lgb] 

    ## train_data 表示训练集,train_label 表示训练集的标签,test_data表示训练集

    ntrain = train_data.shape[0]  ## 训练集样本数量

    ntest = test_data.shape[0]   ## 测试集样本数量

    train_stack = np.zeros(ntrain,n) ##  n表示n个模型

    test_stack = np.zeros(ntest,n) ##

    kf = kfold.split(train_data, train_label)

    for i,model in enumerate(stack_model):

        for j, (train_fold, validate) in enumerate(kf):

                    X_train, X_validate, label_train, label_validate =

                        train_data[train_fold, :], train_data[validate, :], train_label[train_fold], train_label[validate]

                   

                    model.fit(X_train,label_train)

                    train_stack[validate,i] = model.predict(X_validate)

                    test_stack[:,i] = model.predict(test_data)

                   

    ### 假设就只有两层,那么最后预测:

    final_model  = xgb()  ## 假设第二层我们还是用xgb吧,这个地方也是简写,仅仅表示这个地方是xgb模型

    final_model.fit(train_stack,train_label)

    pre = final_model.predict(test_stack) 

    blending

    Blending与Stacking大致相同,只是Blending的主要区别在于:例如从原始训练数据中选取80%作为训练集,另外20%作为验证集,使用训练好的模型预测验证集。这样N个模型就可以得到第二阶段的训练集,其维度是(原始数据集样本数的20%,N),然后使用这些训练集训练出来一个新的模型。

    测试集的处理同stacking,最终得到的测试集的维度是(测试集的样本数,N)

    Blending的优点:

    1.比stacking简单(因为不用进行k次的交叉验证来获得stacker feature)

    2.避开了一个信息泄露问题:generlizers和stacker使用了不一样的数据集

    3.在团队建模过程中,不需要给队友分享自己的随机种子

    缺点在于:

    1.使用了很少的数据(第二阶段的blender只使用training set10%的量)

    2.blender可能会过拟合(其实大概率是第一点导致的)

    3.stacking使用多次的CV会比较稳健

    对于实践中的结果而言,stacking和blending的效果是差不多的,所以使用哪种方法都没什么所谓,完全取决于个人爱好。

    bagging和boosting

    这些算法在其它文章中已经描述,这里不再重述。

    超参数估计
    网格搜索

    from sklearn.model_selection import GridSearchCV

    from sklearn import svm

    clf = svm.SVC()

    param_grid = [{'C': [1, 10, 100, 1000], 'kernel': ['linear']}, { 'C': [1, 10, 100, 1000], 'gamma': [0.001, 0.0001], 'kernel': ['rbf']}]

    grid = GridSearchCV(clf, param_grid, cv=10)

    grid = grid.fit(X_train, y_train)

    grid_search.best_score_

    grid_search.best_estimator_.get_params()

    网格搜索支持并行化:

    grid_search = GridSearchCV(pipeline, parameters, cv=5, n_jobs=-1)

  • 相关阅读:
    make clean,make distclean与make depend的区别
    HSTS 与 307 状态码
    阿里云CentOS中vsftp安装、配置、卸载
    vsftp管理脚本(CentOS6用)
    通过修改源码,免插件实现wordpress去除链接中的category
    (转载)Peter Norvig:十年学会编程
    BT觀念分享和常見問題彙整
    Mysql 字符编码
    Mysql 整数类型的字段的属性设置及常用的函数
    MySql快速入门
  • 原文地址:https://www.cnblogs.com/yongfuxue/p/10095455.html
Copyright © 2011-2022 走看看