使用 K-Fold 交叉验证标准化数据
standardize data with K-Fold cross validation
我正在使用 StratifiedKFold,所以我的代码如下所示
def train_model(X,y,X_test,folds,model):
scores=[]
for fold_n, (train_index, valid_index) in enumerate(folds.split(X, y)):
X_train,X_valid = X[train_index],X[valid_index]
y_train,y_valid = y[train_index],y[valid_index]
model.fit(X_train,y_train)
y_pred_valid = model.predict(X_valid).reshape(-1,)
scores.append(roc_auc_score(y_valid, y_pred_valid))
print('CV mean score: {0:.4f}, std: {1:.4f}.'.format(np.mean(scores), np.std(scores)))
folds = StratifiedKFold(10,shuffle=True,random_state=0)
lr = LogisticRegression(class_weight='balanced',penalty='l1',C=0.1,solver='liblinear')
train_model(X_train,y_train,X_test,repeted_folds,lr)
现在在训练模型之前我想对数据进行标准化,那么哪种方法是正确的?
1)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
在调用 train_model 函数之前执行此操作
2)
像这样在函数内部进行标准化
def train_model(X,y,X_test,folds,model):
scores=[]
for fold_n, (train_index, valid_index) in enumerate(folds.split(X, y)):
X_train,X_valid = X[train_index],X[valid_index]
y_train,y_valid = y[train_index],y[valid_index]
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_vaid = scaler.transform(X_valid)
X_test = scaler.transform(X_test)
model.fit(X_train,y_train)
y_pred_valid = model.predict(X_valid).reshape(-1,)
scores.append(roc_auc_score(y_valid, y_pred_valid))
print('CV mean score: {0:.4f}, std: {1:.4f}.'.format(np.mean(scores), np.std(scores)))
根据我在第二个选项中的知识,我不会泄露 data.so 如果我不使用管道,哪种方式是正确的?如果我想使用交叉验证,如何使用管道?
何时标准化数据可能是一个更适合 Cross Validated 的问题。
IMO 如果你的数据很大那么它可能并不重要(如果你使用 k-fold 可能不是这种情况)但是既然你可以,最好在你的交叉验证中进行(k 倍),或选项 2。
此外,请参阅 this 了解有关交叉验证中过度拟合的更多信息。
事实上,第二个选项更好,因为缩放器看不到 X_valid
的值来缩放 X_train
。
现在如果你要使用管道,你可以这样做:
from sklearn.pipeline import make_pipeline
def train_model(X,y,X_test,folds,model):
pipeline = make_pipeline(StandardScaler(), model)
...
然后使用pipeline
代替model
。在每次 fit
或 predict
调用时,它会自动标准化手头的数据。
请注意,您还可以使用 scikit-learn 中的 cross_val_score 函数,参数为 scoring='roc_auc'
。
我正在使用 StratifiedKFold,所以我的代码如下所示
def train_model(X,y,X_test,folds,model):
scores=[]
for fold_n, (train_index, valid_index) in enumerate(folds.split(X, y)):
X_train,X_valid = X[train_index],X[valid_index]
y_train,y_valid = y[train_index],y[valid_index]
model.fit(X_train,y_train)
y_pred_valid = model.predict(X_valid).reshape(-1,)
scores.append(roc_auc_score(y_valid, y_pred_valid))
print('CV mean score: {0:.4f}, std: {1:.4f}.'.format(np.mean(scores), np.std(scores)))
folds = StratifiedKFold(10,shuffle=True,random_state=0)
lr = LogisticRegression(class_weight='balanced',penalty='l1',C=0.1,solver='liblinear')
train_model(X_train,y_train,X_test,repeted_folds,lr)
现在在训练模型之前我想对数据进行标准化,那么哪种方法是正确的?
1)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
在调用 train_model 函数之前执行此操作
2)
像这样在函数内部进行标准化
def train_model(X,y,X_test,folds,model):
scores=[]
for fold_n, (train_index, valid_index) in enumerate(folds.split(X, y)):
X_train,X_valid = X[train_index],X[valid_index]
y_train,y_valid = y[train_index],y[valid_index]
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_vaid = scaler.transform(X_valid)
X_test = scaler.transform(X_test)
model.fit(X_train,y_train)
y_pred_valid = model.predict(X_valid).reshape(-1,)
scores.append(roc_auc_score(y_valid, y_pred_valid))
print('CV mean score: {0:.4f}, std: {1:.4f}.'.format(np.mean(scores), np.std(scores)))
根据我在第二个选项中的知识,我不会泄露 data.so 如果我不使用管道,哪种方式是正确的?如果我想使用交叉验证,如何使用管道?
何时标准化数据可能是一个更适合 Cross Validated 的问题。
IMO 如果你的数据很大那么它可能并不重要(如果你使用 k-fold 可能不是这种情况)但是既然你可以,最好在你的交叉验证中进行(k 倍),或选项 2。
此外,请参阅 this 了解有关交叉验证中过度拟合的更多信息。
事实上,第二个选项更好,因为缩放器看不到 X_valid
的值来缩放 X_train
。
现在如果你要使用管道,你可以这样做:
from sklearn.pipeline import make_pipeline
def train_model(X,y,X_test,folds,model):
pipeline = make_pipeline(StandardScaler(), model)
...
然后使用pipeline
代替model
。在每次 fit
或 predict
调用时,它会自动标准化手头的数据。
请注意,您还可以使用 scikit-learn 中的 cross_val_score 函数,参数为 scoring='roc_auc'
。