2016-04-11 27 views
1

pythonでscikit-tensorを使うには?pythonでscikit-tensorを使う方法

パラファック分解でテンソルを分解したい。 入力は次のとおりです。テンソルデータ - 分解 出力の順位は以下のとおりです因子行列

+0

を返します。第1は広すぎ、第2は説得的な答えを引きつける。問題を説明し、今まで何をしていたのか、望ましい出力に特定の入力が与えられているのか、そして2つのポリシー違反の質問を取り除くことで、質問を変えることを検討してください。 –

答えて

0

このコード: 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 
関連する問題