예제 #1
0
    def objective(params):
        # increase_count_by_one()
        feature_hyparams = params[:-1]
        scale_hyparams = params[-1]

        temporal_prior.set_hhparameters(1.)

        for fi, feature_prior in enumerate(feature_priors[1:]):
            feature_prior.set_hyparams(feature_hyparams[fi])

        # does not affect
        feature_priors[0].set_hyparams(1.)
        res = models.crossval_stem_wmvnp(
            features_train,
            responses_train,
            ridges=np.asarray([scale_hyparams]),
            normalize_kernel=False,
            temporal_prior=temporal_prior,
            feature_priors=feature_priors,
            folds=(2, 5),
            method='SVD',
            verbosity=2,
        )
        cvres = res['cvresults'].mean(0).mean(-1).mean()
        print('features:', feature_hyparams)
        print('ridges:', scale_hyparams)
        print(res['spatial'], res['temporal'], res['ridges'])
        print(cvres)
        return (1 - cvres)**2
예제 #2
0
def test_stmvn_prior(method='SVD'):
    ridges = np.logspace(0,1,5)
    nridges = len(ridges)
    ndelays = 10
    delays = range(ndelays)

    features_train, features_test, responses_train, responses_test = get_abc_data()
    features_sizes = [fs.shape[1] for fs in features_train]

    spatial_priors = [sps.SphericalPrior(features_sizes[0]),
                      sps.SphericalPrior(features_sizes[1], hyparams=np.logspace(-3,3,7)),
                      sps.SphericalPrior(features_sizes[2], hyparams=np.logspace(-3,3,7)),
                      ]

    # do not scale first. this removes duplicates
    spatial_priors[0].set_hyparams(1.0)

    # non-diagonal hyper-prior
    W = np.random.randn(ndelays, ndelays)
    W = np.dot(W.T, W)

    tpriors = [tps.SphericalPrior(delays),
               tps.GaussianKernelPrior(delays, hhparams=np.linspace(1,ndelays/2,ndelays)),
               tps.SmoothnessPrior(delays, hhparams=np.logspace(-3,1,2)),
               tps.SmoothnessPrior(delays, wishart=W, hhparams=np.logspace(-3,3,5)),
               tps.SmoothnessPrior(delays, wishart=True),
               tps.SmoothnessPrior(delays, wishart=False),
               tps.HRFPrior([1] if delays == [0] else delays),
               ]

    from tikreg import models

    res = models.crossval_stem_wmvnp(features_train,
                                     responses_train,
                                     temporal_prior=tpriors[2],
                                     feature_priors=spatial_priors,
                                     folds=(1,5),
                                     ridges=ridges,
                                     verbosity=1,
                                     method=method,
                                     )

    # find optima
    cvmean = res['cvresults'].mean(0)
    population_optimal = False
    if population_optimal is True:
        cvmean = np.nan_to_num(cvmean).mean(-1)[...,None]

    for idx in range(cvmean.shape[-1]):
        tpopt, spopt, ropt = models.find_optimum_mvn(cvmean[...,idx],
                                                     res['temporal'],
                                                     res['spatial'],
                                                     res['ridges'],
                                                     )
        txt = "temporal=%0.03f, spatial=(%0.03f,%0.03f, %0.03f), ridge=%0.03f"
        content = tuple([tpopt])+tuple(spopt)+tuple([ropt])
        print(txt % content)
    return res
예제 #3
0
def test_general_solution(temporal_prior_name='spherical'):
    tprior_names = ['spherical', 'smooth', 'hrf', 'gaussian']
    normalize_kernel = False
    method = 'SVD'

    # make sure we can recover the ridge solution
    ridges = np.round(np.logspace(1, 3, 5), 4)
    nridges = len(ridges)

    delays = range(10)  #np.unique(np.random.randint(0,10,10))
    ndelays = len(delays)

    features_train, features_test, responses_train, responses_test = get_abc_data(
    )
    features_sizes = [fs.shape[1] for fs in features_train]

    # custom effective low-rank prior
    a = np.random.randn(features_train[-1].shape[-1], 3)
    sigma_x = np.dot(a, a.T) + np.identity(a.shape[0])
    spatial_priors = [
        sps.SphericalPrior(features_sizes[0], hyparams=[1]),
        sps.SphericalPrior(features_sizes[1], hyparams=[0.1, 1]),
        sps.CustomPrior(sigma_x, hyparams=[0.1, 1])
    ]

    tpriors = [
        tps.SphericalPrior(delays),
        tps.SmoothnessPrior(delays, wishart=False),
        tps.HRFPrior(delays),
        tps.GaussianKernelPrior(delays),
    ]
    tpidx = tprior_names.index(temporal_prior_name)
    temporal_prior = tpriors[tpidx]

    folds = tikutils.generate_trnval_folds(
        responses_train.shape[0],
        sampler='bcv',
        nfolds=(1, 5),
    )
    folds = list(folds)
    res = models.crossval_stem_wmvnp(
        features_train,
        responses_train,
        temporal_prior=temporal_prior,
        feature_priors=spatial_priors,
        folds=folds,
        ridges=ridges,
        verbosity=2,
        method=method,
        normalize_kernel=normalize_kernel,
    )

    # select a non-spherical prior
    spidx = 0
    sprior_ridge = res['spatial'][spidx]
    newridges = res['ridges']
    ridge_scale = newridges[0]

    res = models.estimate_simple_stem_wmvnp(
        features_train,
        responses_train,
        features_test=None,
        responses_test=None,
        temporal_prior=temporal_prior,
        temporal_hhparam=1.0,
        feature_priors=spatial_priors,
        feature_hyparams=sprior_ridge,
        weights=True,
        performance=False,
        predictions=False,
        ridge_scale=ridge_scale,
        verbosity=2,
        method='SVD',
    )

    weights = models.dual2primal_weights(
        res['weights'],
        features_train,
        spatial_priors,
        sprior_ridge,
        temporal_prior,
    )
    weights = np.vstack(weights)

    ### solve problem directly
    Xx = np.hstack([tikutils.delay_signal(t.astype(np.float64), delays)\
                    for i,t in enumerate(features_train)])

    # get scaled priors
    spriors = [
        sp.get_prior(param) for sp, param in zip(spatial_priors, sprior_ridge)
    ]
    # get temporal prior
    tprior = temporal_prior.get_prior(1.0)
    tprior += np.identity(tprior.shape[0]) * 1e-10
    # combine
    from scipy import linalg as LA
    prior = LA.block_diag(*[np.kron(tprior, spr) for spr in spriors])

    # solve problem indirectly # dual
    XSigmaXT = np.linalg.multi_dot(
        [Xx, prior, Xx.T]) + (ridge_scale**2.0) * np.identity(Xx.shape[0])
    alphas = np.dot(np.linalg.inv(XSigmaXT), responses_train)
    assert np.allclose(alphas, res['weights'])
    betas_dual = np.linalg.multi_dot([prior, Xx.T, alphas])
    assert np.allclose(betas_dual, weights)

    # solve problem directly # primal
    penalty = np.linalg.inv(prior)
    XTXSigma = np.dot(Xx.T, Xx) + (ridge_scale**2.0) * penalty
    XTY = np.dot(Xx.T, responses_train)
    betas = np.dot(np.linalg.inv(XTXSigma), XTY)
    # check solutions
    try:
        assert np.allclose(betas, weights)
    except AssertionError:
        # numerical error with HRF because of rank
        print('asserting correlation')
        assert np.allclose(
            np.corrcoef(betas.ravel(), weights.ravel())[0, 1], 1.0)
예제 #4
0
def test_ridge_solution(normalize_kernel=True, method='SVD'):
    # make sure we can recover the ridge solution
    ridges = np.round(np.logspace(-3, 3, 5), 4)
    nridges = len(ridges)

    delays = np.unique(np.random.randint(0, 10, 10))
    ndelays = len(delays)

    features_train, features_test, responses_train, responses_test = get_abc_data(
    )
    features_sizes = [fs.shape[1] for fs in features_train]

    spatial_priors = [
        sps.SphericalPrior(features_sizes[0], hyparams=[1]),
        sps.SphericalPrior(features_sizes[1], hyparams=[0.1, 1]),
        sps.SphericalPrior(features_sizes[2], hyparams=[0.1, 1]),
    ]

    tpriors = [tps.SphericalPrior(delays)]
    temporal_prior = tpriors[0]
    folds = tikutils.generate_trnval_folds(
        responses_train.shape[0],
        sampler='bcv',
        nfolds=(1, 5),
    )
    folds = list(folds)
    res = models.crossval_stem_wmvnp(
        features_train,
        responses_train,
        temporal_prior=temporal_prior,
        feature_priors=spatial_priors,
        folds=folds,
        ridges=ridges,
        verbosity=2,
        method=method,
        normalize_kernel=normalize_kernel,
    )

    # select a non-spherical prior
    spidx = 0
    sprior_ridge = res['spatial'][spidx]
    newridges = res['ridges']
    ridge_scale = newridges[-1]

    # direct fit
    X = np.hstack([tikutils.delay_signal(t.astype(np.float64), delays)*(sprior_ridge[i]**-1)\
                   for i,t in enumerate(features_train)])

    fit = models.cvridge(
        X,
        responses_train,
        folds=folds,
        ridges=newridges,
        verbose=True,
    )

    print(newridges)
    print(res['spatial'].squeeze())
    print(res['ridges'].squeeze())
    assert np.allclose(fit['cvresults'].squeeze(),
                       res['cvresults'].squeeze()[:, spidx])

    fit = models.cvridge(
        X,
        responses_train,
        folds=folds,
        ridges=[ridge_scale],
        verbose=True,
        weights=True,
        kernel_weights=True,
    )

    res = models.estimate_simple_stem_wmvnp(
        features_train,
        responses_train,
        features_test=None,
        responses_test=None,
        temporal_prior=temporal_prior,
        temporal_hhparam=1.0,
        feature_priors=spatial_priors,
        feature_hyparams=sprior_ridge,
        weights=True,
        performance=False,
        predictions=False,
        ridge_scale=ridge_scale,
        verbosity=2,
        method='SVD',
    )

    # check kernel weights are the same
    assert np.allclose(res['weights'].squeeze(), fit['weights'].squeeze())

    primal = models.solve_l2_primal(X,
                                    responses_train,
                                    ridges=[ridge_scale],
                                    weights=True)

    # check projection from kernel to standard form solution is correct
    W = np.dot(X.T, res['weights'])
    assert np.allclose(W, primal['weights'])

    # check projection from standard solution to tikhonov solution is correct
    weights = models.dual2primal_weights(
        res['weights'],
        features_train,
        spatial_priors,
        sprior_ridge,
        temporal_prior,
    )
    weights = np.vstack(weights)

    ### solve problem directly
    Xx = np.hstack([tikutils.delay_signal(t.astype(np.float64), delays)\
                    for i,t in enumerate(features_train)])

    # get scaled priors
    spriors = [
        sp.get_prior(param) for sp, param in zip(spatial_priors, sprior_ridge)
    ]
    # combine
    from scipy import linalg as LA
    sprior = LA.block_diag(*spriors)
    # get temporal prior
    tprior = temporal_prior.get_prior(1.0)
    # get full prior
    prior = np.kron(sprior, tprior)
    # get penalty
    penalty = np.linalg.inv(prior)
    # solve problem directly
    XTXSigma = np.dot(Xx.T, Xx) + ridge_scale**2 * penalty
    XTY = np.dot(Xx.T, responses_train)
    betas = np.dot(np.linalg.inv(XTXSigma), XTY)
    # check solutions
    assert np.allclose(betas, weights)