2016-09-28 3 views
14

파이썬 라이브러리 scikit-tensor을 사용하여 3D 매트릭스를 분해하려고합니다. 나는 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에서 제공 한 정규 분해를 사용하고 있습니다 : 내 코드는 다음과 같다. 또한 분해 된 행렬의 예상되는 차원은 무엇입니까?

+0

cp.py는 말한다 : $ \ approx \ sum_ {r = 1}^{rank} \\ vec {u} _r^{(1)} \ outer \ cdots \ outer \\ vec {u} _r^{(N)} $. 너 그거 해봤 니? 이것은 "P.totensor()"와 동일해야합니다. – Bort

+0

@bort cp.py의 145와 146 행을 의미합니까? –

답변

6

예를 들어, 상기 CP 제품 4 행렬

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

가 너무 Einstein notation

같은

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

또는 NumPy와의
numpy.einsum('az,bz,cz,dz -> abcd', A, B, C, D) 

사용하여 표현 될 수있다 당신 안에 R의 경우는

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

sktensor.ktensor.ktensor도 정확하게 수행하는 방법 totensor()이 당신의 3 매트릭스 경우,

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

를 사용하거나 것이 :

np.allclose(np.einsum('az,bz->ab', P.U[0], P.U[1]), P.totensor()) 
>>> True 
+0

안녕하세요, Nils 님이 답장을 보내 주셔서 감사합니다. 이거 확실하니? 나는 행렬을 다시 만들려고했는데 그 결과가 원래의 텐서에 근접하지 않았습니다. –

+0

글쎄, 그것은 처음부터 텐서를 어떻게 분해 할 수 있는지에 달려 있습니다. 당신의 엡실론이 크다면 두 가지가 눈에 띄게 다를 것입니다. –

+0

cp_als 알고리즘의 경우 처리 할 수있는 잠정적 차원의 수를 제외한 매개 변수는 무엇입니까? –

관련 문제