首页 > 解决方案 > ColumnTransformer 两次创建估算器(并覆盖默认参数)

问题描述

假设我有以下 DataFrame (当然是过度简化了):

df = pd.DataFrame([
   'Hello', 'Bye', 'Hello', 'Hello', 'Bye', 'Hello', 'Bye', 'Hello'
], columns=['A'])

我还有以下估计器/转换器,用于根据相似性将 的所有值聚类AN个集群中:

class Clusterer(BaseEstimator, TransformerMixin):
    def __init__(self, nclusters=2):
        print('__init__({}) called'.format(nclusters))
        self._vectorizer = CountVectorizer(strip_accents='unicode', stop_words='english')
        self._nclusters = nclusters
    def fit(self, X, y=None):
        # Vectorize all values, then cluster
        self._clusters = [
             KMeans(n_clusters=self._nclusters)
             .fit(self._vectorizer.fit_transform(x))
             for x in X.values.T
        ]
        return self
    def transform(self, X):
        # Return cluster labels
        return np.array([c.labels_ for c in self._clusters])

注意print下面的声明__init__

我希望得到以下转变

A
--
0
1
0
0
0
1
0
1
0

请注意,所有内容都已编码为01(我提供的示例是真实数据的真正简化版本)

我创建了以下转换:

ctf = ColumnTransformer([
    ('a', Clusterer(nclusters=2), ['A'])
])

但是,执行后:

ctf.fit_transform(df)

我得到以下打印的语句:

__init__(2)
__init__(None)

由于n_clusters未提供,因此在实际聚类期间会导致错误。

知道我在这里想念什么吗?

标签: pythonpandasscikit-learn

解决方案


所以,这花了我一段时间才弄清楚,但ColumnTransformer实际上会克隆你提供的转换器,当你打电话fitfit_transform

scikit.base.clone的工作方式是它通过 获取估计器的参数get_params,然后set_params使用相同的值调用新实例。

BaseEstimatorget_params已经为and提供了默认实现set_params,但他们假设您将拥有与 parameter 同名的属性,在我的情况下这不是真的(self._nclusters = nclusters由于下划线)。

修复后,一切都按预期工作。


推荐阅读