def fit(self, norm="zscore"): """ Calculate the regression parameters and statistics. """ bold = self.bold.copy() dm = self.dm.copy() # Normalize both the bold and dm if norm != None: bold = self._normalize_array(bold, norm) dm = self._normalize_array(dm, norm) # Add movement regressors... if present try: dm_movement = self.data["movement"] dm = np.vstack((dm, dm_movement)) except KeyError: pass # Append a dummy predictor and run the regression # # Dummy is added at the last minute so it does not # interact with normalization or smoothing routines. dm_dummy = np.ones((dm.shape[0], dm.shape[1] + 1)) dm_dummy[0:dm.shape[0], 0:dm.shape[1]] = dm # Truncate bold or dm_dummy if needed, and Go! try: bold = bold[0:dm_dummy.shape[0]] dm_dummy = dm_dummy[0:len(bold), :] except IndexError: pass self.glm = GLS(bold, dm_dummy).fit()
def _orth_dm(self): """ Orthgonalize (by regression) each col in self.dm with respect to its left neighbor. """ dm = self.dm ## Rename for brevity # Make sure conds and ncol dm # are divisors conds = list(set(self.trials)) nconds = len(conds) - 1 ## Drop baseline ncols = dm.shape[1] - 1 if ncols % nconds: raise ValueError( "The number of condtions and shape of the dm are incompatible." ) # If these are the same size there is nothing to # orthgonalize. if ncols != nconds: orth_dm = np.zeros_like(dm) orth_dm[:, 0] = dm[:, 0] ## Move baseline data over # Use num_col_per_cond, along with nconds # to find the strides we need to take along # the DM to orthgonalize each set of col(s) # belonging to each cond. num_col_per_cond = ncols / nconds for cond in conds: # Skip baseline if cond == 0: continue left = cond right = cond + nconds # Rolling loop over the cols_per_cond # orthgonalizing as we go. # Note: we never use cnt directly... for cnt in range(num_col_per_cond - 1): # Orthgonalize left col to right.... glm = GLS(dm[:, right], dm[:, left]).fit() ## GLS(y, x) orth_dm[:, right] = glm.resid orth_dm[:, left] = dm[:, left] # Shift indices for next iteration. left = deepcopy(right) right = right + nconds self.dm = orth_dm else: print("Nothing to orthgonalize.")
def gls_model(X, y, test_size=0.25): X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=test_size) gls = GLS(y_train, X_train).fit(cov_type='HC1') coeffs = (gls.params.to_frame().rename(columns={ 0: "coeff" }).merge( gls.pvalues.to_frame().rename(columns={0: "p-value"}), left_index=True, right_index=True, ).assign(coeff=lambda df: df.apply( lambda r: r["coeff"] if r["p-value"] < 0.05 else np.nan, axis=1))[[ "coeff" ]]) mse = gls.predict(X_test).pipe(lambda s: (s - y_test)**2).mean() return {"model": gls, "coeffs": coeffs, "mse": mse}