线性N向等式问题的最小二乘

时间:2018-12-26 02:53:46

标签: python algorithm numpy linear-programming least-squares

假设我想找到2条任意高维线的“交点”。两条线实际上不会相交,但是我仍然想找到最相交的点(即,尽可能靠近所有线的点)。

假设这些线具有方向矢量AB和初始点CD, 我可以通过简单地建立一个线性最小二乘问题来找到最大的相交点:转换线相交方程

Ax + C = By + D

最小二乘形式

[A, -B] @ [[x, y]] = D - C 

其中@是矩阵时间向量的标准,然后我可以使用例如np.linalg.lstsq来解决。

但是如何找到3条或更多条任意线的“最大相交点”?如果我遵循同样的规则,我现在有

Ax + D = By + E = Cz + F

我唯一想到的方法是将其分解为三个方程式:

Ax + D = By + E
Ax + D = Cz + F
By + E = Cz + F

并将其转换为最小二乘形式

[A, -B,  0]                 [E - D]
[A,  0, -C] @ [[x, y, z]] = [F - D]
[0,  B, -C]                 [F - E]

问题是最小二乘问题的大小大约增加了行数。我想知道有没有更有效的方法来解决n向等式最小二乘线性问题

我在思考上面By + E = Cz + F提供其他两个术语的必要性。但是,由于此问题没有确切的解决方案(即它们实际上没有相交),因此我相信这样做会在某些变量上产生更多的“权重”吗?

谢谢您的帮助!

编辑

我刚刚使用以下代码测试了在n向平等中将第一个术语与所有其他术语配对(没有其他对)

def lineIntersect(k, b):
    "k, b: N-by-D matrices describing N D-dimensional lines: k[i] * x + b[i]"

    # Convert the problem to least-square form `Ax = B`
    # A is temporarily defined 3-dimensional for convenience
    A = np.zeros((len(k)-1, k.shape[1], len(k)), k.dtype)
    A[:,:,0] = k[0]
    A[range(len(k)-1),:,range(1,len(k))] = -k[1:]

    # Convert to 2-dimensional matrix by flattening first two dimensions
    A = A.reshape(-1, len(k))

    # B should be 1-dimensional vector
    B = (b[1:] - b[0]).ravel()

    x = np.linalg.lstsq(A, B, None)[0]

    return (x[:,None] * k + b).mean(0)

下面的结果表明这样做是不正确的,因为n-way-equality中的第一项是“权重不同”。

第一项输出是常规结果与不同输入顺序(行顺序无关紧要)的结果之间的差异,其中第一项没有变化

第二个输出与第一个字词确实发生了变化相同。

k = np.random.rand(10, 100)
b = np.random.rand(10, 100)
print(np.linalg.norm(lineIntersect(k, b) - lineIntersect(np.r_[k[:1],k[:0:-1]], np.r_[b[:1],b[:0:-1]])))
print(np.linalg.norm(lineIntersect(k, b) - lineIntersect(k[::-1], b[::-1])))

产生

7.889616961715915e-16
0.10702479853076755

4 个答案:

答案 0 :(得分:2)

此问题可能更适合数学stackexchange。另外,有人在这里格式化数学的好方法吗?抱歉,这很难看,我尽了最大努力。

编辑:我误解了Ax+C@ZisIsNotZis的含义,因此忽略了下一段。

  

我不认为您的方法陈述正确。您介意发布您的代码和输出的一个小示例(也许在2d中包含3或4行,以便我们对其进行绘制)?当您尝试查找两条线的交点时,是否不应该Ax+C = Bx+D?如果您进行Ax+C=By+D,则可以在第一行中选择一些x,在第二行中选择一些y,并完全满足两个方程式。因为此处xy的大小应与AB相同,这是空间的尺寸,而不是标量。

有很多方法可以理解找到尽可能靠近所有直线的点的问题。我认为最自然的是,到每一行的欧几里得距离的平方和被最小化。

假设我们在R^n中有一行:c^Tz + d = 0(其中c是单位长度)和另一点x。那么从x到直线的最短向量是:(I-cc^T)(x-d),所以从x到直线的距离的平方是║(I-cc^T)(x-d)║^2。我们可以通过最小化该距离来找到最接近直线的点。请注意,这是min_x ║b-Ax║_2形式的标准最小二乘问题。

现在,假设我们有c_iz+d_i代表i=1,...,m的行。从点d_i^2到第x行的距离i的平方是d_i^2 = ║(I-cc^T)(x-d)║_2^2。现在,我们要解决min_x \sum_{i=1}^{m} d_i^2的问题。

以矩阵形式有:

      ║ ⎡ (I-c_1 c_1^T)(x-d_1) ⎤ ║
      ║ | (I-c_2 c_2^T)(x-d_2) | ║
min_x ║ |      ...             | ║
      ║ ⎣ (I-c_n c_n^T)(x-d_n) ⎦ ║_2

这也是min_x ║b - Ax║_2的形式,因此有很好的求解器。

每个块的大小为n(空间尺寸),有m个块(行数)。因此系统是mn的{​​{1}}。特别是,它的线数是线性的,空间的尺寸是平方的。

它还有一个优势,如果添加一条线,您只需向最小二乘法添加另一个块。这还提供了在添加行时迭代更新解决方案的可能性。

我不确定这种最小二乘系统是否有特殊的求解器。请注意,每个块都是恒等式减去一个秩矩阵,因此可能会提供一些其他结构,这些结构可用于加快处理速度。就是说,我认为使用现有的求解器几乎总是比编写自己的求解器更好,除非您在数值分析方面有相当多的背景或要解决的系统非常专业。

答案 1 :(得分:2)

“相交点”的另一个标准是点x,以使x到直线的距离的平方和尽可能小。像您的标准一样,如果线实际上相交,则几乎相交的点将是实际相交的点。但是,我认为距离平方标准的总和使计算有问题的点变得很简单:

假设我们用一个点表示一条直线,并沿着该直线表示一个单位向量。因此,如果一条直线由p,t表示,那么直线上的点的形式为

p + l*t for scalar l

点x与线p,t的距离平方是

(x-p)'*(x-p) - square( t'*(x-p))

如果我们有N条线p [i],t [i],则距点x的距离的总和为

   Sum { (x-p[i])'*(x-p[i]) - square( t[i]'*(x[i]-p[i]))}

对此进行扩展,我得到的就是

x'*S*x - 2*x'*V + K

其中

S = N*I - Sum{ t[i]*t[i]'}
V = Sum{ p[i] - (t[i]'*p[i])*t[i] }

并且K不依赖于x

除非所有线都是平行的,否则S将(严格地)是正定的,因此是可逆的,在这种情况下,我们的距离平方和为

(x-inv(S)*V)'*S*(x-inv(S)*V) + K - V'*inv(S)*V

因此,将x最小化

inv(S)*V

因此,练习是:标准化“方向向量”(并使用与缩放方向相同的因子缩放每个点),如上所述形成S和V,求解

S*x = V for x

答案 2 :(得分:1)

一些想法不是解决方案:

如果nD空间中的线具有参数方程式(单位为Dir向量)

 L(t) = Base + Dir * t

然后从点P到这条线的平方距离是

W = P - Base
Dist^2 = (W - (W.dot.Dir) * Dir)^2

如果可以用适合LSQ方法的形式编写Min(Sum(Dist[i]^2))(通过每个点坐标进行偏导数),则可以用(x1..xn)坐标向量求解所得系统。

(情况类似于通常的LSQ的许多点和单行的反转)

答案 3 :(得分:0)

您说您有两条“高维”线。这意味着指示行的矩阵的列多于行。

如果是这种情况,并且您可以有效地找到低阶分解,例如 A =LRᵀ,那么您可以重写最小二乘问题的解 min || Ax- y ||² x =(RᵀRLᵀL)⁻¹Lᵀy

如果 m 是线的数量,而 n 是线的尺寸,则这将从 O(mn²+nʷ ) O(nr²+mr²),其中 r = min(m,n)

然后的问题是找到这种分解。

相关问题