Почему произведение собственного вектора и соответствующего собственного значения не равно произведению исходной матрицы и собственного вектора?

Когда я умножаю собственный вектор на матрицу, это должно привести к тому же результату, что и умножение этого собственного вектора на его соответствующее собственное значение. Я пытаюсь проверить, что мои собственные векторы и собственные значения работают так, как заявлено, но результаты кажутся неправильными.

cov_matrix = np.cov(scaled_data)
eig_vals, eig_vecs = np.linalg.eigh(cov_matrix)

a = cov_matrix.dot(eig_vecs[:, 0])
b = eig_vecs[:, 0] * eig_vals[0]

Когда я печатаю a и b, они имеют одинаковую форму, но их значения разные. Что здесь не так?


person cmgodwin    schedule 18.07.2020    source источник
comment
столбец eig_vecs [:, i] - это собственный вектор, соответствующий собственному значению eig_val [i], а не строка eig_vecs [i]   -  person Yacola    schedule 18.07.2020
comment
Спасибо! Я отредактировал код (возможно, неправильно, но не уверен), чтобы исправить это, но a и b по-прежнему возвращают разные векторы.   -  person cmgodwin    schedule 18.07.2020
comment
примечание np.linalg.eigh работает только с комплексной эрмитовой (сопряженной симметричной) или реальной симметричной матрицей (взятой из документации). Вы уверены, что ваша матрица симметрична? Если да, укажите конкретный пример для scaled_data   -  person Roim    schedule 18.07.2020


Ответы (1)


Попробуйте следующее:

import numpy as np

np.random.seed(42) # for reproducibility
A = np.random.random((10,10)) + np.random.random((10,10)) * 1j
eig_vals, eig_vecs = np.linalg.eigh(A)

np.allclose(A @ eig_vecs[:, 0], eig_vals[0] * eig_vecs[:, 0])
>>> False

Имейте в виду, что возврат np.linalg.eigh собственные значения и собственные векторы комплексной эрмитовой (сопряженной симметричной) или вещественной симметричной матрицы. Итак, для эрмитовой матрицы:

A = (A + A.T.conj())/2  # Here A is forced Hermitian now
eig_vals, eig_vecs = np.linalg.eigh(A)

print(np.allclose(A @ eig_vecs[:, 0], eig_vals[0] * eig_vecs[:, 0]))
>>> True

Перед диагонализацией проверьте, симметричен ли cov_matrix чему-то вроде np.allclose(cov_matrix, cov_matrix.T.conj()). Если нет, вы можете просто использовать np.linalg.eig .

person Yacola    schedule 18.07.2020
comment
cov_matrix действительно симметричен, я проверил ваше предложение об использовании np.allclose(cov_matrix, cov_matrix.T). Кроме того, при замене A = np.random.random((10,10)) на A=cov_matrix ваш код вернул истину. Я думаю, что что-то не так с тем, как я проверяю значения. - person cmgodwin; 18.07.2020
comment
Я делал print(a[0]), print(b[0]) и print(a[0] == b[0]) с идеей, что значения будут идентичны, но это должно быть каким-то образом ошибочно. - person cmgodwin; 18.07.2020
comment
Хорошо, я понял проблему, которая на самом деле связана с вашим первоначальным комментарием о столбцах, являющихся собственными векторами. Я использовал eig_vecs = eig_vecs [:: - 1], чтобы перевернуть порядок в списке, который смешивал все собственные векторы. np.allclose затем смутил меня тем, что в некоторых случаях все еще возвращалось истина, но это было только для незначительных собственных значений, поэтому векторы выглядели достаточно близко. Большое спасибо за вашу помощь, я бы смотрел на это еще несколько часов. - person cmgodwin; 18.07.2020