В латентном семантическом анализе, как вы рекомбинируете разложенные матрицы после обрезания сингулярных значений?
Я читаю матричные декомпозиции и скрытую семантическую индексацию (онлайн-издание © 2009 Cambridge UP)
Я пытаюсь понять, как вы уменьшаете количество измерений в матрице. На странице 13 есть пример, который я пытаюсь воспроизвести, используя numpy Python.
Давайте назовем исходную матрицу вхождения "a" и три разложенные матрицы SVD (разложение по сингулярному значению) "U", "S" и "V".
Проблема в том, что после того, как я обнуляю меньшие значения единственного числа в "S", когда я умножаю вместе "U", "S" и "V", используя numpy, ответ не тот, который дан в pdf, Нижние 3 ряда не все нули. Самое смешное, что когда я просто умножаю "S" и "V", я получаю правильный ответ.
Это удивительно, но умножение "S" и "V" - это то, что вам нужно сделать в книге Мэннинга и Шутце "Основы статистической обработки естественного языка". Но это не то, что PDF-файл говорит, что вы должны сделать на странице 10.
Так что здесь происходит?
1 ответ
Умножив S
а также V
это именно то, что вам нужно сделать, чтобы уменьшить размерность с SVD/LSA.
>>> C = np.array([[1, 0, 1, 0, 0, 0],
... [0, 1, 0, 0, 0, 0],
... [1, 1, 0, 0, 0, 0],
... [1, 0, 0, 1, 1, 0],
... [0, 0, 0, 1, 0, 1]])
>>> from scipy.linalg import svd
>>> U, s, VT = svd(C, full_matrices=False)
>>> s[2:] = 0
>>> np.dot(np.diag(s), VT)
array([[ 1.61889806, 0.60487661, 0.44034748, 0.96569316, 0.70302032,
0.26267284],
[-0.45671719, -0.84256593, -0.29617436, 0.99731918, 0.35057241,
0.64674677],
[ 0. , 0. , 0. , 0. , 0. ,
0. ],
[ 0. , 0. , 0. , 0. , 0. ,
0. ],
[ 0. , 0. , 0. , 0. , 0. ,
0. ]])
Это дает матрицу, в которой все, кроме последних нескольких строк, являются нулями, поэтому их можно удалить, и на практике это матрица, которую вы будете использовать в приложениях:
>>> np.dot(np.diag(s[:2]), VT[:2])
array([[ 1.61889806, 0.60487661, 0.44034748, 0.96569316, 0.70302032,
0.26267284],
[-0.45671719, -0.84256593, -0.29617436, 0.99731918, 0.35057241,
0.64674677]])
PDF описывает на стр. 10 рецепт, чтобы получить низкоуровневую реконструкцию входных данных. C
, Ранг!= Размерность, а размер сдвига и плотность матрицы реконструкции делают его нецелесообразным для использования в АЛП; его цель в основном математическая. Одна вещь, которую вы можете сделать с этим, это проверить, насколько хорошая реконструкция для различных значений k
:
>>> U, s, VT = svd(C, full_matrices=False)
>>> C2 = np.dot(U[:, :2], np.dot(np.diag(s[:2]), VT[:2]))
>>> from scipy.spatial.distance import euclidean
>>> euclidean(C2.ravel(), C.ravel()) # Frobenius norm of C2 - C
1.6677932876555255
>>> C3 = np.dot(U[:, :3], np.dot(np.diag(s[:3]), VT[:3]))
>>> euclidean(C3.ravel(), C.ravel())
1.0747879905228703
Проверка работоспособности против учёных TruncatedSVD
(полное раскрытие: я написал это):
>>> from sklearn.decomposition import TruncatedSVD
>>> TruncatedSVD(n_components=2).fit_transform(C.T)
array([[ 1.61889806, -0.45671719],
[ 0.60487661, -0.84256593],
[ 0.44034748, -0.29617436],
[ 0.96569316, 0.99731918],
[ 0.70302032, 0.35057241],
[ 0.26267284, 0.64674677]])