

def PMF(X, rank=10, learning_rate=0.001, momentum=0.8, regularization=0.25, minibatch_size=1000, max_epoch=1000, nan_value=0, status_percentage=0.1, random_state=None):
    '\n    Python implementation of Probabilistic Matrix Factorization (PMF).\n\n    Parameters\n    ----------\n    X: numpy array or scipy.sparse coo matrix, shape (n_users, n_items)\n        Input data. If a dense array is passed in, it will be converted to a\n        sparse matrix by looking for all `nan_value` numbers and treating them\n        as empty.\n\n    rank: int, optional (default=10)\n       Rank of the low-rank factor matrices. A higher rank should result in a\n       better approximation, at the cost of more memory and slower computataion.\n\n    learning_rate: float, optional (default=0.001)\n        Learning rate for minibatch gradient descent.\n\n    momentum: float, optional (default=0.8)\n        Momentum for minibatch gradient descent.\n\n    regularization: float, optional (default=0.25)\n        L2 regularization penalty for minibatch gradient descent.\n\n    minibatch_size: int, optional (default=1000)\n       The size of each minibatch. If this is larger than size of the dataset,\n       will default to running over the whole dataset.\n\n    max_epoch: int, optional (default=1000)\n        The maximum number of epochs.\n\n    nan_value: int, optional (default=0)\n        This value will be masked out of the input for calculations\n        Should match the value considered the "not rated" in the dataset X.\n\n    status_percentage: float in (0, 1), optional (default=0.1)\n        The relative percentage of `max_epochs` when status will be printed.\n        For example, 0.1 is every 10%, 0.01 is every 1%, and so on. For\n        the default values of max_epoch=1000, status_percentage=0.1 this\n        is equivalent to a status print every 100 epochs.\n\n    random_state: RandomState, int, or None, optional (default=None)\n        Random state to pass in. Can be an int, None, or np.random.RandomState\n        object.\n\n\n    Returns\n    -------\n    U: array-like, shape (X.shape[0], rank)\n        Row basis for reconstruction.\n        Usage:\n        reconstruction = np.dot(U, V.T) + X_mean\n\n    V: array-like, shape (X.shape[1], rank)\n        Column basis for reconstruction.\n        Usage:\n        reconstruction = np.dot(U, V.T) + X_mean\n\n    X_mean: float\n        Global mean prediction, needed for reconstruction\n        Usage\n        reconstruction = np.dot(U, V.T) + X_mean\n\n\n    Notes\n    -----\n    Based on code from Ruslan Salakhutdinov\n    http://www.cs.toronto.edu/~rsalakhu/code_BPMF/pmf.m\n\n    Probabilistic Matrix Factorization, R. Salakhutdinov and A. Mnih,\n    Advances in Neural Information Processing Systems 20, 2008\n    '
    if (not sparse.isspmatrix_coo(X)):
        val_index = np.where((X != nan_value))
        X = sparse.coo_matrix((X[(val_index[0], val_index[1])], (val_index[0], val_index[1])))
    X_mean = X.mean()
    lr = learning_rate
    reg = regularization
    mom = momentum
    if ((random_state is None) or (type(random_state) is int)):
        random_state = np.random.RandomState(random_state)
    (N, M) = X.shape
    U = (0.1 * random_state.randn(N, rank))
    V = (0.1 * random_state.randn(M, rank))
    U_inc = np.zeros_like(U)
    V_inc = np.zeros_like(V)
    dU = np.zeros_like(U)
    dV = np.zeros_like(V)
    epoch = 0
    status_inc = int(np.ceil((max_epoch * status_percentage)))
    print(('Printing updates every %i epochs' % status_inc))
    status_points = (list(range(0, max_epoch, status_inc)) + [(max_epoch - 1)])
    X_s = X.tolil()
    while (epoch < max_epoch):
        (r, c) = X.nonzero()
        mb_indices = minibatch_indices(zip(r, c), minibatch_size)
        n_batches = len(mb_indices)
        shuffle_in_unison(r, c)
        mean_abs_err = 0.0
        for (i, j) in mb_indices:
            dU[:, :] = 0.0
            dV[:, :] = 0.0
            r_i = r[i:j]
            c_i = c[i:j]
            X_i = (X_s[(r_i, c_i)].toarray().ravel() - X_mean)
            pred = np.sum((U[r_i] * V[c_i]), axis=1)
            mean_abs_err += (np.sum(np.abs((pred - X_i))) / (n_batches * (j - i)))
            grad_loss = (2 * (pred - X_i))
            grad_U = ((grad_loss[:, None] * V[c_i]) + (reg * U[r_i]))
            grad_V = ((grad_loss[:, None] * U[r_i]) + (reg * V[c_i]))
            dU[r_i] = grad_U
            dV[c_i] = grad_V
            U_inc = ((mom * U_inc) + (lr * dU))
            V_inc = ((mom * V_inc) + (lr * dV))
            U -= U_inc
            V -= V_inc
        if (epoch in status_points):
            print(('Epoch %i of %i' % ((epoch + 1), max_epoch)))
            print(('Mean absolute error %f' % mean_abs_err))
        epoch += 1
    return (U, V, X_mean)

dataset/ETHPy150Open kastnerkyle/PyCon2015/matrix_factorization.py PMF/original