在阅读了很多关于pipeline.fit()操作的内容并且使用不同的verbose参数设置进行了检查后,我仍然困惑于我的管道为什么会多次访问某个步骤的transform方法。
下面是一个微不足道的示例pipeline,使用3折交叉验证的GridSearchCV进行fit,但只有一个超参数集合的param-grid。因此,我预期通过管道运行三次。正如预期的那样,step1和step2都调用了fit三次,但是每个步骤都调用了多次transform。这是为什么呢?下面是最小化的代码示例和日志输出。
# library imports
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import KFold
from sklearn.linear_model import LogisticRegression
from sklearn.base import TransformerMixin, BaseEstimator
from sklearn.pipeline import Pipeline
# Load toy data
iris = datasets.load_iris()
X = pd.DataFrame(iris.data, columns = iris.feature_names)
y = pd.Series(iris.target, name='y')
# Define a couple trivial pipeline steps
class mult_everything_by(TransformerMixin, BaseEstimator):
def __init__(self, multiplier=2):
self.multiplier = multiplier
def fit(self, X, y=None):
print "Fitting step 1"
return self
def transform(self, X, y=None):
print "Transforming step 1"
return X* self.multiplier
class do_nothing(TransformerMixin, BaseEstimator):
def __init__(self, meaningless_param = 'hello'):
self.meaningless_param=meaningless_param
def fit(self, X, y=None):
print "Fitting step 2"
return self
def transform(self, X, y=None):
print "Transforming step 2"
return X
# Define the steps in our Pipeline
pipeline_steps = [('step1', mult_everything_by()),
('step2', do_nothing()),
('classifier', LogisticRegression()),
]
pipeline = Pipeline(pipeline_steps)
# To keep this example super minimal, this param grid only has one set
# of hyperparams, so we are only fitting one type of model
param_grid = {'step1__multiplier': [2], #,3],
'step2__meaningless_param': ['hello'] #, 'howdy', 'goodbye']
}
# Define model-search process/object
# (fit one model, 3-fits due to 3-fold cross-validation)
cv_model_search = GridSearchCV(pipeline,
param_grid,
cv = KFold(3),
refit=False,
verbose = 0)
# Fit all (1) models defined in our model-search object
cv_model_search.fit(X,y)
输出:
Fitting step 1
Transforming step 1
Fitting step 2
Transforming step 2
Transforming step 1
Transforming step 2
Transforming step 1
Transforming step 2
Fitting step 1
Transforming step 1
Fitting step 2
Transforming step 2
Transforming step 1
Transforming step 2
Transforming step 1
Transforming step 2
Fitting step 1
Transforming step 1
Fitting step 2
Transforming step 2
Transforming step 1
Transforming step 2
Transforming step 1
Transforming step 2
return_train_score
的解释,这就涵盖了所有打印的步骤。所以它是如何工作的。但是最后两个transform
对于return_train_score
真的必要吗?正如您在第2点中指出的那样,“对于训练...[我们有]fit step1
,transform step1
,fit step2
,transform step2
”。然后管道“将转换后的数据拟合到分类器上”(您的3)。此时,我们已经拥有了生成train_score
所需的一切:我们拟合的分类器将.predict()我们的train-preds。而且我们已经给出了train_y。那么为什么后面还需要额外的转换步骤呢? - Max PowerPipeline
的内存参数用于缓存转换器,但我不认为这解决了这个问题。虽然我可能误解了它。 - Max Power