如何创建预处理管道,包括内置的 scikit 学习转换器、自定义转换器,其中之一用于特征工程?

概括

我正在努力创建一个带有内置转换器和自定义转换器的预处理管道,其中包括一个可以向数据添加额外属性并进一步对添加的属性执行转换的转换器。

附加属性示例:

  • 有一个 phValue 属性缺少数据。我想尝试创建一个附加属性,该属性将在 phLabel 列中将 phValue 标记为 (Acid, Neutral, Base)。

  • 也是每个序列特征的字符串长度。

这将需要输入 phValue 的缺失值,然后创建其他属性和进一步的转换器,这些转换器也将转换 sequence_length 属性。

我可怕的变压器。

这是我如何创建自定义转换器的示例,我可以将其用于手动预处理,但是,在创建完整的预处理管道时,这不是处理它的正确方法。

def data_to_frame(X):

    if isinstance(X, pd.DataFrame):

        return X

    elif isinstance(X, sparse.csr_matrix):

        return pd.DataFrame(X, indices, atributes)

    elif isinstance(X, np.ndarray):

        return pd.DataFrame(X, indices, atributes)

    else:

        raise Exception("Incorrect Data Structure Passed")


class CombinedAttributesAdder(BaseEstimator, TransformerMixin):

    def __init__(self, no_difference = True): # no *args or **kargs

        self.no_difference = no_difference

    def fit(self, X, y=None):

        return self # nothing else to do

    def transform(self, X):

        atributes.extend(['sequence_length', 'difference', 'phLabel'])

        sequence_length = X.sequence.str.len()

        difference = X['residueCount'] - sequence_length

        phLabel = X['phValue'].apply(ph_labels)

        if self.no_difference:

            atributes.append('no_difference')

            no_difference = (difference == 0)

            return np.c_[X, sequence_length, difference, phLabel, no_difference]

        else:

            return np.c_[X, sequence_length, difference, phLabel]

变形金刚中的 Pandas 操作。

我想在变形金刚中执行的操作特定于熊猫。我的解决方案是将输入的 numpy 数组转换为数据帧,并在转换函数中将其作为 numpy 数组返回。我将全局变量用于属性和索引。我意识到这是一种乏善可陈的方法。我如何在我的自定义转换器中使用 pandas 操作?


泛舟湖上清波郎朗
浏览 122回答 1
1回答

尚方宝剑之说

这应该按预期工作——很可能你的实现有问题——可以尝试处理一个虚拟数据集。并不TransformerMixin真正关心输入是numpy还是pandas.DataFrame,它将按“预期”工作。import pandas as pdimport numpy as npfrom sklearn.base import TransformerMixinfrom sklearn.preprocessing import StandardScalerfrom sklearn.preprocessing import FunctionTransformerfrom sklearn.pipeline import make_pipelineclass CustomTransformer(TransformerMixin):    def __init__(self, some_stuff=None, column_names= []):        self.some_stuff = some_stuff        self.column_names = column_names    def fit(self, X, y=None):        return self    def transform(self, X):        # do stuff on X, and return dataframe        # of the same shape - this gets messy        # if the preceding item is a numpy array        # and not a dataframe        if isinstance(X, np.ndarray):            X = pd.DataFrame(X, columns=self.column_names)                X['str_len'] = X['my_str'].apply(lambda x: str(x)).str.len()        X['custom_func'] = X['val'].apply(lambda x: 1 if x > 0.5 else -1)        return Xdf = pd.DataFrame({    'my_str': [111, 2, 3333],    'val': [0, 1, 1]})# mixing this works as expectedmy_pipeline = make_pipeline(StandardScaler(), CustomTransformer(column_names=["my_str", "val"]))my_pipeline.fit_transform(df)# using this by itself works as wellmy_pipeline = make_pipeline(CustomTransformer(column_names=["my_str", "val"]))my_pipeline.fit_transform(df)输出是:In [  ]: my_pipeline = make_pipeline(StandardScaler(), CustomTransformer(column_names=["my_str", "val"]))     ...: my_pipeline.fit_transform(df)                                                                                                                                                                                                  Out[  ]:      my_str       val  str_len  custom_func0 -0.671543 -1.414214       19           -11 -0.742084  0.707107       18            12  1.413627  0.707107       17            1In [  ]: my_pipeline = make_pipeline(CustomTransformer(column_names=["my_str", "val"]))     ...: my_pipeline.fit_transform(df)                                                                                                                                                                                                  Out[  ]:    my_str  val  str_len  custom_func0     111    0        3           -11       2    1        1            12    3333    1        4            1sklearn-pandas或者,如果您想直接将事物映射到数据框,则可以使用from sklearn_pandas import DataFrameMapper# using sklearn-pandasstr_transformer = FunctionTransformer(lambda x: x.apply(lambda y: y.str.len()))cust_transformer = FunctionTransformer(lambda x: (x > 0.5) *2 -1)mapper = DataFrameMapper([    (['my_str'], str_transformer),    (['val'], make_pipeline(StandardScaler(), cust_transformer))], input_df=True, df_out=True)mapper.fit_transform(df)输出:In [  ]: mapper.fit_transform(df)                                                                                                                                                                                                       Out[47]:    my_str  val0       3   -11       2    12       1    1使用 sklearn pandas 可以让您更具体地将输入作为数据框,将输出作为数据框,并允许您将每一列单独映射到每个感兴趣的管道,而不是将列名编码/硬编码为对象的一部分TransformerMixin。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python