Exemple #1
0
    def fit(self, X, y=None):
        """
        X : ndarray, shape = (n_samples * n_times, n_dimensions)
            Data matrix.
        y : added for compatiblity
        gamma: float,
            Step size of the proximal gradient descent.
        """
        X = check_array(X)
        if self.mode.lower() == "symmetric_fbs":
            raise ValueError("Not implemented.")

        elif self.mode.lower() == "coordinate_descent":
            print("sono qui")
            thetas_pred = []
            historys = []
            if self.intercept:
                X = np.hstack((X, np.ones((X.shape[0], 1))))
            for ix in range(X.shape[1]):
                verbose = max(0, self.verbose - 1)
                res = fit_each_variable(X,
                                        ix,
                                        self.alpha,
                                        tol=self.tol,
                                        verbose=verbose)
                thetas_pred.append(res[0])
                historys.append(res[1:])
            self.precision_ = build_adjacency_matrix(thetas_pred,
                                                     how=self.reconstruction)
            self.history = historys
        else:
            raise ValueError("Unknown optimization mode. Found " + self.mode +
                             ". Options are 'coordiante_descent', "
                             "'symmetric_fbs'")
        return self
 def fit(self, X, y=None):
     """
     X : ndarray, shape = (n_samples * n_times, n_dimensions)
         Data matrix.
     y : added for compatiblity
     gamma: float,
         Step size of the proximal gradient descent.
     """
     X = check_array(X)
     if self.mode.lower() == 'symmetric_fbs':
         res = _fit(X,
                    self.alpha,
                    tol=self.tol,
                    gamma=self.gamma,
                    max_iter=self.max_iter,
                    verbose=self.verbose)
         self.precision_ = res[0]
         self.history = res[1:]
     elif self.mode.lower() == 'coordinate_descent':
         raise ValueError('Not implemented')
         # thetas_pred = []
         # historys = []
         # for ix in range(X.shape[1]):
         #     res = fit_each_variable(X, ix, self.alpha, tol=self.tol,
         #                             gamma=self.gamma,
         #                             verbose=self.verbose)
         #     thetas_pred.append(res[0])
         #     historys.append(res[1:])
         # self.precision_ = build_adjacency_matrix(thetas_pred,
         #                                          how=self.reconstruction)
         # self.history = historys
     elif self.mode.lower() == 'logistic_regression':
         thetas_pred = []
         for ix in range(X.shape[1]):
             verbose = min(0, self.verbose - 1)
             selector = np.array([i for i in range(X.shape[1]) if i != ix])
             print('pd')
             res = LogisticRegression(C=1 / self.alpha,
                                      penalty='l1',
                                      solver='liblinear',
                                      verbose=verbose,
                                      random_state=0).fit(
                                          X[:, selector], X[:, ix]).coef_
             thetas_pred.append(res)
         self.precision_ = build_adjacency_matrix(thetas_pred,
                                                  how=self.reconstruction)
     else:
         raise ValueError('Unknown optimization mode. Found ' + self.mode +
                          ". Options are 'coordiante_descent', "
                          "'symmetric_fbs'")
     return self
Exemple #3
0
 def fit(self, X, y=None, gamma=1e-3):
     """
     X : ndarray, shape = (n_samples * n_times, n_dimensions)
         Data matrix.
     y : added for compatiblity
     gamma: float,
         Step size of the proximal gradient descent.
     """
     X = check_array(X)
     thetas_pred = []
     historys = []
     for ix in range(X.shape[1]):
         res = fit_each_variable(X, ix, self.alpha)
         thetas_pred.append(res[0])
         historys.append(res[1:])
     self.precision_ = build_adjacency_matrix(thetas_pred, how=self.reconstruction)
     self.history = historys
     return self
def _fit_time_poisson_model(
    X,
    alpha=0.01,
    rho=1,
    kernel=None,
    max_iter=100,
    verbose=False,
    psi="laplacian",
    gamma=0.1,
    tol=1e-4,
    rtol=1e-4,
    return_history=False,
    return_n_iter=True,
    compute_objective=True,
    stop_at=None,
    stop_when=1e-4,
    n_cores=-1,
):
    """Time-varying graphical model solver.

    Solves the following problem via ADMM:
        min sum_{i=1}^T -n_i log_likelihood(K_i, X_i) + alpha ||K_i||_{od,1}
            + sum_{s>t}^T k(s,t) Psi(K_s - K_t)

    where X is a matrix n_i x D, the observations at time i and the
    log-likelihood changes according to the distribution.

    Parameters
    ----------
    X : ndarray, shape (n_times, n_samples, n_features)
        Data matrix. It has to contain two values: 0 or 1, -1 or 1.
        alpha, beta : float, optional
        Regularisation parameter.
    rho : float, optional
        Augmented Lagrangian parameter.
    max_iter : int, optional
        Maximum number of iterations.
    tol : float, optional
        Absolute tolerance for convergence.
    rtol : float, optional
        Relative tolerance for convergence.
    return_history : bool, optional
        Return the history of computed values.
    init : {'empirical', 'zeros', ndarray}, default 'empirical'
        How to initialise the inverse covariance matrix. Default is take
        the empirical covariance and inverting it.

    Returns
    -------
    X : numpy.array, 2-dimensional
        Solution to the problem.
    history : list
        If return_history, then also a structure that contains the
        objective value, the primal and dual residual norms, and tolerances
        for the primal and dual residual norms at each iteration.

    """
    psi, prox_psi, psi_node_penalty = check_norm_prox(psi)
    n_times, n_samples, n_features = X.shape
    n_samples = np.array([n_samples] * n_times)

    if kernel is None:
        kernel = np.eye(n_times)

    K = np.zeros((n_times, n_features, n_features))

    Z_M = {}
    U_M = {}
    Z_M_old = {}

    for m in range(1, n_times):
        # all possible non markovians jumps
        Z_L = K.copy()[:-m]
        Z_R = K.copy()[m:]
        Z_M[m] = (Z_L, Z_R)

        U_L = np.zeros_like(Z_L)
        U_R = np.zeros_like(Z_R)
        U_M[m] = (U_L, U_R)

        Z_L_old = np.zeros_like(Z_L)
        Z_R_old = np.zeros_like(Z_R)
        Z_M_old[m] = (Z_L_old, Z_R_old)

    checks = [convergence(obj=objective(X, K, Z_M, alpha, kernel, psi))]
    for iteration_ in range(max_iter):
        # update K
        A = np.zeros_like(K)
        for m in range(1, n_times):
            A[:-m] += Z_M[m][0] - U_M[m][0]
            A[m:] += Z_M[m][1] - U_M[m][1]

        A /= n_times
        A += A.transpose(0, 2, 1)
        A /= 2.0
        # K_new = np.zeros_like(K)

        for t in range(n_times):
            thetas_pred = []
            for v in range(n_features):
                inner_verbose = max(0, verbose - 1)
                res = fit_each_variable(X[t, :, :],
                                        v,
                                        alpha,
                                        tol=tol,
                                        verbose=inner_verbose,
                                        A=A[t, :, :],
                                        T=n_times,
                                        rho=rho)
                thetas_pred.append(res[0])

            K[t, :, :] = build_adjacency_matrix(thetas_pred, "union")

        # other Zs
        for m in range(1, n_times):
            U_L, U_R = U_M[m]
            A_L = K[:-m] + U_L
            A_R = K[m:] + U_R
            if not psi_node_penalty:
                prox_e = prox_psi(A_R - A_L,
                                  lamda=2.0 *
                                  np.diag(kernel, m)[:, None, None] / rho)
                Z_L = 0.5 * (A_L + A_R - prox_e)
                Z_R = 0.5 * (A_L + A_R + prox_e)
            else:
                Z_L, Z_R = prox_psi(
                    np.concatenate((A_L, A_R), axis=1),
                    lamda=0.5 * np.diag(kernel, m)[:, None, None] / rho,
                    rho=rho,
                    tol=tol,
                    rtol=rtol,
                    max_iter=max_iter,
                )
            Z_M[m] = (Z_L, Z_R)

            # update other residuals
            U_L += K[:-m] - Z_L
            U_R += K[m:] - Z_R

        # diagnostics, reporting, termination checks
        rnorm = np.sqrt(
            sum(
                squared_norm(K[:-m] - Z_M[m][0]) +
                squared_norm(K[m:] - Z_M[m][1]) for m in range(1, n_times)))

        snorm = rho * np.sqrt(
            sum(
                squared_norm(Z_M[m][0] - Z_M_old[m][0]) +
                squared_norm(Z_M[m][1] - Z_M_old[m][1])
                for m in range(1, n_times)))

        obj = objective(X, K, Z_M, alpha, kernel,
                        psi) if compute_objective else np.nan

        check = convergence(
            obj=obj,
            rnorm=rnorm,
            snorm=snorm,
            e_pri=n_features * n_times * tol + rtol * max(
                np.sqrt(
                    sum(
                        squared_norm(Z_M[m][0]) + squared_norm(Z_M[m][1])
                        for m in range(1, n_times))),
                np.sqrt(
                    squared_norm(K) + sum(
                        squared_norm(K[:-m]) + squared_norm(K[m:])
                        for m in range(1, n_times))),
            ),
            e_dual=n_features * n_times * tol + rtol * rho * np.sqrt(
                sum(
                    squared_norm(U_M[m][0]) + squared_norm(U_M[m][1])
                    for m in range(1, n_times))),
        )
        for m in range(1, n_times):
            Z_M_old[m] = (Z_M[m][0].copy(), Z_M[m][1].copy())

        if verbose:
            print("obj: %.4f, rnorm: %.4f, snorm: %.4f,"
                  "eps_pri: %.4f, eps_dual: %.4f" % check[:5])

        checks.append(check)
        if stop_at is not None:
            if abs(check.obj - stop_at) / abs(stop_at) < stop_when:
                break

        if check.rnorm <= check.e_pri and check.snorm <= check.e_dual:
            break

        rho_new = update_rho(rho,
                             rnorm,
                             snorm,
                             iteration=iteration_,
                             **(update_rho_options or {}))
        # scaled dual variables should be also rescaled
        # U_0 *= rho / rho_new
        for m in range(1, n_times):
            U_L, U_R = U_M[m]
            U_L *= rho / rho_new
            U_R *= rho / rho_new
        rho = rho_new
    else:
        warnings.warn("Objective did not converge.")

    return_list = [K]
    if return_history:
        return_list.append(checks)
    if return_n_iter:
        return_list.append(iteration_ + 1)
    return return_list