Java SVD с JAMA или еще

У меня есть облако точек, и мне нужна наиболее подходящая линия. Я использую JAMA, но не знаю почему, что-то не работает. Наверное, это я не понимаю, как это работает. У меня есть Матрица Nx3 (это то, что поддерживает JAMA svd), и я получаю правильный Matrix V от Svd. Мне нужен правильный сингулярный вектор (строка или столбец?), соответствующий наибольшему сингулярному значению. Этот вектор должен представлять основное направление.

Предполагается, что каждый вектор имеет 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;
}

Наверное, я что-то не учитываю. Не знаю, может быть, мне следует использовать другую технику или другую библиотеку.


person G4bri3l    schedule 25.01.2012    source источник
comment
Почему вы не делаете простую линейную регрессию? Подгонка наименьших квадратов должна хорошо сработать.   -  person duffymo    schedule 25.01.2012
comment
@duffymo Потому что я не знаю, как это сделать и как это работает в 3D, где z не зависит от x и y. Я хотел бы получить некоторую помощь по этому поводу.   -  person G4bri3l    schedule 25.01.2012
comment
У меня есть набросанный документ, объясняющий это, но я не могу отправить вам доступ сейчас. линейная регрессия Google с несколькими переменными; вы получите что-то вроде этого: stat.yale.edu/ Курсы/1997-98/101/linmult.htm. SVD великолепна, но это не мой первый выбор.   -  person duffymo    schedule 25.01.2012


Ответы (2)


Из Википедии по СВД:

Невырожденные сингулярные числа всегда имеют уникальные левый и правый сингулярные векторы, с точностью до умножения на единичный фазовый множитель (для реального случая с точностью до знака).

Проще говоря, вы не можете полагаться на знак выходных сингулярных векторов.

Вам также может понадобиться центрировать данные перед SVD.

Почему бы вам не выполнить регрессию?

person cyborg    schedule 25.01.2012
comment
Именно в этом была проблема. Я нашел это трудным путем, но все равно спасибо. Это был ответ на мою проблему. Я не использую регрессию, потому что мне нужен SVD и для других вещей в моем проекте, поэтому вместо того, чтобы писать новые строки, я просто использую то, что у меня уже есть. И все теперь работает исправно. - person G4bri3l; 26.01.2012

Если ваше уравнение принимает следующий вид:

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, в котором это описано более подробно.

person duffymo    schedule 25.01.2012
comment
Большое тебе спасибо. Вы были полезны, я прокомментировал другой ответ, почему я все еще использую SVD. - person G4bri3l; 26.01.2012