用于 sklearn 管道的 pandas 到 numpy 数组

Posted

技术标签:

【中文标题】用于 sklearn 管道的 pandas 到 numpy 数组【英文标题】:pandas to numpy array for sklearn pipeline 【发布时间】:2017-03-05 11:20:35 【问题描述】:

我有一个转换器,可以计算每组值的百分比。最初,使用 pandas 是因为我从 pandas 开始,并且 colnames 更好处理。但是,现在我需要集成到 sklearn-pipeline 中。

如何转换我的 Transformer 以支持来自 sklearn 管道 的 numpy 数组,而不是 pandas 数据帧? 关键是 self.colname 不能用于 numpy 数组,我认为分组需要以不同的方式执行。

如何实现此类转换器的持久性,因为这些权重需要可从磁盘加载,以便在管道中部署此类转换器。

class PercentageTransformer(TransformerMixin):
    def __init__(self, colname,typePercentage='totalTarget', _target='TARGET', _dropOriginal=True):
        self.colname = colname
        self._target = _target
        self._dropOriginal = _dropOriginal
        self.typePercentage = typePercentage

    def fit(self, X, y, *_):
        original = pd.concat([y,X], axis=1)
        grouped = original.groupby([self.colname, self._target]).size()
        if self.typePercentage == 'totalTarget':
            df = grouped / original[self._target].sum()
        else:
            df = (grouped / grouped.groupby(level=0).sum())

        if self.typePercentage == 'totalTarget':
            nameCol = "pre_" + self.colname
        else:
            nameCol = "pre2_" + self.colname
        self.nameCol = nameCol
        grouped = df.reset_index(name=nameCol)
        groupedOnly = grouped[grouped[self._target] == 1]
        groupedOnly = groupedOnly.drop(self._target, 1)

        self.result =  groupedOnly
        return self

    def transform(self, dataF):
        mergedThing = pd.merge(dataF, self.result, on=self.colname, how='left')
        mergedThing.loc[(mergedThing[self.nameCol].isnull()), self.nameCol] = 0
        if self._dropOriginal:
            mergedThing = mergedThing.drop(self.colname, 1)
        return mergedThing

它会在这样的管道中使用:

pipeline =  Pipeline([
    ('features', FeatureUnion([
        ('continuous', Pipeline([
            ('extract', ColumnExtractor(CONTINUOUS_FIELDS)),
        ])),
        ('factors', Pipeline([
            ('extract', ColumnExtractor(FACTOR_FIELDS)),
            # using labelencoding and all bias
            ('bias',  PercentageAllTransformer(FACTOR_FIELDS, _dropOriginal=True, typePercentage='totalTarget')),
        ]))
    ], n_jobs=-1)),
    ('estimator', estimator)
])

pipeline 将配备 Xy,两者都是数据帧。我不确定X.as_matrix 是否会有所帮助。

【问题讨论】:

pandas 对象是 numpy 对象的包装器。没有pandas数组,相信你的意思是Series?无论如何,也许您的问题只需返回 self.values 而不是 self 就可以解决。 关于持久性,有几种方法可以解决。 Python中的对象序列化一般会使用pickle模块。 确实我的意思是熊猫数据框。关键是如果我理解正确:原始original.groupby([self.colname, self._target]不再是数据框,而是一个numpy数组,例如colnames 不再起作用。所以 self.values 似乎还不够。 否,groupby 返回一个groupby 对象,通常用于生成新的DataFrame。您不能像往常一样访问self.colname, self._target,因为默认情况下,这些用作index 到新的DataFrame。将as_index=False 传递给groupby 以将您的分组列保留为列。 【参考方案1】: 来回转换事物

Pandas 有一个 .to_records() 方法,正如你提到的,还有一个 .as_matrix() 方法。 .to_records() 方法实际上会为您保留列名。 Numpy 确实支持数组中的命名列。见here。

坚持

Pandas 有一个 pandas.to_pickle(obj, filename) 方法,它接受一个 pandas 对象和pickles 它。有对应的 pandas.read_pickle(filename) 方法。

Numpy 也有 save 和 load 函数。

【讨论】:

以上是关于用于 sklearn 管道的 pandas 到 numpy 数组的主要内容,如果未能解决你的问题,请参考以下文章

管道中的 Sklearn_pandas 返回 TypeError: 'builtin_function_or_method' object is not iterable

Groupby 在一列 pandas 数据帧上,并使用 GridsearchCv 使用通用 sklearn 管道训练每个组的特征和目标 (X, y)

如何将 sklearn 管道转换为 pyspark 管道?

Sklearn 的 SimpleImputer 不能在管道中工作?

用于自定义操作的 sklearn 管道

选择用于对用户文本数据进行分类的 sklearn 管道