簡體   English   中英

訓練玩具 Xgboost model 時手動復制 cross_val_score 會導致奇怪的結果

[英]Manually replicating cross_val_score leads to strange resutls when training a toy Xgboost model

在超調 XGboost 玩具 model 時,我嘗試復制cross_val_score()的結果。

我使用代碼 NO.1 進行交叉驗證,其結果用作基准,然后使用代碼 NO.2 和 NO.3 通過手動編程交叉驗證循環來復制 CV 結果。

代碼 NO.2 和代碼 NO.3 的主要區別在於,我將 XGboost 分類器的初始化放在代碼 NO.3 的 for 循環之外,而放在代碼 NO.2 的 for 循環內。 我預計只有代碼 NO.2(循環內版本)產生的結果與自動cross_val_score得到的結果相同。 令我驚訝的是,所有三個版本的代碼共享相同的結果。

我的問題是:我們不應該為 cross_val_score 的源代碼中提到的每個驗證克隆cross_val_score嗎? 在代碼 NO.3 中,經過訓練的 Xgboost 模型在驗證過程中不是獨立的,對吧? 非獨立性符合交叉驗證的精神,不是嗎? 但為什么我從他們那里得到相同的結果?

代碼 NO.1

params = {
    'objective': 'binary:logistic',
    'eval_metric': 'auc'
}
model = XGBClassifier(**params)
kfold = StratifiedKFold(n_splits=N_SPLITS, random_state=SEED)
results = cross_val_score(model, X, Y, scoring='accuracy', cv=kfold) # only a single metric is permitted. model is cloned not relay across folds.
print(f'Accuracy: {results.mean()*100:.4f}% ({results.std()*100:.3f})')

代碼 NO.2

x_train = all_df.drop('Survived', axis=1).iloc[:train_rows].values 
y_train = train_label.iloc[:train_rows].values
y_oof = np.zeros(x_train.shape[0])
acc_scores = []
kfold = StratifiedKFold(n_splits=N_SPLITS, random_state=SEED)
for i, (train_index, valid_index) in enumerate(kfold.split(x_train, y_train)):
    model = XGBClassifier(**params) # <=======================================
    X_A, X_B = x_train[train_index, :], x_train[valid_index, :]
    y_A, y_B = y_train[train_index], y_train[valid_index]
    model.fit(X_A, y_A, eval_set=[(X_B, y_B)])
    y_oof[valid_index] = model.predict(X_B)
    acc_scores.append(accuracy_score(y_B, y_oof[valid_index]))

代碼 NO.3

x_train = all_df.drop('Survived', axis=1).iloc[:train_rows].values 
y_train = train_label.iloc[:train_rows].values
y_oof = np.zeros(x_train.shape[0])
acc_scores = []
kfold = StratifiedKFold(n_splits=N_SPLITS, random_state=SEED)
model = XGBClassifier(**params) # <=======================================
for i, (train_index, valid_index) in enumerate(kfold.split(x_train, y_train)):
    X_A, X_B = x_train[train_index, :], x_train[valid_index, :]
    y_A, y_B = y_train[train_index], y_train[valid_index]
    model.fit(X_A, y_A, eval_set=[(X_B, y_B)])
    y_oof[valid_index] = model.predict(X_B)
    acc_scores.append(accuracy_score(y_B, y_oof[valid_index]))

當您在XGBClassifier實例(或理想情況下,任何與 sklearn 兼容的估計器)上調用fit時,學習將從頭開始,因此模型在驗證中確實是獨立的。

當然,重新初始化或克隆 model 會稍微安全一些,特別是如果您不確定該實現不會保留任何可供使用的信息。 cross_val_scorecross_validate的包裝器,實際上需要克隆,以防return_estimator=True ,因此需要保存 model 的各種副本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM