将先前 sklearn 管道步骤中的对象属性作为参数传递给下一步方法

Pass object attribute from previous sklearn pipeline step as argument to next step method

tl;dr:有什么方法可以调用 .get_feature_names() 拟合 从上一步转换的数据在管道的下一步中用作超参数的管道?


我有一个 Pipeline,其中包括使用 TfidfVectorizer 拟合和转换文本数据,然后运行 ​​RandomForestClassifier。我想 GridSearchCV 跨越分类器中 max_features 的各个级别,基于转换从文本产生的特征数量。

#setup pipeline
pipe = Pipeline([
    ('vect', TfidfVectorizer(max_df=.4,
                            min_df=3,
                            norm='l1',
                            stop_words='english',
                            use_idf=False)),
    ('rf', RandomForestClassifier(random_state=1,
                                  criterion='entropy',
                                  n_estimators=800))
])

#setup parameter grid
params = {
    'rf__max_features': np.arange(1, len(vect.get_feature_names()),1)
}

实例化returns出现以下错误:

NameError: name 'vect' is not defined

编辑:

如果我正在调制 TfidfVectorizer 的参数,例如 ngram_range,这将更相关(并且未在示例代码中说明),可以看出这将如何改变特征的数量输出到下一步...

在安装管道中的任何内容之前填充参数网格,因此您不能直接执行此操作。您也许可以对网格搜索进行猴子修补,like here,但我希望它会更加困难,因为您的第二个参数取决于第一步的拟合结果。

我认为最好的方法是只对 max_features 使用分数值,即从矢量化器中出来的列的百分比。

如果你真的想要每个整数 max_features 的分数,我认为最简单的方法可能是有两个嵌套的网格搜索,内部的只在其 [= 时实例化参数 space 13=] 被称为:

estimator = RandomForestClassifier(
    random_state=1,
    criterion='entropy',
    n_estimators=800
    )

class MySearcher(GridSearchCV):
    def fit(self, X, y):
        m = X.shape[1]
        self.param_grid = {'max_features': np.arange(1, m, 1)}
        return super().fit(X, y)

pipe = Pipeline([
    ('vect', TfidfVectorizer(max_df=.4,
                             min_df=3,
                             norm='l1',
                             stop_words='english',
                             use_idf=False)),
    ('rf', MySearcher(estimator=estimator, 
                      param_grid={'fake': ['passes', 'check']}))
])

现在搜索结果将被笨拙地嵌套(例如,ngram_range 的最佳值会为您提供 pipe 的改装副本,其第二步本身将具有 [=11] 的最佳值=] 和相应的改装随机森林)。还有,内部搜索可用的数据会少一些。