Python 在fit方法具有3个参数的自定义类上使用sklearn GridSearchCV
我正在从事一个项目,该项目涉及将一些算法实现为python类并测试它们的性能。我决定把它们写成sklearn估计器,以便用于验证 但是,我的一个算法不只是将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本地副本以满足我的需要绝非易事(
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来说明这一点?很抱歉混淆。