def comp_varexp(Y,S,nneuron): """ Compute variance explained from the GLM results, with parameters set above """ y = np.squeeze(Y[nneuron,:]) #spike train of interest stimulus = S[:,None] #same stimulus for all neurons X = build_convolved_matrix(stimulus, Y.T, Ks, couple) #design matrix with features projected onto basis functions glm = GLMCV(distr="binomial", tol=1e-5, eta=1.0, score_metric="deviance", alpha=0., learning_rate=1e-6, max_iter=1000, cv=3, verbose=True) #important to have v slow learning_rate glm.fit(X, y) yhat = simulate_glm('binomial', glm.beta0_, glm.beta_, X) #simulate spike rate given the firring results varexp = np.corrcoef(y,yhat) return varexp
def test_glmcv(distr): """Test GLMCV class.""" raises(ValueError, GLM, distr='blah') raises(ValueError, GLM, distr='gaussian', max_iter=1.8) scaler = StandardScaler() n_samples, n_features = 100, 10 # coefficients beta0 = 1. / (np.float(n_features) + 1.) * \ np.random.normal(0.0, 1.0) beta = 1. / (np.float(n_features) + 1.) * \ np.random.normal(0.0, 1.0, (n_features,)) solvers = ['batch-gradient', 'cdfast'] score_metric = 'pseudo_R2' learning_rate = 2e-1 for solver in solvers: if distr == 'gamma' and solver == 'cdfast': continue glm = GLMCV(distr, learning_rate=learning_rate, solver=solver, score_metric=score_metric, cv=2) assert (repr(glm)) np.random.seed(glm.random_state) X_train = np.random.normal(0.0, 1.0, [n_samples, n_features]) y_train = simulate_glm(glm.distr, beta0, beta, X_train) X_train = scaler.fit_transform(X_train) glm.fit(X_train, y_train) beta_ = glm.beta_ assert_allclose(beta, beta_, atol=0.5) # check fit y_pred = glm.predict(scaler.transform(X_train)) assert (y_pred.shape[0] == X_train.shape[0]) # test picky score_metric check within fit(). glm.score_metric = 'bad_score_metric' # reuse last glm raises(ValueError, glm.fit, X_train, y_train)
def test_glmcv(): """Test GLMCV class.""" scaler = StandardScaler() n_samples, n_features = 100, 10 # coefficients beta0 = 1. / (np.float(n_features) + 1.) * \ np.random.normal(0.0, 1.0) beta = 1. / (np.float(n_features) + 1.) * \ np.random.normal(0.0, 1.0, (n_features,)) distrs = ['softplus', 'gaussian', 'poisson', 'binomial', 'probit', 'gamma'] solvers = ['batch-gradient', 'cdfast'] score_metric = 'pseudo_R2' learning_rate = 2e-1 for solver in solvers: for distr in distrs: if distr == 'gamma' and solver == 'cdfast': continue glm = GLMCV(distr, learning_rate=learning_rate, solver=solver, score_metric=score_metric) assert_true(repr(glm)) np.random.seed(glm.random_state) X_train = np.random.normal(0.0, 1.0, [n_samples, n_features]) y_train = simulate_glm(glm.distr, beta0, beta, X_train) X_train = scaler.fit_transform(X_train) glm.fit(X_train, y_train) beta_ = glm.beta_ assert_allclose(beta, beta_, atol=0.5) # check fit y_pred = glm.predict(scaler.transform(X_train)) assert_equal(y_pred.shape[0], X_train.shape[0])
def kernel_MSE(Y, S, nneuron, Ks): """ Compute MSE from the GLM results, with simulated activity, stimulus, and the ground truth kernel """ ###GLM y = np.squeeze(Y[nneuron, :]) #spike train of interest stimulus = S[:, None] #same stimulus for all neurons X = build_convolved_matrix( stimulus, Y.T, Ks, couple) #design matrix with features projected onto basis functions glm = GLMCV(distr="binomial", tol=1e-5, eta=1.0, score_metric="deviance", alpha=0., learning_rate=0.1, max_iter=1000, cv=3, verbose=True) #important to have v slow learning_rate glm.fit(X, y) ###store kernel theta_rec = glm.beta_[1:] theta_rec = theta_rec.reshape(nbasis, N + 1) K_rec = np.zeros((N + 1, pad)) for ii in range(N + 1): K_rec[ii, :] = np.dot(theta_rec[:, ii], Ks) ###normalize and shift kernels K_rec_norm = np.array([ K_rec[ii, :] / np.linalg.norm(K_rec[ii, :]) for ii in range(N + 1) ]) # K_tru_norm = np.array([ allK[nneuron, ii, :] / np.linalg.norm(allK[nneuron, ii, :]) for ii in range(N + 1) ]) # # K_rec_norm = K_rec_norm.T-K_rec_norm[:,-1] # K_tru_norm = K_tru_norm.T-K_tru_norm[:,-1] mses = np.sum((K_rec_norm - K_tru_norm)**2, axis=1) #measuring MSE for each kernel return mses
# %% ############################################################################### # %% inference method (single) nneuron = 2 pad = 100 #window for kernel nbasis = 7 #number of basis couple = 1 #wether or not coupling cells considered Y = np.squeeze(rate[nneuron,:]) #spike train of interest Ks = (np.fliplr(basis_function1(pad,nbasis).T).T).T #basis function used for kernel approximation stimulus = stim[:,None] #same stimulus for all neurons X = build_convolved_matrix(stimulus, rate.T, Ks, couple) #design matrix with features projected onto basis functions ###pyGLMnet function with optimal parameters glm = GLMCV(distr="binomial", tol=1e-5, eta=1.0, score_metric="deviance", alpha=0., learning_rate=1e-6, max_iter=1000, cv=3, verbose=True) #important to have v slow learning_rate glm.fit(X, Y) # %% direct simulation yhat = simulate_glm('binomial', glm.beta0_, glm.beta_, X) #simulate spike rate given the firring results plt.figure() plt.plot(Y*1.) #ground truth plt.plot(yhat,'--') # %%reconstruct kernel theta = glm.beta_ dc_ = theta[0] theta_ = theta[1:] if couple == 1: theta_ = theta_.reshape(nbasis,N+1) #nbasis times (stimulus + N neurons) allKs = np.array([theta_[:,kk] @ Ks for kk in range(N+1)]) elif couple == 0:
gl_glm = GLMCV(distr="binomial", tol=1e-3, group=group_idxs, score_metric="pseudo_R2", alpha=1.0, cv=3) # set up the lasso model glm = GLMCV(distr="binomial", tol=1e-3, score_metric="pseudo_R2", alpha=1.0, cv=3) print("gl_glm: ", gl_glm) print("glm: ", glm) ########################################################## # Fit models gl_glm.fit(Xtrain, ytrain) glm.fit(Xtrain, ytrain) ########################################################## # Visualize model scores on test set plt.figure() plt.semilogx(gl_glm.reg_lambda, gl_glm.scores_, 'go-') plt.semilogx(glm.reg_lambda, glm.scores_, 'ro--') plt.legend(['Group Lasso', 'Lasso'], frameon=False, loc='best') plt.xlabel('$\lambda$') plt.ylabel('pseudo-$R^2$') plt.tick_params(axis='y', right='off') plt.tick_params(axis='x', top='off')
# Fit models from sklearn.model_selection import train_test_split Xtrain, Xtest, Ytrain, Ytest = train_test_split(features, spike_counts, test_size=0.2, random_state=42) ######################################################## from pyglmnet import utils n_samples = Xtrain.shape[0] Tau = utils.tikhonov_from_prior(prior_cov, n_samples) glm = GLMCV(distr='poisson', alpha=0., Tau=Tau, score_metric='pseudo_R2', cv=3) glm.fit(Xtrain, Ytrain) print("train score: %f" % glm.score(Xtrain, Ytrain)) print("test score: %f" % glm.score(Xtest, Ytest)) weights = glm.beta_ ######################################################## # Visualize for time_bin_ in range(n_temporal_basis): RF = strf_model.make_image_from_spatial_basis( spatial_basis, weights[range(time_bin_, n_spatial_basis * n_temporal_basis, n_temporal_basis)]) plt.subplot(1, n_temporal_basis, time_bin_ + 1) plt.imshow(RF, cmap='Blues', interpolation='none')
n_samples, n_features = X.shape ######################################################## # Split the data into training and test sets X_train, X_test, y_train, y_test = \ train_test_split(X, y, test_size=0.33, random_state=0) ######################################################## # Fit a gaussian distributed GLM with elastic net regularization # use the default value for reg_lambda glm = GLMCV(distr='gaussian', alpha=0.05, score_metric='pseudo_R2') # fit model glm.fit(X_train, y_train) # score the test set prediction y_test_hat = glm.predict(X_test) print ("test set pseudo $R^2$ = %f" % glm.score(X_test, y_test)) ######################################################## # Plot the true and predicted test set target values plt.plot(y_test[:50], 'ko-') plt.plot(y_test_hat[:50], 'ro-') plt.legend(['true', 'pred'], frameon=False) plt.xlabel('Counties') plt.ylabel('Per capita violent crime') plt.tick_params(axis='y', right='off')
def fit_group_lasso( X, knockoffs, y, groups, use_pyglm=True, y_dist=None, group_lasso=True, **kwargs, ): """ Fits a group lasso model. :param X: n x p design matrix :param knockoffs: n x p knockoff matrix :param groups: p length numpy array of groups :param use_pyglm: If true, use the pyglmnet grouplasso Else use the regular one :param y_dist: Either "gaussian" or "binomial" (for logistic regression) :param group_lasso: If False, do not use group regularization. :param kwargs: kwargs for group-lasso GroupLasso class. In particular includes reg_vals, a list of regularizations (lambda values) which defaults to [(0.05, 0.05)]. In each tuple of the list, the first value is the group regularization, the second value is the individual regularization. """ warnings.filterwarnings("ignore") # Parse some kwargs/defaults if "max_iter" in kwargs: max_iter = kwargs.pop("max_iter") else: max_iter = 100 if "tol" in kwargs: tol = kwargs.pop("tol") else: tol = 1e-2 if "cv" in kwargs: cv = kwargs.pop("cv") else: cv = 5 if "learning_rate" in kwargs: learning_rate = kwargs.pop("learning_rate") else: learning_rate = 2 if y_dist is None: y_dist = parse_y_dist(y) # Bind data n = X.shape[0] p = X.shape[1] features = np.concatenate([X, knockoffs], axis=1) # By default, all variables are their own group if groups is None: groups = np.arange(1, p + 1, 1) m = np.unique(groups).shape[0] # If m == p, meaning each variable is their own group, # just fit a regular lasso if m == p or not group_lasso: return fit_lasso(X, knockoffs, y, y_dist, **kwargs) # Make sure variables and their knockoffs are in the same group # This is necessary for antisymmetry doubled_groups = np.concatenate([groups, groups], axis=0) # Randomize coordinates to make sure everything is symmetric inds, rev_inds = random_permutation_inds(2 * p) features = features[:, inds] doubled_groups = doubled_groups[inds] # Standardize - important for pyglmnet performance, # highly detrimental for group_lasso performance if use_pyglm: features = (features - features.mean()) / features.std() if y_dist == "gaussian": y = (y - y.mean()) / y.std() # Get regularizations if "reg_vals" in kwargs: reg_vals = kwargs.pop("reg_vals") else: reg_vals = [(x, x) for x in DEFAULT_REG_VALS] # Fit pyglm model using warm starts if use_pyglm: l1_regs = [x[0] for x in reg_vals] gl = GLMCV( distr=y_dist, tol=tol, group=doubled_groups, alpha=1.0, learning_rate=learning_rate, max_iter=max_iter, reg_lambda=l1_regs, cv=cv, solver="cdfast", ) gl.fit(features, y) # Pull score, rename best_score = -1 * calc_mse(gl, features, y) best_gl = gl # Fit model if not use_pyglm: best_gl = None best_score = -1 * np.inf for group_reg, l1_reg in reg_vals: # Fit logistic/gaussian group lasso if not use_pyglm: if y_dist.lower() == "gaussian": gl = GroupLasso( groups=doubled_groups, tol=tol, group_reg=group_reg, l1_reg=l1_reg, **kwargs, ) elif y_dist.lower() == "binomial": gl = LogisticGroupLasso( groups=doubled_groups, tol=tol, group_reg=group_reg, l1_reg=l1_reg, **kwargs, ) else: raise ValueError( f"y_dist must be one of gaussian, binomial, not {y_dist}" ) gl.fit(features, y.reshape(n, 1)) score = -1 * calc_mse(gl, features, y.reshape(n, 1)) # Score, possibly select if score > best_score: best_score = score best_gl = gl warnings.resetwarnings() return best_gl, inds, rev_inds
def fit(self, X, Y, get_history_terms=True): """ Fits the model to the data in X to predict the response Y. Imports models and creates model instance as well. Parameters ---------- X: float, n_samples x n_features, features of interest Y: float, n_samples x 1, population activity get_history_terms = Boolean. Whether to compute the temporal features. Note that if spike_history and cov_history are False, no history will be computed anyways and the flag does nothing. """ if self.default_params: warnings.warn( '\n Using default hyperparameters. Consider optimizing on' + ' a held-out dataset using, e.g. hyperopt or random search') # make the covariate matrix. Include spike or covariate history? # The different methods here are to satisfy the needs of recurrent keras # models if get_history_terms: if self.tunemodel == 'lstm': X, Y = self.get_all_with_history_keras(X, Y) else: X, Y = self.get_all_with_history(X, Y) if self.tunemodel == 'glm': model = GLMCV(**self.params) model.fit(X, Y) # we want the last of the regularization path # self.model = model[-1] self.GLMCV = model self.model = model.glm_ elif self.tunemodel == 'feedforward_nn': if np.ndim(X) == 1: X = np.transpose(np.atleast_2d(X)) params = self.params model = Sequential() model.add( Dense(params['n1'], input_dim=np.shape(X)[1], kernel_initializer='glorot_normal', activation='relu', kernel_regularizer=l2(params['l2']))) model.add(Dropout(params['dropout'])) model.add(BatchNormalization()) model.add( Dense(params['n2'], kernel_initializer='glorot_normal', activation='relu', kernel_regularizer=l2(params['l2']))) model.add(BatchNormalization()) model.add(Dense(1, activation='softplus')) optim = adam(lr=params['lr'], clipnorm=params['clipnorm'], decay=params['decay'], beta_1=1 - params['b1'], beta_2=1 - params['b2']) model.compile( loss='poisson', optimizer=optim, ) hist = model.fit(X, Y, batch_size=128, epochs=30, verbose=self.verbose) self.model = model elif self.tunemodel == 'xgboost': dtrain = xgb.DMatrix(X, label=Y) num_round = 200 self.model = xgb.train(self.params, dtrain, num_round) elif self.tunemodel == 'random_forest': self.model = RandomForestRegressor(**self.params) self.model.fit(X, Y) elif self.tunemodel == 'lstm': if np.ndim(X) == 1: X = np.transpose(np.atleast_2d(X)) params = self.params model = Sequential() #Declare model #Add recurrent layer model.add(LSTM(int(params['n_units']),input_shape=(X.shape[1],X.shape[2]),\ dropout_W=params['dropout'],dropout_U=params['dropout'])) #Within recurrent layer, include dropout model.add(Dropout(params['dropout']) ) #Dropout some units (recurrent layer output units) #Add dense connections to output layer model.add(Dense(1, activation='softplus')) #Fit model (and set fitting parameters) model.compile(loss='poisson', optimizer='rmsprop', metrics=['accuracy']) model.fit(X, Y, epochs=int(params['epochs']), batch_size=int(params['batch_size']), verbose=self.verbose) #Fit the model self.model = model else: #using predefined model self.model.fit(X, Y)
#fake spike train output rate = np.concatenate((input_,-input_,output_)).reshape(3,lt) ### input signal, output, and negative output nneuron = 0 pad = 100 #window for kernel nbasis = 7 #number of basis couple = 1 #wether or not coupling cells considered Y = np.squeeze(rate[nneuron,:]) #spike train of interest Ks = (np.fliplr(basis_function1(pad,nbasis).T).T).T #basis function used for kernel approximation stimulus = input_[:,None] #same stimulus for all neurons X = build_convolved_matrix(stimulus, rate.T, Ks, couple) #design matrix with features projected onto basis functions ###pyGLMnet function with optimal parameters distr = "binomial" glm = GLMCV(distr=distr, tol=1e-5, eta=1.0, score_metric="deviance", alpha=0., learning_rate=1e-6, max_iter=1000, cv=3, verbose=True) #important to have v slow learning_rate glm.fit(X, Y) # %% direct simulation yhat = simulate_glm(distr, glm.beta0_, glm.beta_, X) #simulate spike rate given the firring results plt.figure() plt.plot(Y*1.,label='input') #ground truth plt.plot(yhat,'--',label='ouput_est') plt.plot(-output_,'k',alpha=0.5,label='target') plt.legend() # %% theta = glm.beta_ dc_ = theta[0] theta_ = theta[1:] if couple == 1: theta_ = theta_.reshape(nbasis,N+1) #nbasis times (stimulus + N neurons)
n_samples, n_features = X.shape ######################################################## # Split the data into training and test sets X_train, X_test, y_train, y_test = \ train_test_split(X, y, test_size=0.33, random_state=0) ######################################################## # Fit a gaussian distributed GLM with elastic net regularization # use the default value for reg_lambda glm = GLMCV(distr='gaussian', alpha=0.05, score_metric='pseudo_R2') # fit model glm.fit(X_train, y_train) # score the test set prediction y_test_hat = glm.predict(X_test) print ("test set pseudo $R^2$ = %f" % glm.score(X_test, y_test)) ######################################################## # Now use plain grid search cv to compare import numpy as np # noqa from sklearn.model_selection import GridSearchCV # noqa from sklearn.cross_validation import StratifiedKFold # noqa cv = StratifiedKFold(y_train, 3) reg_lambda = np.logspace(np.log(0.5), np.log(0.01), 10,
# %% ############################################################################### ############################################################################### # %% test pyGLM ### This is super-easy if we rely on built-in GLM fitting code glm = GLMCV(distr="binomial", tol=1e-3, score_metric="pseudo_R2", alpha=1.0, learning_rate=3, max_iter=100, cv=3, verbose=True) glm.fit(X, np.squeeze(spk)) # %% plt.figure() pyglm_infer = glm.beta_ plt.plot(pyglm_infer / np.linalg.norm(pyglm_infer)) plt.plot(K / np.linalg.norm(K), '--') # %% Two-neuron circuit with pyGLMnet ############################################################################### ############################################################################### # %% combine basis function here ###convolve with basis first?? N = 2 dt = 0.1 #ms T = 10000
gl_glm = GLMCV(distr="binomial", tol=1e-2, group=group_idxs, score_metric="pseudo_R2", alpha=1.0) # set up the lasso model glm = GLMCV(distr="binomial", tol=1e-2, score_metric="pseudo_R2", alpha=1.0) print("gl_glm: ", gl_glm) print("glm: ", glm) ########################################################## # Fit models gl_glm.fit(Xtrain, ytrain) glm.fit(Xtrain, ytrain) ########################################################## # Visualize model scores on test set plt.figure() plt.semilogx(gl_glm.reg_lambda, gl_glm.scores_, 'go-') plt.semilogx(glm.reg_lambda, glm.scores_, 'ro--') plt.legend(['Group Lasso', 'Lasso'], frameon=False, loc='best') plt.xlabel('$\lambda$') plt.ylabel('pseudo-$R^2$') plt.tick_params(axis='y', right='off') plt.tick_params(axis='x', top='off')