Python 在fit方法具有3个参数的自定义类上使用sklearn GridSearchCV

Python 在fit方法具有3个参数的自定义类上使用sklearn GridSearchCV,python,numpy,machine-learning,scikit-learn,grid-search,Python,Numpy,Machine Learning,Scikit Learn,Grid Search,我正在从事一个项目,该项目涉及将一些算法实现为python类并测试它们的性能。我决定把它们写成sklearn估计器,以便用于验证 但是,我的一个算法不只是将X和y作为参数。这对于估算器来说是一个问题,因为似乎没有办法只将X和y传递给估算器的拟合方法。源代码显示了GridSearchCV.fit的以下参数: def-fit(self,X,y=None,groups=None,**fit_参数): 当然,下游方法只需要这两个参数。显然,修改我的GridSearchCV本地副本以满足我的需要绝非易事(

我正在从事一个项目,该项目涉及将一些算法实现为python类并测试它们的性能。我决定把它们写成sklearn估计器,以便用于验证

但是,我的一个算法不只是将
X
y
作为参数。这对于估算器来说是一个问题,因为似乎没有办法只将
X
y
传递给估算器的拟合方法。源代码显示了
GridSearchCV.fit
的以下参数:

def-fit(self,X,y=None,groups=None,**fit_参数):

当然,下游方法只需要这两个参数。显然,修改我的
GridSearchCV
本地副本以满足我的需要绝非易事(或明智之举)

作为参考,IMC基本上声明$R\n约为XW^THY^T$。因此,我的拟合方法采用以下形式:

def-fit(self、R、X、Y):

因此,尝试以下操作失败,因为Y值从未传递给
IMC.fit
方法:

imc = IMC()
params = {...}
gs = GridSearchCV(imc, param_grid=params)
gs.fit(R, X, Y)
def fit(self, R, X, Y=None):
    if Y is None:
        split = np.where(np.all(X == 999, axis=0))[0][0]
        Y = X[:, split + 1:]
        X = X[:, :split]
    ...
我已经通过这样修改
IMC.fit
方法为此创建了一个变通方法(这也必须插入
score
方法):

这允许我使用水平堆叠X和Y,并在它们之间插入一列所有
999
。然后可以将此数组传递到
GridSearchCV.fit
,如下所示:

data = np.hstack([X, np.ones((X.shape[0],1)) * 999, Y])
gs.fit(R, data)
这种方法很有效,但感觉很粗糙。因此,我的问题是:


使用
GridSearchCV
向fit方法传递2个以上参数是否有一种普遍接受的方法或最佳实践?因此,在从一位朋友那里获得了一些关于()的灵感后,我构建了一个更加优雅的解决方案

同样,问题的框架如下:

我有一种矩阵补全方法,它将
X
Y
R
作为参数,并尝试构造
W
H
,以最小化
R
中所有观察到的指数的
R-XWHY
fit
方法的基本实现如下所示:

def fit(X, Y, R):
    W, H = do_minimization(X, Y, R)
    return W, H
def fit(X, y):
    W, H = do_minimization(X, y)
    return W, H
这不适合标准的sklearn模型,其中fit采用
X
(输入模型的功能)和
y
(结果),如下所示:

def fit(X, Y, R):
    W, H = do_minimization(X, Y, R)
    return W, H
def fit(X, y):
    W, H = do_minimization(X, y)
    return W, H
在您开始使用
GridSearchCV
或其他交叉验证方法之前,这并不是一个真正的问题,因为他们希望数据符合后一种格式。因此,为了将这两个概念结合起来,我需要一种方法,将两个完全不同的矩阵
X
Y
打包到一个单一的结构中,而不丢失这两个矩阵的独立性

在我花了5分钟的时间来做这件事的时候,我想出了一个骇人的解决方案。在矩阵
R
形状
n,m
中,行对应于
X
中的记录,列对应于
Y
中的记录,存在
b
总条目。如果我们对所有这些条目采用行和列索引,并对行和列分别采用
X
索引和
Y
,我们将得到
X
Y
的等长矩阵。然后可以水平堆叠这些数据,用一列无意义的数据隔开,并毫无疑问地传递给交叉验证方法(我们只需要原始类中的两个辅助方法,在拟合之前从堆栈中重建原始的
X
Y

这个问题的重点是找到优雅的解决方案,或者最好是现有的解决方案。情况似乎并非如此,因此我将为继承sklearn构建的任何未来估计器/分类器提出以下模型,这些估计器/分类器需要的不仅仅是拟合方法的单一特征矩阵

创建一个数据处理程序 当使用
GridSearchCV
时,
fit
方法在调用估计器
fit
方法之前进行一轮检查。其中一个方法确定通过的
X
数组是否正确。该测试基本上检查
X
是否实现了
\getitem\uuu
iloc
,并且长度相同作为
y
。此长度检查要求
X
具有
shape
属性。此时,分割索引和拟合可以按预期计算。因此,我们需要一个实现
\uu getitem\uuuuuu
并具有
shape
属性的包装器

class DataHandler(object):

    def __init(self, X, Y):
        self.X = X
        self.Y = Y
        self.shape = self.X.shape

    def __getitem__(self, x):
        return self.X[x], self.Y[x]
就是这样!我们现在可以修改
fit
方法以匹配sklearn样式,但是在本例中,它不是数组
X
,而是元组(由
\uuu getitem\uuuuuuuu
方法返回的结果)或
DataHandler
类的实例


现在,
GridSearchCV
只需传递一个包含
X
Y
数组的
DataHandler
实例,即可正常工作。

使用上面提到的**fit_参数有什么问题吗?请参阅:@MarcusV。我相信我昨天误解了你的评论。我回去用
**fit_params
但最终与计分员发生了问题。显然,
fit_params
没有被级联到计分方法,因为我在我的类中使用默认的
score
方法,额外的矩阵不会被传递进来。请参阅此信息的感谢。鉴于此帖子是一个简单的例子岁了,这仍然是你处理这个问题的方式吗?我对
IMC.fit
签名的样子有点困惑。它是
def-fit(self,X,y)
,但是
X
将是
元组
还是
数据处理程序
实例?你有没有一个repo来说明这一点?很抱歉混淆。