scikit-learn 改变 X 和 Y 的自定义转换器/管道

Posted

技术标签:

【中文标题】scikit-learn 改变 X 和 Y 的自定义转换器/管道【英文标题】:scikit-learn custom transformer / pipeline that changes X and Y 【发布时间】:2016-04-16 02:41:09 【问题描述】:

我有一组 N 个数据点 X = x1, ..., xn 和一组 N 个目标值/类 Y = y1, ..., yn

给定 yi 的特征向量的构造考虑了数据点的“窗口”(因为没有更好的术语),例如我可能想堆叠“最后 4 个数据点”,即 xi-4、xi-3、xi-2、 xi-1 用于预测 yi

显然,对于 4 的窗口大小,无法为前三个目标值构造这样的特征向量,我想简单地删除它们。同样对于最后一个数据点 xn.

这不是问题,除非我希望这作为 sklearn 管道的一部分进行。到目前为止,我已经成功地为其他任务编写了一些自定义转换器,但那些不能(据我所知)改变 Y 矩阵。

有没有一种方法可以做到这一点,我不知道或者我是否坚持这样做作为管道之外的预处理? (这意味着,我将无法使用 GridsearchCV 找到最佳窗口大小和移位。)

我已经尝试搜索这个,但我想出的只是this question,它处理从 X 矩阵中删除样本。那里接受的答案让我想,scikit-learn 不支持我想做的事情,但我想确定一下。

【问题讨论】:

***.com/a/70191787/10375049 【参考方案1】:

你是对的,你不能在 sklearn Pipeline 中调整你的目标。这并不意味着您不能进行网格搜索,但这确实意味着您可能必须以更多的手动方式进行。我建议编写一个函数对y 进行转换和过滤,然后手动循环通过ParameterGrid 创建的调整网格。如果这对您没有意义,请使用您拥有的代码编辑您的帖子以获得进一步的帮助。

【讨论】:

是的,我就是这个意思。我不能只是将我的管道转储到 GridSearchCV 中,我发现这是最方便的 CV 方法。我相当肯定我可以让它手动工作。谢谢 是否值得将其作为功能请求提出?似乎这是一个常见的要求(对于多个输出变量的问题)【参考方案2】:

我正在为类似的问题而苦苦挣扎,很遗憾您无法在转换器之间传递 y 值。话虽如此,我以一种有点肮脏的方式绕过了这个问题。

我将 y 值存储为转换器的实例属性。这样,当管道调用fit_transform 时,我可以在transform 方法中访问它们。然后,transform 方法传递一个元组(X, self.y_stored),这是下一个估计器所期望的。这意味着我必须编写包装器估计器,它非常难看,但它可以工作!

类似这样的:


class MyWrapperEstimator(RealEstimator):
    def fit(X, y=None):
        if isinstance(X, tuple):
            X, y = X
        super().fit(X=X, y=y)

【讨论】:

你能解释一下吗?我面临同样的问题,这似乎可以完成这项工作。所以你的转换方法返回 (X, self.y_stored) 并且包装器使连接工作?你能提供一些代码吗?提前致谢。 老实说,我什至不记得我在这里所做工作的背景,但基于对问题和答案的快速浏览,我做了一些编辑,希望能有所帮助。跨度> 【参考方案3】:

对于堆叠最后 4 个数据点的具体示例,您可以使用seglearn。

>>> import numpy as np
>>> import seglearn
>>> x = np.arange(10)[None,:]
>>> x
array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
>>> y = x
>>> new_x, new_y, _ = seglearn.transform.SegmentXY(width=4, overlap=0.75).fit_transform(x, y)
>>> new_x
array([[0, 1, 2, 3],
       [1, 2, 3, 4],
       [2, 3, 4, 5],
       [3, 4, 5, 6],
       [4, 5, 6, 7],
       [5, 6, 7, 8],
       [6, 7, 8, 9]])
>>> new_y
array([3, 4, 5, 6, 7, 8, 9])

seglearn 声称与 scikit-learn 兼容,因此您应该能够在 scikit-learn 管道的开头安装 SegmentXY。但是,我自己还没有在管道中尝试过。

【讨论】:

以上是关于scikit-learn 改变 X 和 Y 的自定义转换器/管道的主要内容,如果未能解决你的问题,请参考以下文章

逻辑回归-5. scikit-learn中的逻辑回归

Scikit-Learn:标签不是 x 出现在所有训练示例中

scikit-learn 线性回归算法库小结

scikit-learn 中自定义内核 SVM 的交叉验证

高斯过程 scikit-learn - 异常

scikit-learn 中每个数据拆分的交叉验证指标