Python 寻找与集合中所有向量的距离大致相等的向量

Python 寻找与集合中所有向量的距离大致相等的向量,python,vector,linear-algebra,mathematical-optimization,approximate,Python,Vector,Linear Algebra,Mathematical Optimization,Approximate,我有一组300万个向量(每个维度300个),我在这300个昏暗的空间中寻找一个新的点,它与所有其他点(向量)的距离大致相等 我可以做的是初始化一个随机向量v,然后在v上运行优化,目标是: 其中d_xy是向量x和向量y之间的距离,但这在计算上非常昂贵 我正在寻找这个问题的近似的解向量,它可以在非常大的向量集上快速找到。(或任何为我提供类似功能的库-任何语言)来自: 一般来说,没有与4个或更多点等距的点 平面中的位置,或n个标注中的n+2点 用一个点表示点集合的标准如下 在统计学、机器学习和计算机

我有一组300万个向量(每个维度300个),我在这300个昏暗的空间中寻找一个新的点,它与所有其他点(向量)的距离大致相等

我可以做的是初始化一个随机向量v,然后在v上运行优化,目标是:

其中d_xy是向量x和向量y之间的距离,但这在计算上非常昂贵

我正在寻找这个问题的近似的解向量,它可以在非常大的向量集上快速找到。(或任何为我提供类似功能的库-任何语言)

来自:

一般来说,没有与4个或更多点等距的点 平面中的位置,或n个标注中的n+2点

用一个点表示点集合的标准如下 在统计学、机器学习和计算机科学中考虑。这个 质心是最小二乘意义上的最佳选择,但是 还有很多其他的可能性

质心是平面中的点C,其 最小平方距离$\sum | CP | i | ^2$。人们还可以进行优化 一个不同的衡量中心,或坚持代表 是一个点(如加权函数的图论中心) 生成树),或以某种方式为点指定权重 以它们的质心为例


请特别注意,“质心是最小二乘意义上的最佳选择”,因此成本函数(即最小二乘成本)的最佳解决方案就是简单地平均所有点的坐标(这将为您提供质心)。

我同意,一般来说,这是一个非常棘手的优化问题,尤其是在你描述的尺度上。每个目标函数评估都需要对n个维度为m的点进行O(nm+n^2)运算——O(nm)计算从每个点到新点的距离,O(n^2)计算给定距离的目标。当m=300和n=3M时,这相当可怕。因此,即使是一个函数的评估也很难,更不用说解决完整的优化问题了

在另一个答案中提到的一种方法是取点的质心,它可以有效地计算——O(nm)。这种方法的一个缺点是,它可能在拟议的目标上做得很糟糕。例如,考虑一维空间中具有值为300万的1点和具有值0的1点的情况。通过检查,最优解为v=0.5,目标值为0(与每个点的距离相等),但质心将选择目标值为300万的v=1(好的,比该值小一点)

我认为比质心更好的方法是分别优化每个维度(忽略其他维度的存在)。虽然在这种情况下,目标函数的计算成本仍然很高,但一些代数知识表明,目标函数的导数很容易计算。它是所有对(i,j)的总和,其中iv的值为4*((v-i)+(v-j))。记住,我们优化的是单个维度,因此点i和j是一维的,v也是一维的。因此,对于每个维度,我们可以对数据进行排序(O(n lg n)),然后使用二进制搜索和基本代数计算O(n)时间内值v的导数。然后我们可以使用
scipy.optimize.newton
找到导数的零点,它将是该维度的最佳值。迭代所有维度,我们将得到问题的近似解

首先考虑所提出的方法与质心方法在一个简单的设置中,一维数据点{ 0, 3, 3 }:

import bisect
import scipy.optimize

def fulldist(x, data):
    dists = [sum([(x[i]-d[i])*(x[i]-d[i]) for i in range(len(x))])**0.5 for d in data]
    obj = 0.0
    for i in range(len(data)-1):
        for j in range(i+1, len(data)):
            obj += (dists[i]-dists[j]) * (dists[i]-dists[j])
    return obj

def f1p(x, d):
    lownum = bisect.bisect_left(d, x)
    highnum = len(d) - lownum
    lowsum = highnum * (x*lownum - sum([d[i] for i in range(lownum)]))
    highsum = lownum * (x*highnum - sum([d[i] for i in range(lownum, len(d))]))
    return 4.0 * (lowsum + highsum)

data = [(0.0,), (3.0,), (3.0,)]
opt = []
centroid = []
for d in range(len(data[0])):
    thisdim = [x[d] for x in data]
    meanval = sum(thisdim) / len(thisdim)
    centroid.append(meanval)
    thisdim.sort()
    opt.append(scipy.optimize.newton(f1p, meanval, args=(thisdim,)))
print "Proposed", opt, "objective", fulldist(opt, data)
# Proposed [1.5] objective 0.0
print "Centroid", centroid, "objective", fulldist(centroid, data)
# Centroid [2.0] objective 2.0
所提出的方法可以找到精确的最优解,而质心法会有一点遗漏

考虑一个稍大一点的例子,1000个维度为300的点,每个点都是从高斯混合绘制的。每个点的值正态分布,平均值为0,方差为1,概率为0.1,正态分布,平均值为100,方差为1,概率为0.9:

data = []
for n in range(1000):
    d = []
    for m in range(300):
        if random.random() <= 0.1:
            d.append(random.normalvariate(0.0, 1.0))
        else:
            d.append(random.normalvariate(100.0, 1.0))
    data.append(d)
data=[]
对于范围(1000)内的n:
d=[]
对于范围(300)内的m:

如果random.random()你试过什么吗?@farhawa我试过运行一个python脚本,它使用scipy.optimize.minimize()来最小化我上面描述的目标函数。当然,每次迭代需要3米的距离计算,然后一个O(n^2)经过向量集,所以它只在合理的时间内对极小的向量集(大约10000个)起作用你能举一个你的向量的例子吗?我理解正确了吗:你想找到向量v,它在所有距离上与你集合中的所有其他向量之和最小?也许某种随机方法是合适的,在这种方法中,你检查每个v的向量i的随机样本,然后选择一个在所有距离上关于该随机集的总和最小的向量。也许蒙特卡罗模拟能有所帮助。只有我的2美分(这不是一个高度限定的评论,但可能是一个暗示)。@提问:如果我不太清楚,很抱歉——我正在寻找一个向量(不是我原来的3M向量集的一部分),它与所有其他向量一样远。我并没有试图减少向量与集合中其他部分的距离之和。我不相信数学StackExchange上的(被接受的)答案。构造一组点位于超球面上但其质心远离超球面本身中心的例子很容易。@StefanoM:是的,但我认为答案(或我的答案)并没有说明这一点?如果你在超球体的一个“极点”附近构造一组点,那么很明显,该集合的质心不会是超球体的中心。我想不出有哪一组点在超球面上均匀分布,它们的质心不是超球面