Предположим, что у вас есть следующий пример:
n = 4;
rng(0)
A = rand(n,n);
B = A * A';
Если матрица B
полный ранг, вы не можете точно покрыть исходную матрицу, используя меньшее количество параметров. Итак, вы можете только приблизительно it. Основная идея здесь заключается в минимизации ошибки восстановления.
Вы можете разложить B
на свои собственные векторы, используя eigenvalue decomposition. Вы можете использовать eig
в MATLAB, но потом вам нужно отсортировать собственные значения и соответствующие собственные векторы. Вместо этого я предпочитаю Singular Value Decomposition и использовать svd
в MATLAB. Обратите внимание, что SVD дает оптимальное решение для ошибки восстановления в приближении матрицы низкого ранга.
[U,S,~] = svd(B);
U = U * sqrt(S);
Мы знаем, что B = U * U'
сейчас. См. Соотношение между SVD и разложением на собственные значения here.
Как я уже говорил, нам необходимо его приблизить. Я выбираю размеры, покрывающие 99% от общей дисперсии следующим образом:
coverage = cumsum(diag(S.^2));
coverage = coverage ./ norm(S,'fro')^2;
[~, nEig] = max(coverage > 0.99);
U2 = U(:,1:nEig);
U2 имеет 2 колонки вместо 4 в этом случае. Если данные скоррелированы, коэффициент усиления будет еще меньше. Результаты заключаются в следующем:
B
B1 = U*U'
B2 = U2*U2'
B =
2.8966 2.1881 1.1965 2.1551
2.1881 1.9966 0.6827 1.8861
1.1965 0.6827 0.7590 0.5348
2.1551 1.8861 0.5348 2.0955
B1 =
2.8966 2.1881 1.1965 2.1551
2.1881 1.9966 0.6827 1.8861
1.1965 0.6827 0.7590 0.5348
2.1551 1.8861 0.5348 2.0955
B2 =
2.8896 2.2134 1.1966 2.1385
2.2134 1.9018 0.6836 1.9495
1.1966 0.6836 0.7586 0.5339
2.1385 1.9495 0.5339 2.0528
Это похоже на хорошее приближение.
«нижнее измерение» «r произвольно» - r не является произвольным в соответствии с вашим названием; r <= n – ninjagecko