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:\n", 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:\n", scores)

print("Average MAE score (across experiments):")
print(scores.mean())

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

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

猜你喜欢

转载自www.cnblogs.com/fb1704011013/p/11203161.html