2012-06-20 3 views
3

У меня нет опыта работы с Python. Я просмотрел некоторые учебные материалы, но сложно понять расширенный код. Поэтому я пришел сюда для более конкретного ответа. Для меня миссия - повторить код на моем компьютере.Как запустить .py модуль?

Вот сценарий:

Я аспирант изучает тензорной факторизации в отношении обучения. В документе [1] обеспечивает код для запуска этого алгоритма следующим образом:

import logging, time 
from numpy import dot, zeros, kron, array, eye, argmax 
from numpy.linalg import qr, pinv, norm, inv 
from scipy.linalg import eigh 
from numpy.random import rand 

__version__ = "0.1" 
__all__ = ['rescal', 'rescal_with_random_restarts'] 

__DEF_MAXITER = 500 
__DEF_INIT = 'nvecs' 
__DEF_PROJ = True 
__DEF_CONV = 1e-5 
__DEF_LMBDA = 0 

_log = logging.getLogger('RESCAL') 

def rescal_with_random_restarts(X, rank, restarts=10, **kwargs): 
    """ 
    Restarts RESCAL multiple time from random starting point and 
    returns factorization with best fit. 
    """ 
    models = [] 
    fits = [] 
    for i in range(restarts): 
     res = rescal(X, rank, init='random', **kwargs) 
     models.append(res) 
     fits.append(res[2]) 
    return models[argmax(fits)] 

def rescal(X, rank, **kwargs): 
    """ 
    RESCAL 

    Factors a three-way tensor X such that each frontal slice 
    X_k = A * R_k * A.T. The frontal slices of a tensor are 
    N x N matrices that correspond to the adjecency matrices 
    of the relational graph for a particular relation. 

    For a full description of the algorithm see: 
     Maximilian Nickel, Volker Tresp, Hans-Peter-Kriegel, 
     "A Three-Way Model for Collective Learning on Multi-Relational Data", 
     ICML 2011, Bellevue, WA, USA 

    Parameters 
    ---------- 
    X : list 
     List of frontal slices X_k of the tensor X. The shape of each X_k is ('N', 'N') 
    rank : int 
     Rank of the factorization 
    lmbda : float, optional 
     Regularization parameter for A and R_k factor matrices. 0 by default 
    init : string, optional 
     Initialization method of the factor matrices. 'nvecs' (default) 
     initializes A based on the eigenvectors of X. 'random' initializes 
     the factor matrices randomly. 
    proj : boolean, optional 
     Whether or not to use the QR decomposition when computing R_k. 
     True by default 
    maxIter : int, optional 
     Maximium number of iterations of the ALS algorithm. 500 by default. 
    conv : float, optional 
     Stop when residual of factorization is less than conv. 1e-5 by default 

    Returns 
    ------- 
    A : ndarray 
     array of shape ('N', 'rank') corresponding to the factor matrix A 
    R : list 
     list of 'M' arrays of shape ('rank', 'rank') corresponding to the factor matrices R_k 
    f : float 
     function value of the factorization 
    iter : int 
     number of iterations until convergence 
    exectimes : ndarray 
     execution times to compute the updates in each iteration 
    """ 

    # init options 
    ainit = kwargs.pop('init', __DEF_INIT) 
    proj = kwargs.pop('proj', __DEF_PROJ) 
    maxIter = kwargs.pop('maxIter', __DEF_MAXITER) 
    conv = kwargs.pop('conv', __DEF_CONV) 
    lmbda = kwargs.pop('lmbda', __DEF_LMBDA) 
    if not len(kwargs) == 0: 
     raise ValueError('Unknown keywords (%s)' % (kwargs.keys())) 

    sz = X[0].shape 
    dtype = X[0].dtype 
    n = sz[0] 
    k = len(X) 

    _log.debug('[Config] rank: %d | maxIter: %d | conv: %7.1e | lmbda: %7.1e' % (rank, 
     maxIter, conv, lmbda)) 
    _log.debug('[Config] dtype: %s' % dtype) 

    # precompute norms of X 
    normX = [norm(M)**2 for M in X] 
    Xflat = [M.flatten() for M in X] 
    sumNormX = sum(normX) 

    # initialize A 
    if ainit == 'random': 
     A = array(rand(n, rank), dtype=dtype) 
    elif ainit == 'nvecs': 
     S = zeros((n, n), dtype=dtype) 
     T = zeros((n, n), dtype=dtype) 
     for i in range(k): 
      T = X[i] 
      S = S + T + T.T 
     evals, A = eigh(S,eigvals=(n-rank,n-1)) 
    else : 
     raise 'Unknown init option ("%s")' % ainit 

    # initialize R 
    if proj: 
     Q, A2 = qr(A) 
     X2 = __projectSlices(X, Q) 
     R = __updateR(X2, A2, lmbda) 
    else : 
     R = __updateR(X, A, lmbda) 

    # compute factorization 
    fit = fitchange = fitold = f = 0 
    exectimes = [] 
    ARAt = zeros((n,n), dtype=dtype) 
    for iter in xrange(maxIter): 
     tic = time.clock() 
     fitold = fit 
     A = __updateA(X, A, R, lmbda) 
     if proj: 
      Q, A2 = qr(A) 
      X2 = __projectSlices(X, Q) 
      R = __updateR(X2, A2, lmbda) 
     else : 
      R = __updateR(X, A, lmbda) 

     # compute fit value 
     f = lmbda*(norm(A)**2) 
     for i in range(k): 
      ARAt = dot(A, dot(R[i], A.T)) 
      f += normX[i] + norm(ARAt)**2 - 2*dot(Xflat[i], ARAt.flatten()) + lmbda*(R[i].flatten()**2).sum() 
     f *= 0.5 

     fit = 1 - f/sumNormX 
     fitchange = abs(fitold - fit) 

     toc = time.clock() 
     exectimes.append(toc - tic) 
     _log.debug('[%3d] fit: %.5f | delta: %7.1e | secs: %.5f' % (iter, 
      fit, fitchange, exectimes[-1])) 
     if iter > 1 and fitchange < conv: 
      break 
    return A, R, f, iter+1, array(exectimes) 

def __updateA(X, A, R, lmbda): 
    n, rank = A.shape 
    F = zeros((n, rank), dtype=X[0].dtype) 
    E = zeros((rank, rank), dtype=X[0].dtype) 

    AtA = dot(A.T,A) 
    for i in range(len(X)): 
     F += dot(X[i], dot(A, R[i].T)) + dot(X[i].T, dot(A, R[i])) 
     E += dot(R[i], dot(AtA, R[i].T)) + dot(R[i].T, dot(AtA, R[i])) 
    A = dot(F, inv(lmbda * eye(rank) + E)) 
    return A 

def __updateR(X, A, lmbda): 
    r = A.shape[1] 
    R = [] 
    At = A.T  
    if lmbda == 0: 
     ainv = dot(pinv(dot(At, A)), At) 
     for i in range(len(X)): 
      R.append(dot(ainv, dot(X[i], ainv.T))) 
    else : 
     AtA = dot(At, A) 
     tmp = inv(kron(AtA, AtA) + lmbda * eye(r**2)) 
     for i in range(len(X)): 
      AtXA = dot(At, dot(X[i], A)) 
      R.append(dot(AtXA.flatten(), tmp).reshape(r, r)) 
    return R 

def __projectSlices(X, Q): 
    q = Q.shape[1] 
    X2 = [] 
    for i in range(len(X)): 
     X2.append(dot(Q.T, dot(X[i], Q))) 
    return X2 

Это скучное, чтобы вставить такой длинный код, но нет никакого другого пути, чтобы выяснить мои проблемы. Я сожалею об этом.

импортировать этот модуль и передать их аргументы в соответствии с авторским website:

import pickle, sys 
from rescal import rescal 

rank = sys.argv[1] 
X = pickle.load('us-presidents.pickle') 
A, R, f, iter, exectimes = rescal(X, rank, lmbda=1.0) 

Набор данных нам-presidents.rdf можно найти here.

Мои вопросы:

  1. По коду запиской, тензор X представляет собой список. Я не совсем понимаю это, как связать список с тензором в Python? Могу ли я понять тензор = список в Python?
  2. Должен ли я сначала преобразовать формат RDF в формат тройки (субъект, предикат, объект)? Я не уверен в структуре данных X. Как мне присваивать значения X вручную?
  3. Затем, как запустить его?

Я вставляю код автора без его разрешения, является ли это актом нарушения? если так, мне очень жаль, и я скоро его удалю.

Проблемы могут быть немного скучными, но они важны для меня. Любая помощь будет принята с благодарностью.

[1] Максимилиан Никель, Volker Tresp, Hans-Peter Кригель, трехходовой модель для коллективного обучения на нескольких реляционных данных, в Трудах 28-й Международной конференции по вопросам машинного обучения, 2011, Bellevue, WA , USA

+0

для запуска модуля просто сделать: Python MODULENAME – codecool

ответ

1

Чтобы ответить Q2: вам нужно преобразовать RDF и сохранить его, прежде чем вы сможете загрузить его из файла 'us-presidents.pickle'. Автор этого кода, вероятно, сделал это один раз, потому что исходный формат пика Python загружается быстрее. Поскольку формат pickle включает в себя тип данных данных, возможно, что X - это некоторый экземпляр класса numpy, и вам понадобится пример файла pickle, используемый этим кодом, или какой-то код, делающий pickle.dump, чтобы выяснить, как преобразовать от RDF до этого конкретного файла pickle, так как rescal ожидает его.

Так что это может ответить Q1: тензор состоит из списка элементов. Из кода вы можете видеть, что параметр X для rescal имеет длину (k = len(X)) и может быть проиндексирован (T = X[i]). Таким образом, элементы используются в качестве списка (даже если это может быть какой-то другой тип данных, который просто ведет себя как таковой).

В стороне: если вы не знакомы с Python и просто интересуетесь результатом вычислений, вы можете получить дополнительную помощь, связавшись с автором программного обеспечения.

+0

круто, теперь вопрос заключается в том, чтобы получить файл «нам-presidents.pickle» путем трансформации или контрактации автору, я буду попробуй. – fishiwhj

1
  1. According to the code note, the tensor X is a list. I don't quite understand this, how do I relate a list to a tensor in Python? Can I understand tensor = list in Python?

Не обязательно, но автор кода решил представить тензорные данные в виде структуры списка. Как сказано в комментариях указать, список X содержит:

List of frontal slices X_k of the tensor X. The shape of each X_k is ('N', 'N')

Это означает, что тензор repesented в виде списка кортежей: [(N, N), ..., (N, N)].

  1. I'm not sure of the data structure of X. How do I assignment values to X by hand?

Теперь, когда мы теперь являемся структурой данных X, мы можем присвоить ему значения с помощью присваивания. Следующее назначит кортеж (1, 3) на первую позицию в списке X (как первая позиция имеет индекс 0, второй в положении 1, и так далее):

X[0] = (1, 3) 

Аналогично, следующие будут назначать кортеж (2, 4) на вторую позицию:

X[1] = (2, 4) 
+0

Спасибо, но когда вы назначаете X [0] = (1,3), возникает ERROR: Файл «C: \ Python27 \ rescal.py», строка 88, в rescal sz = X [0] .shape AttributeError : объект 'tuple' не имеет атрибута 'shape' – fishiwhj

+0

В этом случае элементы X не являются кортежами, а объектами другого типа. Попробуйте 'print type (X [0])' перед выполнением каких-либо назначений, чтобы проверить, что такое тип, а затем построить объекты этого типа. Затем вы можете назначить эти объекты X (например, 'X [0] = ...'). –

+0

Я нашел метод формы в numpy [tutorial] (http://www.scipy.org/Tentative_NumPy_Tutorial#head-62ef2d3c0a5b4b7d6fdc48e4a60fe48b1ffe5006), спасибо большое! – fishiwhj