Thực hiện xác nhận chéo lồng nhau


10

Tôi đang cố gắng tìm hiểu xem sự hiểu biết của tôi về xác thực chéo lồng nhau có đúng không, do đó tôi đã viết ví dụ về đồ chơi này để xem tôi có đúng không:

import operator
import numpy as np
from sklearn import cross_validation
from sklearn import ensemble
from sklearn.datasets import load_boston

# set random state
state = 1

# load boston dataset
boston = load_boston()

X = boston.data
y = boston.target

outer_scores = []

# outer cross-validation
outer = cross_validation.KFold(len(y), n_folds=3, shuffle=True, random_state=state)
for fold, (train_index_outer, test_index_outer) in enumerate(outer):
    X_train_outer, X_test_outer = X[train_index_outer], X[test_index_outer]
    y_train_outer, y_test_outer = y[train_index_outer], y[test_index_outer]

    inner_mean_scores = []

    # define explored parameter space.
    # procedure below should be equal to GridSearchCV
    tuned_parameter = [1000, 1100, 1200]
    for param in tuned_parameter:

        inner_scores = []

        # inner cross-validation
        inner = cross_validation.KFold(len(X_train_outer), n_folds=3, shuffle=True, random_state=state)
        for train_index_inner, test_index_inner in inner:
            # split the training data of outer CV
            X_train_inner, X_test_inner = X_train_outer[train_index_inner], X_train_outer[test_index_inner]
            y_train_inner, y_test_inner = y_train_outer[train_index_inner], y_train_outer[test_index_inner]

            # fit extremely randomized trees regressor to training data of inner CV
            clf = ensemble.ExtraTreesRegressor(param, n_jobs=-1, random_state=1)
            clf.fit(X_train_inner, y_train_inner)
            inner_scores.append(clf.score(X_test_inner, y_test_inner))

        # calculate mean score for inner folds
        inner_mean_scores.append(np.mean(inner_scores))

    # get maximum score index
    index, value = max(enumerate(inner_mean_scores), key=operator.itemgetter(1))

    print 'Best parameter of %i fold: %i' % (fold + 1, tuned_parameter[index])

    # fit the selected model to the training set of outer CV
    # for prediction error estimation
    clf2 = ensemble.ExtraTreesRegressor(tuned_parameter[index], n_jobs=-1, random_state=1)
    clf2.fit(X_train_outer, y_train_outer)
    outer_scores.append(clf2.score(X_test_outer, y_test_outer))

# show the prediction error estimate produced by nested CV
print 'Unbiased prediction error: %.4f' % (np.mean(outer_scores))

# finally, fit the selected model to the whole dataset
clf3 = ensemble.ExtraTreesRegressor(tuned_parameter[index], n_jobs=-1, random_state=1)
clf3.fit(X, y)

Bất kỳ suy nghĩ đánh giá cao.


3
Bạn cũng có thể cung cấp một phiên bản hiểu biết của bạn về xác thực chéo trong văn bản cho những người không đọc Python không?
gung - Phục hồi Monica

Câu trả lời:


14

UPS, mã là sai, nhưng theo một cách rất tinh tế !

a) việc tách bộ tàu thành tập huấn luyện bên trong và tập kiểm tra là OK.

b) vấn đề là hai dòng cuối cùng, phản ánh sự hiểu lầm tinh tế về mục đích của xác nhận chéo lồng nhau. Mục đích của CV lồng nhau không phải là chọn các tham số, mà là để đánh giá khách quan về độ chính xác dự kiến ​​của thuật toán của bạn, trong trường hợp này ensemble.ExtraTreesRegressortrong dữ liệu này có siêu tham số tốt nhất bất kể chúng có thể là gì .

Và đây là những gì mã của bạn tính toán chính xác cho đến dòng:

    print 'Unbiased prediction error: %.4f' % (np.mean(outer_scores))

Nó đã sử dụng CV lồng nhau để tính toán dự đoán không thiên vị của bộ phân loại. Nhưng lưu ý rằng mỗi lần vượt qua của vòng lặp bên ngoài có thể tạo ra một siêu tham số tốt nhất khác nhau, như bạn đã biết khi bạn viết dòng này:

   print 'Best parameter of %i fold: %i' % (fold + 1, tuned_parameter[index])

Vì vậy, bây giờ bạn cần một vòng lặp CV tiêu chuẩn để chọn siêu tham số tốt nhất cuối cùng, sử dụng các nếp gấp:

tuned_parameter = [1000, 1100, 1200]
for param in tuned_parameter:

    scores = []

    # normal cross-validation
    kfolds = cross_validation.KFold(len(y), n_folds=3, shuffle=True, random_state=state)
    for train_index, test_index in kfolds:
        # split the training data
        X_train, X_test = X[train_index], X[test_index]
        y_train, y_test = y[train_index], y[test_index]

        # fit extremely randomized trees regressor to training data
        clf2_5 = ensemble.ExtraTreesRegressor(param, n_jobs=-1, random_state=1)
        clf2_5.fit(X_train, y_train)
        scores.append(clf2_5.score(X_test, y_test))

    # calculate mean score for folds
    mean_scores.append(np.mean(scores))

# get maximum score index
index, value = max(enumerate(mean_scores), key=operator.itemgetter(1))

print 'Best parameter : %i' % (tuned_parameter[index])

đó là mã của bạn nhưng có tham chiếu đến bên trong bị loại bỏ.

Bây giờ tham số tốt nhất là tuned_parameter[index], và bây giờ bạn có thể tìm hiểu trình phân loại cuối cùng clf3như trong mã của bạn.


Cảm ơn! Tôi đã xem xét rằng tôi có thể chọn các besttham số khác nhau trong các nếp gấp khác nhau, nhưng tôi không biết cách chọn các tham số tốt nhất. stats.stackexchange.com/questions/65128/ Mạnh - ở đây, trong câu trả lời được đề cập rằng thực sự không mong muốn chọn mô hình tốt nhất trong số các mô hình k bên ngoài. Có thể tôi vẫn đang hiểu nhầm điều gì đó, nhưng tôi nghĩ rằng ý tưởng của vòng CV bên trong là chọn mô hình hoạt động tốt nhất và vòng CV bên ngoài là để ước tính hiệu suất. Bạn có thể vui lòng cung cấp mã sửa đổi đầy đủ?
abudis 4/2/2015

Được rồi, tôi nghĩ rằng tôi đã nhận được điều đó. Tôi muốn xem mã sửa đổi đầy đủ, chỉ để chắc chắn. Cảm ơn.
abudis 6/2/2015

1
Tôi bối rối về câu trả lời của Jacques Weller và tôi nghĩ rằng nó đáng để làm rõ nó. Vì vậy, Wainer có gợi ý rằng một vòng lặp CV tiêu chuẩn nên tuân theo mã được cung cấp bởi câu hỏi ban đầu hay nó chỉ nên thay thế mã phần "bên trong" ban đầu? thanx

Vòng CV tiêu chuẩn tuân theo vòng CV lồng nhau
Jacques Wainer

2
Phần đầu tiên là tính toán một dự đoán không thiên vị về lỗi. Nếu bạn đang thử nghiệm nhiều thuật toán khác nhau, bạn chỉ nên thực hiện phần 1, sau đó chọn thuật toán có lỗi thấp nhất và chỉ với phần đó, thực hiện phần 2 để chọn siêu âm. Nếu bạn được thiết lập chỉ sử dụng một thuật toán, thì phần 1 sẽ ít quan trọng hơn, trừ khi bạn muốn bảo vệ ông chủ hoặc khách hàng của bạn rằng dự đoán tốt nhất về lỗi tương lai của trình phân loại là x và bạn phải tính x bằng cách sử dụng phần 1 CV lồng nhau.
Jacques Wainer

0

Để tóm tắt câu trả lời của Jacques,

CV lồng nhau là cần thiết cho ước tính lỗi không thiên vị của một mô hình. Chúng ta có thể so sánh điểm của các mô hình khác nhau theo cách này. Sau đó, sử dụng thông tin này, chúng tôi có thể thực hiện một vòng CV gấp K riêng biệt để điều chỉnh tham số của các mô hình đã chọn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.