zoukankan      html  css  js  c++  java
  • python学习11之交叉验证

      本次学习,我们将学习如何使用交叉验证来更好地度量模型性能。

      1、介绍

        机器学习是一个迭代的过程。我们将面临使用什么预测变量、使用什么类型的模型、向这些模型提供什么参数等选择。

        到目前为止,通过使用验证集(或holdout)度量模型质量,我们已经以数据驱动的方式做出了这些选择。

        为了看到这一点,假设您有一个5000行数据集。您通常将大约20%的数据保存为验证数据集,即1000行。但这在确定模型分数方面留下了一些随机的机会。

        也就是说,一个模型在一组1000行上可能做得很好,即使它在另一组1000行上是不准确的。在极端情况下,我们可以想象验证集中只有一行数据。

        一般来说,验证集越大,我们对模型质量的度量中随机性(即“噪声”)就越小,也就越可靠。

        不幸的是,我们只能通过从训练数据中删除行来获得较大的验证集,而较小的训练数据集意味着较差的模型

      2、什么是交叉验证

        在交叉验证中,我们对数据的不同子集运行建模过程,以获得模型质量的多个度量。

        例如,我们可以将数据分成5个部分,每个部分占整个数据集的20%。

        在本例中,我们将数据分成5个“折叠”。

        然后,我们为每个折叠运行一个实验:

        在实验1中,我们使用第一个折叠作为验证集(或holdout),其他所有内容作为训练数据。这给了我们一个基于20% holdout集的模型质量度量。

        在实验2中,我们持有来自第二次折叠的数据(并且使用除第二次折叠以外的所有方法来训练模型)。然后使用holdout集对模型质量进行第二次估计。

        我们重复这个过程,使用每一个折叠一次作为抵抗。把这个在一起,100%的数据被用作抵抗在某种程度上,我们最终得到的模型质量,是基于所有的行数据集(即使我们不同时使用所有行)。

      3、什么时候应该使用交叉验证?

        交叉验证为模型质量提供了更精确的度量,如果我们要做很多建模决策,这一点尤其重要。然而,它可能需要更长的时间来运行,因为它估计了多个模型(每个折叠一个)。

        那么,考虑到这些权衡,我们应该在什么时候使用每种方法呢?对于小型数据集,额外的计算负担并不大,我们应该运行交叉验证。

        对于较大的数据集,一个验证集就足够了。我们的代码将运行得更快,并且我们可能拥有足够的数据,因此不需要重用其中的一些数据来进行保留。

        对于大数据集和小数据集的组成没有简单的阈值。但是如果我们的模型需要几分钟甚至更少的时间来运行,那么切换到交叉验证可能是值得的。

        或者,我们可以运行交叉验证,看看每个实验的分数是否接近。如果每个实验产生相同的结果,一个验证集可能就足够了。

      4、举例说明

        1)、用的数据还是之前学习得墨尔本住房情况的数据。

            我们用X加载输入数据,用y加载输出数据。

    import pandas as pd
    import csv
    data = pd.read_csv('E:/data_handle/melb_data.csv')
    
    cols_to_use = ['Rooms', 'Distance', 'Landsize', 'BuildingArea', 'YearBuilt']
    X = data[cols_to_use]
    
    y = data.Price

        2)、创建管道

            然后,我们定义了一个管道,它使用一个灌输器来填充缺失的值和一个随机森林模型来进行预测。

              虽然可以在没有管道的情况下进行交叉验证,但是非常困难!使用管道将使代码非常简单。
    from sklearn.ensemble import RandomForestRegressor
    from sklearn.pipeline import Pipeline
    from sklearn.impute import SimpleImputer
    
    my_pipeline = Pipeline(steps=[('preprocessor',SimpleImputer()),
                                  ('model',RandomForestRegressor(n_estimators=50,random_state=0))])

        3)、获取MAE的得分

    from sklearn.model_selection import cross_val_score
    #乘以-1,因为sklearn计算* - * MAE
    score = -1 * cross_val_score(my_pipeline, X, y, cv=5, scoring='neg_mean_absolute_error')
    print("MAE score:
    ", score)

        4)、求取MAE的平均值

            评分参数选择要报告的模型质量度量:

              在本例中,我们选择了负平均绝对误差(MAE)。scikit-learn的文档显示了一个选项列表。

               我们指定负MAE有点奇怪。Scikit-learn有一个约定,其中所有的指标都是定义好的,所以一个高的数字更好。
              在这里使用否定词可以使它们与约定保持一致,尽管在其他地方几乎没有听到过否定词MAE。
               我们通常需要一个模型质量的单一度量来比较其他模型。我们取所有实验的平均值。
    print("Average MAE score (across experiments):")
    print(scores.mean())
        5)、总结
            使用交叉验证产生了一个更好的模型质量度量,并带来了清理代码的额外好处:
              注意,我们不再需要跟踪单独的培训和验证集。因此,特别是对于小数据集,这是一个很好的改进!
      5、总的代码
          
    import pandas as pd
    import csv
    
    from sklearn.ensemble import RandomForestRegressor
    from sklearn.pipeline import Pipeline
    from sklearn.impute import SimpleImputer
    
    from sklearn.model_selection import cross_val_score
    
    data = pd.read_csv('E:/data_handle/melb_data.csv')
    
    cols_to_use = ['Rooms', 'Distance', 'Landsize', 'BuildingArea', 'YearBuilt']
    X = data[cols_to_use]
    
    y = data.Price
    
    my_pipeline = Pipeline(steps=[('preprocessor',SimpleImputer()),
                                  ('model',RandomForestRegressor(n_estimators=50,random_state=0))])
    #乘以-1,因为sklearn计算* - * MAE
    scores = -1 * cross_val_score(my_pipeline, X, y, cv=5, scoring='neg_mean_absolute_error')
    print("MAE score:
    ", scores)
    
    print("Average MAE score (across experiments):")
    print(scores.mean())

    本次学习到此结束!!!!!

    加油,虽然很难,但是坚持下去应该能学会。

  • 相关阅读:
    GIL锁、进程池和线程池、同步和异步
    线程
    socket编程
    单例模式
    反射、自定义内置方法来定制类的功能、元类
    elasticSearch(一)--数据1
    docker学习整理(三)
    docker学习整理(二)
    docker学习整理(一)
    IDEA 配置mybatis生成代码
  • 原文地址:https://www.cnblogs.com/fb1704011013/p/11203161.html
Copyright © 2011-2022 走看看