1 回答
TA貢獻1798條經驗 獲得超7個贊
您將 X 拆分為 X_train 和 X_test。對于 cv,您將 X_train 拆分為 5 折,而手動將 X 拆分為 5 折。即您手動使用的點數比使用 cv 的點數多。
更改results = lgb.cv(params, lgb.Dataset(X_train, y_train)為results = lgb.cv(params, lgb.Dataset(X, y)
此外,可以有不同的參數。例如,lightgbm 使用的線程數會改變結果。在 cv 期間,模型并行擬合。因此,使用的線程數可能與您的手動順序訓練不同。
第一次更正后編輯:
您可以使用以下代碼使用手動拆分/ cv 獲得相同的結果:
from sklearn.datasets import load_breast_cancer
import pandas as pd
from sklearn.model_selection import train_test_split, KFold
from sklearn.metrics import roc_auc_score
import lightgbm as lgb
import numpy as np
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.Series(data.target)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
folds = KFold(5, random_state=42)
params = {
'task': 'train',
'boosting_type': 'gbdt',
'objective':'binary',
'metric':'auc',
}
data_all = lgb.Dataset(X_train, y_train)
results = lgb.cv(params, data_all,
folds=folds.split(X_train),
num_boost_round=1000,
early_stopping_rounds=100)
print('LGBM\'s cv score: ', results['auc-mean'][-1])
val_scores = []
for train_idx, val_idx in folds.split(X_train):
data_trd = lgb.Dataset(X_train.iloc[train_idx],
y_train.iloc[train_idx],
reference=data_all)
gbm = lgb.train(params,
data_trd,
num_boost_round=len(results['auc-mean']),
verbose_eval=100)
val_scores.append(roc_auc_score(y_train.iloc[val_idx], gbm.predict(X_train.iloc[val_idx])))
print('Manual score: ', np.mean(np.array(val_scores)))
產量
LGBM's cv score: 0.9914524426410262
Manual score: 0.9914524426410262
與眾不同的是這條線reference=data_all。在 cv 期間,變量的分箱(指lightgbm doc)是使用整個數據集 (X_train) 構建的,而在您的 for 循環手冊中,它是基于訓練子集 (X_train.iloc[train_idx]) 構建的。通過傳遞對包含所有數據的數據集的引用,lightGBM 將重用相同的分箱,給出相同的結果
添加回答
舉報
