我在我的数据集上试验特征选择,我注意到我得到了不同的结果:a)将特征选择放在包裹在GridSearchCV对象中的管道内并调用' fit'和b)调用fit_transform在特征选择器上,然后在分类器上应用GridSearhCV,从特征选择器中获取fit_transformed特征矩阵。是因为' fit'之间的区别?和' fit_transform'?不确定我是否清楚自己,但这里是gridsearch的代码:
fs=SelectFromModel(LogisticRegression(class_weight='balanced',penalty="l1",C=0.01))
fs_params = {} #deliberately leaving these empty for comparison
classifier = svm.LinearSVC()
cl_params = {} #deliberately leaving these empty for comparison
pipe = []
params=[]
pipe.append(('fs', fs))
params.append(fs_params)
pipe.append(('classify', classifier))
params.append(cl_params)
pipeline=Pipeline(pipe)
piped_classifier = GridSearchCV(pipeline, param_grid=params, cv=10,
n_jobs=-1)
piped_classifier.fit(X_train, y_train)
nfold_predictions=cross_val_predict(piped_classifier.best_estimator_, X_train, y_train, cv=10)
best_estimator = piped_classifier.best_estimator_
best_param = piped_classifier.best_params_
cv_score = piped_classifier.best_score_
#followed by code to print scores
以及在GridSearchCV之外进行特征选择的代码:
select = SelectFromModel(LogisticRegression(class_weight='balanced',penalty="l1",C=0.01))
X_ = select.fit_transform(X_train,y_train) #line A
classifier = svm.LinearSVC()
piped_classifier = GridSearchCV(classifier, param_grid=params, cv=10,
n_jobs=-1)
piped_classifier.fit(X_, y_train)
nfold_predictions=cross_val_predict(piped_classifier.best_estimator_, X_, y_train, cv=10)
best_estimator = piped_classifier.best_estimator_
best_param = piped_classifier.best_params_
cv_score = piped_classifier.best_score_
#followed by code to print scores
对于第一个代码,我得到的分数如下:
P=0.31 R=0.17 F1=0.22
而对于第二个,分数更好:
P=0.41 R=0.28 F=0.33
我能想到的唯一可能导致此问题的是第二个代码片段中的A行,它调用fit_transform。除此之外,我认为两个代码片段应该做同样的任务。
任何建议都非常感激。
答案 0 :(得分:1)
一般情况下,由于data leakage
,您可能会遇到不同的结果在你的第二个片段中,gridsearch在X_train
的片段上训练svc但是,所有X_train
在第一个示例中,您可以避免此问题。
这可以大大降低泛化性能。但是,目前还不清楚你是如何获得关于P,R和F的信息的。它们来自测试集吗?
但是,我不确定这是否可以解释指标差异的程度。至少您的代码显示了使用数据泄漏时的典型过度拟合,并且在对特征选择进行流水线操作时性能会下降。
您还可以查看scikit-learn documentation on nested cross-validation
让我添加一个重要的评论:在第二种方法中,您将修复在开始时传递给您的svc的功能。因此,svc将在每个折叠上使用相同的特征。而在第一个示例中,传递给网格搜索的功能可能会从折叠变为折叠!