コード例 #1
0
def regression_warp(nu, beta, y, alpha):
    """
    calculates optimal warping for function linear regression

    :param nu: numpy ndarray of shape (M,N) of M functions with N samples
    :param beta: numpy ndarray of shape (M,N) of M functions with N samples
    :param y: numpy ndarray of shape (1,N) of M functions with N samples
    responses
    :param alpha: numpy scalar

    :rtype: numpy array
    :return gamma_new: warping function

    """
    T = beta.shape[1]
    betanu = cf.q_to_curve(nu)

    betaM, O_M, tauM = cf.find_rotation_and_seed_coord(betanu, beta)
    q = cf.curve_to_q(betaM)
    gam_M = cf.optimum_reparam_curve(nu, q)
    betaM = cf.group_action_by_gamma_coord(betaM, gam_M)
    qM = cf.curve_to_q(betaM)
    y_M = cf.innerprod_q2(qM, nu)

    betam, O_m, taum = cf.find_rotation_and_seed_coord(-1 * betanu, beta)
    q = cf.curve_to_q(betam)
    gam_m = cf.optimum_reparam_curve(-1 * nu, q)
    betam = cf.group_action_by_gamma_coord(betam, gam_m)
    qm = cf.curve_to_q(betam)
    y_m = cf.innerprod_q2(qm, nu)

    if y > alpha + y_M:
        O_hat = O_M
        gamma_new = gam_M
        tau = tauM
    elif y < alpha + y_m:
        O_hat = O_m
        gamma_new = gam_m
        tau = taum
    else:
        gamma_new, O_hat, tau = cf.curve_zero_crossing(y - alpha, beta, nu, y_M, y_m, gam_M,
                                                               gam_m)

    return(gamma_new, O_hat, tau)
コード例 #2
0
ファイル: curve_stats.py プロジェクト: jdtuck/fdasrsf_python
def oc_srvf_align(beta, mode='O'):
    """
    This claculates the mean of a set of curves and aligns them
    :param beta: numpy ndarray of shape (n, M, N) describing N curves
    in R^M
    :param mode: Open ('O') or closed curve ('C') (default 'O')

    :rtype: tuple of numpy array
    :return betan: aligned curves
    :return qn: aligned srvf
    :return betamean: mean curve
    :return mu: mean srvf
    """
    n, T, N = beta.shape
    # find mean
    mu, betamean, v, q = curve_karcher_mean(beta, mode=mode)

    qn = zeros((n, T, N))
    betan = zeros((n, T, N))
    centroid2 = cf.calculatecentroid(betamean)
    betamean = betamean - tile(centroid2, [T, 1]).T
    q_mu = cf.curve_to_q(betamean)
    # align to mean
    for ii in range(0, N):
        beta1 = beta[:, :, ii]
        centroid1 = cf.calculatecentroid(beta1)
        beta1 = beta1 - tile(centroid1, [T, 1]).T

        # Iteratively optimize over SO(n) x Gamma
        for i in range(0, 1):
            # Optimize over SO(n)
            beta1, O_hat, tau = cf.find_rotation_and_seed_coord(betamean,
                                                                beta1)
            q1 = cf.curve_to_q(beta1)

            # Optimize over Gamma
            gam = cf.optimum_reparam_curve(q1, q_mu, 0.0)
            gamI = uf.invertGamma(gam)
            # Applying optimal re-parameterization to the second curve
            beta1 = cf.group_action_by_gamma_coord(beta1, gamI)

        # Optimize over SO(n)
        beta1, O_hat, tau = cf.find_rotation_and_seed_coord(betamean, beta1)
        qn[:, :, ii] = cf.curve_to_q(beta1)
        betan[:, :, ii] = beta1

    align_results = collections.namedtuple('align', ['betan', 'qn', 'betamean', 'mu'])
    out = align_results(betan, qn, betamean, q_mu)
    return out
コード例 #3
0
def oc_srvf_align(beta, mode='O'):
    """
    This claculates the mean of a set of curves and aligns them
    :param beta: numpy ndarray of shape (n, M, N) describing N curves
    in R^M
    :param mode: Open ('O') or closed curve ('C') (default 'O')

    :rtype: tuple of numpy array
    :return betan: aligned curves
    :return qn: aligned srvf
    :return betamean: mean curve
    :return mu: mean srvf
    """
    n, T, N = beta.shape
    # find mean
    mu, betamean, v, q = curve_karcher_mean(beta, mode=mode)

    qn = zeros((n, T, N))
    betan = zeros((n, T, N))
    centroid2 = cf.calculatecentroid(betamean)
    betamean = betamean - tile(centroid2, [T, 1]).T
    q_mu = cf.curve_to_q(betamean)
    # align to mean
    for ii in range(0, N):
        beta1 = beta[:, :, ii]
        centroid1 = cf.calculatecentroid(beta1)
        beta1 = beta1 - tile(centroid1, [T, 1]).T

        # Iteratively optimize over SO(n) x Gamma
        for i in range(0, 1):
            # Optimize over SO(n)
            beta1, O_hat, tau = cf.find_rotation_and_seed_coord(betamean,
                                                                beta1)
            q1 = cf.curve_to_q(beta1)

            # Optimize over Gamma
            gam = cf.optimum_reparam_curve(q1, q_mu, 0.0)
            gamI = uf.invertGamma(gam)
            # Applying optimal re-parameterization to the second curve
            beta1 = cf.group_action_by_gamma_coord(beta1, gamI)

        # Optimize over SO(n)
        beta1, O_hat, tau = cf.find_rotation_and_seed_coord(betamean, beta1)
        qn[:, :, ii] = cf.curve_to_q(beta1)
        betan[:, :, ii] = beta1

    align_results = collections.namedtuple('align', ['betan', 'qn', 'betamean', 'mu'])
    out = align_results(betan, qn, betamean, q_mu)
    return out
コード例 #4
0
def align_sub(beta_mean, q_mu, beta1):
    # Iteratively optimize over SO(n) x Gamma
    for i in range(0, 1):
        # Optimize over SO(n)
        beta1, O_hat, tau = cf.find_rotation_and_seed_coord(beta_mean, beta1)
        q1 = cf.curve_to_q(beta1)

        # Optimize over Gamma
        gam = cf.optimum_reparam_curve(q1, q_mu, 0.0)
        gamI = uf.invertGamma(gam)
        # Applying optimal re-parameterization to the second curve
        beta1 = cf.group_action_by_gamma_coord(beta1, gamI)

    # Optimize over SO(n)
    beta1, O_hat, tau = cf.find_rotation_and_seed_coord(beta_mean, beta1)

    return (beta1, q1, gamI)
コード例 #5
0
ファイル: curve_stats.py プロジェクト: jdtuck/fdasrsf_python
    def srvf_align(self, rotation=True, parallel=False, cores=-1, method="DP"):
        """
        This aligns a set of curves to the mean and computes mean if not computed
        :param rotation: compute optimal rotation (default = T)
        :param parallel: run in parallel (default = F)
        :param cores: number of cores for parallel (default = -1 (all))
        :param method: method to apply optimization (default="DP") options are "DP" or "RBFGS"
        """
        n, T, N = self.beta.shape

        modes = ['O', 'C']
        mode = [i for i, x in enumerate(modes) if x == self.mode]
        if len(mode) == 0:
            mode = 0
        else:
            mode = mode[0]

        # find mean
        if not hasattr(self, 'beta_mean'):
            self.karcher_mean()

        self.qn = zeros((n, T, N))
        self.betan = zeros((n, T, N))
        self.gams = zeros((T, N))
        centroid2 = cf.calculatecentroid(self.beta_mean)
        self.beta_mean = self.beta_mean - tile(centroid2, [T, 1]).T

        # align to mean
        out = Parallel(n_jobs=-1)(delayed(cf.find_rotation_and_seed_unique)(
            self.q_mean, self.q[:, :, n], mode, rotation, method)
                                  for n in range(N))
        for ii in range(0, N):
            self.gams[:, ii] = out[ii][2]
            self.qn[:, :, ii] = out[ii][0]
            btmp = out[ii][1].dot(self.beta[:, :, ii])
            self.betan[:, :,
                       ii] = cf.group_action_by_gamma_coord(btmp, out[ii][2])

        return
コード例 #6
0
def oc_elastic_prediction(beta, model, y=None):
    """
    This function identifies a regression model with phase-variablity
    using elastic methods

    :param beta: numpy ndarray of shape (M,N) of M functions with N samples
    :param model: identified model from elastic_regression
    :param y: truth, optional used to calculate SSE

    :rtype: tuple of numpy array
    :return alpha: alpha parameter of model
    :return beta: beta(t) of model
    :return fn: aligned functions - numpy ndarray of shape (M,N) of M
    functions with N samples
    :return qn: aligned srvfs - similar structure to fn
    :return gamma: calculated warping functions
    :return q: original training SRSFs
    :return B: basis matrix
    :return b: basis coefficients
    :return SSE: sum of squared error

    """
    T = model.q.shape[1]
    n = beta.shape[2]
    N = model.q.shape[2]

    q, beta = preproc_open_curve(beta, T)

    if model.type == 'oclinear' or model.type == 'oclogistic':
        y_pred = np.zeros(n)
    elif model.type == 'ocmlogistic':
        m = model.n_classes
        y_pred = np.zeros((n, m))

    for ii in range(0, n):
        diff = model.q - q[:, :, ii][:, :, np.newaxis]
        # dist = np.linalg.norm(np.abs(diff), axis=(0, 1)) ** 2
        dist = np.zeros(N)
        for jj in range(0, N):
            dist[jj] = np.linalg.norm(np.abs(diff[:, :, jj])) ** 2
        if model.type == 'oclinear' or model.type == 'oclogistic':
            # beta1 = cf.shift_f(beta[:, :, ii], int(model.tau[dist.argmin()]))
            beta1 = beta[:, :, ii]
        else:
            beta1 = beta[:, :, ii]
        beta1 = model.O[:, :, dist.argmin()].dot(beta1)
        beta1 = cf.group_action_by_gamma_coord(beta1,
                                               model.gamma[:, dist.argmin()])
        q_tmp = cf.curve_to_q(beta1)

        if model.type == 'oclinear':
            y_pred[ii] = model.alpha + cf.innerprod_q2(q_tmp, model.nu)
        elif model.type == 'oclogistic':
            y_pred[ii] = model.alpha + cf.innerprod_q2(q_tmp, model.nu)
        elif model.type == 'ocmlogistic':
            for jj in range(0, m):
                y_pred[ii, jj] = model.alpha[jj] + cf.innerprod_q2(q_tmp, model.nu[:, :, jj])

    if y is None:
        if model.type == 'oclinear':
            SSE = None
        elif model.type == 'oclogistic':
            y_pred = phi(y_pred)
            y_labels = np.ones(n)
            y_labels[y_pred < 0.5] = -1
            PC = None
        elif model.type == 'ocmlogistic':
            y_pred = phi(y_pred.ravel())
            y_pred = y_pred.reshape(n, m)
            y_labels = y_pred.argmax(axis=1) + 1
            PC = None
    else:
        if model.type == 'oclinear':
            SSE = sum((y - y_pred) ** 2)
        elif model.type == 'oclogistic':
            y_pred = phi(y_pred)
            y_labels = np.ones(n)
            y_labels[y_pred < 0.5] = -1
            TP = sum(y[y_labels == 1] == 1)
            FP = sum(y[y_labels == -1] == 1)
            TN = sum(y[y_labels == -1] == -1)
            FN = sum(y[y_labels == 1] == -1)
            PC = (TP + TN) / float(TP + FP + FN + TN)
        elif model.type == 'ocmlogistic':
            y_pred = phi(y_pred.ravel())
            y_pred = y_pred.reshape(n, m)
            y_labels = y_pred.argmax(axis=1) + 1
            PC = np.zeros(m)
            cls_set = np.arange(1, m + 1)
            for ii in range(0, m):
                cls_sub = np.delete(cls_set, ii)
                TP = sum(y[y_labels == (ii + 1)] == (ii + 1))
                FP = sum(y[np.in1d(y_labels, cls_sub)] == (ii + 1))
                TN = sum(y[np.in1d(y_labels, cls_sub)] ==
                         y_labels[np.in1d(y_labels, cls_sub)])
                FN = sum(np.in1d(y[y_labels == (ii + 1)], cls_sub))
                PC[ii] = (TP + TN) / float(TP + FP + FN + TN)

            PC = sum(y == y_labels) / float(y_labels.size)

    if model.type == 'oclinear':
        prediction = collections.namedtuple('prediction', ['y_pred', 'SSE'])
        out = prediction(y_pred, SSE)
    elif model.type == 'oclogistic':
        prediction = collections.namedtuple('prediction', ['y_prob',
                                                           'y_labels', 'PC'])
        out = prediction(y_pred, y_labels, PC)
    elif model.type == 'ocmlogistic':
        prediction = collections.namedtuple('prediction', ['y_prob',
                                                           'y_labels', 'PC'])
        out = prediction(y_pred, y_labels, PC)

    return out
コード例 #7
0
def oc_elastic_mlogistic(beta, y, B=None, df=20, T=100, max_itr=30, cores=-1,
                         deltaO=.003, deltag=.003):
    """
    This function identifies a multinomial logistic regression model with
    phase-variability using elastic methods for open curves

    :param beta: numpy ndarray of shape (n, M, N) describing N curves
    in R^M
    :param y: numpy array of labels {1,2,...,m} for m classes
    :param B: optional matrix describing Basis elements
    :param df: number of degrees of freedom B-spline (default 20)
    :param T: number of desired samples along curve (default 100)
    :param max_itr: maximum number of iterations (default 20)
    :param cores: number of cores for parallel processing (default all)
    :type beta: np.ndarray

    :rtype: tuple of numpy array
    :return alpha: alpha parameter of model
    :return nu: nu(t) of model
    :return betan: aligned curves - numpy ndarray of shape (n,T,N)
    :return O: calculated rotation matrices
    :return gamma: calculated warping functions
    :return B: basis matrix
    :return b: basis coefficients
    :return Loss: logistic loss

    """
    n = beta.shape[0]
    N = beta.shape[2]
    time = np.linspace(0, 1, T)

    if n > 500:
        parallel = True
    elif T > 100:
        parallel = True
    else:
        parallel = True

    # Code labels
    m = y.max()
    Y = np.zeros((N, m), dtype=int)
    for ii in range(0, N):
        Y[ii, y[ii] - 1] = 1

    # Create B-Spline Basis if none provided
    if B is None:
        B = bs(time, df=df, degree=4, include_intercept=True)
    Nb = B.shape[1]

    q, beta = preproc_open_curve(beta, T)
    qn = q.copy()
    beta0 = beta.copy()

    gamma = np.tile(np.linspace(0, 1, T), (N, 1))
    gamma = gamma.transpose()
    O_hat = np.tile(np.eye(n), (N, 1, 1)).T

    itr = 1
    LL = np.zeros(max_itr+1)
    while itr <= max_itr:
        print("Iteration: %d" % itr)

        Phi = np.ones((N, n * Nb + 1))
        for ii in range(0, N):
            for jj in range(0, n):
                for kk in range(1, Nb + 1):
                    Phi[ii, jj * Nb + kk] = trapz(qn[jj, :, ii] * B[:, kk - 1], time)

        # Find alpha and beta using l_bfgs
        b0 = np.zeros(m * (n * Nb + 1))
        out = fmin_l_bfgs_b(mlogit_loss, b0, fprime=mlogit_gradient,
                            args=(Phi, Y), pgtol=1e-10, maxiter=200,
                            maxfun=250, factr=1e-30)
        b = out[0]
        B0 = b.reshape(n * Nb + 1, m)
        alpha = B0[0, :]
        nu = np.zeros((n, T, m))
        for i in range(0, m):
            for j in range(0, n):
                nu[j, :, i] = B.dot(B0[(j * Nb + 1):((j + 1) * Nb + 1), i])

        # compute the logistic loss
        LL[itr] = mlogit_loss(b, Phi, Y)

        # find gamma
        gamma_new = np.zeros((T, N))
        if parallel:
            out = Parallel(n_jobs=cores)(delayed(mlogit_warp_grad)(alpha, nu, q[:, :, n], Y[n, :], deltaO=deltaO, deltag=deltag) for n in range(N))
            for ii in range(0, N):
                gamma_new[:, ii] = out[ii][0]
                beta1n = cf.group_action_by_gamma_coord(out[ii][1].dot(beta0[:, :, ii]), out[ii][0])
                beta[:, :, ii] = beta1n
                O_hat[:, :, ii] = out[ii][1]
                qn[:, :, ii] = cf.curve_to_q(beta[:, :, ii])
        else:
            for ii in range(0, N):
                gammatmp, Otmp = mlogit_warp_grad(alpha, nu, q[:, :, ii], Y[ii, :], deltaO=deltaO, deltag=deltag)
                gamma_new[:, ii] = gammatmp
                beta1n = cf.group_action_by_gamma_coord(Otmp.dot(beta0[:, :, ii]), gammatmp)
                beta[:, :, ii] = beta1n
                O_hat[:, :, ii] = Otmp
                qn[:, :, ii] = cf.curve_to_q(beta[:, :, ii])

        if norm(gamma - gamma_new) < 1e-5:
            break
        else:
            gamma = gamma_new.copy()

        itr += 1

    model = collections.namedtuple('model', ['alpha', 'nu', 'betan', 'q',
                                             'gamma', 'O', 'B', 'b',
                                             'Loss', 'n_classes', 'type'])
    out = model(alpha, nu, beta, q, gamma_new, O_hat, B, b[1:-1], LL[1:itr],
                m, 'ocmlogistic')
    return out
コード例 #8
0
def oc_elastic_regression(beta, y, B=None, df=40, T=200, max_itr=20, cores=-1):
    """
    This function identifies a regression model for open curves
    using elastic methods

    :param beta: numpy ndarray of shape (n, M, N) describing N curves
    in R^M
    :param y: numpy array of N responses
    :param B: optional matrix describing Basis elements
    :param df: number of degrees of freedom B-spline (default 20)
    :param T: number of desired samples along curve (default 100)
    :param max_itr: maximum number of iterations (default 20)
    :param cores: number of cores for parallel processing (default all)
    :type beta: np.ndarray

    :rtype: tuple of numpy array
    :return alpha: alpha parameter of model
    :return beta: beta(t) of model
    :return fn: aligned functions - numpy ndarray of shape (M,N) of M
    functions with N samples
    :return qn: aligned srvfs - similar structure to fn
    :return gamma: calculated warping functions
    :return q: original training SRSFs
    :return B: basis matrix
    :return b: basis coefficients
    :return SSE: sum of squared error

    """
    n = beta.shape[0]
    N = beta.shape[2]
    time = np.linspace(0, 1, T)

    if n > 500:
        parallel = True
    elif T > 100:
        parallel = True
    else:
        parallel = False

    # Create B-Spline Basis if none provided
    if B is None:
        B = bs(time, df=df, degree=4, include_intercept=True)
    Nb = B.shape[1]

    q, beta = preproc_open_curve(beta, T)
    beta0 = beta.copy()
    qn = q.copy()

    gamma = np.tile(np.linspace(0, 1, T), (N, 1))
    gamma = gamma.transpose()
    O_hat = np.tile(np.eye(n), (N, 1, 1)).T

    itr = 1
    SSE = np.zeros(max_itr)
    while itr <= max_itr:
        print("Iteration: %d" % itr)
        # align data

        # OLS using basis
        Phi = np.ones((N, n * Nb + 1))
        for ii in range(0, N):
            for jj in range(0, n):
                for kk in range(1, Nb + 1):
                    Phi[ii, jj * Nb + kk] = trapz(qn[jj, :, ii] * B[:, kk - 1], time)

        xx = dot(Phi.T, Phi)
        inv_xx = inv(xx)
        xy = dot(Phi.T, y)
        b = dot(inv_xx, xy)

        alpha = b[0]
        nu = np.zeros((n, T))
        for ii in range(0, n):
            nu[ii, :] = B.dot(b[(ii * Nb + 1):((ii + 1) * Nb + 1)])

        # compute the SSE
        int_X = np.zeros(N)
        for ii in range(0, N):
            int_X[ii] = cf.innerprod_q2(qn[:, :, ii], nu)

        SSE[itr - 1] = sum((y.reshape(N) - alpha - int_X) ** 2)

        # find gamma
        gamma_new = np.zeros((T, N))
        if parallel:
            out = Parallel(n_jobs=cores)(delayed(regression_warp)(nu, beta0[:, :, n], y[n], alpha) for n in range(N))
            for ii in range(0, N):
                gamma_new[:, ii] = out[ii][0]
                beta1n = cf.group_action_by_gamma_coord(out[ii][1].dot(beta0[:, :, ii]), out[ii][0])
                beta[:, :, ii] = beta1n
                O_hat[:, :, ii] = out[ii][1]
                qn[:, :, ii] = cf.curve_to_q(beta[:, :, ii])
        else:
            for ii in range(0, N):
                beta1 = beta0[:, :, ii]
                gammatmp, Otmp, tau = regression_warp(nu, beta1, y[ii], alpha)
                gamma_new[:, ii] = gammatmp
                beta1n = cf.group_action_by_gamma_coord(Otmp.dot(beta0[:, :, ii]), gammatmp)
                beta[:, :, ii] = beta1n
                O_hat[:, :, ii] = Otmp
                qn[:, :, ii] = cf.curve_to_q(beta[:, :, ii])


        if np.abs(SSE[itr - 1] - SSE[itr - 2]) < 1e-15:
            break
        else:
            gamma = gamma_new

        itr += 1

    tau = np.zeros(N)

    model = collections.namedtuple('model', ['alpha', 'nu', 'betan' 'q', 'gamma',
                                             'O', 'tau', 'B', 'b', 'SSE', 'type'])
    out = model(alpha, nu, beta, q, gamma, O_hat, tau, B, b[1:-1], SSE[0:itr], 'oclinear')
    return out
コード例 #9
0
def oc_elastic_logistic(beta, y, B=None, df=60, T=100, max_itr=40, cores=-1,
                        deltaO=.1, deltag=.05, method=1):
    """
    This function identifies a logistic regression model with
    phase-variablity using elastic methods for open curves

    :param beta: numpy ndarray of shape (n, M, N) describing N curves
    in R^M
    :param y: numpy array of N responses
    :param B: optional matrix describing Basis elements
    :param df: number of degrees of freedom B-spline (default 20)
    :param T: number of desired samples along curve (default 100)
    :param max_itr: maximum number of iterations (default 20)
    :param cores: number of cores for parallel processing (default all)
    :type beta: np.ndarray

    :rtype: tuple of numpy array
    :return alpha: alpha parameter of model
    :return nu: nu(t) of model
    :return betan: aligned curves - numpy ndarray of shape (n,T,N)
    :return O: calulated rotation matrices
    :return gamma: calculated warping functions
    :return B: basis matrix
    :return b: basis coefficients
    :return Loss: logistic loss

    """
    n = beta.shape[0]
    N = beta.shape[2]
    time = np.linspace(0, 1, T)

    if n > 500:
        parallel = True
    elif T > 100:
        parallel = True
    else:
        parallel = True

    # Create B-Spline Basis if none provided
    if B is None:
        B = bs(time, df=df, degree=4, include_intercept=True)
    Nb = B.shape[1]

    q, beta = preproc_open_curve(beta, T)
    beta0 = beta.copy()
    qn = q.copy()

    gamma = np.tile(np.linspace(0, 1, T), (N, 1))
    gamma = gamma.transpose()
    O_hat = np.tile(np.eye(n), (N, 1, 1)).T

    itr = 1
    LL = np.zeros(max_itr + 1)
    while itr <= max_itr:
        print("Iteration: %d" % itr)

        Phi = np.ones((N, n * Nb + 1))
        for ii in range(0, N):
            for jj in range(0, n):
                for kk in range(1, Nb + 1):
                    Phi[ii, jj * Nb + kk] = trapz(qn[jj, :, ii] * B[:, kk - 1], time)

        # Find alpha and beta using l_bfgs
        b0 = np.zeros(n * Nb + 1)
        out = fmin_l_bfgs_b(logit_loss, b0, fprime=logit_gradient,
                            args=(Phi, y), pgtol=1e-10, maxiter=200,
                            maxfun=250, factr=1e-30)
        b = out[0]
        b = b/norm(b)
        # alpha_norm = b1[0]
        alpha = b[0]
        nu = np.zeros((n, T))
        for ii in range(0, n):
            nu[ii, :] = B.dot(b[(ii * Nb + 1):((ii + 1) * Nb + 1)])

        # compute the logistic loss
        LL[itr] = logit_loss(b, Phi, y)

        # find gamma
        gamma_new = np.zeros((T, N))
        if parallel:
            out = Parallel(n_jobs=cores)(delayed(logistic_warp)(alpha, nu, q[:, :, ii], y[ii], deltaO=deltaO, deltag=deltag, method=method) for ii in range(N))
            for ii in range(0, N):
                gamma_new[:, ii] = out[ii][0]
                beta1n = cf.group_action_by_gamma_coord(out[ii][1].dot(beta0[:, :, ii]), out[ii][0])
                beta[:, :, ii] = beta1n
                O_hat[:, :, ii] = out[ii][1]
                if np.isinf(beta1n).any() or np.isnan(beta1n).any():
                    Tracer()()
                qn[:, :, ii] = cf.curve_to_q(beta[:, :, ii])
        else:
            for ii in range(0, N):
                q1 = q[:, :, ii]
                gammatmp, Otmp, tautmp = logistic_warp(alpha, nu, q1, y[ii],deltaO=deltaO, deltag=deltag, method=method)
                gamma_new[:, ii] = gammatmp
                beta1n = cf.group_action_by_gamma_coord(Otmp.dot(beta0[:, :, ii]), gammatmp)
                beta[:, :, ii] = beta1n
                O_hat[:, :, ii] = Otmp
                qn[:, :, ii] = cf.curve_to_q(beta[:, :, ii])

        if norm(gamma - gamma_new) < 1e-5:
            break
        else:
            gamma = gamma_new.copy()

        itr += 1

    tau = np.zeros(N)

    model = collections.namedtuple('model', ['alpha', 'nu', 'betan', 'q',
                                             'gamma', 'O', 'tau', 'B', 'b', 'Loss',
                                             'type'])
    out = model(alpha, nu, beta, q, gamma_new, O_hat, tau, B, b[1:-1],
                LL[1:itr], 'oclogistic')
    return out
コード例 #10
0
    def calc_model(self, B=None, lam=0, df=40, T=200, max_itr=20, cores=-1):
        """
        This function identifies a regression model for open curves
        using elastic methods

        :param B: optional matrix describing Basis elements
        :param lam: regularization parameter (default 0)
        :param df: number of degrees of freedom B-spline (default 20)
        :param T: number of desired samples along curve (default 100)
        :param max_itr: maximum number of iterations (default 20)
        :param cores: number of cores for parallel processing (default all)
        """
        n = self.beta.shape[0]
        N = self.beta.shape[2]
        time = np.linspace(0, 1, T)

        if n > 500:
            parallel = True
        elif T > 100:
            parallel = True
        else:
            parallel = False

        binsize = np.diff(time)
        binsize = binsize.mean()

        # Create B-Spline Basis if none provided
        if B is None:
            B = bs(time, df=df, degree=4, include_intercept=True)
        Nb = B.shape[1]

        # second derivative for regularization
        Bdiff = np.zeros((T, Nb))
        for ii in range(0, Nb):
            Bdiff[:, ii] = np.gradient(np.gradient(B[:, ii], binsize), binsize)

        q, beta = preproc_open_curve(self.beta, T)
        self.q = q
        beta0 = beta.copy()
        qn = q.copy()

        gamma = np.tile(np.linspace(0, 1, T), (N, 1))
        gamma = gamma.transpose()
        O_hat = np.tile(np.eye(n), (N, 1, 1)).T

        itr = 1
        self.SSE = np.zeros(max_itr)
        while itr <= max_itr:
            print("Iteration: %d" % itr)
            # align data

            # OLS using basis
            Phi = np.ones((N, n * Nb + 1))
            for ii in range(0, N):
                for jj in range(0, n):
                    for kk in range(1, Nb + 1):
                        Phi[ii,
                            jj * Nb + kk] = trapz(qn[jj, :, ii] * B[:, kk - 1],
                                                  time)

            R = np.zeros((n * Nb + 1, n * Nb + 1))
            for kk in range(0, n):
                for ii in range(1, Nb + 1):
                    for jj in range(1, Nb + 1):
                        R[kk * Nb + ii, kk * Nb + jj] = trapz(
                            Bdiff[:, ii - 1] * Bdiff[:, jj - 1], time)

            xx = np.dot(Phi.T, Phi)
            inv_xx = inv(xx + lam * R)
            xy = np.dot(Phi.T, self.y)
            b = np.dot(inv_xx, xy)

            alpha = b[0]
            nu = np.zeros((n, T))
            for ii in range(0, n):
                nu[ii, :] = B.dot(b[(ii * Nb + 1):((ii + 1) * Nb + 1)])

            # compute the SSE
            int_X = np.zeros(N)
            for ii in range(0, N):
                int_X[ii] = cf.innerprod_q2(qn[:, :, ii], nu)

            self.SSE[itr - 1] = sum((self.y.reshape(N) - alpha - int_X)**2)

            # find gamma
            gamma_new = np.zeros((T, N))
            if parallel:
                out = Parallel(n_jobs=cores)(
                    delayed(regression_warp)(nu, q[:, :, n], self.y[n], alpha)
                    for n in range(N))
                for ii in range(0, N):
                    gamma_new[:, ii] = out[ii][0]
                    beta1n = cf.group_action_by_gamma_coord(
                        out[ii][1].dot(beta0[:, :, ii]), out[ii][0])
                    beta[:, :, ii] = beta1n
                    O_hat[:, :, ii] = out[ii][1]
                    qn[:, :, ii] = cf.curve_to_q(beta1n)[0]
            else:
                for ii in range(0, N):
                    q1 = q[:, :, ii]
                    gammatmp, Otmp = regression_warp(nu, q1, self.y[ii], alpha)
                    gamma_new[:, ii] = gammatmp
                    beta1n = cf.group_action_by_gamma_coord(
                        Otmp.dot(beta0[:, :, ii]), gammatmp)
                    beta[:, :, ii] = beta1n
                    O_hat[:, :, ii] = Otmp
                    qn[:, :, ii] = cf.curve_to_q(beta1n)[0]

            if np.abs(self.SSE[itr - 1] - self.SSE[itr - 2]) < 1e-15:
                break
            else:
                gamma = gamma_new

            itr += 1

        tau = np.zeros(N)
        self.alpha = alpha
        self.nu = nu
        self.beta0 = beta0
        self.betan = beta
        self.gamma = gamma
        self.qn = qn
        self.B = B
        self.O = O_hat
        self.b = b[1:-1]
        self.SSE = self.SSE[0:itr]

        return
コード例 #11
0
    def calc_model(self,
                   B=None,
                   df=20,
                   T=100,
                   max_itr=30,
                   cores=-1,
                   deltaO=.003,
                   deltag=.003):
        """
        This function identifies a multinomial logistic regression model with
        phase-variability using elastic methods for open curves

        :param B: optional matrix describing Basis elements
        :param df: number of degrees of freedom B-spline (default 20)
        :param T: number of desired samples along curve (default 100)
        :param max_itr: maximum number of iterations (default 20)
        :param cores: number of cores for parallel processing (default all)

        """
        n = self.beta.shape[0]
        N = self.beta.shape[2]
        time = np.linspace(0, 1, T)
        m = self.y.max()

        if n > 500:
            parallel = True
        elif T > 100:
            parallel = True
        else:
            parallel = True

        # Create B-Spline Basis if none provided
        if B is None:
            B = bs(time, df=df, degree=4, include_intercept=True)
        Nb = B.shape[1]

        q, beta = preproc_open_curve(self.beta, T)
        qn = q.copy()
        beta0 = beta.copy()

        gamma = np.tile(np.linspace(0, 1, T), (N, 1))
        gamma = gamma.transpose()
        O_hat = np.tile(np.eye(n), (N, 1, 1)).T

        itr = 1
        LL = np.zeros(max_itr + 1)
        while itr <= max_itr:
            print("Iteration: %d" % itr)

            Phi = np.ones((N, n * Nb + 1))
            for ii in range(0, N):
                for jj in range(0, n):
                    for kk in range(1, Nb + 1):
                        Phi[ii,
                            jj * Nb + kk] = trapz(qn[jj, :, ii] * B[:, kk - 1],
                                                  time)

            # Find alpha and beta using l_bfgs
            b0 = np.zeros(m * (n * Nb + 1))
            out = fmin_l_bfgs_b(mlogit_loss,
                                b0,
                                fprime=mlogit_gradient,
                                args=(Phi, self.Y),
                                pgtol=1e-10,
                                maxiter=200,
                                maxfun=250,
                                factr=1e-30)
            b = out[0]
            B0 = b.reshape(n * Nb + 1, m)
            alpha = B0[0, :]
            nu = np.zeros((n, T, m))
            for i in range(0, m):
                for j in range(0, n):
                    nu[j, :, i] = B.dot(B0[(j * Nb + 1):((j + 1) * Nb + 1), i])

            # compute the logistic loss
            LL[itr] = mlogit_loss(b, Phi, self.Y)

            # find gamma
            gamma_new = np.zeros((T, N))
            if parallel:
                out = Parallel(n_jobs=cores)(
                    delayed(mlogit_warp_grad)(alpha,
                                              nu,
                                              q[:, :, n],
                                              self.Y[n, :],
                                              deltaO=deltaO,
                                              deltag=deltag) for n in range(N))
                for ii in range(0, N):
                    gamma_new[:, ii] = out[ii][0]
                    beta1n = cf.group_action_by_gamma_coord(
                        out[ii][1].dot(beta0[:, :, ii]), out[ii][0])
                    beta[:, :, ii] = beta1n
                    O_hat[:, :, ii] = out[ii][1]
                    qn[:, :, ii] = cf.curve_to_q(beta[:, :, ii])[0]
            else:
                for ii in range(0, N):
                    gammatmp, Otmp = mlogit_warp_grad(alpha,
                                                      nu,
                                                      q[:, :, ii],
                                                      self.Y[ii, :],
                                                      deltaO=deltaO,
                                                      deltag=deltag)
                    gamma_new[:, ii] = gammatmp
                    beta1n = cf.group_action_by_gamma_coord(
                        Otmp.dot(beta0[:, :, ii]), gammatmp)
                    beta[:, :, ii] = beta1n
                    O_hat[:, :, ii] = Otmp
                    qn[:, :, ii] = cf.curve_to_q(beta[:, :, ii])[0]

            if norm(gamma - gamma_new) < 1e-5:
                break
            else:
                gamma = gamma_new.copy()

            itr += 1

        self.alpha = alpha
        self.nu = nu
        self.beta0 = beta0
        self.betan = beta
        self.q = q
        self.qn = qn
        self.gamma = gamma_new
        self.O = O_hat
        self.B = B
        self.b = b[1:-1]
        self.Loss = LL[1:itr]
        self.n_classes = m

        return
コード例 #12
0
    def predict(self, newdata=None):
        """
        This function performs prediction on regression model on new data if available or current stored data in object
        Usage:  obj.predict()
                obj.predict(newdata)

        :param newdata: dict containing new data for prediction (needs the keys below, if None predicts on training data)
        :type newdata: dict
        :param beta: numpy ndarray of shape (M,N) of M functions with N samples
        :param y: truth if available
        """

        if newdata != None:
            beta = newdata['beta']
            y = newdata['y']

            T = self.q.shape[1]
            n = beta.shape[2]
            N = self.q.shape[2]

            q, beta = preproc_open_curve(beta, T)

            y_pred = np.zeros(n)
            for ii in range(0, n):
                diff = self.q - q[:, :, ii][:, :, np.newaxis]
                dist = np.zeros(N)
                for jj in range(0, N):
                    dist[jj] = np.linalg.norm(np.abs(diff[:, :, jj]))**2
                beta1 = beta[:, :, ii]
                beta1 = self.O[:, :, dist.argmin()].dot(beta1)
                beta1 = cf.group_action_by_gamma_coord(
                    beta1, self.gamma[:, dist.argmin()])
                q_tmp = cf.curve_to_q(beta1)[0]

                y_pred[ii] = self.alpha + cf.innerprod_q2(q_tmp, self.nu)

            if y is None:
                y_pred = phi(y_pred)
                y_labels = np.ones(n)
                y_labels[y_pred < 0.5] = -1
                self.PC = None
            else:
                y_pred = phi(y_pred)
                y_labels = np.ones(n)
                y_labels[y_pred < 0.5] = -1
                TP = sum(y[y_labels == 1] == 1)
                FP = sum(y[y_labels == -1] == 1)
                TN = sum(y[y_labels == -1] == -1)
                FN = sum(y[y_labels == 1] == -1)
                self.PC = (TP + TN) / float(TP + FP + FN + TN)

            self.y_pred = y_pred
            self.y_labels = y_labels

        else:
            n = self.q.shape[2]
            N = self.q.shape[2]
            y_pred = np.zeros(n)
            for ii in range(0, n):
                diff = self.q - self.q[:, :, ii][:, :, np.newaxis]
                dist = np.zeros(N)
                for jj in range(0, N):
                    dist[jj] = np.linalg.norm(np.abs(diff[:, :, jj]))**2
                beta1 = self.beta0[:, :, ii]
                beta1 = self.O[:, :, dist.argmin()].dot(beta1)
                beta1 = cf.group_action_by_gamma_coord(
                    beta1, self.gamma[:, dist.argmin()])
                q_tmp = cf.curve_to_q(beta1)[0]

                y_pred[ii] = self.alpha + cf.innerprod_q2(q_tmp, self.nu)

            y_pred = phi(y_pred)
            y_labels = np.ones(n)
            y_labels[y_pred < 0.5] = -1
            TP = sum(self.y[y_labels == 1] == 1)
            FP = sum(self.y[y_labels == -1] == 1)
            TN = sum(self.y[y_labels == -1] == -1)
            FN = sum(self.y[y_labels == 1] == -1)
            self.PC = (TP + TN) / float(TP + FP + FN + TN)

            self.y_pred = y_pred
            self.y_labels = y_labels

        return
コード例 #13
0
ファイル: geodesic.py プロジェクト: glemaitre/fdasrsf
def init_path_rand(beta1, beta_mid, beta2, T=100, k=5):
    """
    Initializes a path in \cal{C}. beta1, beta_mid beta2 are already
    standardized curves. Creates a path from beta1 to beta_mid to beta2 in
    shape space, then projects to the closed shape manifold.

    :param beta1: numpy ndarray of shape (2,M) of M samples (first curve)
    :param betamid: numpy ndarray of shape (2,M) of M samples (mid curve)
    :param beta2: numpy ndarray of shape (2,M) of M samples (end curve)
    :param T: Number of samples of curve (Default = 100)
    :param k: number of samples along path (Default = 5)

    :rtype: numpy ndarray
    :return alpha: a path between two q-functions
    :return beta:  a path between two curves
    :return O: rotation matrix

    """
    alpha = zeros((2, T, k))
    beta = zeros((2, T, k))

    q1 = cf.curve_to_q(beta1)
    q_mid = cf.curve_to_q(beta_mid)

    # find optimal rotation of q2
    beta2, O1, tau1 = cf.find_rotation_and_seed_coord(beta1, beta2)
    q2 = cf.curve_to_q(beta2)

    # find the optimal coorespondence
    gam = cf.optimum_reparam_curve(q2, q1)
    gamI = uf.invertGamma(gam)

    # apply optimal reparametrization
    beta2n = cf.group_action_by_gamma_coord(beta2, gamI)

    # find optimal rotation of q2
    beta2n, O2, tau1 = cf.find_rotation_and_seed_coord(beta1, beta2n)
    centroid2 = cf.calculatecentroid(beta2n)
    beta2n = beta2n - tile(centroid2, [T, 1]).T
    q2n = cf.curve_to_q(beta2n)
    O = O1.dot(O2)

    # Initialize a path as a geodesic through q1 --- q_mid --- q2
    theta1 = arccos(cf.innerprod_q2(q1, q_mid))
    theta2 = arccos(cf.innerprod_q2(q_mid, q2n))
    tmp = arange(2, int((k - 1) / 2) + 1)
    t = zeros(tmp.size)
    alpha[:, :, 0] = q1
    beta[:, :, 0] = beta1

    i = 0
    for tau in range(2, int((k - 1) / 2) + 1):
        t[i] = (tau - 1.0) / ((k - 1) / 2.0)
        qnew = (1 / sin(theta1)) * (sin((1 - t[i]) * theta1) * q1 + sin(t[i] * theta1) * q_mid)
        alpha[:, :, tau - 1] = cf.project_curve(qnew)
        x = cf.q_to_curve(alpha[:, :, tau - 1])
        a = -1 * cf.calculatecentroid(x)
        beta[:, :, tau - 1] = x + tile(a, [T, 1]).T
        i += 1

    alpha[:, :, int((k - 1) / 2)] = q_mid
    beta[:, :, int((k - 1) / 2)] = beta_mid

    i = 0
    for tau in range(int((k - 1) / 2) + 1, k - 1):
        qnew = (1 / sin(theta2)) * (sin((1 - t[i]) * theta2) * q_mid + sin(t[i] * theta2) * q2n)
        alpha[:, :, tau] = cf.project_curve(qnew)
        x = cf.q_to_curve(alpha[:, :, tau])
        a = -1 * cf.calculatecentroid(x)
        beta[:, :, tau] = x + tile(a, [T, 1]).T
        i += 1

    alpha[:, :, k - 1] = q2n
    beta[:, :, k - 1] = beta2n

    return (alpha, beta, O)
コード例 #14
0
ファイル: geodesic.py プロジェクト: glemaitre/fdasrsf
def geod_sphere(beta1, beta2, k=5):
    """
    This function caluclates the geodecis between open curves beta1 and
    beta2 with k steps along path

    :param beta1: numpy ndarray of shape (2,M) of M samples
    :param beta2: numpy ndarray of shape (2,M) of M samples
    :param k: number of samples along path (Default = 5)

    :rtype: numpy ndarray
    :return dist: geodesic distance
    :return path: geodesic path
    :return O: rotation matrix

    """
    lam = 0.0
    elastic = 1
    rotation = 1
    returnpath = 1
    n, T = beta1.shape

    beta1 = cf.resamplecurve(beta1, T)
    beta2 = cf.resamplecurve(beta2, T)

    centroid1 = cf.calculatecentroid(beta1)
    beta1 = beta1 - tile(centroid1, [T, 1]).T
    centroid2 = cf.calculatecentroid(beta2)
    beta2 = beta2 - tile(centroid2, [T, 1]).T

    q1 = cf.curve_to_q(beta1)
    if rotation:
        beta2, O1, tau = cf.find_rotation_and_seed_coord(beta1, beta2)
        q2 = cf.curve_to_q(beta2)
    else:
        O1 = eye(2)
        q2 = cf.curve_to_q(beta2)

    if elastic:
        # Find the optimal coorespondence
        gam = cf.optimum_reparam_curve(q2, q1, lam)
        gamI = uf.invertGamma(gam)
        # Applying optimal re-parameterization to the second curve
        beta2n = cf.group_action_by_gamma_coord(beta2, gamI)
        q2n = cf.curve_to_q(beta2n)

        if rotation:
            beta2n, O2, tau = cf.find_rotation_and_seed_coord(beta1, beta2n)
            centroid2 = cf.calculatecentroid(beta2n)
            beta2n = beta2n - tile(centroid2, [T, 1]).T
            q2n = cf.curve_to_q(beta2n)
            O = O1.dot(O2)
    else:
        q2n = q2
        O = O1

    # Forming geodesic between the registered curves
    dist = arccos(cf.innerprod_q2(q1, q2n))

    if returnpath:
        PsiQ = zeros((n, T, k))
        PsiX = zeros((n, T, k))
        for tau in range(0, k):
            s = dist * tau / (k - 1.0)
            PsiQ[:, :, tau] = (sin(dist - s) * q1 + sin(s) * q2n) / sin(dist)
            PsiX[:, :, tau] = cf.q_to_curve(PsiQ[:, :, tau])

        path = PsiQ
    else:
        path = 0

    return (dist, path, O)
コード例 #15
0
def geod_sphere(beta1, beta2, k=5):
    """
    This function calculates the geodesics between open curves beta1 and
    beta2 with k steps along path

    :param beta1: numpy ndarray of shape (2,M) of M samples
    :param beta2: numpy ndarray of shape (2,M) of M samples
    :param k: number of samples along path (Default = 5)

    :rtype: numpy ndarray
    :return dist: geodesic distance
    :return path: geodesic path
    :return O: rotation matrix

    """
    lam = 0.0
    elastic = 1
    rotation = 1
    returnpath = 1
    n, T = beta1.shape

    beta1 = cf.resamplecurve(beta1, T)
    beta2 = cf.resamplecurve(beta2, T)

    centroid1 = cf.calculatecentroid(beta1)
    beta1 = beta1 - tile(centroid1, [T, 1]).T
    centroid2 = cf.calculatecentroid(beta2)
    beta2 = beta2 - tile(centroid2, [T, 1]).T

    q1 = cf.curve_to_q(beta1)
    if rotation:
        beta2, O1, tau = cf.find_rotation_and_seed_coord(beta1, beta2)
        q2 = cf.curve_to_q(beta2)
    else:
        O1 = eye(2)
        q2 = cf.curve_to_q(beta2)

    if elastic:
        # Find the optimal coorespondence
        gam = cf.optimum_reparam_curve(q2, q1, lam)
        gamI = uf.invertGamma(gam)
        # Applying optimal re-parameterization to the second curve
        beta2n = cf.group_action_by_gamma_coord(beta2, gamI)
        q2n = cf.curve_to_q(beta2n)

        if rotation:
            beta2n, O2, tau = cf.find_rotation_and_seed_coord(beta1, beta2n)
            centroid2 = cf.calculatecentroid(beta2n)
            beta2n = beta2n - tile(centroid2, [T, 1]).T
            q2n = cf.curve_to_q(beta2n)
            O = O1.dot(O2)
    else:
        q2n = q2
        O = O1

    # Forming geodesic between the registered curves
    dist = arccos(cf.innerprod_q2(q1, q2n))

    if returnpath:
        PsiQ = zeros((n, T, k))
        PsiX = zeros((n, T, k))
        for tau in range(0, k):
            s = dist * tau / (k - 1.)
            PsiQ[:, :, tau] = (sin(dist-s)*q1+sin(s)*q2n)/sin(dist)
            PsiX[:, :, tau] = cf.q_to_curve(PsiQ[:, :, tau])

        path = PsiQ
    else:
        path = 0

    return(dist, path, O)
コード例 #16
0
def init_path_rand(beta1, beta_mid, beta2, T=100, k=5):
    r"""
    Initializes a path in :math:`\cal{C}`. beta1, beta_mid beta2 are already
    standardized curves. Creates a path from beta1 to beta_mid to beta2 in
    shape space, then projects to the closed shape manifold.

    :param beta1: numpy ndarray of shape (2,M) of M samples (first curve)
    :param betamid: numpy ndarray of shape (2,M) of M samples (mid curve)
    :param beta2: numpy ndarray of shape (2,M) of M samples (end curve)
    :param T: Number of samples of curve (Default = 100)
    :param k: number of samples along path (Default = 5)

    :rtype: numpy ndarray
    :return alpha: a path between two q-functions
    :return beta:  a path between two curves
    :return O: rotation matrix

    """
    alpha = zeros((2, T, k))
    beta = zeros((2, T, k))

    q1 = cf.curve_to_q(beta1)
    q_mid = cf.curve_to_q(beta_mid)

    # find optimal rotation of q2
    beta2, O1, tau1 = cf.find_rotation_and_seed_coord(beta1, beta2)
    q2 = cf.curve_to_q(beta2)

    # find the optimal coorespondence
    gam = cf.optimum_reparam_curve(q2, q1)
    gamI = uf.invertGamma(gam)

    # apply optimal reparametrization
    beta2n = cf.group_action_by_gamma_coord(beta2, gamI)

    # find optimal rotation of q2
    beta2n, O2, tau1 = cf.find_rotation_and_seed_coord(beta1, beta2n)
    centroid2 = cf.calculatecentroid(beta2n)
    beta2n = beta2n - tile(centroid2, [T, 1]).T
    q2n = cf.curve_to_q(beta2n)
    O = O1.dot(O2)

    # Initialize a path as a geodesic through q1 --- q_mid --- q2
    theta1 = arccos(cf.innerprod_q2(q1, q_mid))
    theta2 = arccos(cf.innerprod_q2(q_mid, q2n))
    tmp = arange(2, int((k-1)/2)+1)
    t = zeros(tmp.size)
    alpha[:, :, 0] = q1
    beta[:, :, 0] = beta1

    i = 0
    for tau in range(2, int((k-1)/2)+1):
        t[i] = (tau-1.)/((k-1)/2.)
        qnew = (1/sin(theta1))*(sin((1-t[i])*theta1)*q1+sin(t[i]*theta1)*q_mid)
        alpha[:, :, tau-1] = cf.project_curve(qnew)
        x = cf.q_to_curve(alpha[:, :, tau-1])
        a = -1*cf.calculatecentroid(x)
        beta[:, :, tau-1] = x + tile(a, [T, 1]).T
        i += 1

    alpha[:, :, int((k-1)/2)] = q_mid
    beta[:, :, int((k-1)/2)] = beta_mid

    i = 0
    for tau in range(int((k-1)/2)+1, k-1):
        qnew = (1/sin(theta2))*(sin((1-t[i])*theta2)*q_mid
                                + sin(t[i]*theta2)*q2n)
        alpha[:, :, tau] = cf.project_curve(qnew)
        x = cf.q_to_curve(alpha[:, :, tau])
        a = -1*cf.calculatecentroid(x)
        beta[:, :, tau] = x + tile(a, [T, 1]).T
        i += 1

    alpha[:, :, k-1] = q2n
    beta[:, :, k-1] = beta2n

    return(alpha, beta, O)
コード例 #17
0
    def predict(self, newdata=None):
        """
        This function performs prediction on regression model on new data if available or current stored data in object
        Usage:  obj.predict()
                obj.predict(newdata)

        :param newdata: dict containing new data for prediction (needs the keys below, if None predicts on training data)
        :type newdata: dict
        :param beta: numpy ndarray of shape (M,N) of M functions with N samples
        :param y: truth if available
        """

        if newdata != None:
            beta = newdata['beta']
            y = newdata['y']

            T = self.q.shape[1]
            n = beta.shape[2]
            N = self.q.shape[2]

            q, beta = preproc_open_curve(beta, T)

            m = self.n_classes
            y_pred = np.zeros((n, m))
            for ii in range(0, n):
                diff = self.q - q[:, :, ii][:, :, np.newaxis]
                dist = np.zeros(N)
                for jj in range(0, N):
                    dist[jj] = np.linalg.norm(np.abs(diff[:, :, jj]))**2
                beta1 = beta[:, :, ii]
                beta1 = self.O[:, :, dist.argmin()].dot(beta1)
                beta1 = cf.group_action_by_gamma_coord(
                    beta1, self.gamma[:, dist.argmin()])
                q_tmp = cf.curve_to_q(beta1)[0]

                for jj in range(0, m):
                    y_pred[ii, jj] = self.alpha[jj] + cf.innerprod_q2(
                        q_tmp, self.nu[:, :, jj])

            if y is None:
                y_pred = phi(y_pred.ravel())
                y_pred = y_pred.reshape(n, m)
                y_labels = y_pred.argmax(axis=1) + 1
                self.PC = None
            else:
                y_pred = phi(y_pred.ravel())
                y_pred = y_pred.reshape(n, m)
                y_labels = y_pred.argmax(axis=1) + 1
                PC = np.zeros(m)
                cls_set = np.arange(1, m + 1)
                for ii in range(0, m):
                    cls_sub = np.delete(cls_set, ii)
                    TP = sum(y[y_labels == (ii + 1)] == (ii + 1))
                    FP = sum(y[np.in1d(y_labels, cls_sub)] == (ii + 1))
                    TN = sum(y[np.in1d(y_labels, cls_sub)] == y_labels[np.in1d(
                        y_labels, cls_sub)])
                    FN = sum(np.in1d(y[y_labels == (ii + 1)], cls_sub))
                    PC[ii] = (TP + TN) / float(TP + FP + FN + TN)

                self.PC = sum(y == y_labels) / float(y_labels.size)

            self.y_pred = y_pred
            self.y_labels = y_labels

        else:
            n = self.q.shape[2]
            N = self.q.shape[2]
            m = self.n_classes
            y_pred = np.zeros((n, m))
            for ii in range(0, n):
                diff = self.q - self.q[:, :, ii][:, :, np.newaxis]
                dist = np.zeros(N)
                for jj in range(0, N):
                    dist[jj] = np.linalg.norm(np.abs(diff[:, :, jj]))**2
                beta1 = self.beta0[:, :, ii]
                beta1 = self.O[:, :, dist.argmin()].dot(beta1)
                beta1 = cf.group_action_by_gamma_coord(
                    beta1, self.gamma[:, dist.argmin()])
                q_tmp = cf.curve_to_q(beta1)[0]

                for jj in range(0, m):
                    y_pred[ii, jj] = self.alpha[jj] + cf.innerprod_q2(
                        q_tmp, self.nu[:, :, jj])

            y_pred = phi(y_pred.ravel())
            y_pred = y_pred.reshape(n, m)
            y_labels = y_pred.argmax(axis=1) + 1
            PC = np.zeros(m)
            cls_set = np.arange(1, m + 1)
            for ii in range(0, m):
                cls_sub = np.delete(cls_set, ii)
                TP = sum(y[y_labels == (ii + 1)] == (ii + 1))
                FP = sum(y[np.in1d(y_labels, cls_sub)] == (ii + 1))
                TN = sum(y[np.in1d(y_labels, cls_sub)] == y_labels[np.in1d(
                    y_labels, cls_sub)])
                FN = sum(np.in1d(y[y_labels == (ii + 1)], cls_sub))
                PC[ii] = (TP + TN) / float(TP + FP + FN + TN)

            self.PC = sum(self.y == y_labels) / float(y_labels.size)

            self.y_pred = y_pred
            self.y_labels = y_labels

        return