Java SVD 与 JAMA 或其他

发布于 2024-12-28 23:21:57 字数 784 浏览 0 评论 0原文

我有一堆点,我需要最合适的线。我正在使用 JAMA,但不知道为什么,有些东西不起作用。可能是我不明白它是如何工作的。我有一个 Nx3 Matrix(这是 JAMA svd 支持的),并且我从 Svd 获得了正确的 Matrix V。我需要的向量是对应于最大奇异值的右奇异向量(行或列?)。该向量应该代表主要方向。

每个向量都应该有 y 作为最大正值,x 可以是正值也可以是负值,z 应该是负值。但有时我得到的向量具有负 y 值,或者无论如何它指向错误的方向。

我的点云非常规则,几乎都沿着 y 轴定位(z 小且为负)。所以主要方向应该很容易找到。但它仍然无法正常工作。

在这种情况下,我得到了右矩阵 V 的行向量(我也尝试了列向量)。我已经从“pointSet”中减去了质心。

public static Matrix bestDirection(Matrix pointSet){

    Matrix bestFittingLine = new Matrix(3,1);
    SingularValueDecomposition svd = pointSet.svd();

    bestFittingLine.set(0, 0, svd.getV().get(0, 0));
    bestFittingLine.set(1, 0, svd.getV().get(0, 1));
    bestFittingLine.set(2, 0, svd.getV().get(0, 2));

    return bestFittingLine;
}

我想也许我没有考虑某些事情。我不知道也许我应该使用另一种技术或另一个库。

I have a cloud of Points and I need the best fitting Line. I'm using JAMA but I don't know why, something is not working. Probably it's me who doesn't get how it works. I have a Nx3 Matrix (this is what JAMA svd supports) and I get the right Matrix V from the Svd. The vector I need is the right singular vector (row or coloumn ? ) corresponding to the greatest singular value. This vector is supposed to represent the main direction.

Every vector is supposed to have y as the greatest positive value, x can be both positive or negative and z is supposed to be negative. But sometimes the vector I get has a negative y value, or anyway it's pointing in the wrong direction.

My cloud of Points are pretty regular, the are all postioned almost along the y axis (with z small and negative). So the main direction is supposed to be really easy to find. But it's still not working properly.

In this case I'm getting the row vector (I tried the coloumn vector too) of the right Matrix V. I already substracted the centroid from "pointSet".

public static Matrix bestDirection(Matrix pointSet){

    Matrix bestFittingLine = new Matrix(3,1);
    SingularValueDecomposition svd = pointSet.svd();

    bestFittingLine.set(0, 0, svd.getV().get(0, 0));
    bestFittingLine.set(1, 0, svd.getV().get(0, 1));
    bestFittingLine.set(2, 0, svd.getV().get(0, 2));

    return bestFittingLine;
}

I guess maybe I'm not considering something. Idk maybe I should use another technique or another library.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅气尐潴 2025-01-04 23:21:57

来自 SVD 的维基百科:

非简并奇异值始终具有唯一的左奇异向量和右奇异向量,最多乘以单位相位因子(对于实际情况最多符号)。

简而言之,您不能依赖输出奇异向量的符号。

您可能还需要在 SVD 之前将数据居中。

为什么不执行回归?

From Wikipedia on SVD:

Non-degenerate singular values always have unique left and right singular vectors, up to multiplication by a unit phase factor (for the real case up to sign).

Simply put, you can't rely on the sign of the output singular vectors.

You may also need to center the data before SVD.

Why won't you perform a regression?

分分钟 2025-01-04 23:21:57

如果你的方程采用这种形式:

z = a0 + a1*x + a2*y

对于 N 个点,你的矩阵方程看起来像这样:

z(i) = a0 + a1*x(i) + a2*y(i)  i = 1, N

左边是一个 Nx1 向量;右侧是一个 Nx3 矩阵乘以一个 3x1 的未知向量。

将两边都乘以 A(转置),最终得到一个 3x3 矩阵,乘以未知系数的 3x1 向量,该矩阵等于 3x1 向量。使用标准矩阵解来求解未知系数。即使是封闭的形式,这也很容易做到。

这是简化的线性最小二乘解。这是一个 scribd 文档,其中详细说明了这一点。

If your equation takes this form:

z = a0 + a1*x + a2*y

Your matrix equation looks like this for N points:

z(i) = a0 + a1*x(i) + a2*y(i)  i = 1, N

The left hand side is an Nx1 vector; the right hand side is an Nx3 matrix multiplying an unknown vector that's 3x1.

Multiply both sides by A(transpose) and you end up with a 3x3 matrix multiplying a 3x1 vector of unknown coefficients that's equal to a 3x1 vector. Use standard matrix solutions to solve for the unknown coefficients. It'd be easy to do, even in closed form.

That's the linear least squares solution simplified. Here's a scribd document that spells it out in more detail.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文