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 的自定义转换器/管道的主要内容,如果未能解决你的问题,请参考以下文章