13

I am trying to decompose a 3D matrix using python library scikit-tensor. I managed to decompose my Tensor (with dimensions 100x50x5) into three matrices. My question is how can I compose the initial matrix again using the decomposed matrix produced with Tensor factorization? I want to check if the decomposition has any meaning. My code is the following:

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)

I am using the canonical decomposition as provided from the scikit-tensor library function cp_als. Also what is the expected dimensionality of the decomposed matrices?

Jose Ramon
  • 5,572
  • 25
  • 76
  • 152
  • cp.py says: $A\approx\sum_{r=1}^{rank} \\vec{u}_r^{(1)} \outer \cdots \outer \\vec{u}_r^{(N)}$. Have you tried that? This should be identical to "P.totensor()" – Bort Sep 30 '16 at 14:12
  • @Bort you mean the lines 145 and 146 of cp.py? – Jose Ramon Sep 30 '16 at 15:26

2 Answers2

7

The CP product of, for example, 4 matrices

X_{abcd} = \displaystyle\sum_{z=0}^{Z}{A_{az} B_{bz} C_{cz} D_{dz} + \epsilon_{abcd}}

can be expressed using Einstein notation as

X_{abcd} = A_{az} B_{bz} C_{cz} D_{dz} + \epsilon_{abcd}

or in numpy as

numpy.einsum('az,bz,cz,dz -> abcd', A, B, C, D)

so in your case you would use

numpy.einsum('az,bz->ab', P.U[0], P.U[1])

or, in your 3-matrix case

numpy.einsum('az,bz,cz->abc', P.U[0], P.U[1], P.U[2])

sktensor.ktensor.ktensor also have a method totensor() that does exactly this:

np.allclose(np.einsum('az,bz->ab', P.U[0], P.U[1]), P.totensor())
>>> True
Nils Werner
  • 34,832
  • 7
  • 76
  • 98
0

See an explanation of CP here. You may also use tensorlearn package to rebuild the tensor.

axar
  • 1
  • 1