我使用预先计算的指标与Scikit-Learn的最近邻居/半径分类一起工作。这意味着,我将成对距离的n_samples_train x n_samples_train矩阵传递给分类器的拟合方法。
现在我想知道为什么要这样做。使用knn学习只是意味着“存储样本”,但距离的计算应该只在稍后进行,在泛化期间(在该步骤中,我当然会计算我的训练样本和我的测试样本之间的距离矩阵,所以a大小为n_samples_train x n_samples_test的矩阵。
例如,在SVM的情况下,我将预先计算的矩阵(Gramian,相似性矩阵)传递给smv.SVC对象的fit方法。然后进行优化,找到支持向量等等。在那里,这个矩阵在训练期间是绝对必要的。
但是我没有理由认为需要一个适合邻居/半径分类的预先计算矩阵。
有人可以给我一个相关提示吗?
我喜欢跳过针对scikit learn的训练矩阵的计算。
致以最诚挚的问候,谢谢。 : - )
答案 0 :(得分:0)
这很老,但是我在寻找相关问题时碰巧发现了它。
从本质上讲,这是性能问题。假设您一次拟合了k个近邻/半径分类器,然后使用它对多个不同的测试点集进行分类。如果内核矩阵未预先计算,则每次调用fit()时都必须计算内核矩阵。实施这些分类器的方式利用了以下事实:您正在使用正(半)定函数,并可以使用该函数加快kd树或球树的最近邻点/半径搜索新点的速度,它构建了一个结构,该结构对到每个子树之外的点的距离进行限制。对于n个样本和k个邻居(至少对于球树),可以在iirc O(k * log(n))时间内完成这种结构的构造。因此,通过提前进行一些工作,可以大大加快新点的分类。
要通过实用的解决方案回答您的问题,如果要使用自定义指标,则无需传递预先计算的距离矩阵。如果您将可调用量作为度量标准,距离矩阵仍将被预先计算为一个度,但是它将透明地在拟合过程中发生,并且实际上比使用蛮力计算所有样本对之间的距离更有效自己(注意,如果输入稀疏,分类器仍将使用蛮力。它仍将使用多个核,因此可能比自己动手更可取,但行为会有所不同。)
因此可以总结一下:您完全正确的是,预先拟合的距离矩阵对于拟合一般的k个最近邻分类器并不是绝对必要的。但是,通过预先计算-无论是执行还是传递可调用对象-随后的分类效率都更高。 Sklearn显然选择了针对自定义指标进行预计算-可能是因为使用python函数n *(n-1)/ 2倍的开销使该路由比使用高度优化的内置指标慢得多,其中许多指标部分或全部完全在cython中实施。但是在拟合之前,您无需将其作为显式步骤进行计算。