1
pythonでscikit-tensorを使うには?pythonでscikit-tensorを使う方法
パラファック分解でテンソルを分解したい。 入力は次のとおりです。テンソルデータ - 分解 出力の順位は以下のとおりです因子行列
pythonでscikit-tensorを使うには?pythonでscikit-tensorを使う方法
パラファック分解でテンソルを分解したい。 入力は次のとおりです。テンソルデータ - 分解 出力の順位は以下のとおりです因子行列
このコード: parafac_base機能Xテンソルを取得し、1で2つの質問です3つの因子行列
import operator, logging
import numpy as np
def ribs(loadings):
'''
Convert a list of n loading matrices [A_{fi}, B_{fj}, C_{fk}, ...] into ribs
[A_{fi11...}, B_{f1j1...}, C_{f11k...}, ...]. These ribs can be multiplied
with numpy broadcasting to fill a tensor with data.
'''
loadings = [np.atleast_2d(l) for l in loadings]
nfactors = loadings[0].shape[0]
assert np.alltrue([l.ndim == 2 and l.shape[0] == nfactors for l in loadings])
ribs = []
for mi in range(len(loadings)):
shape = [nfactors] + [-1 if fi == mi else 1 for fi in range(len(loadings))]
ribs.append(loadings[mi].reshape(shape))
return ribs
def para_compose(ribs):
return np.sum(reduce(operator.mul, ribs), axis=0)
def parafac_base(x, nfactors, max_iter):
'''
PARAFAC is a multi-way tensor decomposition method. Given a tensor X, and a
number of factors nfactors, PARAFAC decomposes the X in n factors for each
dimension in X using alternating least squares:
X_{ijk} = \sum_{f} a_{fi} b_{fj} c_{fk} + e_{ijk}
PARAFAC can be seen as a generalization of PCA to higher order arrays [1].
Return a ([a, b, c, ...], mse)
[1] Rasmus Bro. PARAFAC. Tutorial and applications. Chemometrics and
Intelligent Laboratory Systems, 38(2):149-171, 1997.
'''
log = logging.getLogger('psychic.parafac')
loadings = [np.random.rand(nfactors, n) for n in x.shape]
last_mse = np.inf
for i in range(max_iter):
# 1) forward (predict x)
xhat = para_compose(ribs(loadings))
# 2) stopping?
mse = np.mean((xhat - x) ** 2)
if last_mse - mse < 1e-10 or mse < 1e-20:
break
last_mse = mse
for mode in range(len(loadings)):
log.debug('iter: %d, dir: %d' % (i, mode))
# a) Re-compose using other factors
Z = ribs([l for li, l in enumerate(loadings) if li != mode])
Z = reduce(operator.mul, Z)
# b) Isolate mode
Z = Z.reshape(nfactors, -1).T # Z = [long x fact]
Y = np.rollaxis(x, mode)
Y = Y.reshape(Y.shape[0], -1).T # Y = [mode x long]
# c) least squares estimation: x = np.lstsq(Z, Y) -> Z x = Y
new_fact, _, _, _ = np.linalg.lstsq(Z, Y)
loadings[mode] = new_fact
if not i < max_iter - 1:
log.warning('parafac did not converge in %d iterations (mse=%.2g)' %
(max_iter, mse))
return loadings, mse
を返します。第1は広すぎ、第2は説得的な答えを引きつける。問題を説明し、今まで何をしていたのか、望ましい出力に特定の入力が与えられているのか、そして2つのポリシー違反の質問を取り除くことで、質問を変えることを検討してください。 –