Повторно составить тензор после тензорной факторизации
Я пытаюсь разложить 3D-матрицу, используя библиотеку python scikit-tensor. Мне удалось разложить мой тензор (с размерами 100x50x5) на три матрицы. Мой вопрос заключается в том, как я могу снова скомпоновать исходную матрицу, используя разложенную матрицу, полученную с фазовращением тензора? Я хочу проверить, имеет ли разложение какое-либо значение. Мой код следующий:
import logging
from scipy.io.matlab import loadmat
from sktensor import dtensor, cp_als
import numpy as np
//Set logging to DEBUG to see CP-ALS information
logging.basicConfig(level=logging.DEBUG)
T = np.ones((400, 50))
T = dtensor(T)
P, fit, itr, exectimes = cp_als(T, 10, init='random')
// how can I re-compose the Matrix T? TA = np.dot(P.U[0], P.U[1].T)
Я использую каноническое разложение, как это предусмотрено библиотечной функцией scikit-тензора cp_als. Также какова ожидаемая размерность разложенных матриц?
Ответы
Ответ 1
CP-произведение, например, 4-х матриц
![X_{abcd} = \displaystyle\sum_{z=0}^{Z}{A_{az} B_{bz} C_{cz} D_{dz} + \epsilon_{abcd}}]()
может быть выражена с помощью обозначение Эйнштейна как
![X_{abcd} = A_{az} B_{bz} C_{cz} D_{dz} + \epsilon_{abcd}]()
или в numpy как
numpy.einsum('az,bz,cz,dz -> abcd', A, B, C, D)
поэтому в вашем случае вы будете использовать
numpy.einsum('az,bz->ab', P.U[0], P.U[1])
или, в вашем случае с 3 матрицами
numpy.einsum('az,bz,cz->abc', P.U[0], P.U[1], P.U[2])
sktensor.ktensor.ktensor
также имеет метод totensor()
, который выполняет именно это:
np.allclose(np.einsum('az,bz->ab', P.U[0], P.U[1]), P.totensor())
>>> True