首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >加快马氏距离计算

加快马氏距离计算
EN

Stack Overflow用户
提问于 2019-03-10 18:45:52
回答 1查看 851关注 0票数 1

背景:

我正在实现顺序反向选择算法,以从数据集中选择特征。所讨论的数据集是MNIST。我有60000个长度为784的向量。

该算法要求我从784中删除一个特性,即fi,并选择其余的783个特性,在下面的代码中称为selection。然后,我必须计算每个向量的Mahalanobis到它的尊重类的平均值。一旦这个迭代完成,我就省略了两个特性,然后是三个特性等等。每一次迭代都需要3分钟。

我必须选择500个特征,所以上面是重复500次,所以在总的Mahalanobis距离是计算500 x 784 = 392,000倍。这要求我计算协方差矩阵的逆。这个协方差矩阵的逆不存在,因为它是奇异的,所以我使用的是numpy的伪逆。

问题

就像你可以想象到的,上面的速度非常慢。计算伪逆是一个最慢的过程.我想我可以先计算伪逆,然后删除与fi相关的相应列和行。然而,结果表明,这个伪逆矩阵并不等于从我已经删除fi的向量中直接计算的伪逆矩阵。

我试过什么

我在很大程度上尝试过将其矢量化,并对数组的堆栈进行处理,结果发现分解方法更慢。我试过np.einsum,cdist,甚至numexpr。什么都帮不上忙。

这让我相信,我加速这个过程的最佳机会就是将协方差和伪逆计算从这个循环中移出。这是我目前的代码:

代码语言:javascript
运行
AI代码解释
复制
def mahalanobis(self, data, lbls, selection):
    subset data[:,tuple(selection)]

    for n in range(10):
        class_rows = subset[np.where(y == n)]
        mean = np.mean(class_rows, axis = )
        pseudoInverse = pinv(covariance(class_rows))
        delta = C - u
        d[n] = np.mean(np.sum(((delta @ pseudoInverse) * delta), axis = -1))
    return np.mean(d)

问题

我怎样才能加快计算速度?从我在过去一周所做的测试来看,这一计算中最慢的部分似乎是行pseudoInverse = pinv(covariance(class_rows))

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-10 20:12:18

现在,您的代码实质上是:

代码语言:javascript
运行
AI代码解释
复制
def mahalanobis(delta, cov):
    ci = np.linalg.pinv(cov)
    return np.sum(((delta @ ci) * delta), axis=-1)

你可以通过以下方法来加速这件事:

  • 直接使用svd而不是pinv,并消除不使用的共轭。
  • eigh代替svd,利用协方差矩阵的对称性
代码语言:javascript
运行
AI代码解释
复制
def mahalanobis_eigh(delta, cov):
    s, u = np.linalg.eigh(cov)
    # note: missing filtering of small s, which you might want to consider adding - pinv already does this for you
    ci = u @ (1/s[...,None] * u.T)
    return np.sum(((delta @ ci) * delta), axis=-1)

值得注意的是,这个函数和您的函数对于复杂的值都没有正确的工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55094599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档