fit_transform()需要传入2个参数,但是在使用LabelBinarizer时却传入了3个参数。

97
我是一名有用的助手,可以为您翻译文本。

我完全不了解机器学习,但我一直在使用无监督学习技术。

以下是我的样本数据(清理后)截图:

样本数据

我已经建立了这两个管道来清理数据:

num_attribs = list(housing_num)
cat_attribs = ["ocean_proximity"]

print(type(num_attribs))

num_pipeline = Pipeline([
    ('selector', DataFrameSelector(num_attribs)),
    ('imputer', Imputer(strategy="median")),
    ('attribs_adder', CombinedAttributesAdder()),
    ('std_scaler', StandardScaler()),
])

cat_pipeline = Pipeline([
    ('selector', DataFrameSelector(cat_attribs)),
    ('label_binarizer', LabelBinarizer())
])

然后我将这两个管道进行了联合,其代码如下所示:

from sklearn.pipeline import FeatureUnion

full_pipeline = FeatureUnion(transformer_list=[
        ("num_pipeline", num_pipeline),
        ("cat_pipeline", cat_pipeline),
    ])

现在我正在尝试对数据进行fit_transform,但出现了错误。

转换代码:

housing_prepared = full_pipeline.fit_transform(housing)
housing_prepared

错误信息:

fit_transform() 接受 2 个位置参数,但提供了 3 个


6
LabelBinarizer不应该与X(特征)一起使用,而是仅用于标签。因此,fit和fit_transform方法被更改为仅包括单个对象y。但是Pipeline(适用于特征)将尝试将X和y都发送给它。因此会出现错误。 - Vivek Kumar
4
你应该在管道之外使用LabelBinarizer将分类特征转换为独热编码,或者可以使用pandas.get_dummies() - Vivek Kumar
17个回答

1

我见过许多自定义标签二值化器,但这个repo的对我很有用。

class LabelBinarizerPipelineFriendly(LabelBinarizer):
    def fit(self, X, y=None):
        """this would allow us to fit the model based on the X input."""
        super(LabelBinarizerPipelineFriendly, self).fit(X)
    def transform(self, X, y=None):
        return super(LabelBinarizerPipelineFriendly, self).transform(X)

    def fit_transform(self, X, y=None):
        return super(LabelBinarizerPipelineFriendly, self).fit(X).transform(X)

然后将cat_pipeline编辑为:

cat_pipeline = Pipeline([
        ('selector', DataFrameSelector(cat_attribs)),
        ('label_binarizer', LabelBinarizerPipelineFriendly()),
    ])

祝你一切顺利!


1
你可以创建一个自定义转换器来为你进行编码。
class CustomLabelEncode(BaseEstimator, TransformerMixin):
    def fit(self, X, y=None):
        return self
    def transform(self, X):
        return LabelEncoder().fit_transform(X);

在这个例子中,我们使用了LabelEncoding,但您也可以使用LabelBinarizer。

1

您可以在您的代码中使用这个修改过的LabelBinarizer类:

class mod_LabelBinarizer(LabelBinarizer):
    def fit_transform(self, X, y=None):
        self.fit(X)
        return self.transform(X) 

现在你可以在编写cat_pipeline时,使用mod_LabelBinarizer()代替LabelBinarizer(),你的代码应该像这样:
cat_pipeline = Pipeline([
    ('selector', DataFrameSelector(cat_attribs)),
    ('label_binarizer', mod_LabelBinarizer())
])

0

最终我自己动手实现了它

class LabelBinarizer(BaseEstimator, TransformerMixin):
    def fit(self, X, y=None):
        X = self.prep(X)
        unique_vals = []
        for column in X.T:
            unique_vals.append(np.unique(column))
        self.unique_vals = unique_vals
    def transform(self, X, y=None):
        X = self.prep(X)
        unique_vals = self.unique_vals
        new_columns = []
        for i, column in enumerate(X.T):
            num_uniq_vals = len(unique_vals[i])
            encoder_ring = dict(zip(unique_vals[i], range(len(unique_vals[i]))))
            f = lambda val: encoder_ring[val]
            f = np.vectorize(f, otypes=[np.int])
            new_column = np.array([f(column)])
            if num_uniq_vals <= 2:
                new_columns.append(new_column)
            else:
                one_hots = np.zeros([num_uniq_vals, len(column)], np.int)
                one_hots[new_column, range(len(column))]=1
                new_columns.append(one_hots)
        new_columns = np.concatenate(new_columns, axis=0).T        
        return new_columns

    def fit_transform(self, X, y=None):
        self.fit(X)
        return self.transform(X)

    @staticmethod
    def prep(X):
        shape = X.shape
        if len(shape) == 1:
            X = X.values.reshape(shape[0], 1)
        return X

看起来可以工作

lbn = LabelBinarizer()
thingy = np.array([['male','male','female', 'male'], ['A', 'B', 'A', 'C']]).T
lbn.fit(thingy)
lbn.transform(thingy)

返回

array([[1, 1, 0, 0],
       [1, 0, 1, 0],
       [0, 1, 0, 0],
       [1, 0, 0, 1]])

0

在我的情况下,它有所帮助

def _binarize(series: pd.Series) -> pd.Series:
    return series.astype(int)


binary_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy="most_frequent")),
    ('binary_encoder', FunctionTransformer(_binarize))
])

0

最简单的方法是在你的管道中用OrdinalEncoder()替换LabelBinarize()。


-1
我们可以只需添加属性sparce_output=False。
cat_pipeline = Pipeline([
  ('selector', DataFrameSelector(cat_attribs)),
  ('label_binarizer', LabelBinarizer(sparse_output=False)),   
])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接