zoukankan      html  css  js  c++  java
  • 机器学习sklearn(二十二): 模型评估(二)交叉验证:评估估算器的表现(二)计算交叉验证的指标

    计算交叉验证的指标

    使用交叉验证最简单的方法是在估计器和数据集上调用 cross_val_score 辅助函数。

    下面的示例展示了如何通过分割数据,拟合模型和计算连续 5 次的分数(每次不同分割)来估计 linear kernel 支持向量机在 iris 数据集上的精度:

    >>> from sklearn.model_selection import cross_val_score
    >>> clf = svm.SVC(kernel='linear', C=1)
    >>> scores = cross_val_score(clf, iris.data, iris.target, cv=5)
    >>> scores                                              
    array([0.96..., 1.  ..., 0.96..., 0.96..., 1.        ])

    评分估计的平均得分和 95% 置信区间由此给出:

    >>> print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))
    Accuracy: 0.98 (+/- 0.03)

    默认情况下,每个 CV 迭代计算的分数是估计器的 score 方法。可以通过使用 scoring 参数来改变计算方式如下:

    >>> from sklearn import metrics
    >>> scores = cross_val_score(
    ...     clf, iris.data, iris.target, cv=5, scoring='f1_macro')
    >>> scores                                              
    array([0.96..., 1.  ..., 0.96..., 0.96..., 1.        ])

    详情请参阅 scoring 参数: 定义模型评估规则 。 在 Iris 数据集的情形下,样本在各个目标类别之间是平衡的,因此准确度和 F1-score 几乎相等。

    当 cv 参数是一个整数时, cross_val_score 默认使用 KFold 或 StratifiedKFold 策略,后者会在估计器派生自 ClassifierMixin 时使用。

    也可以通过传入一个交叉验证迭代器来使用其他交叉验证策略,比如:

    >>> from sklearn.model_selection import ShuffleSplit
    >>> n_samples = iris.data.shape[0]
    >>> cv = ShuffleSplit(n_splits=5, test_size=0.3, random_state=0)
    >>> cross_val_score(clf, iris.data, iris.target, cv=cv)  
    array([0.977..., 0.977..., 1.  ..., 0.955..., 1.        ])

    另外一种可选方案是使用一个可迭代生成器作为索引数组产生(train, test) 划分,比如:

    >>> def custom_cv_2folds(X):
    ...     n = X.shape[0]
    ...     i = 1
    ...     while i <= 2:
    ...         idx = np.arange(n * (i - 1) / 2, n * i / 2, dtype=int)
    ...         yield idx, idx
    ...         i += 1
    ...
    >>> custom_cv = custom_cv_2folds(iris.data)
    >>> cross_val_score(clf, iris.data, iris.target, cv=custom_cv)
    array([1.        , 0.973...])

    保留数据的数据转换

    正如在训练集中保留的数据上测试一个 predictor (预测器)是很重要的一样,预处理(如标准化,特征选择等)和

    类似的 data transformations 也应该从训练集中学习,并应用于预测数据以进行预测:

    >> from sklearn import preprocessing
    >> X_train, X_test, y_train, y_test = train_test_split(
      ...     iris.data, iris.target, test_size=0.4, random_state=0)
    >> scaler = preprocessing.StandardScaler().fit(X_train)
    >> X_train_transformed = scaler.transform(X_train)
    >> clf = svm.SVC(C=1).fit(X_train_transformed, y_train)
    >> X_test_transformed = scaler.transform(X_test)
    >> clf.score(X_test_transformed, y_test)  
      0.9333...

    Pipeline 可以更容易地组合估计器,在交叉验证下使用如下:

    >> from sklearn.pipeline import make_pipeline
    >> clf = make_pipeline(preprocessing.StandardScaler(), svm.SVC(C=1))
    >> cross_val_score(clf, iris.data, iris.target, cv=cv)
      ...                                                 
      array([ 0.97...,  0.93...,  0.95...])

    1. cross_validate 函数和多度量评估

    cross_validate 函数与 cross_val_score 在下面的两个方面有些不同 -

    • 它允许指定多个指标进行评估.
    • 除了测试得分之外,它还会返回一个包含训练得分,拟合次数, score-times (得分次数)的一个字典。 It returns a dict containing training scores, fit-times and score-times in addition to the test score.

    对于单个度量评估,其中 scoring 参数是一个字符串,可以调用或 None , keys 将是 - ['test_score', 'fit_time', 'score_time']

    而对于多度量评估,返回值是一个带有以下的 keys 的字典 - ['test_<scorer1_name>', 'test_<scorer2_name>', 'test_<scorer...>', 'fit_time', 'score_time']

    return_train_score 默认设置为 True 。 它增加了所有 scorers(得分器) 的训练得分 keys 。如果不需要训练 scores ,则应将其明确设置为 False 。

    你还可以通过设置return_estimator=True来保留在所有训练集上拟合好的估计器。

    可以将多个测度指标指定为list,tuple或者是预定义评分器(predefined scorer)的名字的集合

    >>> from sklearn.model_selection import cross_validate
    >>> from sklearn.metrics import recall_score
    >>> scoring = ['precision_macro', 'recall_macro']
    >>> clf = svm.SVC(kernel='linear', C=1, random_state=0)
    >>> scores = cross_validate(clf, iris.data, iris.target, scoring=scoring,
    ...                         cv=5)
    >>> sorted(scores.keys())
    ['fit_time', 'score_time', 'test_precision_macro', 'test_recall_macro']
    >>> scores['test_recall_macro']                       
    array([0.96..., 1.  ..., 0.96..., 0.96..., 1.        ])

    或作为一个字典 mapping 得分器名称预定义或自定义的得分函数:

    >>> from sklearn.metrics.scorer import make_scorer
    >>> scoring = {'prec_macro': 'precision_macro',
    ...            'rec_macro': make_scorer(recall_score, average='macro')}
    >>> scores = cross_validate(clf, iris.data, iris.target, scoring=scoring,
    ...                         cv=5, return_train_score=True)
    >>> sorted(scores.keys())                 
    ['fit_time', 'score_time', 'test_prec_macro', 'test_rec_macro',
     'train_prec_macro', 'train_rec_macro']
    >>> scores['train_rec_macro']                         
    array([0.97..., 0.97..., 0.99..., 0.98..., 0.98...])

    这里是一个使用单一指标的 cross_validate 的示例:

    >>> scores = cross_validate(clf, iris.data, iris.target,
    ...                         scoring='precision_macro', cv=5,
    ...                         return_estimator=True)
    >>> sorted(scores.keys())
    ['estimator', 'fit_time', 'score_time', 'test_score']

    2. 通过交叉验证获取预测

    除了返回结果不同,函数 cross_val_predict 具有和 cross_val_score 相同的接口, 对于每一个输入的元素,如果其在测试集合中,将会得到预测结果。交叉验证策略会将可用的元素提交到测试集合有且仅有一次(否则会抛出一个异常)。

    警告 :交叉预测可能使用不当

    cross_val_predict函数的结果可能会与cross_val_score函数的结果不一样,因为在这两种方法中元素的分组方式不一样。函数cross_val_score在所有交叉验证的折子上取平均。但是,函数cross_val_predict只是简单的返回由若干不同模型预测出的标签或概率。因此,cross_val_predict不是一种适当的泛化错误的度量。

    函数cross_val_predict比较适合做下列事儿:

    • 从不同模型获得的预测结果的可视化。
    • 模型混合: 在集成方法中,当一个有监督估计量的预测被用来训练另一个估计量时

    可用的交叉验证迭代器在下面的章节将提到。

    示例

  • 相关阅读:
    GIT DIFF生成.PATCH文件
    C++中static关键字作用总结
    模版与泛型编程
    模版以及全特化,偏特化
    重载运算与类型转换
    GDB调试工具(待整理)
    面向对象(primer)
    7种获取高度的区别
    把页面主体内容限定在安全区内
    ios浏览器下载,apple-itunes-app
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/14905042.html
Copyright © 2011-2022 走看看