2

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,人们可以看到这如何将特征输出的数量更改为下一步......

4

1 回答 1

1

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

我认为最好的方法,虽然它不会产生你所追求的,只是使用小数值max_features,即来自矢量化器的列的百分比。

如果您真的想要每个 integer 的分数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和一个相应的改装随机森林)。此外,可用于内部搜索的数据会小一些。

于 2020-04-24T21:22:45.107 回答