代码之家  ›  专栏  ›  技术社区  ›  Outcast

SkLearn调用嵌套交叉验证

  •  4
  • Outcast  · 技术社区  · 8 年前

    SkLearn page 以下是嵌套交叉验证的示例:

    from sklearn.datasets import load_iris
    from matplotlib import pyplot as plt
    from sklearn.svm import SVC
    from sklearn.model_selection import GridSearchCV, cross_val_score, KFold
    import numpy as np
    
    print(__doc__)
    
    # Number of random trials
    NUM_TRIALS = 30
    
    # Load the dataset
    iris = load_iris()
    X_iris = iris.data
    y_iris = iris.target
    
    # Set up possible values of parameters to optimize over
    p_grid = {"C": [1, 10, 100],
              "gamma": [.01, .1]}
    
    # We will use a Support Vector Classifier with "rbf" kernel
    svm = SVC(kernel="rbf")
    
    # Arrays to store scores
    non_nested_scores = np.zeros(NUM_TRIALS)
    nested_scores = np.zeros(NUM_TRIALS)
    
    # Loop for each trial
    for i in range(NUM_TRIALS):
    
        # Choose cross-validation techniques for the inner and outer loops,
        # independently of the dataset.
        # E.g "LabelKFold", "LeaveOneOut", "LeaveOneLabelOut", etc.
        inner_cv = KFold(n_splits=4, shuffle=True, random_state=i)
        outer_cv = KFold(n_splits=4, shuffle=True, random_state=i)
    
        # Non_nested parameter search and scoring
        clf = GridSearchCV(estimator=svm, param_grid=p_grid, cv=inner_cv)
        clf.fit(X_iris, y_iris)
        non_nested_scores[i] = clf.best_score_
    
        # Nested CV with parameter optimization
        nested_score = cross_val_score(clf, X=X_iris, y=y_iris, cv=outer_cv)
        nested_scores[i] = nested_score.mean()
    
    score_difference = non_nested_scores - nested_scores
    
    print("Average difference of {0:6f} with std. dev. of {1:6f}."
          .format(score_difference.mean(), score_difference.std()))
    
    # Plot scores on each trial for nested and non-nested CV
    plt.figure()
    plt.subplot(211)
    non_nested_scores_line, = plt.plot(non_nested_scores, color='r')
    nested_line, = plt.plot(nested_scores, color='b')
    plt.ylabel("score", fontsize="14")
    plt.legend([non_nested_scores_line, nested_line],
               ["Non-Nested CV", "Nested CV"],
               bbox_to_anchor=(0, .4, .5, 0))
    plt.title("Non-Nested and Nested Cross Validation on Iris Dataset",
              x=.5, y=1.1, fontsize="15")
    
    # Plot bar chart of the difference.
    plt.subplot(212)
    difference_plot = plt.bar(range(NUM_TRIALS), score_difference)
    plt.xlabel("Individual Trial #")
    plt.legend([difference_plot],
               ["Non-Nested CV - Nested CV Score"],
               bbox_to_anchor=(0, 1, .8, 0))
    plt.ylabel("score difference", fontsize="14")
    
    plt.show()
    

    我不知道我是否遗漏了一些东西,但这正是嵌套交叉验证的一个例子吗?

    问题 在这个例子中,参数优化和模型评估都是用同一个数据集完成的,而前者应该用训练和验证集来完成,而后者应该用测试集来完成。

    具体地说,在这个例子中,“内部”和“外部”循环都使用 X_iris 和 y_iris

    • clf.fit(X_iris, y_iris) (网格搜索)
    • cross_val_score(clf, X=X_iris, y=y_iris, cv=outer_cv)
    0 回复  |  直到 8 年前
    推荐文章