-
Notifications
You must be signed in to change notification settings - Fork 0
/
ridgecv_pca.py
297 lines (190 loc) · 8.63 KB
/
ridgecv_pca.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# coding: utf-8
# # Examples of all decoders (except Kalman Filter)
#
# In this example notebook, we:
# 1. Import the necessary packages
# 2. Load a data file (spike trains and outputs we are predicting)
# 3. Preprocess the data for use in all decoders
# 4. Run all decoders and print the goodness of fit
# 5. Plot example decoded outputs
#
# See "Examples_kf_decoder" for a Kalman filter example. <br>
# Because the Kalman filter utilizes different preprocessing, we don't include an example here. to keep this notebook more understandable
# ## 1. Import Packages
#
# Below, we import both standard packages, and functions from the accompanying .py files
# In[2]:
#Import standard packages
import numpy as np
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt
import sys,os
from scipy import io
from scipy import stats,signal
import pickle
import h5py
#Import function to get the covariate matrix that includes spike history from previous bins
from preprocessing_funcs import get_spikes_with_history
#Import metrics
from metrics import get_R2
from metrics import get_rho
#Import decoder functions
#from decoders import WienerCascadeDecoder
# from decoders import WienerFilterDecoder
# from decoders import DenseNNDecoder
# from decoders import SimpleRNNDecoder
# from decoders import GRUDecoder
# from decoders import LSTMDecoder
# from decoders import XGBoostDecoder
# from decoders import SVRDecoder
from sklearn.model_selection import train_test_split
from sklearn.decomposition import PCA
from sklearn import linear_model
from sklearn.externals import joblib
from sklearn.model_selection import GridSearchCV
from sklearn.preprocessing import StandardScaler
import seaborn as sns
sns.set_style('white')
def load_data(folder,spectrogram=0):
head_data = h5py.File('all_head_data.hdf5','r')
dx = head_data['dx'][:]
dy = head_data['dy'][:]
dz = head_data['dz'][:]
oz = head_data['oz'][:]
oy = head_data['oy'][:]
ox = head_data['ox'][:]
ay = head_data['ay'][:]
ax = head_data['ax'][:]
az = head_data['az'][:]
xyz = np.sqrt(ax**2 + ay**2 + az**2)
theta = np.rad2deg(np.arctan(ax/ay))
head_data.close()
#xy_acc = head_data['xy_acc']
#theta = head_data['theta']
#time = head_data['time']
y = np.vstack([dx,dy,dz,ax,ay,az,ox,oy,oz,xyz,theta]).T
y_name = ['dx','dy','dz','ax','ay','az','ox','oy','oz','xyz','theta']
#y = np.vstack([oz,dz,xyz,theta]).T
#y_name = ['oz','dz','xyz','theta']
#lfp_file = np.load('lfp_power.npz')
lfp_file = h5py.File('lfp_power.hdf5','r')
lfp_power = lfp_file['lfp_power'][:].T
lfp_file.close()
print 'Shape of head data = ', y.shape
print 'Shape of LFP power = ', lfp_power.shape
for i in range(len(y_name)):
y[:,i] = signal.medfilt(y[:,i],[9])
idx = 10000 #int(y.shape[0]/2)
print 'max idx = ', idx
return y[0:idx,], lfp_power[0:idx,:],y_name
def preprocess(y,neural_data):
# ## 3. Preprocess Data
# ### 3A. User Inputs
# The user can define what time period to use spikes from (with respect to the output).
# In[25]:
bins_before=25 #How many bins of neural data prior to the output are used for decoding
bins_current=1 #Whether to use concurrent time bin of neural data
bins_after=25 #How many bins of neural data after the output are used for decoding
# ### 3B. Format Covariates
# #### Format Input Covariates
# In[26]:
# Format for recurrent neural networks (SimpleRNN, GRU, LSTM)
# Function to get the covariate matrix that includes spike history from previous bins
X=get_spikes_with_history(neural_data,bins_before,bins_after,bins_current)
# Format for Wiener Filter, Wiener Cascade, XGBoost, and Dense Neural Network
#Put in "flat" format, so each "neuron / time" is a single feature
X_flat=X.reshape(X.shape[0],(X.shape[1]*X.shape[2]))
####### reduce dimensionality of the input data (X) from ~8,000 to 100:
pca = PCA(n_components=100)
print 'Reducing Dimensionality with PCA'
#pca.fit(X_flat[::10,:])
#X_flat = pca.transform(X_flat)
X_flat = pca.fit_transform(X_flat)
# ### 3C. Split into training / testing / validation sets
# Note that hyperparameters should be determined using a separate validation set.
# Then, the goodness of fit should be be tested on a testing set (separate from the training and validation sets).
# #### User Options
# In[32]:
#Set what part of data should be part of the training/testing/validation sets
training_range=[0, 0.5]
# #testing_range=[0.7, 0.85]
valid_range=[0.5,1]
# # #### Split Data
# # In[81]:
num_examples=X.shape[0]
# print 'Splitting Data into Training and Testing Sets'
# #Note that each range has a buffer of"bins_before" bins at the beginning, and "bins_after" bins at the end
# #This makes it so that the different sets don't include overlapping neural data
training_set=np.arange(np.int(np.round(training_range[0]*num_examples))+bins_before,np.int(np.round(training_range[1]*num_examples))-bins_after)
# #testing_set=np.arange(np.int(np.round(testing_range[0]*num_examples))+bins_before,np.int(np.round(testing_range[1]*num_examples))-bins_after)
valid_set=np.arange(np.int(np.round(valid_range[0]*num_examples))+bins_before,np.int(np.round(valid_range[1]*num_examples))-bins_after)
# #Get training data
# X_train=X[training_set,:,:]
X_flat_train=X_flat[training_set,:]
y_train=y[training_set,:]
# #Get testing data
# #X_test=X[testing_set,:,:]
# #X_flat_test=X_flat[testing_set,:]
# #y_test=y[testing_set,:]
# #Get validation data
# X_valid=X[valid_set,:,:]
X_flat_valid=X_flat[valid_set,:]
y_valid=y[valid_set,:]
X_flat_train, X_flat_valid, y_train, y_valid = train_test_split(X_flat, y, test_size=0.5,shuffle=False,random_state=42)
print 'Z-scoring Data'
X_scaler = StandardScaler().fit(X_flat_train)
y_scaler = StandardScaler().fit(y_train)
X_flat_train = X_scaler.transform(X_flat_train)
y_train = y_scaler.transform(y_train)
X_flat_valid = X_scaler.transform(X_flat_valid)
y_valid = y_scaler.transform(y_valid)
return X_flat_train,X_flat_valid,y_train,y_valid
# ## 4. Run Decoders
def run_ridge(X_train,X_test,y_train,y_test,y_name):
# ### 4D. SVR (Support Vector Regression)
#Declare model
#Fit model
for head_item in range(len(y_name)):
ridge_model = linear_model.RidgeCV(alphas=[0.01, 0.1, 1, 10,100])
### fit one at a time and save/plot the results
print '########### Fitting RidgeCV on %s data ###########' % y_name[head_item]
y_train_item = y_train[:,head_item]
#y_train_item = np.reshape(y_train_item,[y_train.shape[0],1])
print 'shape of y_train_item = ', y_train_item.shape
y_test_item = y_test[:,head_item]
#y_test_item = np.reshape(y_test_item,[y_test_item.shape[0],1])
ridge_model.fit(X_train,y_train_item)
#Get predictions
y_prediction=ridge_model.predict(X_test)
#Get metric of fit
#R2s_svr=get_R2(y_test_item,y_prediction)
R2 = ridge_model.score(X_test,y_test_item)
print(y_name[head_item], 'R2:', R2)
print 'saving prediction ...'
np.savez(y_name[head_item] + '_ridgecv_ypredicted.npz',y_test=y_test_item,y_prediction=y_prediction)
print 'saving model ...'
joblib.dump(ridge_model, y_name[head_item] + '_ridgecv.pkl')
print 'plotting results...'
plot_results(y_test_item,y_prediction,y_name[head_item],R2)
def plot_results(y_valid,y_valid_predicted,y_name,R2s,model_name='RidgeCV'):
f, axarr = plt.subplots(2,dpi=600)
axarr[0].set_title(model_name +' Model of %s. R^2 = %f ' % (y_name,R2s))
axarr[0].plot(y_valid,linewidth=0.1)
axarr[0].set_ylabel('Head Data')
axarr[0].plot(y_valid_predicted,linewidth=0.1,color='red')
axarr[0].set_xlabel('Time (samples)')
axarr[1].scatter(y_valid,y_valid_predicted,alpha=0.05,marker='o')
#axarr[1].set_title('R2 = ' + str(R2s))
axarr[1].set_xlabel('Actual')
axarr[1].set_ylabel('Predicted')
axarr[1].axis('equal')
sns.despine(left=True,bottom=True)
f.savefig(model_name + '_%s.pdf' % y_name)
# In[ ]:
if __name__ == "__main__":
#model_type = sys.argv[1] ## wiener or lstm
print '############################ Running Ridge Regression with Cross Validation ############################'
head_data,neural_data,y_name = load_data(os.getcwd())
X_flat_train,X_flat_valid,y_train,y_valid = preprocess(head_data,neural_data)
run_ridge(X_flat_train,X_flat_valid,y_train,y_valid,y_name)