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

时间:2019-07-27 15:53:44

标签: python pipeline random-forest tfidfvectorizer gridsearchcv

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)
}

实例化返回以下错误:

NameError: name 'vect' is not defined

编辑:

如果我正在调制TfidfVectorizer的参数(例如ngram_range),则这更相关(示例代码中未作说明),人们可以看到这如何将输出的要素数量更改为下一步...

1 个答案:

答案 0 :(得分:1)

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

我认为,最好的方法虽然不会完全产生您想要的结果,但只是对max_features使用分数值,即从矢量化器出来的列的百分比。

如果您真的想要为每个整数max_features得分,我认为最简单的方法可能是进行两个嵌套的网格搜索,内部的仅在调用其fit时实例化参数空间:

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的经过改进的副本,其第二步本身的最佳值将为max_features以及相应的经过改装的随机森林)。另外,可用于内部搜索的数据会小一些。