From 07eedc0a6283dc358c026c156f29a814b37d34df Mon Sep 17 00:00:00 2001 From: Saatvik Shah Date: Wed, 6 May 2015 05:33:40 +0530 Subject: [PATCH] adding tfi competition code --- FindingELO/main.py | 33 +- FindingELO/main.py~ | 63 - FindingELO/settings.json | 4 +- InriaBCIChallenge/4foldcvlogs.txt | 59 + InriaBCIChallenge/batchio.py | 69 + InriaBCIChallenge/classifier.py | 373 +++++ InriaBCIChallenge/extras.py | 78 ++ InriaBCIChallenge/filters.py | 158 +++ InriaBCIChallenge/logs.txt | 49 + InriaBCIChallenge/losocvlogs.txt | 1343 +++++++++++++++++++ InriaBCIChallenge/main.py | 121 ++ InriaBCIChallenge/model_gen.py | 56 + InriaBCIChallenge/settings.json | 5 + InriaBCIChallenge/transforms.py | 515 +++++++ TFI/.ipynb_checkpoints/EDA-checkpoint.ipynb | 114 ++ TFI/EDA.ipynb | 406 ++++++ TFI/batchio.py | 89 ++ TFI/classifier.py | 97 ++ TFI/classifier_bak.py | 77 ++ TFI/extras.py | 28 + TFI/settings.json | 3 + TFI/validation.py | 159 +++ TFI/validation_copy.py | 157 +++ 23 files changed, 3974 insertions(+), 82 deletions(-) delete mode 100644 FindingELO/main.py~ create mode 100644 InriaBCIChallenge/4foldcvlogs.txt create mode 100644 InriaBCIChallenge/batchio.py create mode 100644 InriaBCIChallenge/classifier.py create mode 100644 InriaBCIChallenge/extras.py create mode 100644 InriaBCIChallenge/filters.py create mode 100644 InriaBCIChallenge/logs.txt create mode 100644 InriaBCIChallenge/losocvlogs.txt create mode 100644 InriaBCIChallenge/main.py create mode 100644 InriaBCIChallenge/model_gen.py create mode 100644 InriaBCIChallenge/settings.json create mode 100644 InriaBCIChallenge/transforms.py create mode 100644 TFI/.ipynb_checkpoints/EDA-checkpoint.ipynb create mode 100644 TFI/EDA.ipynb create mode 100644 TFI/batchio.py create mode 100644 TFI/classifier.py create mode 100644 TFI/classifier_bak.py create mode 100644 TFI/extras.py create mode 100644 TFI/settings.json create mode 100644 TFI/validation.py create mode 100644 TFI/validation_copy.py diff --git a/FindingELO/main.py b/FindingELO/main.py index ab814c4..eb7ef8c 100644 --- a/FindingELO/main.py +++ b/FindingELO/main.py @@ -2,8 +2,7 @@ from extras import * from features import * from sklearn.cross_validation import cross_val_score -from sklearn.linear_model import LinearRegression -from sklearn.ensemble import RandomForestRegressor,GradientBoostingRegressor +from sklearn.linear_model import LogisticRegression from sklearn.base import clone import warnings import sys @@ -12,7 +11,7 @@ def clf_generator(): clfs = [ # RandomForestRegressor(n_estimators=3000,verbose=1,n_jobs=1), # GradientBoostingRegressor(n_estimators=5000,verbose=1,learning_rate=0.01), - LinearRegression(), + LogisticRegression(), ] for clf in clfs: yield clf,clone(clf) @@ -26,20 +25,20 @@ def main(): for clf_w,clf_b in clf_generator(): print list(X.columns.values) print clf_w - print cross_val_score(estimator=clf_w, - scoring="mean_absolute_error", - cv=4, - X=X, - y=yw, - n_jobs=-1) - print cross_val_score(estimator=clf_b, - scoring="mean_absolute_error", - cv=4, - X=X, - y=yb, - n_jobs=-1) - print "\n" - continue + # print cross_val_score(estimator=clf_w, + # scoring="mean_absolute_error", + # cv=4, + # X=X, + # y=yw, + # n_jobs=-1) + # print cross_val_score(estimator=clf_b, + # scoring="mean_absolute_error", + # cv=4, + # X=X, + # y=yb, + # n_jobs=-1) + # print "\n" + # continue print "Training ..." clf_w.fit(X,yw) clf_b.fit(X,yb) diff --git a/FindingELO/main.py~ b/FindingELO/main.py~ deleted file mode 100644 index 943d714..0000000 --- a/FindingELO/main.py~ +++ /dev/null @@ -1,63 +0,0 @@ -from batchio import * -from extras import * -from features import * -import numpy as np -from sklearn.cross_validation import cross_val_score -from sklearn.linear_model import LinearRegression,\ - LogisticRegression,SGDRegressor,Perceptron -from sklearn.tree import DecisionTreeRegressor,\ - ExtraTreeRegressor -from sklearn.svm import LinearSVC,SVC -from sklearn.ensemble import RandomForestRegressor,\ - BaggingRegressor -from sklearn.preprocessing import StandardScaler -from sklearn.metrics import mean_absolute_error -from sklearn.base import clone -import warnings -import sys - -def clf_generator(): - clfs = [ - RandomForestRegressor(n_estimators=2000,verbose=1,n_jobs=1), - # BaggingRegressor(base_estimator=LinearRegression(),n_estimators=5000), - # LinearRegression(), - ] - for clf in clfs: - yield clf,clone(clf) - -def main(): - params = load_params() - train_df,test_df = data_parse(params) - X,yw,yb = process_features(train_df,"train",params) - #Scale up X - for clf_w,clf_b in clf_generator(): - print list(X.columns.values) - print clf_w - # print cross_val_score(estimator=clf_w, - # scoring="mean_absolute_error", - # cv=4, - # X=X, - # y=yw, - # n_jobs=1) - # print cross_val_score(estimator=clf_b, - # scoring="mean_absolute_error", - # cv=4, - # X=X, - # y=yb, - # n_jobs=1) - print "\n" - print "Training ..." - clf_w.fit(X,yw) - clf_b.fit(X,yb) - print "Testing ..." - X = process_features(test_df,"test",params) - #print test_df.head() - yw = clf_w.predict(X) - yb = clf_b.predict(X) - create_submission(test_df["Event"],yw,yb) - -if __name__ == '__main__': - warnings.filterwarnings("ignore") - #sys.stdout = open("logs.txt","a") - main() - diff --git a/FindingELO/settings.json b/FindingELO/settings.json index 2d9893f..3714e8f 100644 --- a/FindingELO/settings.json +++ b/FindingELO/settings.json @@ -1,5 +1,5 @@ { - "data_dir" : "../data/FindingELO", - "cache_dir" : "../data/FindingELO/cache", + "data_dir" : "../../data/FindingELO", + "cache_dir" : "../../data/FindingELO/cache", "num_partitions" : 3 } \ No newline at end of file diff --git a/InriaBCIChallenge/4foldcvlogs.txt b/InriaBCIChallenge/4foldcvlogs.txt new file mode 100644 index 0000000..e368d96 --- /dev/null +++ b/InriaBCIChallenge/4foldcvlogs.txt @@ -0,0 +1,59 @@ +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 4 folds for each of 1 candidates, totalling 4 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 10.7s +[Parallel(n_jobs=-1)]: Done 4 out of 4 | elapsed: 11.0s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.661 (+/-0.025) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +____KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched__EEGConcatExtracter__Downsampler_dec_12__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched____EEGConcatExtracter__Downsampler_dec_12 +(5440, 260, 3) +Fitting 4 folds for each of 1 candidates, totalling 4 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 10.5s +[Parallel(n_jobs=-1)]: Done 4 out of 4 | elapsed: 10.9s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.661 (+/-0.022) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +____KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched__EEGConcatExtracter__Downsampler_dec_24__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched____EEGConcatExtracter__Downsampler_dec_24 +(5440, 260, 3) +Fitting 4 folds for each of 1 candidates, totalling 4 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 5.6s +[Parallel(n_jobs=-1)]: Done 4 out of 4 | elapsed: 5.9s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.658 (+/-0.025) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +____KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched__EEGConcatExtracter__Downsampler_dec_12__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched____EEGConcatExtracter__Downsampler_dec_24 +(5440, 260, 3) +Fitting 4 folds for each of 1 candidates, totalling 4 fits +[Parallel(n_jobs=-1)]: Done 1 out of 4 | elapsed: 9.0s remaining: 26.9s +[Parallel(n_jobs=-1)]: Done 4 out of 4 | elapsed: 9.2s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.657 (+/-0.025) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} \ No newline at end of file diff --git a/InriaBCIChallenge/batchio.py b/InriaBCIChallenge/batchio.py new file mode 100644 index 0000000..a5f5d27 --- /dev/null +++ b/InriaBCIChallenge/batchio.py @@ -0,0 +1,69 @@ +from pandas import read_csv +import os +from extras import * +import numpy as np +from model_gen import get_preproc + +def read_metadata(params): + """ + Return metadata about channels and extra associated information given in 'ChannelsLocation.csv' + """ + metadata_fname = "ChannelsLocation.csv" + return read_csv(os.path.join(params.data_dir,metadata_fname)) + +def read_maindata(params,type): + """ + Read training/testing set files and extract the essential X,y matrices + which can be processed further. To do this we first get list of files + corresponding to subjects given in 'settings.json'. Then parse these to + get a final list of dataframes with every item corresponding to a single + feedback event and mapped y label + :param params:'settings.json' paramters + :param type:'train' or 'test' + :return: if 'train' then returns X,y + if 'test' then returns X + """ + assert (type == "train" or type == "test"),"type field must be either train or test" + flist,subjsess_list = get_filelist(params,type) + X = [] + if type == "train": + train_labels = read_csv(os.path.join(params.data_dir,"TrainLabels.csv")) + y = [] + for findex in range(len(flist)): + X.extend(get_x(read_csv(flist[findex]),0,260)) + y.extend(train_labels[ + train_labels["IdFeedBack"].str.contains( + subjsess_list[findex])]["Prediction"]) + assert (len(X) == len(y)),"Training and Prediction Set values dont match" + return (np.array(X),y) + elif type == "test": + for findex in range(len(flist)): + X.extend(get_x(read_csv(flist[findex]),0,260)) + return (np.array(X)) + +def get_x(my_df,start_offset,end_offset): + """ + Every loaded csv file has EEG + EOG + FeedbackEvent info + This function takes a loaded csv, extracts the necessary feedback events + Finally depending on provided indices here it extracts required time periods + of data for every feedback event + :param my_df: csv read as dataframe + :return: list of dataframes where each dataframe corresponds + to data for a given time period corresponding to a FeedbackEvent + """ + fb_list = [] + fb_indices = my_df[my_df["FeedBackEvent"] == 1].index.tolist() + my_df = my_df.drop('FeedBackEvent', axis = 1).drop('Time',axis=1).drop('EOG',axis=1).as_matrix() + # my_df = my_df.drop('FeedBackEvent', axis = 1).as_matrix() + my_df = get_preproc().transform(my_df) + for fb_ind in fb_indices: + fb_list.append(my_df[fb_ind + start_offset:fb_ind + end_offset,:]) + return fb_list + + + + + + + + diff --git a/InriaBCIChallenge/classifier.py b/InriaBCIChallenge/classifier.py new file mode 100644 index 0000000..b43b75e --- /dev/null +++ b/InriaBCIChallenge/classifier.py @@ -0,0 +1,373 @@ +import theano +import theano.tensor as T +import numpy as np +import time +from copy import deepcopy,copy + +def shared_dataset(data_xy, borrow=True): + """ Function that loads the dataset into shared variables + + The reason we store our dataset in shared variables is to allow + Theano to copy it into the GPU memory (when code is run on GPU). + Since copying data into the GPU is slow, copying a minibatch everytime + is needed (the default behaviour if the data is not in a shared + variable) would lead to a large decrease in performance. + """ + data_x, data_y = data_xy + shared_x = theano.shared(np.asarray(data_x, + dtype=theano.config.floatX), + borrow=borrow) + shared_y = theano.shared(np.asarray(data_y, + dtype=theano.config.floatX), + borrow=borrow) + # When storing data on the GPU it has to be stored as floats + # therefore we will store the labels as ``floatX`` as well + # (``shared_y`` does exactly that). But during our computations + # we need them as ints (we use labels as index, and if they are + # floats it doesn't make sense) therefore instead of returning + # ``shared_y`` we will have to cast it to int. This little hack + # lets ous get around this issue + return shared_x, T.cast(shared_y, 'int32') + +class Layer: + """Neural Network Layer + """ + + def __init__(self, n_in, n_out,activation,hidden=False): + """ Initialize the parameters of the logistic regression + + :type input: theano.tensor.TensorType + :param input: symbolic variable that describes the input of the + architecture (one minibatch) + + :type n_in: int + :param n_in: number of input units, the dimension of the space in + which the datapoints lie + + :type n_out: int + :param n_out: number of output units, the dimension of the space in + which the labels lie + + :type activation: Tensor function + :param activation: tensor function + + """ + # start-snippet-1 + # initialize with 0 the weights W as a matrix of shape (n_in, n_out) + if hidden is True: + rng = np.random.RandomState(1234) + W_values = np.asarray( + rng.uniform( + low=-np.sqrt(6. / (n_in + n_out)), + high=np.sqrt(6. / (n_in + n_out)), + size=(n_in, n_out) + ), + dtype=theano.config.floatX + ) + if activation == T.nnet.sigmoid: + W_values *= W_values*4 + else: + W_values = np.zeros((n_in, n_out),dtype=theano.config.floatX) + self.W = theano.shared( + value= W_values, + name='W', + borrow=True + ) + # initialize the baises b as a vector of n_out 0s + self.b = theano.shared( + value=np.zeros( + (n_out,), + dtype=theano.config.floatX + ), + name='b', + borrow=True + ) + self.params = [self.W,self.b] + self.activation = activation + #self.ypred = T.argmax(self.decision_function_tensor(),axis=1) + + + def decision_function_tensor(self,tensor_x): + """ + Prediction function for Logistic Regression + :param data_x: TensorType input of data + :return:returns y predictions as a Tensor variable + """ + lin_op = (T.dot(tensor_x, self.W) + self.b) + if self.activation is None: + return lin_op + else: + return self.activation(lin_op) + + def negative_log_likelihood(self, tensor_x, tensor_y): + """Return the mean of the negative log-likelihood of the prediction + of this model under a given target distribution. + + :type y: theano.tensor.TensorType + :param y: corresponds to a vector that gives for each example the + correct label + + Note: we use the mean instead of the sum so that + the learning rate is less dependent on the batch size + """ + tensor_ypredproba = self.decision_function_tensor(tensor_x) + return -T.mean(T.log(tensor_ypredproba)[T.arange(tensor_y.shape[0]), tensor_y]) + +class LogisticRegression: + """ Apply minibatch logistic regression + + :type n_in: int + :param n_in: number of input units, the dimension of the space in + which the datapoints lie + + :type n_out: int + :param n_out: number of output units, the dimension of the space in + which the labels lie + + """ + + def __init__(self,n_in,n_out,batch_size=600,learning_rate=0.13,iterations=500,verbose=0): + self.n_in = n_in + self.n_out = n_out + self.batch_size = batch_size + self.learning_rate = learning_rate + self.iters = iterations + self.verbose = verbose + + def fit(self,data_x,data_y): + print "Training" + start = time.clock() + n_batches = data_x.get_value(borrow=True).shape[0]/self.batch_size + tensor_x = T.matrix('x') + tensor_y = T.ivector('y') + index = T.lscalar('index') + self.single_layer = Layer(self.n_in,self.n_out,T.nnet.softmax) + cost = self.single_layer.negative_log_likelihood(tensor_x, tensor_y) + g_W = T.grad(cost,self.single_layer.W) + g_b = T.grad(cost,self.single_layer.b) + updates = [(self.single_layer.W,self.single_layer.W - g_W*self.learning_rate), + (self.single_layer.b,self.single_layer.b - g_b*self.learning_rate)] + train_batch = theano.function([index],[cost], + updates=updates, + givens={tensor_x : data_x[index*self.batch_size : (index + 1)*self.batch_size], + tensor_y : data_y[index*self.batch_size : (index + 1)*self.batch_size]}) + train_batch_costs = [0 for i in xrange(n_batches)] + for iter in xrange(self.iters): + for minibatch_index in xrange(n_batches): + train_batch_costs[minibatch_index] = train_batch(minibatch_index) + if self.verbose==1: print "Iter %d --> %f" % (iter,np.mean(train_batch_costs)) + end = time.clock() + print "Finished Training Logistic Regression Model\n" \ + "Iterations %d\n" \ + "Time Taken : %d secs" % (self.iters,end - start) + + + def predict(self,data_x): + n_batches = data_x.get_value(borrow=True).shape[0]/self.batch_size + tensor_x = T.matrix('x') + index = T.lscalar('index') + tensor_ypred = self.prediction_tensor(tensor_x) + predictor = theano.function([index],tensor_ypred, + givens={tensor_x : data_x[index*self.batch_size:(index + 1)*self.batch_size]}) + ypred = [predictor(i) for i in xrange(n_batches)] + return np.hstack(ypred) + + def predict_proba(self,data_x): + tensor_x = T.matrix('x') + tensor_ypredproba = self.single_layer.decision_function_tensor(tensor_x) + predproba_func = theano.function([],tensor_ypredproba, + givens={tensor_x : data_x}) + return predproba_func() + + def prediction_tensor(self,data_x): + """ + Returns the predicted y value as a tensor variable + :param tensor_x: TensorType matrix on input data + :return: TensorType tensor_ypred output + """ + return T.argmax(self.single_layer.decision_function_tensor(data_x),axis=1) + + def accuracy(self, data_x,data_y): + """Return a float representing the number of errors in the minibatch + over the total number of examples of the minibatch ; zero one + loss over the size of the minibatch + + :type y: theano.tensor.TensorType + :param y: corresponds to a vector that gives for each example the + correct label + """ + n_batches = data_x.get_value(borrow=True).shape[0]/self.batch_size + tensor_x = T.matrix('x') + tensor_y = T.ivector('y') + index = T.lscalar('index') + tensor_ypred = self.prediction_tensor(tensor_x) + if tensor_y.ndim != tensor_ypred.ndim: + raise TypeError( + 'y should have the same shape as self.y_pred', + ('y', tensor_y.type, 'y_pred', tensor_ypred.type) + ) + # check if y is of the correct datatype + if tensor_y.dtype.startswith('int'): + # the T.neq operator returns a vector of 0s and 1s, where 1 + # represents a mistake in prediction + avg_acc_tensor = T.mean(T.eq(tensor_ypred, tensor_y)) + else: + raise NotImplementedError() + avg_accuracy_fn = theano.function([index],avg_acc_tensor, + givens={tensor_x : data_x[index*self.batch_size:(index + 1)*self.batch_size], + tensor_y : data_y[index*self.batch_size:(index + 1)*self.batch_size]}) + avg_acc = np.mean([avg_accuracy_fn(i) for i in xrange(n_batches)]) + return avg_acc + +class MLP: + + def __init__(self,n_in,n_hidden,n_out,batch_size=600,learning_rate=0.13,iterations=200,l1=0.000,l2=0.0001,verbose=0): + self.n_in = n_in + self.n_hidden = n_hidden + self.n_out = n_out + self.hidden_layer = Layer(self.n_in,self.n_hidden,T.tanh,hidden=True) + self.reg_layer = Layer(self.n_hidden,self.n_out,T.nnet.softmax) + self.layers = [self.hidden_layer,self.reg_layer] + self.L1 = sum(abs(layer.W).sum() for layer in self.layers) + self.L2 = sum(abs(layer.W ** 2).sum() for layer in self.layers) + self.params = [] + for layer in self.layers: self.params.extend(layer.params) + self.batch_size = batch_size + self.learning_rate = learning_rate + self.iters = iterations + self.verbose = verbose + self.l1_factor = l1 + self.l2_factor = l2 + self.minibatch_count = 0 + self.train_err = [] + + def decision_function_tensor(self,tensor_x): + final_dec_fn = tensor_x + for layer in self.layers: + final_dec_fn = layer.decision_function_tensor(final_dec_fn) + return final_dec_fn + + def negative_log_likelihood(self,tensor_x,tensor_y): + tensor_ypredproba = self.decision_function_tensor(tensor_x) + return -T.mean(T.log(tensor_ypredproba)[T.arange(tensor_y.shape[0]), tensor_y]) + + def minibatch_trainer(self,data_x,data_y): + tensor_x = T.matrix('x') + tensor_y = T.ivector('y') + cost = ( + self.negative_log_likelihood(tensor_x, tensor_y) + + self.l1_factor * self.L1 + + self.l2_factor * self.L2 + ) + # compute the gradient of cost with respect to theta (sotred in params) + # the resulting gradients will be stored in a list gparams + gparams = [T.grad(cost, param) for param in self.params] + updates = [ + (param, param - self.learning_rate * gparam) + for param, gparam in zip(self.params, gparams) + ] + train_batch = theano.function([],[cost], + updates=updates, + givens={tensor_x : data_x, + tensor_y : data_y}) + return train_batch() + + def partial_fit(self,data_x,data_y): + self.minibatch_count += 1 + self.train_err.append(self.minibatch_trainer(data_x,data_y)) + if self.minibatch_count % 1000: + if self.verbose==1: print "Iter %d --> %f" % (self.minibatch_count,np.mean(self.train_err)) + self.train_err = [] + + def fit(self,data_x,data_y): + # Initializations + tensor_x = T.matrix('x') + tensor_y = T.ivector('y') + index = T.lscalar('index') + print "Training" + start = time.clock() + n_batches = data_x.get_value(borrow=True).shape[0]/self.batch_size + cost = ( + self.negative_log_likelihood(tensor_x, tensor_y) + + self.l1_factor * self.L1 + + self.l2_factor * self.L2 + ) + # compute the gradient of cost with respect to theta (sotred in params) + # the resulting gradients will be stored in a list gparams + gparams = [T.grad(cost, param) for param in self.params] + updates = [ + (param, param - self.learning_rate * gparam) + for param, gparam in zip(self.params, gparams) + ] + train_batch = theano.function([index],[cost], + updates=updates, + givens={tensor_x : data_x[index*self.batch_size : (index + 1)*self.batch_size], + tensor_y : data_y[index*self.batch_size : (index + 1)*self.batch_size]}) + train_batch_costs = [0 for i in xrange(n_batches)] + for iter in xrange(self.iters): + for minibatch_index in xrange(n_batches): + train_batch_costs[minibatch_index] = train_batch(minibatch_index) + if self.verbose==1: print "Iter %d --> %f" % (iter,np.mean(train_batch_costs)) + end = time.clock() + print "Finished Training Logistic Regression Model\n" \ + "Iterations %d\n" \ + "Time Taken : %d secs" % (self.iters,end - start) + + def predict(self,data_x): + n_batches = data_x.get_value(borrow=True).shape[0]/self.batch_size + tensor_x = T.matrix('x') + index = T.lscalar('index') + tensor_ypred = self.prediction_tensor(tensor_x) + predictor = theano.function([index],tensor_ypred, + givens={tensor_x : data_x[index*self.batch_size: + (index + 1)*self.batch_size]}) + ypred = [predictor(i) for i in xrange(n_batches)] + return np.hstack(ypred) + + def predict_proba(self,data_x): + tensor_x = T.matrix('x') + tensor_ypredproba = self.decision_function_tensor(tensor_x) + predproba_func = theano.function([],tensor_ypredproba, + givens={tensor_x : data_x}) + return predproba_func() + + def prediction_tensor(self,tensor_x): + """ + Returns the predicted y value as a tensor variable + :param tensor_x: TensorType matrix on input data + :return: TensorType tensor_ypred output + """ + return T.argmax(self.decision_function_tensor(tensor_x),axis=1) + + def accuracy(self, data_x,data_y): + """Return a float representing the number of errors in the minibatch + over the total number of examples of the minibatch ; zero one + loss over the size of the minibatch + + :type y: theano.tensor.TensorType + :param y: corresponds to a vector that gives for each example the + correct label + """ + n_batches = data_x.get_value(borrow=True).shape[0]/self.batch_size + tensor_x = T.matrix('x') + tensor_y = T.ivector('y') + index = T.lscalar('index') + tensor_ypred = self.prediction_tensor(tensor_x) + if tensor_y.ndim != tensor_ypred.ndim: + raise TypeError( + 'y should have the same shape as self.y_pred', + ('y', tensor_y.type, 'y_pred', tensor_ypred.type) + ) + # check if y is of the correct datatype + if tensor_y.dtype.startswith('int'): + # the T.neq operator returns a vector of 0s and 1s, where 1 + # represents a mistake in prediction + avg_acc_tensor = T.mean(T.eq(tensor_ypred, tensor_y)) + else: + raise NotImplementedError() + avg_accuracy_fn = theano.function([index],avg_acc_tensor, + givens={tensor_x : data_x[index*self.batch_size:(index + 1)*self.batch_size], + tensor_y : data_y[index*self.batch_size:(index + 1)*self.batch_size]}) + avg_acc = np.mean([avg_accuracy_fn(i) for i in xrange(n_batches)]) + return avg_acc + diff --git a/InriaBCIChallenge/extras.py b/InriaBCIChallenge/extras.py new file mode 100644 index 0000000..d4321bb --- /dev/null +++ b/InriaBCIChallenge/extras.py @@ -0,0 +1,78 @@ +import json +import os +import numpy as np + +class Params: + """ + Variable used to associate parameters derived from 'settings.json' + Usage + >>> params = Params() + >>> params.var1 = 100 + """ + pass + + +def load_params(): + """ + Load parameters from settings.json and store in Params object variable + :return:set of parameters loaded from settings.json + """ + json_data = open("settings.json") + data = json.load(json_data) + params = Params() + params.data_dir = data["data_dir"] + params.cache_dir = data["cache_dir"] + params.train_subjects = data["train_subjects"] + return params + +def get_num_subjects(fnames): + """ + Given the list of filenames(training/testing) it returns the list of subjects to which these files point + :param fnames: list of filenames + :return:list of assosciated subjects + """ + fnames = [f.split("_")[1] for f in fnames] + subjects = list(set([int(f.strip("S")) for f in fnames])) + return subjects + +def get_filelist(params,type): + """ + Given the params variable and type of set required it returns only + those list of files corresponding to number of subjects given for training input + :param params: fixed Params containing values loaded from settings.json + :param type: 'train' or 'test' + :return: list of sorted files + list of associated subjects + """ + assert (type == "train" or type == "test"),"type field must be either train or test" + data_path = os.path.join(params.data_dir,type) + if type == "train" : num_subjects = params.train_subjects + if type == "test" : num_subjects = 10 #all subjects + file_list = [] + subj_sess_names = [] + for dirname,_,fnames in os.walk(data_path): + subjects = get_num_subjects(fnames)[:num_subjects] + subjects.sort() + fnames.sort() + for f in fnames: + subj_num = int(f.split("_")[1].strip("S")) + if subj_num in subjects: + file_list.append(os.path.join(data_path,f)) + subj_sess_names.append(f.strip("Data_").strip(".csv")) + return file_list,subj_sess_names + +# def visualize_pretform(X,y,chan): +# Xerr = [] +# Xnoerr = [] +# X = X[:,:,chan] +# for i in xrange(len(y)): +# if y[i] == 1: +# Xerr.append(X[i]) +# else: +# Xnoerr.append(X[i]) +# Xerravg = np.mean(np.vstack(Xerr),axis=0) +# Xnoerravg = np.mean(np.vstack(Xnoerr),axis=0) +# plt.plot(Xerravg,"--go",label="Error") +# plt.plot(Xnoerravg,"--ro",label = "No Error") +# plt.legend() +# plt.show() + diff --git a/InriaBCIChallenge/filters.py b/InriaBCIChallenge/filters.py new file mode 100644 index 0000000..34abfb5 --- /dev/null +++ b/InriaBCIChallenge/filters.py @@ -0,0 +1,158 @@ +from __future__ import division +from scipy.signal import cheby1,filtfilt,butter,ellip +import numpy as np + +""" +Contains +->Chebyshev Filter +->Butterworth Filter +->Elliptic Filter +Add +-2d data handling +""" + +class BaseFilter: + + def fit(self,X,y=None): + return self + + def transform(self,X): + return X + +class ChebshevFilter(BaseFilter): + + def __init__(self,sampling_rate,fc1 = 0.1,fc2 = 15,order = 8,ripple = 0.5,input_type="continuous"): + self.fc1 = fc1 + self.fc2 = fc2 + self.order = order + self.ripple = ripple + self.fe = sampling_rate + self.input_type = input_type + + def make_filter(self): + b,a = cheby1(self.order,self.ripple,[float(2*self.fc1)/self.fe,float(2*self.fc2)/self.fe],btype="bandpass",output="ba") + return b,a + + def transform(self,X): + b,a = self.make_filter() + if self.input_type == "epoched": + n_epochs,n_samples,n_channels = X.shape + Xfilt = np.zeros((n_epochs,n_samples,n_channels)) + for epoch in xrange(n_epochs): + for channel in xrange(n_channels): + Xfilt[epoch,:,channel] = filtfilt(b,a,X[epoch,:,channel]) + elif self.input_type == "continuous": + n_samples,n_channels = X.shape + Xfilt = np.zeros((n_samples,n_channels)) + for channel in xrange(n_channels): + Xfilt[:,channel] = filtfilt(b,a,X[:,channel].T) + else: + raise Exception("Incorrect input-type : choose 'epoched'/'continuous'") + return Xfilt + + def __repr__(self): + return '_'.join(["ChebyshevFilter",str(self.fc1),str(self.fc2),str(self.order),str(self.fe),str(self.input_type),str(self.ripple)]) + +class ButterworthFilter(BaseFilter): + + def __init__(self,fc1 = 0.1,fc2 = 15,order = 8,sampling_rate = 128,input_type="continuous"): + self.fc1 = fc1 + self.fc2 = fc2 + self.order = order + self.fe = sampling_rate + self.input_type = input_type + + def make_filter(self): + b,a = butter(self.order,[2*self.fc1/self.fe,2*self.fc2/self.fe],output="ba",btype="bandpass") + return b,a + + def transform(self,X): + b,a = self.make_filter() + if self.input_type == "epoched": + n_epochs,n_samples,n_channels = X.shape + Xfilt = np.zeros((n_epochs,n_samples,n_channels)) + for epoch in xrange(n_epochs): + for channel in xrange(n_channels): + Xfilt[epoch,:,channel] = filtfilt(b,a,X[epoch,:,channel]) + elif self.input_type == "continuous": + n_samples,n_channels = X.shape + Xfilt = np.zeros((n_samples,n_channels)) + for channel in xrange(n_channels): + Xfilt[:,channel] = filtfilt(b,a,X[:,channel].T) + else: + raise Exception("Incorrect input-type : choose 'epoched'/'continuous'") + return Xfilt + + def __repr__(self): + return '_'.join(["ButterworthFilter",str(self.fc1),str(self.fc2),str(self.order),str(self.fe),str(self.input_type)]) + +class EllipticFilter(BaseFilter): + + def __init__(self,fc1 = 0.1,fc2 = 15,order = 8,sampling_rate = 128,attentuation = 60,input_type="continuous"): + self.fc1 = fc1 + self.fc2 = fc2 + self.order = order + self.fe = sampling_rate + self.input_type = input_type + self.attentuation = attentuation + + def make_filter(self): + b,a = ellip(self.order,self.attentuation,[2*self.fc1/self.fe,2*self.fc2/self.fe],output="ba",btype="bandpass") + return b,a + + def transform(self,X): + b,a = self.make_filter() + if self.input_type == "epoched": + n_epochs,n_samples,n_channels = X.shape + Xfilt = np.zeros((n_epochs,n_channels,n_samples)) + for epoch in xrange(n_epochs): + for channel in xrange(n_channels): + Xfilt[epoch,:,channel] = filtfilt(b,a,X[epoch,:,channel]) + elif self.input_type == "continuous": + n_samples,n_channels = X.shape + Xfilt = np.zeros((n_samples,n_channels)) + for channel in xrange(n_channels): + Xfilt[:,channel] = filtfilt(b,a,X[:,channel]) + else: + raise Exception("Incorrect input-type : choose 'epoched'/'continuous'") + return Xfilt + + def __repr__(self): + return '_'.join(["EllipticFilter",str(self.fc1),str(self.fc2),str(self.order),str(self.fe),str(self.input_type)]) + +class FilterBank(BaseFilter): + + def __init__(self,fc1 = 0.1,fc2 = 15,order = 8,ripple = 0.5,sampling_rate = 128,M = 8,input_type="continuous"): + self.fc1 = fc1 + self.fc2 = fc2 + self.order = order + self.fs = sampling_rate + self.input_type = input_type + self.ripple = ripple + self.M = M + self.d = (fc2 - fc1)/M + + def filter_params(self,m): + Wn = [2*(self.fc1 + self.d*(m))/self.fs,2*(self.fc1 + self.d*(m+1))/self.fs] + b,a = cheby1(self.order,self.ripple,Wn,btype="bandpass") + return b,a + + def transform(self,X): + if self.input_type == "epoched": + n_epochs,n_samples,n_channels = X.shape + Xfilt = np.zeros((n_epochs,n_samples,n_channels*self.M)) + for epoch in xrange(n_epochs): + for channel in xrange(n_channels): + for m in xrange(self.M): + b,a = self.filter_params(m) + Xfilt[epoch,:,self.M*channel + m] = filtfilt(b,a,X[epoch,:,channel]) + elif self.input_type == "continuous": + n_samples,n_channels = X.shape + Xfilt = np.zeros((n_samples,n_channels*self.M)) + for channel in xrange(n_channels): + for m in xrange(self.M): + b,a = self.filter_params(m) + Xfilt[:,self.M*channel + m] = filtfilt(b,a,X[:,channel]) + else: + raise Exception("Incorrect input-type : choose 'epoched'/'continuous'") + return Xfilt \ No newline at end of file diff --git a/InriaBCIChallenge/logs.txt b/InriaBCIChallenge/logs.txt new file mode 100644 index 0000000..e258550 --- /dev/null +++ b/InriaBCIChallenge/logs.txt @@ -0,0 +1,49 @@ +CV Logs +GBM + SubjectFeedbackinfo + Cz features +with cv_iterator(8 fold) = 0.531 for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05} +with 4 fold cv = 0.617 (+/-0.030) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05} + +GBM + SubjectFeedbackinfo + Filtered Cz features chan 28 +with cv_iterator(16 fold) = 0.547 (+/-0.034) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +with 4 fold cv = 0.670 (+/-0.022) for {'max_features': 0.5, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} + +GBM + SubjectFeedbackinfo + Filtered chan 29 features +with cv_iterator(8 fold) = +with 4 fold cv = + +GBM + SubjectFeedbackinfo + Filtered chan 30 features +with cv_iterator(8 fold) = +with 4 fold cv = + +GBM + SubjectFeedbackinfo + Filtered all chan features +with cv_iterator(16 fold) = 0.546 (+/-0.035)/0.548 (+/-0.032) for Downsampling different rates +with 4 fold cv = 0.648/0.655 for Downsampling different rates + +GBM + SubjectFeedbackinfo + Filtered 28-30 chan features +with cv_iterator(16 fold) = 0.552 (+/-0.032)/0.557 (+/-0.033)/0.559 (+/-0.032) + + +GBM + Cz features +with cv_iterator(8 fold) = 0.509 (+/-0.025) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05} +with 4 fold cv = 0.540 (+/-0.009) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05} + +GBM + Filtered Cz features(chan 28) +with cv_iterator(8 fold) = 0.587 (+/-0.005) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05} +with 4 fold cv = 0.546 (+/-0.038) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05} + + +GBM + Chan 29 features +with cv_iterator(8 fold) = 0.513 (+/-0.024) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05} +with 4 fold cv = 0.528 (+/-0.013) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05} + +GBM + Filtered Chan 29 features +with cv_iterator(8 fold) = 0.562 (+/-0.035) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05} +with 4 fold cv = 0.580 (+/-0.008) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05} + +GBM + Filtered Chan 30 features +with cv_iterator(8 fold) = 0.554 (+/-0.038) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05} +with 4 fold cv = 0.581 (+/-0.005) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05} + +GBM on each channel separatly +Grid scores on development set: +0.604 (+/-0.030) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} diff --git a/InriaBCIChallenge/losocvlogs.txt b/InriaBCIChallenge/losocvlogs.txt new file mode 100644 index 0000000..419956f --- /dev/null +++ b/InriaBCIChallenge/losocvlogs.txt @@ -0,0 +1,1343 @@ +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched__WaveletTransform__EEGConcatExtracter__Downsampler_dec_8 +[Parallel(n_jobs=-1)]: Done 1 out of 1651 | elapsed: 0.1s remaining: 3.4min +[Parallel(n_jobs=-1)]: Done 2721 out of 5440 | elapsed: 17.1s remaining: 17.1s +[Parallel(n_jobs=-1)]: Done 5440 out of 5440 | elapsed: 35.2s finished +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.5s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.2s remaining: 3.6s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.0s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.554 (+/-0.025) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.3s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.1s remaining: 3.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.0s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.559 (+/-0.032) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched____EEGConcatExtracter__Downsampler_dec_8 +(5440, 260, 3) +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.8s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.4s remaining: 2.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.551 (+/-0.030) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched__FlattenedFFT_47 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.503 (+/-0.026) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched__FreqEigNCoeff_47 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 10.5s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 30.3s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.512 (+/-0.017) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.3s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.2s remaining: 3.7s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.3s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.556 (+/-0.030) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.2s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.1s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.567 (+/-0.034) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_25_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.3s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.9s remaining: 3.2s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.0s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.561 (+/-0.037) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_30_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.2s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.1s remaining: 3.6s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.2s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.558 (+/-0.031) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_6_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.1s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.1s remaining: 3.5s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.0s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.564 (+/-0.031) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_20_6_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.1s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.1s remaining: 3.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.0s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.561 (+/-0.032) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_25_6_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.3s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.1s remaining: 3.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.0s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.561 (+/-0.034) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_30_6_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.3s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.0s remaining: 3.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.0s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.562 (+/-0.035) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_15_8_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.3s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.0s remaining: 3.3s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.9s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.533 (+/-0.020) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_20_8_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.3s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.529 (+/-0.014) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_25_8_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.1s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.9s remaining: 3.2s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.1s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.512 (+/-0.020) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_30_8_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.2s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.5s remaining: 4.1s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.2s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.518 (+/-0.022) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.3s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.2s remaining: 3.7s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.9s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.563 (+/-0.034) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 7.2s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 8.7s remaining: 14.5s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 21.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.560 (+/-0.038) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[18, 19, 20, 28, 29, 30]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 2.2s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 3.0s remaining: 4.9s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 6.4s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.558 (+/-0.035) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[18, 19, 20, 28, 29, 30]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 14.0s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 16.1s remaining: 26.8s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 42.2s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.544 (+/-0.036) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +____KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_20_4_200_epoched__GlobalFeatures +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 4.1s remaining: 6.8s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 7.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.558 (+/-0.032) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +/data/.virtualenvs/P300BCI/local/lib/python2.7/site-packages/sklearn/lda.py:161: UserWarning: Variables are collinear + warnings.warn("Variables are collinear") +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.3s +/data/.virtualenvs/P300BCI/local/lib/python2.7/site-packages/sklearn/lda.py:161: UserWarning: Variables are collinear + warnings.warn("Variables are collinear") +/data/.virtualenvs/P300BCI/local/lib/python2.7/site-packages/sklearn/lda.py:161: UserWarning: Variables are collinear + warnings.warn("Variables are collinear") +/data/.virtualenvs/P300BCI/local/lib/python2.7/site-packages/sklearn/lda.py:161: UserWarning: Variables are collinear + warnings.warn("Variables are collinear") +/data/.virtualenvs/P300BCI/local/lib/python2.7/site-packages/sklearn/lda.py:161: UserWarning: Variables are collinear + warnings.warn("Variables are collinear") +/data/.virtualenvs/P300BCI/local/lib/python2.7/site-packages/sklearn/lda.py:161: UserWarning: Variables are collinear + warnings.warn("Variables are collinear") +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.4s remaining: 2.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.2s finished +Cross Validation Stats +Best parameters set: +LDA(n_components=None, priors=None) +Grid scores on development set: +0.557 (+/-0.025) for {} +Training +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 6 candidates, totalling 96 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 6.5min +[Parallel(n_jobs=-1)]: Done 50 jobs | elapsed: 27.1min +[Parallel(n_jobs=-1)]: Done 96 out of 96 | elapsed: 45.2min finished +Cross Validation Stats +Best parameters set: +SVC(C=1, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0, + kernel='linear', max_iter=-1, probability=False, random_state=None, + shrinking=True, tol=0.001, verbose=False) +Grid scores on development set: +0.525 (+/-0.025) for {'kernel': 'linear', 'C': 0.1} +0.500 (+/-0.000) for {'kernel': 'rbf', 'C': 0.1} +0.525 (+/-0.025) for {'kernel': 'linear', 'C': 0.5} +0.500 (+/-0.000) for {'kernel': 'rbf', 'C': 0.5} +0.536 (+/-0.030) for {'kernel': 'linear', 'C': 1} +0.500 (+/-0.000) for {'kernel': 'rbf', 'C': 1} +__KeepChannel_[28, 29, 30]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 3 candidates, totalling 48 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 6.7min +[Parallel(n_jobs=-1)]: Done 38 out of 48 | elapsed: 39.9min remaining: 10.5min +[Parallel(n_jobs=-1)]: Done 48 out of 48 | elapsed: 56.1min finished +Cross Validation Stats +Best parameters set: +SVC(C=1, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0, + kernel='linear', max_iter=-1, probability=False, random_state=None, + shrinking=True, tol=0.001, verbose=False) +Grid scores on development set: +0.536 (+/-0.030) for {'kernel': 'linear', 'C': 1} +0.533 (+/-0.027) for {'kernel': 'linear', 'C': 2} +0.525 (+/-0.025) for {'kernel': 'linear', 'C': 3} +Training +__KeepChannel_[46]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_4 +Fitting 16 folds for each of 4 candidates, totalling 64 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 2.6s +[Parallel(n_jobs=-1)]: Done 50 jobs | elapsed: 27.4s +[Parallel(n_jobs=-1)]: Done 54 out of 64 | elapsed: 28.9s remaining: 5.3s +[Parallel(n_jobs=-1)]: Done 64 out of 64 | elapsed: 35.8s finished +Cross Validation Stats +Best parameters set: +RandomForestClassifier(bootstrap=True, compute_importances=None, + criterion='gini', max_depth=3, max_features='auto', + max_leaf_nodes=None, min_density=None, min_samples_leaf=1, + min_samples_split=2, n_estimators=3000, n_jobs=1, + oob_score=False, random_state=42, verbose=0) +Grid scores on development set: +0.570 (+/-0.034) for {'n_estimators': 3000, 'max_depth': 1, 'verbose': 0} +0.586 (+/-0.040) for {'n_estimators': 3000, 'max_depth': 2, 'verbose': 0} +0.595 (+/-0.048) for {'n_estimators': 3000, 'max_depth': 3, 'verbose': 0} +0.595 (+/-0.050) for {'n_estimators': 3000, 'max_depth': 4, 'verbose': 0} +__KeepChannel_[46]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_4 +Fitting 16 folds for each of 18 candidates, totalling 288 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 10.8s +[Parallel(n_jobs=-1)]: Done 50 jobs | elapsed: 1.7min +[Parallel(n_jobs=-1)]: Done 200 jobs | elapsed: 9.2min +[Parallel(n_jobs=-1)]: Done 278 out of 288 | elapsed: 14.7min remaining: 31.7s +[Parallel(n_jobs=-1)]: Done 288 out of 288 | elapsed: 15.2min finished +Cross Validation Stats +Best parameters set: +RandomForestClassifier(bootstrap=True, compute_importances=None, + criterion='gini', max_depth=3, max_features=0.75, + max_leaf_nodes=None, min_density=None, min_samples_leaf=1, + min_samples_split=4, n_estimators=6000, n_jobs=1, + oob_score=False, random_state=42, verbose=0) +Grid scores on development set: +0.599 (+/-0.050) for {'max_features': 0.25, 'min_samples_split': 2, 'n_estimators': 6000, 'max_depth': 3} +0.599 (+/-0.050) for {'max_features': 0.25, 'min_samples_split': 3, 'n_estimators': 6000, 'max_depth': 3} +0.599 (+/-0.050) for {'max_features': 0.25, 'min_samples_split': 4, 'n_estimators': 6000, 'max_depth': 3} +0.601 (+/-0.050) for {'max_features': 0.5, 'min_samples_split': 2, 'n_estimators': 6000, 'max_depth': 3} +0.601 (+/-0.050) for {'max_features': 0.5, 'min_samples_split': 3, 'n_estimators': 6000, 'max_depth': 3} +0.601 (+/-0.050) for {'max_features': 0.5, 'min_samples_split': 4, 'n_estimators': 6000, 'max_depth': 3} +0.602 (+/-0.050) for {'max_features': 0.75, 'min_samples_split': 2, 'n_estimators': 6000, 'max_depth': 3} +0.602 (+/-0.050) for {'max_features': 0.75, 'min_samples_split': 3, 'n_estimators': 6000, 'max_depth': 3} +0.603 (+/-0.050) for {'max_features': 0.75, 'min_samples_split': 4, 'n_estimators': 6000, 'max_depth': 3} +0.598 (+/-0.051) for {'max_features': 0.25, 'min_samples_split': 2, 'n_estimators': 6000, 'max_depth': 4} +0.598 (+/-0.051) for {'max_features': 0.25, 'min_samples_split': 3, 'n_estimators': 6000, 'max_depth': 4} +0.598 (+/-0.051) for {'max_features': 0.25, 'min_samples_split': 4, 'n_estimators': 6000, 'max_depth': 4} +0.599 (+/-0.051) for {'max_features': 0.5, 'min_samples_split': 2, 'n_estimators': 6000, 'max_depth': 4} +0.599 (+/-0.051) for {'max_features': 0.5, 'min_samples_split': 3, 'n_estimators': 6000, 'max_depth': 4} +0.599 (+/-0.051) for {'max_features': 0.5, 'min_samples_split': 4, 'n_estimators': 6000, 'max_depth': 4} +0.600 (+/-0.050) for {'max_features': 0.75, 'min_samples_split': 2, 'n_estimators': 6000, 'max_depth': 4} +0.600 (+/-0.050) for {'max_features': 0.75, 'min_samples_split': 3, 'n_estimators': 6000, 'max_depth': 4} +0.600 (+/-0.050) for {'max_features': 0.75, 'min_samples_split': 4, 'n_estimators': 6000, 'max_depth': 4} +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.583 (+/-0.036) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[46]__ButterworthFilter_0.1_20_6_200_epoched__EEGConcatExtracter__Downsampler_dec_4 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.0s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.604 (+/-0.034) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[46]__ButterworthFilter_0.1_20_8_200_epoched__EEGConcatExtracter__Downsampler_dec_4 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.9s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.6s remaining: 2.7s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.1s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.527 (+/-0.031) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[46]__ChebyshevFilter_0.1_20_8_200_epoched_0.5__EEGConcatExtracter__Downsampler_dec_4 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.1s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.8s remaining: 3.0s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.2s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.525 (+/-0.024) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[46]__ChebyshevFilter_0.1_20_6_200_epoched_0.5__EEGConcatExtracter__Downsampler_dec_4 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.1s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.8s remaining: 2.9s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.2s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.594 (+/-0.030) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[46]__ChebyshevFilter_0.1_20_4_200_epoched_0.5__EEGConcatExtracter__Downsampler_dec_4 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.0s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.7s remaining: 2.9s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.1s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.599 (+/-0.038) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +######################## +CHANNEL SELECTION +######################## +Training +__KeepChannel_[0]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.1s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.1s remaining: 3.6s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.5s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.536 (+/-0.029) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[1]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.0s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.3s remaining: 3.8s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.9s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.504 (+/-0.021) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[2]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.2s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.3s remaining: 3.8s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.528 (+/-0.036) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[3]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.8s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.5s remaining: 4.2s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.521 (+/-0.022) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[4]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.2s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.5s remaining: 4.1s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.521 (+/-0.028) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[5]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.1s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.4s remaining: 4.0s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.511 (+/-0.026) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[6]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.2s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.2s remaining: 3.7s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.524 (+/-0.032) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[7]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.1s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.3s remaining: 3.8s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.0s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.543 (+/-0.029) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[8]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.2s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.7s remaining: 4.5s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 5.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.527 (+/-0.033) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[9]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.8s remaining: 3.1s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.9s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.531 (+/-0.032) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[10]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.4s remaining: 2.3s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.1s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.520 (+/-0.030) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[11]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.5s remaining: 2.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.536 (+/-0.025) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[12]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.7s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.531 (+/-0.023) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[13]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.7s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.8s remaining: 2.9s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.534 (+/-0.030) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[14]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.5s remaining: 2.5s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.8s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.531 (+/-0.017) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[15]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.9s remaining: 3.1s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.559 (+/-0.031) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[16]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.1s remaining: 3.5s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.8s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.562 (+/-0.038) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[17]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.7s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.6s remaining: 2.6s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.8s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.547 (+/-0.028) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[18]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.9s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.534 (+/-0.031) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[19]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.6s remaining: 2.6s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.529 (+/-0.030) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[20]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.7s remaining: 2.8s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.5s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.551 (+/-0.034) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +__KeepChannel_[20]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.8s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.4s remaining: 2.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.547 (+/-0.034) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[21]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.7s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.3s remaining: 2.2s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.546 (+/-0.026) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[22]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.8s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.4s remaining: 2.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.526 (+/-0.027) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[23]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.7s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.3s remaining: 2.2s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.552 (+/-0.030) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[24]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.8s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.4s remaining: 2.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.572 (+/-0.038) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[25]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.7s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.3s remaining: 2.1s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.5s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.554 (+/-0.033) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[26]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.8s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.4s remaining: 2.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.564 (+/-0.036) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[27]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.8s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.4s remaining: 2.3s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.552 (+/-0.039) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[28]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.8s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.4s remaining: 2.3s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.551 (+/-0.035) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[29]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.7s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.3s remaining: 2.2s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.5s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.558 (+/-0.034) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[30]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.7s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.4s remaining: 2.3s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.576 (+/-0.031) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[31]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.7s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.4s remaining: 2.3s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.576 (+/-0.035) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[32]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.8s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.5s remaining: 2.5s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.8s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.574 (+/-0.035) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[33]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.7s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.4s remaining: 2.3s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.568 (+/-0.034) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[34]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.0s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.583 (+/-0.037) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[35]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.2s remaining: 2.0s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.5s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.579 (+/-0.041) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[36]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.7s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.3s remaining: 2.2s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.577 (+/-0.041) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[37]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.2s remaining: 2.0s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.4s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.567 (+/-0.038) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[38]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.2s remaining: 2.0s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.4s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.579 (+/-0.037) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[39]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.8s remaining: 3.0s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.9s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.589 (+/-0.029) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +__KeepChannel_[40]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.8s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.7s remaining: 2.9s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 4.0s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.569 (+/-0.028) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[41]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.5s remaining: 2.5s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.2s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.559 (+/-0.029) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[42]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.8s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.7s remaining: 2.9s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.5s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.571 (+/-0.035) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[43]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.0s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.8s remaining: 3.0s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.571 (+/-0.036) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[44]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.0s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.8s remaining: 3.0s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.8s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.562 (+/-0.039) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[45]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.7s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.9s remaining: 3.2s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.576 (+/-0.042) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[46]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.9s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.7s remaining: 2.9s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.597 (+/-0.034) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[47]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.1s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.7s remaining: 2.8s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.576 (+/-0.038) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[48]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.9s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.7s remaining: 2.9s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.8s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.561 (+/-0.033) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[49]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.0s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.7s remaining: 2.8s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.6s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.546 (+/-0.033) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[50]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 1.1s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.7s remaining: 2.8s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.7s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.559 (+/-0.026) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[51]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 2.0s remaining: 3.4s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 3.8s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.583 (+/-0.036) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[52]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.2s remaining: 2.0s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.4s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.588 (+/-0.032) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} +Training +__KeepChannel_[53]__ButterworthFilter_0.1_20_4_200_epoched__EEGConcatExtracter__Downsampler_dec_8 +Fitting 16 folds for each of 1 candidates, totalling 16 fits +[Parallel(n_jobs=-1)]: Done 1 jobs | elapsed: 0.6s +[Parallel(n_jobs=-1)]: Done 6 out of 16 | elapsed: 1.2s remaining: 2.0s +[Parallel(n_jobs=-1)]: Done 16 out of 16 | elapsed: 2.4s finished +Cross Validation Stats +Best parameters set: +GradientBoostingClassifier(init=None, learning_rate=0.05, loss='deviance', + max_depth=2, max_features=0.25, max_leaf_nodes=None, + min_samples_leaf=1, min_samples_split=2, n_estimators=500, + random_state=None, subsample=1.0, verbose=0, + warm_start=False) +Grid scores on development set: +0.523 (+/-0.021) for {'max_features': 0.25, 'n_estimators': 500, 'learning_rate': 0.05, 'max_depth': 2} diff --git a/InriaBCIChallenge/main.py b/InriaBCIChallenge/main.py new file mode 100644 index 0000000..950334f --- /dev/null +++ b/InriaBCIChallenge/main.py @@ -0,0 +1,121 @@ +from batchio import * +from transforms import SubjectFeedbackInfo,EOGInfo +from extras import load_params +from sklearn.grid_search import GridSearchCV +from model_gen import proc_generator,clf_generator +import itertools +from classifier import shared_dataset + +def cross_validation(X,y,clf,cv_params): + cv_iterator = cv_indices(16,X.shape[0]) + clf_cv = GridSearchCV(clf,cv_params,cv=cv_iterator,scoring="roc_auc",n_jobs=-1,verbose=1) + X,y = shared_dataset((X,y)) + clf_cv.fit(X,y) + print "Cross Validation Stats" + print("Best parameters set:") + print(clf_cv.best_estimator_) + print("Grid scores on development set:") + for params, mean_score, scores in clf_cv.grid_scores_: + print("%0.3f (+/-%0.03f) for %r" + % (mean_score, scores.std() / 2, params)) + return clf_cv + +def cv_indices(num_folds,num_samples): + """ + Given number of samples and num_folds automatically create a subjectwise cross validator + Assumption: per subject we have 340 samples of data + >>> cv_set = cv_indices(2,680) + >>> cv_set + >>> (([0:340],[340:680]),([340:680,0:340])) + Algo: + 1.Compute all the permutations. + 2.itreate through all the permutations and first calculate the train indices by taking first five then + six,seven so on of each combination of arrangement.The rest will be the values of test indices + 3. Finally zip it to form the indices. + :param num_folds: folds for cv + :param num_samples: number of samples of input of data (should be a multiple of 340) + :return: return a zipped list of tuples + of ranges of training and testing data + """ + n_epoch = 340 + n_subjects = num_samples/n_epoch + rem=num_samples%n_epoch + assert (rem == 0),"samples passed in not a multiple of 340" + assert (num_folds<=n_subjects),"number of subjects is less then number of folds" + n_set = np.round(n_subjects/num_folds) + n_set = int(n_set) + n_subjects=int(n_subjects) + flag=[] + for i in range(num_folds): + if i21): + Xds = scipy.signal.resample(Xfilt,math.floor(n_samples/2)) + n_samples=len(Xds) + b,a = scipy.signal.cheby1(4,0.5,cutoff_freq/2,btype='low') + Xfiltds = scipy.signal.filtfilt(b,a,Xds) + tformed.append(Xfiltds) + XWT2D.append(np.hstack(tformed)) + return np.vstack(XWT2D).T + +class WaveletTransform(BaseTransformer): + + #added by Ani + + def __init__(self,fs=247.0,fc=47.0): + self.fs=fs + self.fc=fc + + + def transform(self,X): + n_epochs, n_samples, n_channels = X.shape + cutoff_freq = 2*self.fc/self.fs + # Parallel Test + XWT2d = np.array(Parallel(n_jobs=-1,verbose=2)(delayed(apply_wt)(X[k],cutoff_freq) + for k in xrange(n_epochs))) + #print(np.mean(XWT2d,axis=0)) + #mean=np.mean(XWT2d,axis=0) + #print mean.shape + return XWT2d + + def __repr__(self): + return "WaveletTransform" + +class ActualWaveletTransform(BaseTransformer): + """ + Apply Wavelet transform on Epoched EEG Data + Get the multilevel approx. coefficients + """ + def __init__(self): + self.wvlt = pywt.Wavelet('db2') + + def transform(self, X): + n_epochs,n_samples,n_channels = X.shape + print X.shape + Xwvtf = [] + for epoch in xrange(n_epochs): + Xepwvtf = [] + for chan in xrange(n_channels): + Xepwvtf.append(pywt.dwt(X[epoch,:,chan],self.wvlt)[0]) + Xwvtf.append(Xepwvtf) + Xwvtf = np.array(Xwvtf) + n_epochs,n_channels,n_samples = Xwvtf.shape + Xwvtf = Xwvtf.reshape(n_epochs,n_samples,n_channels) + return Xwvtf + + +class RejectChannel(BaseTransformer): + """ + Reject specific channels + """ + + def __init__(self, toreject, num_channels=64): + all = range(num_channels) + self.toreject = toreject + self.tokeep = list(set(all) - set(toreject)) + + + def transform(self, X): + return X[:, :, self.tokeep] + + def __repr__(self): + return "RejectChannel_" + str(self.toreject) + +class KeepChannel(BaseTransformer): + """ + Reject specific channels + """ + + def __init__(self, tokeep): + self.tokeep = tokeep + + + def transform(self, X): + num_epochs,num_samples,num_channels = X.shape + return X[:, :, self.tokeep].reshape(num_epochs,num_samples,len(self.tokeep)) + + def __repr__(self): + return "KeepChannel_" + str(self.tokeep) + +class FlattenedFFT(BaseTransformer): + def __init__(self, slice_index): + self.slice_index = slice_index + + def transform(self, X): + n_epochs, n_samples, n_channels = X.shape + Xfft = [] + for ep in xrange(n_epochs): + xfft = [] + for chan in xrange(n_channels): + xfft.append(np.log10(np.abs(np.fft.rfft(X[ep, :, chan], axis=0)[1:self.slice_index]))) + Xfft.append(np.hstack(xfft)) + return np.vstack(Xfft) + + def __repr__(self): + return "FlattenedFFT_" + str(self.slice_index) + +class FreqEigNCoeff(BaseTransformer): + def __init__(self, slice_index): + self.slice_index = slice_index + + def transform(self, X): + n_epochs, n_samples, n_channels = X.shape + Xfft = [] + for ep in xrange(n_epochs): + xfft = [] + for chan in xrange(n_channels): + xfft.append(np.log10(np.abs(np.fft.rfft(X[ep, :, chan], axis=0)[1:self.slice_index]))) + # Here samples per channel are features + scaled = scale(np.vstack(xfft).T, axis=0) + corr_matrix = np.corrcoef(scaled) + eigenvalues = np.abs(np.linalg.eig(corr_matrix)[0]) + eigenvalues.sort() + corr_coefficients = self.upper_right_triangle(corr_matrix) + Xfft.append(np.concatenate((corr_coefficients, eigenvalues))) + return np.vstack(Xfft) + + def upper_right_triangle(self, corr_matrix): + num_d1, num_d2 = corr_matrix.shape + coeff = [] + for i in xrange(num_d1): + coeff.append(corr_matrix[i, i:]) + return np.hstack(coeff) + + def __repr__(self): + return "FreqEigNCoeff_" + str(self.slice_index) + +class TimeEigNCoeff(BaseTransformer): + """ + Finds Time Eigenvalues and Flattened Correlation Matrix + """ + + def transform(self, X): + n_epochs, n_samples, n_features = X.shape + Xtime = [] + for ep in xrange(n_epochs): + scaled = scale(np.vstack(X[ep].T), axis=0) + corr_matrix = np.corrcoef(scaled) + eigenvalues = np.abs(np.linalg.eig(corr_matrix)[0]) + eigenvalues.sort() + corr_coefficients = self.upper_right_triangle(corr_matrix) + Xtime.append(np.concatenate((corr_coefficients, eigenvalues))) + return np.vstack(Xtime) + + def upper_right_triangle(self, corr_matrix): + num_d1, num_d2 = corr_matrix.shape + coeff = [] + for i in xrange(num_d1): + coeff.append(corr_matrix[i, i:]) + return np.hstack(coeff) + + def __repr__(self): + return "TimeEigNCoeff_" + +class GlobalFeatures(BaseTransformer): + """ + iterate through the matrix of 180*165*64(flashes,samples,channels) + """ + + def transform(self, X): + n_epochs, n_samples, n_channels = X.shape + Xop = [] + for i in range(n_epochs): + output = [] + data_current = X[i] + times = len(data_current)-1 + # delta1 = data_current[1:,:] - data_current[:times,:] # the 1st derivative + # delta2 = delta1[1:,:] - delta1[:times-1,:] # the 2nd derivative + output.append(np.max(data_current,axis=0)) + output.append(np.min(data_current,axis=0)) + output.append(np.var(data_current,axis=0)) + output.append(np.std(data_current,axis=0)) + output.append(np.mean(data_current,axis=0)) + output.append(np.median(data_current,axis=0)) + # output.append(np.max(np.max(np.absolute(data_current), axis=0))) + # output.append(np.mean(np.max(np.absolute(data_current), axis=0))) + # output.append(np.var(np.max(np.absolute(data_current), axis=0))) + # output.append(np.var(np.max(data_current, axis=0))) + # output.append(np.var(np.var(np.absolute(data_current), axis=0))) + # output.append(np.mean(np.var(np.absolute(data_current), axis=0))) + # # 1st Derivative Global Features + # output.append(np.max(np.max(np.absolute(delta1), axis=0))) + # output.append(np.mean(np.max(np.absolute(delta1), axis=0))) + # output.append(np.var(np.max(np.absolute(delta1), axis=0))) + # output.append(np.var(np.max(delta1, axis=0))) + # output.append(np.var(np.var(np.absolute(delta1), axis=0))) + # output.append(np.mean(np.var(np.absolute(delta1), axis=0))) + # # 2nd Derivative Global Features + # output.append(np.max(np.max(np.absolute(delta2), axis=0))) + # output.append(np.mean(np.max(np.absolute(delta2), axis=0))) + # output.append(np.var(np.max(np.absolute(delta2), axis=0))) + # output.append(np.var(np.max(delta2, axis=0))) + # output.append(np.var(np.var(np.absolute(delta2), axis=0))) + # output.append(np.mean(np.var(np.absolute(delta2), axis=0))) + Xop.append(np.hstack(output)) + return np.vstack(Xop) + + def __repr__(self): + return "GlobalFeatures" + +class xDAWN_filtering(BaseTransformer): + + def fit(self, X, y): + if y is not None: + X,D = self.generate_teoplitz_matrix(X,y) + self.generate_filter(X,D) + else: + pass + + def transform(self, X): + n_epochs,n_samples,n_channels=X.shape + Xflat = X.reshape((n_epochs*n_samples,n_channels)) + filters = self.filters_load() + projected_data = np.dot(Xflat,filters) + del Xflat,filters + """ + Now make the data into epochs + """ + xDAWN=np.zeros((n_samples,n_channels)) + for i in range(n_epochs): + xDAWN= np.dstack((xDAWN,projected_data[i*n_samples:(i+1)*n_samples,:])) + return xDAWN[:,:,1:].T + + + def generate_teoplitz_matrix(self,X,y): + """ + label corresponding to the flashing(1 for target) + run this code for all the data epochs + """ + n_epochs,n_samples,n_channels = X.shape + Xflat = X.reshape((n_epochs*n_samples,n_channels)) + for i in xrange(n_epochs): + if y[i] == 1: + D1 = np.diag(np.ones(n_samples)) + else: + D1 = np.zeros((n_samples, n_samples)) + + if i==0: + D = D1 + else: + D = np.vstack((D, D1)) + return Xflat,D + + + def generate_filter(self, X ,D): + + """ + Compute QR factorisation + """ + # QR decompositions of X and D + Qx, Rx = np.linalg.qr(X) + # QR decompositions of D + Qd, Rd = np.linalg.qr(D) + + """ + Compute SVD Qd.T Qx + + """ + Phi, Lambda, Psi = np.linalg.svd(np.dot(Qd.T, Qx),full_matrices=True) + Psi = Psi.T + #construct spatial filters + for i in range(Psi.shape[1]): + # Construct spatial filter with index i as Rx^-1*Psi_i + ui = np.dot(np.linalg.inv(Rx), Psi[:,i]) #eq 12 + if i < Phi.shape[1]: + ai = np.dot(np.dot(np.linalg.inv(Rd), Phi[:,i]),Lambda[i]) #eq 15 + if i == 0: + filters = np.atleast_2d(ui).T + ai = np.atleast_2d(ai) + else: + filters = np.hstack((filters,np.atleast_2d(ui).T)) + if i < Phi.shape[1]: + ai = np.vstack((ai, np.atleast_2d(ai))) + self.filters_dump(filters) + return filters + + def filters_dump(self,obj): + f = open("filters.temp","wb") + pkl.dump(obj,f) + f.close() + + def filters_load(self): + f = open("filters.temp","r") + obj = pkl.load(f) + f.close() + return obj + + def __repr__(self): + return "xDAWN_filtering" \ No newline at end of file diff --git a/TFI/.ipynb_checkpoints/EDA-checkpoint.ipynb b/TFI/.ipynb_checkpoints/EDA-checkpoint.ipynb new file mode 100644 index 0000000..63cfba6 --- /dev/null +++ b/TFI/.ipynb_checkpoints/EDA-checkpoint.ipynb @@ -0,0 +1,114 @@ +{ + "metadata": { + "name": "" + }, + "nbformat": 3, + "nbformat_minor": 0, + "worksheets": [ + { + "cells": [ + { + "cell_type": "code", + "collapsed": false, + "input": [ + "from ggplot import *\n", + "import pandas as pd\n", + "import numpy as np" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 1 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "from extras import load_params\n", + "from pandas import read_csv,DataFrame\n", + "import os\n", + "import numpy as np\n", + "\n", + "def init_transforms(data):\n", + " data[\"City\"] = data[\"City\"].apply(lambda x:str(x))\n", + " data[\"is_big_city\"] = data[\"City Group\"].apply(lambda x:int(x==\"Big Cities\"))\n", + " data[\"start_year\"] = data[\"Open Date\"].apply(lambda x:int(x[6:]))\n", + " data[\"start_month\"] = data[\"Open Date\"].apply(lambda x:int(x[:2]))\n", + " data[\"start_day\"] = data[\"Open Date\"].apply(lambda x:int(x[3:5]))\n", + " data[\"num_years\"] = data[\"start_year\"].apply(lambda x:2015 - x)\n", + " data[\"num_months\"] = data[\"num_years\"].apply(lambda x:x*12) - data[\"start_month\"].apply(lambda x:12-x)\n", + " data[\"Type_FC\"] = data[\"Type\"].apply(lambda x:int(x==\"FC\"))\n", + " data[\"Type_IL\"] = data[\"Type\"].apply(lambda x:int(x==\"IL\"))\n", + " data[\"Type_DT\"] = data[\"Type\"].apply(lambda x:int(x==\"DT\"))\n", + " data[\"Type_MB\"] = data[\"Type\"].apply(lambda x:int(x==\"MB\"))\n", + " data = data.drop([\"Id\",\"City\",\"City Group\",\"Open Date\",\n", + " \"Type\"],axis=1)\n", + " return data" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 2 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "def load_data(data_type,shuffle=True):\n", + " assert(data_type == \"train\" or data_type == \"test\" or data_type == \"cv\")\n", + " if data_type == \"cv\": data_type = \"train\"\n", + " path = os.path.join(load_params().data_dir,data_type + \".csv\")\n", + " data = read_csv(path)\n", + " # print data.columns.values\n", + " if data_type != \"test\":\n", + " if shuffle: data = data.reindex(np.random.permutation(data.index))\n", + " y = data.revenue.values\n", + " data = data.drop([\"revenue\"],axis=1)\n", + " data = init_transforms(data)\n", + " return data,y\n", + " #X = data.as_matrix()\n", + " #return np.log(X + 1),y\n", + " else:\n", + " data = init_transforms(data)\n", + " return data\n", + " #X = data.as_matrix()\n", + " #return np.log(X + 1)" + ], + "language": "python", + "metadata": {}, + "outputs": [], + "prompt_number": 8 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [ + "X,y = load_data(\"train\")\n", + "print X" + ], + "language": "python", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "None\n" + ] + } + ], + "prompt_number": 6 + }, + { + "cell_type": "code", + "collapsed": false, + "input": [], + "language": "python", + "metadata": {}, + "outputs": [] + } + ], + "metadata": {} + } + ] +} \ No newline at end of file diff --git a/TFI/EDA.ipynb b/TFI/EDA.ipynb new file mode 100644 index 0000000..941c423 --- /dev/null +++ b/TFI/EDA.ipynb @@ -0,0 +1,406 @@ +{ + "worksheets": [ + { + "cells": [ + { + "cell_type": "code", + "metadata": {}, + "outputs": [], + "input": [ + "from ggplot import *\n", + "import pandas as pd\n", + "import numpy as np\n", + "from extras import load_params\n", + "from pandas import read_csv,DataFrame\n", + "import os\n", + "import numpy as np" + ], + "language": "python", + "prompt_number": 118 + }, + { + "cell_type": "code", + "metadata": {}, + "outputs": [], + "input": [ + "%matplotlib inline" + ], + "language": "python", + "prompt_number": 119 + }, + { + "cell_type": "code", + "metadata": {}, + "outputs": [], + "input": [ + "def init_transforms(data):\n", + " data[\"City\"] = data[\"City\"].apply(lambda x:str(x))\n", + " data[\"is_big_city\"] = data[\"City Group\"].apply(lambda x:int(x==\"Big Cities\"))\n", + " data[\"start_year\"] = data[\"Open Date\"].apply(lambda x:int(x[6:]))\n", + " data[\"start_month\"] = data[\"Open Date\"].apply(lambda x:int(x[:2]))\n", + " data[\"start_day\"] = data[\"Open Date\"].apply(lambda x:int(x[3:5]))\n", + " data[\"num_years\"] = data[\"start_year\"].apply(lambda x:2015 - x)\n", + " data[\"num_months\"] = data[\"num_years\"].apply(lambda x:x*12) - data[\"start_month\"].apply(lambda x:12-x)\n", + " data[\"Type_FC\"] = data[\"Type\"].apply(lambda x:int(x==\"FC\"))\n", + " data[\"Type_IL\"] = data[\"Type\"].apply(lambda x:int(x==\"IL\"))\n", + " data[\"Type_DT\"] = data[\"Type\"].apply(lambda x:int(x==\"DT\"))\n", + " data[\"Type_MB\"] = data[\"Type\"].apply(lambda x:int(x==\"MB\"))\n", + " data = data.drop([\"Id\",\"City\",\"City Group\",\"Open Date\",\n", + " \"Type\",\"start_year\",\"start_month\",\"start_day\",\"num_years\"],axis=1)\n", + " return data" + ], + "language": "python", + "prompt_number": 120 + }, + { + "cell_type": "code", + "metadata": {}, + "outputs": [], + "input": [ + "def load_data(data_type,shuffle=False):\n", + " assert(data_type == \"train\" or data_type == \"test\" or data_type == \"cv\")\n", + " if data_type == \"cv\": data_type = \"train\"\n", + " path = os.path.join(load_params().data_dir,data_type + \".csv\")\n", + " data = read_csv(path)\n", + " # print data.columns.values\n", + " if data_type != \"test\":\n", + " if shuffle: data = data.reindex(np.random.permutation(data.index))\n", + " #y = data.revenue.values\n", + " #data = data.drop([\"revenue\"],axis=1)\n", + " data = init_transforms(data)\n", + " return data\n", + " #X = data.as_matrix()\n", + " #return np.log(X + 1),y\n", + " else:\n", + " data = init_transforms(data)\n", + " return data\n", + " #X = data.as_matrix()\n", + " #return np.log(X + 1)" + ], + "language": "python", + "prompt_number": 121 + }, + { + "cell_type": "code", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "Applied log(X+1)\n" + ] + }, + { + "output_type": "display_data", + "png": "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\nKE4IBQCgOCEUAIDihFAAAIqr1m0MmJS6urrS0dGRJGlvb09ra+sEVwQAHG1CKBOqq6srK1euTGdn\nZ5LkoYceyvr16wVRAJjinI5nQnV0dAwG0CTp7OwcfFcUAJi6hFAAAIoTQplQ7e3taWtrG3zc1taW\n9vb2CawIACjBNaFMqNbW1qxfv94HkwCgYoRQJlxra2s+97nPTXQZAEBBTscDAFCcEAoAQHFCKAAA\nxQmhAAAUJ4QCAFCcEAoAQHFCKAAAxQmhAAAUJ4QCAFCcEAoAQHFCKAAAxQmhAAAUJ4QCAFCcEAoA\nQHFCKAAAxQmhAAAUJ4QCAFCcEAoAQHFCKAAAxQmhAAAUJ4QCAFCcEAoAQHFCKAAAxQmhAAAUJ4QC\nAFCcEAoAQHFCKAAAxTVOdAHHkq6urnR0dCRJ2tvb09raOuzyJIccv3nz5lx33XXZtGlTkuQ1r3lN\n/uVf/iWLFy8e3NZjjz2WT3ziE0mSb3zjGzn99NNzxx13pK+vb3BbmzdvzurVq/OHP/whF110Uf76\nr/968PfXXXdd/ud//ienn356vva1rw1ue/8aV61alY6OjvzgBz/IiSeemC996Uu577778vjjj2fZ\nsmX50Ic+lNtuuy33339/tm3bllqtlssuuyyf+tSnsm7dukM+DwN19/f3521ve1vmz5+fvXv35je/\n+U3OOuusXH311YPrrlq1atifp0+fnr/5m78ZrPvmm2/O448/nte+9rWZNWtWkqRer2fWrFlD6hht\nnw5cPtpxh7J58+Zcf/31SZI1a9YM6e1ItvvCCy/k5ptvHtPc4+GV7PvR3BYAU0dDvV6vT3QRY7V1\n69b09vYWmaurqysrV65MZ2dnkqStrS3r168fEnz2Xz4QOjZv3jxkfHd3dy688ML09fUN2X5jY2N+\n+MMfZvHixXnsscdy+eWXD1l+6qmnZsuWLYPb+sd//MesXLlyyP6fdtppuemmm/L+979/yPYHtt3S\n0jKkxsbGxoPq2N/06dOzb9++YX+///NwqLoPVKvVBmtuamrKSy+9NOzPr3vd63LbbbflQx/60OBz\neSgDdSQZVZ8OXD5gpOMOZfPmzbnooouG7M8PfvCDLF68eETb7erqyqpVq/Lkk0+Oeu7x8Er2fazb\nqtVqWbBgQdFjerKYNWtWdu/ePdFlFFPVXletz4leV8lAr0dr+g033HDD+JdTxq5du9Lf319krptu\nuikPPPDA4OMXXnghtVot559//iGXd3d3p7u7+6Dxt99+e5555pmDtt/f358NGzbkT//0T3P55Zdn\nx44dQ5b39PQM2dbDDz+cbdu2DRnz4osv5uGHHx4ydv9tP//880NqPNJzd7h/n+z/+/2fh0PVfaj9\nHLB/wD3cz1u3bs2vfvWrbNiwYdjtDtTx85//fFR9OnD5gJGOO5SPfexjg/9gGNifgd6OZLuvZO7x\nMJ7zj3Rb06dPz5w5c4oe05NFrVYb9h+DU01Ve121Pid6XSUDvR4t14QCAFCcEDpC7e3taWtrG3zc\n1tY2eN3noZYvXrx4yHWAA+PXrFmTxsaDL8VtbGzMmjVrkrx8DeiBTj311CHb+sY3vpFarTZkzGmn\nnZZvfOMbB21/YNsH1nioOvY3ffr0I/5+/+fhUHUfaP+am5qajvjz6173unzlK18Z8lweykAdo+3T\ngctHO+5Q1qxZc9D+DPR2JNttb2/PkiVLxjT3eHgl+340twXA1OKa0FHwwaSJ+WBSvV7PH/7wh0p9\nMGnXrl2V+mBSVa8dS6p3/VhVe121Pid6XSVjvSZUCD2GVO2FXdU/YIleV4leV0PV+pzodZWMNYQ6\nHQ8AQHFCKAAAxQmhAAAUJ4QCAFCcEAoAQHFCKAAAxR2zX9G0Z8+e7Nmz57C3lpyKpk2bVqlbnzU0\nNAzeR75KfU70ukr0uhqq1udEr6ukoaEh8+fPH/V6w98yZxKbOXNmtm/f7rvHprBarZb58+dn586d\nlepzotdVotfVULU+J3pdJQfewXGknI4HAKA4IRQAgOKEUAAAihNCAQAoTggFAKA4IRQAgOKEUAAA\nihNCAQAoTggFAKA4IRQAgOKEUAAAihNCAQAoTggFAKA4IRQAgOKEUAAAihNCAQAoTggFAKA4IRQA\ngOKEUAAAihNCAQAoTggFAKA4IRQAgOKEUAAAihNCAQAoTggFAKA4IRQAgOIaJ7qAya6rqysdHR1J\nkvb29rS2to54vZtuuin//d//nbPOOiuXXXZZ/u7v/i5J8pd/+Zf56le/miRZs2ZNWlpaDppjJPOO\npraurq7cfPPN+a//+q88//zzWbBgQZYuXZpNmzalXq/nTW96U1avXn3IbWzevDnXX3/9kNp7e3tz\nxhlnZMOGDXn66acze/bsvOUtb8nvf//7JMk555yTT33qU4PbO7DWJIOPV61alXXr1o36Od5/3266\n6ab87Gc/G7Ivw82x/7Lh5hx43h5//PEsW7bsoOdoLK+P4dYZWNbY2JiPfvSjY+r7WF+zo93GeMzD\n0adPHA1eV4yHhnq9Xp/oIsZq69at6e3tPWrb7+rqysqVK9PZ2ZkkaWtry/r16494sHV1deXKK6/M\n5s2bjzhHrVbLySefnKeeempwjttuuy0f//jHD5r35JNPzu7du0dd20jrWbx4ce65554h29i8eXMu\nuuiivPTSS0fcl8NtL8mQWhcvXjy47SRpamoa3P7++1Gr1bJgwYJh+3y4fTvttNMyffr0Q85x4PyH\ne+4Ote39n6OxvD6GW2ck2zvSmLG+Zkda42jGjMZIej1VzZo1a/C4Hm/j3afxUNVeH80+lzbS15Ve\nV8dAr0dr+g033HDD+JdTxq5du9Lf33/Utn/TTTflgQceGHz8wgsvpFar5fzzzz/ieg899NCI5ujv\n78+LL744ZI4NGzbkV7/61UHzXnDBBenr6xt1bSOtp7u7+6BtfOxjH8uWLVtGtC+H297Pf/7zIbV2\nd3enu7t78PG+ffsOuR/Tp0/PnDlzhu3z4fbtxRdfPOwcB85/uOfuUNve/zkay+tjuHVGsr0jjRnr\na3akNY5mzGiMpNdTVa1WGzyux9t492k8VLXXR7PPpY30daXX1THQ69FyTSgAAMUJocNob29PW1vb\n4OO2trbB6wmPtN7AKd8jqdVqOe2004bMsWbNmiPOO5raRlrP4sWLD9rGmjVr0tTUNJJdOez2Dqx1\n8eLFQ+rZf/sjfY4HHG7fTjvttMPOceD8h5vzUNve/zkay+tjuHVGsr0jjRnra3Y0c4zXPBx9+sTR\n4HXFeHFN6BFMpg8mHXidyVT/YNJIryfywaRj/4NJVb12LDn6149Ntg+QVLXXU+06wZG8rvS6OsZ6\nTagQegyp2gu7qn/AEr2uEr2uhqr1OdHrKhlrCHU6HgCA4oRQAACKE0IBAChOCAUAoDghFACA4oRQ\nAACKE0IBAChOCAUAoDghFACA4oRQAACKE0IBAChOCAUAoDghFACA4oRQAACKE0IBAChOCAUAoLjG\nUhPdc8892bhxY+bMmZNrr732oOW/+93vsnbt2rS0tCRJli5dmhUrVpQqDwCAgoZ9J3T79u25/vrr\nc+mll+amm25Kb29v/uRP/iRz587N+eefn82bN494orPOOitXX331sGMWLVqUT37yk/nkJz8pgAIA\nTGHDhtBrrrkmv/zlL/Pe974399xzTy677LK0trbmP//zP3PmmWfmU5/61IgnWrRoUWbOnPmKCwYA\n4Ng37On4733ve9m8eXPmzZuXq666Kscff3x6enoyZ86crFmzJqeccsq4FdLQ0JAtW7bklltuydy5\nc/POd74zJ5xwwrhtHwCAyeOI14ROm/bym6UNDQ2HfDxeFi5cmM985jNpamrKxo0bs3bt2qxevTpJ\n0tPTkx07dgwZ39zcnMbGYpe0TgrTp09PrVab6DKKGehv1fqc6HWV6HU1VK3PiV5XyVh7POxal1xy\nSVatWpUrrrgi3/nOd3LhhRfmr/7qr/KJT3wiHR0dedOb3jSmSQ9lxowZgz+fccYZuf/++7Nr167M\nnj07jz32WB555JEh41esWJG3v/3t4zY/k9fAh9WY+vS6OvS6OvSawxk2hH7ta1/LDTfckHvuuSfv\nete7ct111+WDH/xgzjvvvJx55pm58847x62QHTt2ZM6cOWloaMgzzzyTer2e2bNnJ0mWL1+eJUuW\nDBnf3Nyc7u7u9PX1jVsNk92MGTOyd+/eiS6jmMbGxrS0tFSuz4leV4leV0PV+pzodZUM9HrU6w23\ncPr06ZkxY0aampqybdu2JMm6devGVOC6devy1FNPZdeuXbnxxhtzwQUXpL+/P0ly9tln54knnsij\njz6aadOmpVarZdWqVYPrzps3L/PmzTtom1u3bk1vb++Y6jkWNTY2Vmp/B/T19VVuv/W6OvS6Gqra\n50SvObxhQ+hf/MVf5Gc/+1ne9a53Zf369XnhhRfyz//8z2OaaP9QeSjnnHNOzjnnnDFtGwCAY8uw\nX9H04IMP5nvf+16+/OUv58EHH8x9991Xqi4AAKawYUPozp07c9JJJyVJTj311MFT8gAA8EoMezp+\n3759+eEPf5gkqdfr6evrG3w84MILLzx61QEAMCUNG0JPOOGE/Nmf/dng4+OOO27I4+Tle74DAMBo\nDBtCn3rqqUJlAABQJcNeEwoAAEeDEAoAQHFCKAAAxQmhAAAUJ4QCAFCcEAoAQHFCKAAAxQmhAAAU\nJ4QCAFCcEAoAQHFCKAAAxQmhAAAUJ4QCAFBc40QXwP/X1dWVjo6OJEl7e3taW1uHLLvjjjvS19d3\n0LLRbGc0Y46GiZoX4HD8XYKJIYROEl1dXVm5cmU6OzuTJA899FDWr1+f1tbWYZeNZjujGVN6HwEm\n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\nKVdccUWSl/+of/azn82iRYvyR3/0R7nmmmuyZ8+eJMnDDz+cU045JTfeeGNOPPHEnHTSSbnzzjsH\nt3PBBRfk9ttvH3x855135q1vfevg49/+9re5+OKLc9xxx+W1r33tkP9xAIxWvV7PzJkz88lPfnLw\nv+uuu27ImA0bNuT1r3/9K5pHCAU4grVr1+bBBx/M5s2bc8UVV+SLX/xiuru784//+I9ZuXJlXnjh\nhbz3ve/Nk08+mU2bNg2u961vfSsf/OAHkySf//zns2nTpvziF7/Ipk2b8uyzz+ZLX/rS4Ng//OEP\n6enpyf/+7//m9ttvz3XXXTd4T+aGhobDvtuwc+fOXHzxxbn66quzdevWrF27Ntdee21+85vfHMVn\nBJjKZs6cmZaWlvz6179O8nIo3f8DSFu3bs2ePXuGvS/8SAihAMNoaGjI6tWrc/LJJ+df//Vf8+53\nv3vw06EXXXRRzj777Nx///2ZPXt2rrjiivzbv/1bkmTjxo158sknc/nll6der6ejoyM33nhj5s+f\nn+bm5nzhC1/I2rVrB+ep1Wr54he/mOnTp+dd73pXmpub8+STTx6xvvvuuy+nn356PvKRj2TatGlZ\ntmxZ3v/+93s3FBixdevW5fbbb8///d//5cYbb8zjjz+e97///Xn88cdzyy235Gtf+9qQv0e//vWv\nX/G7oIlrQgGOaOBf+08//XS+/e1v57vf/e7gsr6+vsFPh1511VW5/vrr87d/+7f51re+lfe9732Z\nOXNmnn/++ezatSvLly8fXK9er6e/v3/w8XHHHZdp0/7/+wKzZ8/Ojh07jljb008/nZ/85CdpaWkZ\nUtOHP/zhse8wUCmrVq065O+vvvrqQ/7+ggsuGJd5hVCAIxg4Ff7qV786H/rQh3LrrbcectxFF12U\nrVu35he/+EXWrl2br3zlK0mS448/PrNmzcoTTzyRhQsXjnr+OXPmZOfOnYOP9z8t9upXvzorVqzI\n97///VFvF2AiOR0PMEJXX311vvvd7+b73/9+9u3blz179uThhx/Os88+m+TlU+of+MAH8tnPfjbd\n3d25+OKLkyTTpk1Le3t7Pv3pT2fr1q1JkmeffXbEwXHZsmX5zne+k927d2fTpk1DPqT0nve8J52d\nnfnmN7+Z3t7e9Pb25tFHH81vf/vbcd57gPElhAKM0CmnnJJ77703f//3f58TTjghr371q7NmzZoh\np9Wvuuqq/Md//Ec+8IEPDDm9/g//8A95zWtek3PPPTevetWrcvHFF6ezs3Nw+XBfc/KZz3wmTU1N\nOfHEE/PRj340V1999eD4uXPn5vvf/37Wrl2bk08+OQsXLswXvvCFvPTSS0fhGQAYPw31er0+0UUA\nAFAt3gkFAKA4IRQAgOKEUAAAihNCAQAoTggFAKA4IRQAgOKEUAAAihNCAQAo7v8BD+/QqEF+q/EA\nAAAASUVORK5CYII=\n", + "text": [ + "" + ], + "metadata": {} + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + }, + { + "output_type": "display_data", + "png": "iVBORw0KGgoAAAANSUhEUgAAAqEAAAHuCAYAAACvRNV6AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X1wlfWd///XSXJOckISEkKEAEo6wQC2g0DoiHcFFISt\nVVyFnV2LNyymFtgyODi7uJ1WtjPbnW9bLMUZ5U5l1amIIKECoqUUtnVmRW6KBQUSBhBxqZGckNsT\ncnP9/nByfhxycnJy9z5JrudjxhnPuT7X53qf631d8OJc15V4HMdxBAAAABhKiHcBAAAAcB9CKAAA\nAMwRQgEAAGCOEAoAAABzhFAAAACYS4p3AZ0VDAYVDAblpof7ExIS1NzcHO8yTHk8Hvl8Pl25coVe\n92Nu7bNEr93CbX2W6LWbeDweZWZmdni9PhtCU1JSVFVVpYaGhniXYsbv96uuri7eZZjyer3KzMxU\nTU0Nve7H3NpniV67hdv6LNFrN/F6vZ1aj8vxAAAAMEcIBQAAgDlCKAAAAMwRQgEAAGCOEAoAAABz\nhFAAAACYI4QCAADAHCEUAAAA5gihAAAAMEcIBQAAgDlCKAAAAMwRQgEAAGCOEAoAAABzhFAAAACY\nI4QCAADAHCEUAAAA5gihAAAAMEcIBQAAgDlCKAAAAMwRQgEAAGCOEAoAAABzhFAAAACYI4QCAADA\nHCEUAAAA5gihAAAAMEcIBQAAgDlCKAAAAMwRQgEAAGCOEAoAAABzhFAAAACYI4QCAADAHCEUAAAA\n5gihAAAAMEcIBQAAgDlCKAAAAMwRQgEAAGCOEAoAAABzhFAAAACYI4QCAADAXJLFRi5fvqxt27ap\npqZGklRYWKjJkydHHHvhwgVt2LBBc+fO1U033WRRHgAAAIyZhNCEhATNnDlTubm5qq+v17p165Sf\nn6+cnJywcc3Nzfr973+vUaNGWZQFAACAODEJoenp6UpPT5ckJScna/DgwaqqqmoVQj/88EPddNNN\n+uKLLyzKMlNeXq7169dLkoqKijRo0KBOzfHKK6+osbFRc+bM0ZYtWyLO19a2ysvL9fzzz+vIkSMa\nP368lixZElMdkea79j1JXfp8V883ffp0Pfvss7p48aKmT5+uf//3f291nMRSo7XeUENn9NW6AQB9\nn8dxHMdyg4FAQBs3btSiRYuUnJwcer+yslJvv/22HnvsMW3fvl0FBQWhy/GVlZWqrq4OmyctLU1N\nTU1qbGy0LL/DLl26pNmzZ+vUqVOSpIKCAm3fvl3Z2dmdnsPn8+nKlSut5mtrW5L0ve99T6dPnw7N\nmZ+frx07dkStI9J8Gzdu1OOPPx56Lz8/X5JCc3f08127jWvl5eXpo48+UmJiYsRed8f+7aqeqCE5\nOVn19fXdVWJEvWHftUhKSlJWVpYCgUCvP6e7m0WvexO39tptfZbotZu09LrDHEPBYNBZs2aN88kn\nn7Ra9uabbzrnz593HMdx3n77bef48eOhZXv37nWeffbZsP/27t1rVndX/PjHP3Ykhf334x//uMtz\nRJqvrW21tX57dURa7/bbb49aS0c/X3ufrb35umP/dlVvqKEz+mrdAID+weRyvCQ1NTVp8+bNGjdu\nnMaOHdtq+RdffBG6xFxbW6vS0lIlJCRozJgxKiws1OjRo8PGp6Wl9Yl/XdXW1kZ8r6ysrEtzRJqv\nrW21t15HttvQ0BC1lljmjbW+q7XV6+7Yv13VEzVY/Eu6N+y7Fm79xkRy37cmbu212/os0Ws36ew3\noSaX4x3H0bZt25SamqpZs2a1O764uDjscnxbysrKYgpF8VReXq6HHnoo7JLn1q1bO3Tv3bVzXHs5\nvmW+trYlSQ888ECry/HFxcVR64g034YNG/TEE09EvRzfkc937Tau1XI53nGciL3ujv3bVT1Rg9/v\nV11dXXeVGFFv2HctvF6vcnJy+sQ53d0set2buLXXbuuzRK/dpKXXHWUSQs+dO6dXXnlFQ4YMkcfj\nkSTdfffdunz5siRp0qRJYeP7UwiVeDCpI9uI9GDSmDFjova6Nzxc0901WP0h1hv2neTev6wk9/2F\n5dZeu63PEr12k14dQnsKB3b/xx9i7uDWPkv02i3c1meJXrtJZ0MovzEJAAAA5gihAAAAMEcIBQAA\ngDlCKAAAAMwRQgEAAGCOEAoAAABzhFAAAACYI4QCAADAHCEUAAAA5gihAAAAMEcIBQAAgDlCKAAA\nAMwRQgEAAGCOEAoAAABzhFAAAACYI4QCAADAHCEUAAAA5gihAAAAMEcIBQAAgDlCKAAAAMwRQgEA\nAGCOEAoAAABzhFAAAACYI4QCAADAHCEUAAAA5gihAAAAMEcIBQAAgDlCKAAAAMwRQgEAAGCOEAoA\nAABzhFAAAACYI4QCAADAHCEUAAAA5gihAAAAMEcIBQAAgDlCKAAAAMwRQgEAAGCOEAoAAABzhFAA\n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\nJScn68KFC/riiy80bNgw5ebm6uDBg/rzn/+so0ePatq0aRoxYkTUOWtra9Xc3GxRvlavXq1du3aF\nXl+6dEler1d33HFHm2M6orm5WceOHdOXX34Z+sb02uUtmpqa9N577ykYDIaNqaio0LFjx/Tpp5+2\nWn/fvn3asWNHq3tro22nu/ZttHkqKipUUVHR5vhLly7J5/PphRde0GeffRY25tr1oonUr2hWr16t\n3bt3h70XCARimuOf//mfw/4R0NTUpGPHjukf//Efoy67etttHWvtHYexHKexfPaOHuttbSfWcYmJ\niRowYIDpOd1beL1eV31L5NZeu63PEr12k5Zed5TZ5fg5c+ZEXT5gwAA9/PDDRtUAAAAgnviNSTEq\nKipSQUFB6HVBQYGKioqijumIpKQkrVy5UkVFRbr++usjLm/h8/m0du3aVk/f5eXlaeXKlRHXX7t2\nrdauXdtuHVfP2V1P90V7ai4vLy90ST7SdgsKCrR06VKtWrVKPp8vbMy160UTqV/RFBUVhV0il76+\nHB/LHCtXrgyr1efzaeXKle0uu3rbV98DfXXt7R2HsRyn7enMsd7WdrqjHgBA/2R6T2h3s77PpLy8\nXOvXr5f09V+uke6zaxkTDAYVCAT05z//WUOHDtV//Md/aM+ePZKk6dOn69/+7d9CDybdeOONWrdu\nXSj0lJeX62c/+5l27dqltLQ0rV+/XpmZmXr66aflOI5WrlwZur9wyZIl+tvf/qbp06frX//1X0P3\nDV67fmFhoSTp0KFDevLJJ9XQ0KCsrCxVVlYqKytLKSkp+va3v61HHnlEW7ZskfT1t9evvfaa9u3b\nF3owaeXKlTp8+LD+93//t9WDSS0Plu3bt081NTW64YYbdOedd+qRRx7Ra6+9pr/85S8aM2aMJOnE\niROaMGGCfvSjH0mSnn/+eR05ckTjx48Pq2HhwoUaM2aMysrKdOLECS1btkzS12EuKytL69evV11d\nXcQHklpe+/3+NvvVXr9Xr16tv/zlL6FaY53j9OnTYbVeHWijLWtRW1sbejDp2trbOw5jOU7b05Fj\nvb3txDLOrfeOSe67f8ytvXZbnyV67SadvSeUENqHuPnAptf9m1v7LNFrt3BbnyV67SadDaFcjgcA\nAIA5QigAAADMEUIBAABgjhAKAAAAc4RQAAAAmCOEAgAAwBwhFAAAAOYIoQAAADBHCAUAAIA5QigA\nAADMEUIBAABgjhAKAAAAc4RQAAAAmCOEAgAAwBwhFAAAAOYIoQAAADBHCAUAAIA5QigAAADMEUIB\nAABgjhAKAAAAc4RQAAAAmCOEAgAAwBwhFAAAAOYIoQAAADBHCAUAAIA5QigAAADMEUIBAABgjhAK\nAAAAc4RQAAAAmCOEAgAAwBwhFAAAAOYIoQAAADBHCAUAAIA5QigAAADMEUIBAABgjhAKAAAAc4RQ\nAAAAmPM4juPEu4jOCAaDCgaD6qPld0pCQoKam5vjXYYpj8cjn8+nK1eu0Ot+zK19lui1W7itzxK9\ndhOPx6PMzMwOr5fUA7WYSElJUVVVlRoaGuJdihm/36+6urp4l2HK6/UqMzNTNTU19Lofc2ufJXrt\nFm7rs0Sv3cTr9XZqPS7HAwAAwBwhFAAAAOYIoQAAADBHCAUAAIA5QigAAADMEUIBAABgjhAKAAAA\nc4RQAAAAmCOEAgAAwBwhFAAAAOYIoQAAADBHCAUAAIA5QigAAADMEUIBAABgjhAKAAAAc4RQAAAA\nmCOEAgAAwBwhFAAAAOYIoQAAADBHCAUAAIA5QigAAADMEUIBAABgjhAKAAAAc4RQAAAAmCOEAgAA\nwBwhFAAAAOYIoQAAADBHCAUAAIA5QigAAADMEUIBAABgjhAKAAAAc4RQAAAAmCOEAgAAwBwhFAAA\nAOYIoQAAADCXFO8Cervy8nKtX79eklRUVKRBgwZ1ea5gMCjHceT3+1VUVCRJUd9v2fbw4cNjqi3S\n+21tOxAIaNmyZZKkn/zkJ9qzZ0/E+X7xi19oz549GjJkiFavXq38/PxW27m23qv3VaSxzz//vI4c\nOaLx48dryZIlHdq3Hdn2tePnzJmj119/PeZtRzsGOlpHrJ8rKSlJ8+fP79Lx1hXdedwjvuhl+9hH\nHcc+Q3fwOI7jxLuIziorK1NDQ0OPzV9eXq6HHnpIp06dkiQVFBRo69atnTrZrp2rRX5+viTp9OnT\nUd8vKCjQzp07lZqaGrU2Sa3e37Bhg5544olW287Ly9OFCxci7sOr57vvvvt09uzZ0DKv16utW7fq\n6aefDs0Zqd6WfXVtrfn5+WpqagqbMz8/X8XFxa32rdfrVU5OTlivI83X1rYjjfd6vWGfua1tR9vP\nbX2uaHW0pzuPt66IRx2R+uwWfr9fdXV1PTJ3bzmmrtbbem21j3qyz9Zi3We9rddW+lOvY9XS645K\nXLFixYruL8dGbW2tmpube2z+1atXa9euXaHXly5dktfr1R133NHluVoEAgEFAoF232/Z9m233Ra1\ntsOHD7caSMY4AAANOElEQVR6/9ixY/rrX//aahsVFRVt7r+r53vvvffCljU3N2vfvn06d+5cu/Xe\ncccdrWoNBAKqqKho9Xkj7dvExEQNGDAgrNeR5mtr25HGX/uZ29p2pHXb+1zR6mhPdx5vXRGPOiL1\n2S28Xq8aGxt7ZO7eckxdrbf12mof9WSfrcW6z3pbr630p17HqqXXHWV2Ob64uFglJSUaMGCAFi1a\nFHHMmTNn9N5776mpqUmpqamaP3++VXkAAAAwZPZg0oQJEzRv3rw2l9fV1WnXrl36p3/6Jy1evFj/\n8A//YFVam4qKilRQUBB6XVBQELrvr6tztcjPzw9dxo32fkFBgRYuXNhubZHeX7lyZcRt5+Xlyev1\nRqz36vny8vLClnm9Xq1duzZszkj1tuyra2vKz89vNWd+fn7M+zbSfG1tO9L4az9ztG1HOwY6WkdH\nP1dXjreu6C11oOvoZfvYRx3HPkN3Mb0nNBAI6I033oj4TeiBAwdUXV2tu+66K+b5LO4z6W0PJl19\nn4kbHkxq654iHkzqWdYPHbj13jGp5+8f620PkPTGXlvso/52n2As+6w39tpCf+t1LDp7T2ivCaG7\nd+9WU1OTysrKVF9fr8mTJ+vmm2+WJFVWVqq6ujpsfFpampqamlx130VycrLq6+vjXYappKQkZWVl\nKRAI0Ot+zK19lui1W7itzxK9dpOWXnd4vR6opVOampr0f//3f3rsscfU0NCgDRs2aMSIEcrOztah\nQ4e0f//+sPFTpkzRtGnT4lQtrHXm4EbfQ5/dg167B71GW3pNCB04cKBSU1Pl9Xrl9Xo1cuRIXbx4\nUdnZ2SosLNTo0aPDxqelpfGvKxfgX9Lu4NY+S/TaLdzWZ4leu0mf/yZ09OjR2rVrl5qbm9XY2KgL\nFy7o1ltvlSRlZGQoIyOj1Tpuu88kKSnJVZ/3ao2Nja767G7ttdv6LNFrt3BrnyV6jbaZhdAtW7bo\n7Nmzqq2t1XPPPaepU6eGfm7YpEmTlJOTo1GjRunFF1+Ux+PRxIkTdd1111mVBwAAAENmIXTOnDnt\njrn99tt1++23G1QDAACAeDL7OaEAAABAC0IoAAAAzBFCAQAAYI4QCgAAAHOEUAAAAJgjhAIAAMAc\nIRQAAADmCKEAAAAwRwgFAACAOUIoAAAAzBFCAQAAYI4QCgAAAHOEUAAAAJgjhAIAAMAcIRQAAADm\nCKEAAAAwRwgFAACAOUIoAAAAzBFCAQAAYI4QCgAAAHOEUAAAAJgjhAIAAMAcIRQAAADmCKEAAAAw\nRwgFAACAOUIoAAAAzBFCAQAAYI4QCgAAAHOEUAAAAJgjhAIAAMAcIRQAAADmCKEAAAAwRwgFAACA\nOUIoAAAAzBFCAQAAYI4QCgAAAHOEUAAAAJgjhAIAAMAcIRQAAADmCKEAAAAw53Ecx4l3ER1VWVmp\nQ4cOqbCwUBkZGfEuBz2IXrsDfXYPeu0e9No9OtvrPvlNaHV1tfbv36/q6up4l4IeRq/dgT67B712\nD3rtHp3tdZ8MoQAAAOjbCKEAAAAwRwgFAACAucQVK1asiHcRHeU4jnw+n/Ly8pScnBzvctCD6LU7\n0Gf3oNfuQa/do7O97pNPxwMAAKBvS4p3AdGUlJRo9+7dchxHEydO1B133NFqzK5du1RaWiqv16sH\nHnhAubm5cagUXdVer8+cOaNNmzYpKytLkjR27FhNmTIlHqWiC4qLi1VSUqIBAwZo0aJFEcdwTvcP\n7fWac7r/uHz5srZt26aamhpJUmFhoSZPntxqHOd23xZLnzt6XvfaENrc3Kxdu3bp0UcfVUZGhtat\nW6fRo0crJycnNObUqVMqLy/XkiVL9Pnnn2vHjh0qKiqKY9XojFh6LUkjR47Uww8/HKcq0R0mTJig\nW265Rdu2bYu4nHO6/2iv1xLndH+RkJCgmTNnKjc3V/X19Vq3bp3y8/P5+7qfiaXPUsfO6177YNKF\nCxc0aNAgZWVlKTExUd/61rd04sSJsDEnT57U+PHjJUkjRoxQMBjk55H1QbH0Gv3DyJEjlZKS0uZy\nzun+o71eo/9IT08PfauZnJyswYMHq6qqKmwM53bfF0ufO6rXhtDKykoNHDgw9DojI6PVh62qqgr7\nyfwZGRmqrKw0qxHdI5ZeezwenT9/Xi+++KJef/11ffnll9ZlwgDntHtwTvdPgUBAFy9e1PDhw8Pe\n59zuX9rqc0fP6157Od7j8cS7BBiJpde5ubl66qmn5PP5VFJSok2bNmnJkiUG1QHoCZzT/U99fb02\nb96sWbNm8TR8Pxatzx09r3vtN6Hp6em6fPly6HVlZWWr30cayxj0frH0MTk5WT6fT5J04403qrm5\nWbW1taZ1oudxTrsH53T/0tTUpM2bN2vcuHEaO3Zsq+Wc2/1De33u6Hnda0PosGHDVF5erkAgoMbG\nRh07dkyjR48OGzN69GgdPXpUknT+/HmlpKQoLS0tHuWiC2LpdXV1tVp+mtjnn38ux3GUmpoaj3LR\ngzin3YNzuv9wHEfbt29XTk6Obr311ohjOLf7vlj63NHzulf/nNCWH9vT3NysiRMn6s4779TBgwcl\nSZMmTZIk7dy5U6WlpfL5fJo9e7aGDRsWz5LRSe31+sCBA/roo4+UkJAgr9ermTNn6vrrr49z1eio\nLVu26OzZs6qtrVVaWpqmTp2q5uZmSZzT/U17veac7j/OnTunV155RUOGDAndXnX33XeHvvnk3O4f\nYulzR8/rXh1CAQAA0D/12svxAAAA6L8IoQAAADBHCAUAAIA5QigAAADM9dofVg8AAICeV1xcrJKS\nEg0YMECLFi2KOnb37t06e/asJKmhoUE1NTVavnx5p7ZLCAUAAHCxCRMm6JZbbtG2bdvaHTtr1qzQ\n/3/44Ye6ePFip7dLCAUAAHCxkSNHKhAIhL1XXl6uXbt2qaamRl6vV/fff78GDx4cNuavf/2r7rrr\nrk5vlxAKAACAMO+8846+973vKTs7W59//rl27typxx57LLS8oqJCFRUV+sY3vtHpbRBCASBGjY2N\nSkrij00A/Vt9fb3Onz+vt956K/ReU1NT2Jhjx47pm9/8Zui3J3UGT8cDQBR5eXn6xS9+oXHjxik9\nPV0ffPCBbrvtNmVlZWn8+PHav3+/JOnNN9/Ut7/97bB1f/3rX2v27NmSvv5D/emnn9bIkSM1dOhQ\nLVy4UMFgUJK0b98+jRgxQs8995yGDBmiYcOGaePGjaF5pk6dqpdeein0euPGjbrzzjtDr0+cOKEZ\nM2YoOztbY8aMCfuLAwA6ynEcpaSk6Ic//GHov8WLF4eNOXbsmL71rW91aTuEUABox6ZNm/Tuu+/q\n9OnTmj17tn76058qEAjoV7/6lR566CFdunRJ9913n06ePKnS0tLQer/97W/1/e9/X5K0fPlylZaW\n6ujRoyotLdWFCxf0s5/9LDT2b3/7myorK/XFF1/opZde0uLFi0O/k9nj8bT5bUNNTY1mzJihefPm\nqaysTJs2bdKiRYv06aef9uAeAdCfpaSkKCsrS8ePH5f0dSi9+gGksrIyBYPBqL8XPhaEUACIwuPx\naMmSJRo+fLhee+01ffe73w09HTp9+nRNmjRJO3fuVGpqqmbPnq033nhDklRSUqKTJ0/q/vvvl+M4\nWr9+vZ577jllZmYqLS1NzzzzjDZt2hTajtfr1U9/+lMlJibq7/7u75SWlqaTJ0+2W9+OHTv0jW98\nQ4899pgSEhI0fvx4Pfjgg3wbCiBmW7Zs0UsvvaSvvvpKzz33nI4cOaIHH3xQR44c0YsvvqgXXngh\n7M+j48ePd/lbUIl7QgGgXS3/2j937pzeeustvfPOO6FljY2NoadDH374YS1btkw/+clP9Nvf/lZ/\n//d/r5SUFH355Zeqra1VYWFhaD3HcdTc3Bx6nZ2drYSE//97gdTUVFVXV7db27lz5/Thhx8qKysr\nrKZHH3208x8YgKvMmTMn4vvz5s2L+P7UqVO7ZbuEUABoR8ul8BtuuEGPPPKI1q1bF3Hc9OnTVVZW\npqNHj2rTpk1atWqVJGnw4MHy+/365JNPlJub2+HtDxgwQDU1NaHXV18Wu+GGGzRlyhS9//77HZ4X\nAOKJy/EAEKN58+bpnXfe0fvvv6+mpiYFg0Ht27dPFy5ckPT1JfW5c+fq6aefViAQ0IwZMyRJCQkJ\nKioq0tKlS1VWViZJunDhQszBcfz48Xr77bdVV1en0tLSsIeU7r33Xp06dUqvv/66Ghoa1NDQoI8+\n+kgnTpzo5k8PAN2LEAoAMRoxYoS2b9+un//857ruuut0ww03aOXKlWGX1R9++GH94Q9/0Ny5c8Mu\nr/+///f/NGrUKE2ePFkDBw7UjBkzdOrUqdDyaD/m5KmnnpLP59OQIUM0f/58zZs3LzQ+PT1d77//\nvjZt2qThw4crNzdXzzzzjK5cudIDewAAuo/HcRwn3kUAAADAXfgmFAAAAOYIoQAAADBHCAUAAIA5\nQigAAADMEUIBAABgjhAKAAAAc4RQAAAAmCOEAgAAwNz/B/ab9of3zVQhAAAAAElFTkSuQmCC\n", + "text": [ + "" + ], + "metadata": {} + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + }, + { + "output_type": "display_data", + "png": "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\nesxfGR0KO4tofX29Vq1aFX4FLz8/X7t379b48eP7XNOdx+MJz5qcnNzjiex2uzV58mSdOHGi1/1f\neuml+uKLL8L7fuKJJ7Rq1aqI47/88sv13HPP6fbbbw+v7fLKK69Ikm699dZ+j7P7nN3/3l1v8/fn\nwvXdt5uXl6eOjo6I4+5+e35+vt555x3V1NRowYIFfb5K63a7+/0fd/e8oslyKGsaGhq0ePHi8Kwp\nKSl68803lZeX1+92+/r6Gcrsg5l7ILHYxlC35fF4lJOTY+tzOl6kpaWpra3N9Bi2cWrWiZQzz+v+\nJVLWg9WVdTT6LaKlpaXKzs7WokWLetzW2dmp5557TnfddVdUO44Fu7+46+vrVVJSIkkqLi7u9R/m\nrjV+v19tbW06cuRI+HeolpWVSZJWr16t//qv/wq/WWnq1Knatm2bsrKywtu/9tpr9W//9m+SpN/+\n9re64oortGPHDoVCofC+jx07po0bN+qrr77S4sWL9e///u/hsvKzn/1M+/fvl8/nU0lJiQoLCyVJ\nhw4d0j333KPOzk5dd911+vzzz9XR0aHk5GRdc801uuOOOyLmfP755/X2229HvFnpwQcfVElJid58\n883wm5WSk5M1c+ZMWZalDz74QCdPnlR6erq+//3vq7i4WM8//7z+93//t8djUVxcLEl6+umndfjw\nYc2aNStihnvvvVfTpk1TXV2djhw5ogcffFCS9JOf/ESVlZUR93nhhRd0+PBhTZs2TWlpaZLOvxKZ\nlpbWI6+hZBnNmmPHjoVnffLJJ5WXlzeo7Xbd1vXqZ2pq6pBnH8zcA4nFNoayLaf+gyU57x8tp2ad\naDnzvO5bomU9GCNWRFtaWvTYY4/p008/1Zw5c/Too4/K6/VGPWis8cWd+PhG5gxOzVkia6dwWs4S\nWTvJcIpov5+s9M///M+qrKzUtGnTtHv37vArPAAAAMBw9VtEX331Vb322mv6xS9+oVdffVWVlZV2\nzQUAAIAE128RbWlp0SWXXCLp/Jtlevu4TwAAACAa/f76po6ODr311luSzr/pIxQKhS93+e53vzty\n0wEAACBh9VtEL7roIt19993hy9nZ2RGXJfX6y9MBAACAgfRbRPv6nZYAAADAcPX7M6IAAADASKGI\nAgAAwAiKKAAAAIygiAIAAMAIiigAAACMoIgCAADACIooAAAAjKCIAgAAwAiKKAAAAIygiAIAAMAI\niigAAACMoIgCAADACIooAAAAjKCIAgAAwAiKKAAAAIygiAIAAMAIl2VZlukhouH3++X3+zVKx49K\nUlKSOjs7TY9hK5fLpZSUFLW3t5N1AnNqzhJZO4XTcpbI2klcLpcyMzOjuq87xrPYJjU1VU1NTQoG\ng6ZHsU1aWpra2tpMj2Erj8ejzMxMtbS0kHUCc2rOElk7hdNylsjaSTweT9T35dQ8AAAAjKCIAgAA\nwAiKKAAAAIygiAIAAMAIiigAAACMoIgCAADACIooAAAAjKCIAgAAwAiKKAAAAIygiAIAAMAIiigA\nAACMoIgCAADACIooAAAAjKCIAgAAwAiKKAAAAIygiAIAAMAIiigAAACMoIgCAADACIooAAAAjKCI\nAgAAwAi36QESWX19vUpKSiRJxcXFkhRxefz48YNeV19frx07digUCkVcN5jtdV/r9/tlWZYkyeVy\nybIsuVwupaamavXq1SorK+t1e08//bQOHz6s6dOny+v1Ki0trce229rawtvqfv/BPj4DrR/Odrqv\n6es4+9p217HPmjVLGzdujHrOocxr2lAf03g9DgBAfHNZXa1khJWXl6umpkZjxozRhg0bel1z/Phx\nvfbaa+ro6FB6errWrVvX7zbr6uoUDAZHYtxhq6+v16pVq1RdXS1JysvLkyQdO3ZMkpSfn6/du3dL\n0oDrtm/frn/8x38Mr+nrut6219vavqSkpKi9vb3H9lasWBGep7v+tt11/77KyYWPT1/rPR6PcnJy\n+sx6MNu5cE1vx9lX0brw2PPy8lReXj6s0jyY405LS1NbW1tU+xiuaB7TgfIeyEA5JzKTWZvg1Kyd\nlrNE1k7SlXU0kjdt2rQptuP0Li0tTbNnz9aRI0d0zTXX9Li9ra1NpaWluv3223XTTTcpPz9fKSkp\n/W6ztbVVnZ2dIzXysPzqV7/S/v37w5cbGhrU0NAQvnz27Fl5PB59+OGHA6779NNP9cknnwx4XW/b\n621tXzo6Onrd3oEDB3pd39+2u+7/ne98p9f7Xvj49LU+OTlZY8aM6TPrwWznwjW9HWdvc/7qV7/q\ncewNDQ39HtdABnvcHo9HoVAoqn0MVzSP6UB5D2SgnBOZyaxNcGrWTstZImsn6co6Grb9jOiUKVOU\nmpra5+2ffPKJpk+frnHjxklS1AcEAACA0cG2U/PS+VeT/vCHP/R6av7AgQPq6OhQXV2dAoGA5s2b\np29/+9uSpMbGRjU3N0es9/l86ujoiNv/dZw9e1bLly/v95R7RUWFJA24bufOnbrrrrsiToP2dl1v\n2+ttbV+YE6jtAAAV/UlEQVQuPGXdtb1bbrmlz1PzfW276/7Z2dmDenz6Wu92u5WVlaWGhoZesx7M\ndi5c09tx9jbn2bNnexx7Xl6eKisr+zyugQz2uL1erwKBQFT7GK5oHtOB8h7IQDknMpNZm+DUrJ2W\ns0TWTtKVdTTipoju27dPf/vb37R27VoFg0Ft375dt99+u7Kzs/WnP/1JVVVVEevnz5+vhQsX2jV6\nVL7++mtt2bJFknT//fdLUsTlCRMmDHrdhWv6uq637XVf29ra2uus6enpuuOOO/T888/3ur3HH39c\nBw8e1NVXX620tDSlp6f3ue3utw3l8Rlo/XC2031NX8fZ17a7jv3aa6/Vo48+GvWcQ5nXtKE+pvF6\nHACA+BY3RfR//ud/FAwGw+WyoqJCU6dO1be+9a1R+YroSHDy/7L4H3Vic2rOElk7hdNylsjaSYbz\nimjc/PqmgoIC7d+/X52dnQqFQjp9+rSuv/56SVJGRoYyMjJ63Mdp78Rzu92OOt7uQqGQo47dqVk7\nLWeJrJ3CqTlLZI3+2VZEy8rKdOLECbW2tmrz5s1asGBB+F10c+fOVU5OjqZOnaqtW7fK5XJpzpw5\nuuiii+waDwAAADazrYiuXr16wDU33nijbrzxRhumAQAAgGl8xCcAAACMoIgCAADACIooAAAAjKCI\nAgAAwAiKKAAAAIygiAIAAMAIiigAAACMoIgCAADACIooAAAAjKCIAgAAwAiKKAAAAIygiAIAAMAI\niigAAACMoIgCAADACIooAAAAjKCIAgAAwAiKKAAAAIygiAIAAMAIiigAAACMoIgCAADACIooAAAA\njKCIAgAAwAiKKAAAAIxwWZZlmR4iGn6/X36/X6N0/KgkJSWps7PT9Bi2crlcSklJUXt7O1knMKfm\nLJG1UzgtZ4msncTlcikzMzOq+7pjPIttUlNT1dTUpGAwaHoU26Slpamtrc30GLbyeDzKzMxUS0sL\nWScwp+YskbVTOC1niaydxOPxRH1fTs0DAADACIooAAAAjKCIAgAAwAiKKAAAAIygiAIAAMAIiigA\nAACMoIgCAADACIooAAAAjKCIAgAAwAiKKAAAAIygiAIAAMAIiigAAACMoIgCAADACIooAAAAjKCI\n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\n5ht98803uuKKK4a1H4ooAAxSKBSS2823TQCJLRAI6IsvvtBLL70Uvq6joyNizaeffqpvfetb4U9Z\nihbvmgeAflx++eX6f//v/2nmzJkaO3as3nnnHd1www3KysrSrFmzVFVVJUl68cUXdc0110Tc95e/\n/KWWL18u6fw39oceekhTpkzRxRdfrHvvvVd+v1+S9Pbbb2vy5MnavHmzJk6cqEsuuUQ7d+4Mb2fB\nggV65plnwpd37typm266KXz5yJEjuvnmm5Wdna1p06ZF/OMBAENlWZZSU1P1T//0T+E/9913X8Sa\nTz/9VFddddWw90URBYAB7Nq1S6+++qqOHTum5cuX66c//akaGhr0xBNPaNWqVTp79qx++MMf6ujR\no6qtrQ3f7/e//71uv/12SdLDDz+s2tpaffTRR6qtrdXp06f1s5/9LLz2q6++UmNjo7788ks988wz\nuu+++8Kf4exyufp81aGlpUU333yzioqKVFdXp127dmnDhg3661//OoKPCIBElpqaqqysLP3lL3+R\ndL6Ydn9TUl1dnfx+/4CfIz8YFFEA6IfL5dLGjRs1adIkPf/88/rBD34Qftfo4sWLNXfuXO3bt0/p\n6elavny5/vCHP0iSampqdPToUd16662yLEslJSXavHmzMjMz5fP59Mgjj2jXrl3h/Xg8Hv30pz9V\ncnKyvv/978vn8+no0aMDzldZWakrrrhCa9euVVJSkmbNmqWVK1fyqiiAQSsrK9Mzzzyjr7/+Wps3\nb9bhw4e1cuVKHT58WFu3btV///d/R3w/+stf/hKTV0MlfkYUAAbU9b/+kydP6qWXXtLevXvDt4VC\nofC7Rm+77TY9+OCD+slPfqLf//73+tGPfqTU1FT9/e9/V2trqwoLC8P3syxLnZ2d4cvZ2dlKSvr/\nXxtIT09Xc3PzgLOdPHlS7733nrKysiJmuvPOO6M/YACOsnr16l6vLyoq6vX6BQsWxGzfFFEAGEDX\nafHLLrtMd9xxh7Zt29brusWLF6uurk4fffSRdu3apS1btkiSJkyYoLS0NH322WfKzc0d8v7HjBmj\nlpaW8OXup8guu+wyzZ8/X6+//vqQtwsApnFqHgAGqaioSHv37tXrr7+ujo4O+f1+vf322zp9+rSk\n86fX16xZo4ceekgNDQ26+eabJUlJSUkqLi7W/fffr7q6OknS6dOnB10eZ82apZdfflltbW2qra2N\neOPSsmXLVF1drRdeeEHBYFDBYFDvv/++jhw5EuOjB4DYo4gCwCBNnjxZFRUVevzxx3XRRRfpsssu\n05NPPhlxiv22227TH//4R61ZsybiVPt//ud/aurUqZo3b57GjRunm2++WdXV1eHb+/sVKA888IBS\nUlI0ceJErVu3TkVFReH1Y8eO1euvv65du3Zp0qRJys3N1SOPPKL29vYReAQAILZclmVZpocAAACA\n8/CKKAAAAIygiAIAAMAIiigAAACMoIgCAADACIooAAAAjKCIAgAAwAiKKAAAAIygiAIAAMCI/w/5\nb0ZMc3OIVAAAAABJRU5ErkJggg==\n", + "text": [ + "" + ], + "metadata": {} + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + }, + { + "output_type": "display_data", + "png": "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\n", + "text": [ + "" + ], + "metadata": {} + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + }, + { + "output_type": "display_data", + "png": "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\nrnPHRLKe7HE9q0sqAAAActOsPd0PAACA3EVJBQAAgHEoqQAAADAOJRUAAADGmbVf5g8AAIDM27Nn\nj1pbW1VcXKwtW7aMufbAgQP66KOPJEmxWEw9PT169NFHp/S4lFQAAACM6uqrr9Y111yj3bt3j7v2\n9ttvT/39N7/5jT799NMpPy4lFQAAAKOqqqpSZ2dn2nXhcFgtLS3q6emR2+3WV77yFc2dOzdtzW9/\n+1vdeOONU35cSioAAAAmZe/evbrzzjs1Z84cnTx5Uvv379d9992Xuv3MmTM6c+aMFi1aNOXHoKQC\nwAwZGBiQy8U/qwByW19fn9rb2/Xiiy+mrhscHExb8/777+sv/uIvUr99air4dD8ATMOll16qH/7w\nh7ryyitVUlKi//mf/9Ff/uVfyufzafny5Tp06JAk6Re/+IW+9KUvpW37ox/9SGvXrpX0+T/63/nO\nd1RVVaULL7xQDz30kKLRqCTptdde08KFC7Vjxw7Nnz9fCxYs0DPPPJO6n1WrVunpp59OXX7mmWd0\nww03pC4fPXpUt9xyi+bMmaOlS5em/YcFACYrkUiooKBA3/jGN1J/vvnNb6atef/993X55ZdP63Eo\nqQAwTU1NTXr55Zd1/PhxrV27Vt///vfV2dmpxx57TPX19Tp9+rTuuusuHTt2TG1tbantfv7zn+ue\ne+6RJD366KNqa2vTu+++q7a2Np06dUo/+MEPUms/++wzRSIR/f73v9fTTz+tb37zm6nfie1wOEZ9\ntaKnp0e33HKLNm7cqI6ODjU1NWnLli363e9+l8FnBEAuKygokM/n0wcffCDp89I69ANSHR0dikaj\nuvjii6f1OJRUAJgGh8OhhoYGXXTRRXruued0xx13pD7devPNN6u2tlb79+9XUVGR1q5dq//8z/+U\nJLW2turYsWP6yle+okQioWAwqB07dqisrExer1ff/e531dTUlHoct9ut73//+8rLy9OXv/xleb1e\nHTt2bNz59u3bp0WLFum+++6T0+nU8uXL9dWvfpVXUwFM2K5du/T000/rT3/6k3bs2KG3335bX/3q\nV/X222/rySef1L//+7+n/Xv0wQcfTPtVVIn3pALAtCVfLfj444/14osvau/evanbBgYGUp9u3bBh\ng7Zu3aq///u/189//nP99V//tQoKCvTHP/5R586dU01NTWq7RCKheDyeujxnzhw5nX9+XaGoqEjd\n3d3jzvbxxx/rN7/5jXw+X9pMmzZtmvoOA7CV9evXj3j9xo0bR7x+1apVM/K4lFQAmKbkqfZLLrlE\n9957rxobG0dcd/PNN6ujo0Pvvvuumpqa9OMf/1iSNHfuXBUWFurDDz9UZWXlpB+/uLhYPT09qctD\nT7tdcsklqqur0yuvvDLp+wUAK3G6HwBmyMaNG7V371698sorGhwcVDQa1WuvvaZTp05J+vyU/d13\n363vfOc76uzs1C233CJJcjqdCgQC+va3v62Ojg5J0qlTpyZcLJcvX67/+q//Um9vr9ra2tI+RLVm\nzRqFQiE9//zzisViisVievPNN3X06NEZ3nsAmFmUVACYIQsXLtRLL72kf/7nf9a8efN0ySWXaPv2\n7Wmn7Tds2KBf/epXuvvuu9NO3//Lv/yLLrvsMl177bW64IILdMsttygUCqVuH+trXB5++GF5PB7N\nnz9fX/va17Rx48bU+pKSEr3yyitqamrSRRddpMrKSn33u99Vf39/Bp4BAJg5jkQikbB6CAAAAGAo\nXkkFAACAcSipAAAAMA4lFQAAAMahpAIAAMA4lFQAAAAYh5IKAAAA41BSAQAAYBxKKgAAAIzz/xkW\nuDSoHEZ8AAAAAElFTkSuQmCC\n", + "text": [ + "" + ], + "metadata": {} + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + }, + { + "output_type": "display_data", + "png": "iVBORw0KGgoAAAANSUhEUgAAAqkAAAHzCAYAAAAD24TLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X9wU3W+//FX0iT9ldamULCAFqyksFcRaBf1XtyCv1dU\n2AX/QUT3rtGVXTs67Fz1zuxeZmfuj/1e0VXvXJTi6qiztypccIDa9boKd707syCLuuqFtgxoYa9u\nJaFpS9OmTb5/OMkS+oP+zPmQ83zMMENOPid5n7wafJmTpI54PB4XAAAAYBCn1QMAAAAAZ6OkAgAA\nwDiUVAAAABiHkgoAAADjUFIBAABgHEoqAAAAjOOyegBJikajevHFF9Xb26u+vj7NmTNH119/fb91\n9fX1am5ultvt1ooVK1RaWmrBtAAAAJhoDlO+J7Wnp0cej0d9fX365S9/qRtvvFFlZWXJ6xsbG7Vv\n3z6tWbNGx48f15tvvqlAIGDhxAAAAJgoxpzu93g8kqS+vj7F43Hl5uamXH/48GHNnz9fkjRjxgxF\nIhF1dHSkfU4AAABMPCNO90tSLBbTc889p1AopKqqKk2ZMiXl+vb2dhUWFiYvFxYWKhwOy+v1KhwO\n9yusXq83ZT0AAADOH8aUVKfTqQceeECRSEQvv/yyjh49qlmzZg1r3wMHDmjv3r0p26qrq7V06dKJ\nGBUAAAATzJiSmpCTkyO/368//elPKSW1oKBAbW1tycvhcDj5SmllZaUqKipSbsfr9SoUCqm3tzc9\ngxsgOztb3d3dVo+RNi6XSz6fz3Y5S2RtF3bLWSJrOyFre0jkPKp9x3mWUens7JTT6VRubq6i0aiO\nHDmiJUuWpKypqKjQvn37dPnll6ulpUU5OTnyer2Svj71P9Cp/dbWVkWj0XQcghFcLpetjjeht7fX\ndsdN1vZg15wlsrYTssZgjCipHR0d2r59u+LxuOLxuK644gpdcsklev/99yVJVVVV8vv9ampq0lNP\nPSWPx6Ply5dbPDUAAAAmihElderUqfrBD37Qb3tVVVXK5WXLlqVrJAAAAFjImK+gAgAAABIoqQAA\nADAOJRUAAADGoaQCAADAOJRUAAAAGIeSCgAAAONQUgEAAGAcSioAAACMQ0kFAACAcSipAAAAMA4l\nFQAAAMahpAIAAMA4lFQAAAAYh5IKAAAA41BSAQAAYBxKKgAAAIxDSQUAAIBxKKkAAAAwDiUVAAAA\nxqGkAgAAwDiUVAAAABiHkgoAAADjUFIBAABgHEoqAAAAjENJBQAAgHEoqQAAADAOJRUAAADGccTj\n8bjVQ0yESCSiSCSiDD28ATmdTsViMavHSBuHwyGPx6Oenh5b5SyRtV3YLWeJrO2ErO3B4XCoqKho\nVPu6xnkWY+Tk5Ki9vV3RaNTqUdImNzdXXV1dVo+RNm63W0VFRers7LRVzhJZ24XdcpbI2k7I2h7c\nbveo9+V0PwAAAIxDSQUAAIBxKKkAAAAwDiUVAAAAxqGkAgAAwDiUVAAAABiHkgoAAADjUFIBAABg\nHEoqAAAAjENJBQAAgHEoqQAAADAOJRUAAADGoaQCAADAOJRUAAAAGIeSCgAAAONQUgEAAGAcSioA\nAACMQ0kFAACAcSipAAAAMI7L6gEwPoLBoF544QX19vZq1apV2rp1qyQpEAiouLg4ZV1tbW3KdYlt\nkUhE8Xhcubm5/fYb7gxn3/ZQ20d6u2fPN3Xq1BHdDgAAOH9QUjNAMBjUypUr1djYKEl69tln1dPT\nI0lqaGjQtm3bkmX0zHUNDQ3asmWL7r333uS2hDP3G80Mif0lDbh9tLd75nxvvPGGSkpKhnU7AADg\n/MLp/gxQW1ubUuISBVWSGhsbk69inr2usbFR69ev71cAz95vNDMk9h9s+2hv98zb2bx587BvBwAA\nnF8oqQAAADAOJTUDBAIB+f3+5GWPx5P8u9/vVyAQGHCd3+/Xxo0bU7YNtN9oZkjsP9j20d7umbdz\n3333Dft2AADA+cURj8fjVg8xUVpbWxWNRq0eIy3s+sGpkpISW+WckJubq66uLqvHSBu3223LrO2W\ns0TWdkLW9pDIeTQoqRnErj/4dstZImu7sFvOElnbCVnbw1hKqhGf7m9ra9P27dvV2dkpSaqsrNRV\nV12Vsubo0aOqq6uTz+eTJM2dO1fV1dVpnxUAAAATz4iS6nQ6ddNNN6m0tFTd3d3avHmzysvL+zXv\nsrIyrV692qIpAQAAkC5GfHCqoKBApaWlkqTs7GxNnjxZ7e3tFk8FAAAAqxjxSuqZQqGQvvjiC02f\nPj1lu8PhUEtLizZt2qSCggLdeOONmjJliiQpHA6ro6MjZb3X65XLZdzhTaisrCy53W6rx0ibRL52\ny1kia7uwW84SWdsJWdvDWPI16oNT3d3devHFF/Wtb31Lc+fO7Xedw+GQx+NRU1OT3nzzTdXU1EiS\n3n33Xe3duzdlfXV1tZYuXZq22QEAADB+jPnfl76+Pr322muaN29ev4Iqff02gITZs2dr9+7dOn36\ntPLy8lRZWamKioqU9V6vV6FQSL29vRM+uymys7PV3d1t9Rhp43K55PP5bJezRNZ2YbecJbK2E7K2\nh0TOo9p3nGcZlXg8nvw97FdfffWAazo6OpSfny+Hw6Hjx48rHo8rLy9PklRYWKjCwsJ++9jtay1c\nLpetjjeht7fXdsdN1vZg15wlsrYTssZgjCipn3/+uT766CNNnTpVzz77rCTpuuuuU1tbmySpqqpK\nn376qfbv3y+n0ym3261Vq1ZZOTIAAAAmkBEltaysTBs2bBhyzaJFi7Ro0aL0DAQAAABLGfEVVAAA\nAMCZKKkAAAAwDiUVAAAAxqGkAgAAwDiUVAAAABiHkgoAAADjUFIBAABgHEoqAAAAjENJBQAAgHEo\nqQAAADAOJRUAAADGoaQCAADAOJRUAAAAGIeSCgAAAONQUgEAAGAcSioAAACMQ0kFAACAcVxWDwD7\nCQaDqq2tlSQFAgEVFxdn9P0CAICRo6QirYLBoFauXKnGxkZJUkNDg7Zt2zbhhdGq+wUAAKPD6X6k\nVW1tbbIoSlJjY2Py1c1MvF8AADA6lFQAAAAYh5KKtAoEAvL7/cnLfr9fgUAgY+8XAACMDu9JRVoV\nFxdr27Ztaf8Ak1X3CwAARoeSirQrLi7WI488Ypv7BQAAI8fpfgAAABiHkgoAAADjUFIBAABgHEc8\nHo9bPcREiEQiikQiytDDG5DT6VQsFrN6jLRxOBzyeDzq6emxVc4SWduF3XKWyNpOyNoeHA6HioqK\nRrVvxn5wKicnR+3t7YpGo1aPkja5ubnq6uqyeoy0cbvdKioqUmdnp61ylsjaLuyWs0TWdkLW9uB2\nu0e9L6f7AQAAYBxKKgAAAIxDSQUAAIBxKKkAAAAwDiUVAAAAxqGkAgAAwDiUVAAAABiHkgoAAADj\nUFIBAABgHEoqAAAAjENJBQAAgHEoqQAAADAOJRUAAADGoaQCAADAOJRUAAAAGIeSCgAAAONQUgEA\nAGAcSioAAACMQ0kFAACAcSipAAAAMA4lFQAAAMahpAIAAMA4lFQAAAAYh5IKAAAA41BSAQAAYBxK\nKgAAAIzjsnoASWpra9P27dvV2dkpSaqsrNRVV13Vb119fb2am5vldru1YsUKlZaWpntUAAAApIER\nJdXpdOqmm25SaWmpuru7tXnzZpWXl6ukpCS5prGxUcFgUDU1NTp+/Lh27dqlQCBg4dQAAACYKEac\n7i8oKEi+Kpqdna3Jkyervb09Zc3hw4c1f/58SdKMGTMUiUTU0dGR9lkBAAAw8Yx4JfVMoVBIX3zx\nhaZPn56yvb29XYWFhcnLhYWFCofD8nq9CofD/Qqr1+uVy2Xc4U2orKwsud1uq8dIm0S+dstZImu7\nsFvOElnbCVnbw1jyNeono7u7W6+99ppuvvlmZWdnD3u/AwcOaO/evSnbqqurtXTp0vEeEQby+XxW\nj4A0IWv7IGv7IGsMxpiS2tfXp9dee03z5s3T3Llz+11fUFCgtra25OVwOJx8ZbWyslIVFRUp671e\nr0KhkHp7eyd2cINkZ2eru7vb6jHSxuVyyefz2S5niaztwm45S2RtJ2RtD4mcR7XvOM8yKvF4XG+8\n8YZKSkp09dVXD7imoqJC+/bt0+WXX66Wlhbl5OTI6/VK+vrU/5lvBUhobW1VNBqd0NlN4nK5bHW8\nCb29vbY7brK2B7vmLJG1nZA1BmNESf3888/10UcfaerUqXr22WclSdddd13yldOqqir5/X41NTXp\nqaeeksfj0fLly60cGQAAABPIiJJaVlamDRs2nHPdsmXLJn4YAAAAWM6Ir6ACAAAAzkRJBQAAgHEo\nqQAAADAOJRUAAADGoaQCAADAOJRUAAAAGIeSCgAAAONQUgEAAGAcSioAAACMQ0kFAACAcSipAAAA\nMA4lFQAAAMahpAIAAMA4lFQAAAAYh5IKAAAA41BSAQAAYBxKKgAAAIxDSQUAAIBxKKkAAAAwjsvq\nAQATBYNB1dbWSpICgYCKi4stngiYGPysAzAVJRU4SzAY1MqVK9XY2ChJamho0LZt2/iPNzIOP+sA\nTMbpfuAstbW1yf9oS1JjY2PylSYgk/CzDsBklFQAAAAYh5IKnCUQCMjv9ycv+/1+BQIBCycCJgY/\n6wBMxntSgbMUFxdr27ZtfJgEGY+fdQAmo6QCAyguLtYjjzxi9RjAhONnHYCpON0PAAAA4zji8Xjc\n6iEmQiQSUSQSUYYe3oCcTqdisZjVY6SNw+GQx+NRT0+PrXKWyNou7JazRNZ2Qtb24HA4VFRUNKp9\nM/Z0f05Ojtrb2xWNRq0eJW1yc3PV1dVl9Rhp43a7VVRUpM7OTlvlLJG1XdgtZ4ms7YSs7cHtdo96\nX073AwAAwDiUVAAAABiHkgoAAADjUFIBAABgHEoqAAAAjENJBQAAgHEoqQAAADAOJRUAAADGoaQC\nAADAOJRUAAAAGIeSCgAAAONQUgEAAGAcSioAAACM47J6APQXDAZVW1srSQoEAiouLh5ye+K6F154\nQb29vcnrhlo/nPuVNKz9g8GgnnnmGe3fv1/xeFzf/OY3ddddd2nr1q399j1w4IDuv/9+xWIxfetb\n31Jpaemg80rS008/rQ8++EALFizQgw8+mLIuKytLf//3fy9JOnLkiNavXy9J+slPfqK33357yMdv\n1apVA843EiN9fNMlHXOZeuwAgMzhiMfjcauHmCitra2KRqNWjzEiwWBQK1euVGNjoyTJ7/dr27Zt\nkjTg9kRpO/u6LVu26N577x1w/XDut7y8XNLX5W+o/YPBoFasWJFcl+B2u5OPfWLfo0eP6vbbb+93\n3wPNW15err6+Ph07diy5rry8XC+88ELKum984xt6/PHHtWLFCvX09Ax42wM9fh6PJ7n+XI/NcB6v\n0dzGWOTm5qqrq8uSuaw4drfbrZKSkvPyOT0Wg+WcycjaPsjaHhI5j0bWhg0bNozvOOY4ffq0YrGY\n1WOMyNNPP636+vrk5ZMnT8rtdusPf/jDgNsXL1484D4ff/yx/vjHPw64fjj3GwqFFAqFzrn/008/\nrYaGhn63d+bjntj35z//uTo6OvqtHWjeUCikU6dOpawLhUL91rW2tuqdd95RW1vbgMc12OPX19d3\nzmMbymA5jeQ2xsLtdqu3t9eSuaw49qysLOXn55+Xz+mxGCznTEbW9kHW9pDIeTR4TyoAAACMQ0k1\nTCAQkN/vT172+/0KBAKDbh9sn40bNw66fjj3W15enjzlP9T+gUAgZV2C2+3ut+9zzz034H0PNG95\neblmzpyZsq68vLzfum984xt6/vnn5fF4Br3tgR6/M9ef67EZyFB5WCkdc5l67ACAzMJ7Ug3EB6dG\n9sGpeDyuQ4cO2eqDU0O9pykTPzjFe9fsg6ztg6ztYSzvSaWkZhC7/uDbLWeJrO3CbjlLZG0nZG0P\nYympnO4HAACAcSipAAAAMA4lFQAAAMahpAIAAMA4lFQAAAAYh5IKAAAA47isHiBhx44dampqUn5+\nvtatW9fv+qNHj6qurk4+n0+SNHfuXFVXV6d7TAAAAKSBMSV1wYIFuvLKK7V9+/ZB15SVlWn16tVp\nnAoAAABWMOZ0f1lZmXJycqweAwAAAAYw5pXUc3E4HGppadGmTZtUUFCgG2+8UVOmTJEkhcNhdXR0\npKz3er1yuc6bwxsXWVlZcrvdVo+RNol87ZazRNZ2YbecJbK2E7K2h7Hke978ZJSWlurhhx+Wx+NR\nU1OT6urqVFNTI+nr3we/d+/elPXV1dVaunSpFaMizRLvU0bmI2v7IGv7IGsM5rwpqdnZ2cm/z549\nW7t379bp06eVl5enyspKVVRUpKz3er0KhULq7e1N96iWyc7OVnd3t9VjpI3L5ZLP57NdzhJZ24Xd\ncpbI2k7I2h4SOY9q33GeZcJ0dHQoPz9fDodDx48fVzweV15eniSpsLBQhYWF/fZpbW1VNBpN96iW\ncblctjrehN7eXtsdN1nbg11zlsjaTsgagzGmpG7dulXHjh3T6dOn9cQTT2jJkiWKxWKSpKqqKn36\n6afav3+/nE6n3G63Vq1aZfHEAAAAmCjGlNRzlc5FixZp0aJFaZoGAAAAVjLmK6gAAACABEoqAAAA\njENJBQAAgHEoqQAAADAOJRUAAADGoaQCAADAOMZ8BZWdBYNB1dbWSpICgYCKi4sH3GaiYDCoZ555\nRgcPHtT8+fNVU1Mz4KxDHc9EHatpj6Fp8wAAYDJKqsWCwaBWrlypxsZGSVJDQ4O2bNmie++9N2Xb\ntm3bjCs1wWBQK1as0JEjRyRJ+/fv1zvvvKMdO3b0K6FnH2PieIa6bqyzTcTtZso8AACYjtP9Fqut\nrU0WF0lqbGzU+vXr+21LvAJnktra2mRBTThy5Ei/WQc6xsSaoa4b62wmPYamzQMAgOkoqQAAADAO\nJdVigUBAfr8/ednv92vjxo39tgUCASvGG1IgEFB5eXnKtvLy8n6zDnSMiTVDXTfW2Ux6DE2bBwAA\n0zni8Xjc6iEmSmtrq6LRqNVjnNN4fXAqNzdXXV1dEzrr2az84JTb7VZJScmgOZv2QaXxnMeKrK10\nrqwzld1ylsjaTsjaHhI5jwYlNYPY9QffbjlLZG0XdstZIms7IWt7GEtJ5XQ/AAAAjENJBQAAgHEo\nqQAAADAOJRUAAADGoaQCAADAOJRUAAAAGOecJfWjjz7Sq6++qhMnTkiS6uvr9eCDD2rLli0TPhwA\nAADsaciSWltbq7/5m7/Rxo0btXDhQj3//PN66KGH5HK59POf/1yPPfZYuuYEAACAjbiGuvJf/uVf\n9O6776qqqkq/+93vVF1drU8++UR+v18/+tGPtGTJEv3zP/9zumYFAACATQz5SupXX32lqqoqSdKV\nV14pScnfP37JJZeora1tgscDAACAHQ1ZUv1+v2praxWJRPTcc8+pqKhI//Vf/yVJ2rNnj2bMmJGW\nIQEAAGAvQ57uf/LJJ/Wd73xH999/v+bNm6fdu3fr1ltv1YwZM3T48GFt2rQpXXMCAADARoYsqYsX\nL9YXX3yhL7/8UtOmTZMkHTx4UL/73e902WWXae7cuWkZEgAAAPYyZEmVpKysrGRBlaTp06frjjvu\nmNChAAAAYG+OeDweH82O0WhU999/v375y1+O90zjIhKJKBKJaJSHd15yOp2KxWJWj5E2DodDHo9H\nPT09tspZImu7sFvOElnbCVnbg8PhUFFR0ej2HW1J7e7uVm5urtEPdGtrq6LRqNVjpE1ubq66urqs\nHiNt3G63SkpKbJezRNZ2YbecJbK2E7K2h0TOozHk6f6lS5cOep3J5RQAAADntyFL6r59+/Too4+q\ntLQ0ZbvD4VA0GtVvf/vbCR0OAAAA9jRkSb3iiis0Z86cAT8oFYlEtG7dugkbDAAAAPY15Jf5P/TQ\nQyouLh7wOo/HY+yHpgAAAHB+G7KkLlu2TG+//bZuu+02/cM//IO6u7v/sqPTqXvuuWei5wMAAIAN\nDVlSf/SjH2nXrl2aM2eOtm3bpvXr16drLgAAANjYkCX1zTff1K9//Wv967/+q958803t2rUrXXMB\nAADAxoYsqZ2dncnfNnXRRRepra0tLUMBAADA3ob8dH9fX5/eeecdSVI8Hldvb2/ycsK11147cdMB\nAADAloYsqVOmTNH3v//95OVJkyalXJako0ePTsxkAAAAsK0hS+qxY8fSNAYAAADwF0O+JxUAAACw\nAiUVAAAAxqGkAgAAwDiUVAAAABiHkgoAAADjUFIBAABgHEoqAAAAjENJBQAAgHEoqQAAADAOJRUA\nAADGoaQCAADAOJRUAAAAGIeSCgAAAONQUgEAAGAcl9UDSNKOHTvU1NSk/Px8rVu3bsA19fX1am5u\nltvt1ooVK1RaWprmKQEAAJAuRrySumDBAq1Zs2bQ6xsbGxUMBlVTU6PbbrtNu3btSuN0AAAASDcj\nSmpZWZlycnIGvf7w4cOaP3++JGnGjBmKRCLq6OhI13gAAABIMyNO959Le3u7CgsLk5cLCwsVDofl\n9XolSeFwuF9p9Xq9crnOi8MbN1lZWXK73VaPkTaJfO2Ws0TWdmG3nCWythOytoex5JsRPxkHDhzQ\n3r17U7ZVV1dr6dKlFk2EdPL5fFaPgDQha/sga/sgawzmvCipBQUFamtrS14Oh8Mpr6xWVlaqoqIi\nZR+v16tQKKTe3t60zWm17OxsdXd3Wz1G2rhcLvl8PtvlLJG1XdgtZ4ms7YSs7SGR86j2HedZJkRF\nRYX27dunyy+/XC0tLcrJyUme6pe+Pv1/ZmlNaG1tVTQaTeeolnK5XLY63oTe3l7bHTdZ24Ndc5bI\n2k7IGoMxoqRu3bpVx44d0+nTp/XEE09oyZIlisVikqSqqir5/X41NTXpqaeeksfj0fLlyy2eGAAA\nABPJiJK6atWqc65ZtmxZGiYBAACACYz4CioAAADgTJRUAAAAGIeSCgAAAONQUgEAAGAcSioAAACM\nQ0kFAACAcSipAAAAMA4lFQAAAMahpAIAAMA4lFQAAAAYh5IKAAAA41BSAQAAYBxKKgAAAIxDSQUA\nAIBxKKkAAAAwDiUVAAAAxqGkAgAAwDiUVAAAABiHkgoAAADjUFIBAABgHEoqAAAAjENJBQAAgHEo\nqQAAADAOJRUAAADGoaQCAADAOJRUAAAAGIeSCgAAAOM44vF43OohJkIkElEkElGGHt6AnE6nYrGY\n1WOkjcPhkMfjUU9Pj61ylsjaLuyWs0TWdkLW9uBwOFRUVDSqfV3jPIsxcnJy1N7ermg0avUoaZOb\nm6uuri6rx0gbt9utoqIidXZ22ipniaztwm45S2RtJ2RtD263e9T7crofAAAAxqGkAgAAwDiUVAAA\nABgnY9+TmkmCwaBqa2slSYFAQMXFxQNuAwAAyBSUVMMFg0GtXLlSjY2NkqSGhgZt2bJF9957b8q2\nbdu2afr06VaOCgAAMG443W+42traZBmVpMbGRq1fv77ftsSrqgAAAJmAkgoAAADjUFINFwgE5Pf7\nk5f9fr82btzYb1sgELBiPAAAgAnBe1INV1xcrG3btvX7kNRA2wAAADIFJfU8UFxcrEceeeSc2wAA\nADIFp/sBAABgHEoqAAAAjENJBQAAgHEoqQAAADAOJRUAAADGoaQCAADAOJRUAAAAGIeSCgAAAONQ\nUgEAAGAcSioAAACMQ0kFAACAcSipAAAAMA4lFQAAAMahpAIAAMA4lFQAAAAYh5IKAAAA47isHiCh\nqalJDQ0NisfjWrhwoRYvXpxy/dGjR1VXVyefzydJmjt3rqqrq60YFQAAABPMiJIai8VUX1+vtWvX\nqrCwUJs3b1ZFRYVKSkpS1pWVlWn16tUWTQkAAIB0MeJ0/4kTJ1RcXCyfz6esrCxddtllOnTokNVj\nAQAAwCJGvJIaDod1wQUXJC8XFhbqxIkTKWscDodaWlq0adMmFRQU6MYbb9SUKVOS+3d0dKSs93q9\ncrmMOLy0ycrKktvttnqMtEnka7ecJbK2C7vlLJG1nZC1PYwlXyN+MhwOxznXlJaW6uGHH5bH41FT\nU5Pq6upUU1MjSTpw4ID27t2bsr66ulpLly6dkHlhlsT7lJH5yNo+yNo+yBqDMaKkFhQUqK2tLXk5\nHA6rsLAwZU12dnby77Nnz9bu3bt1+vRp5eXlqbKyUhUVFSnrvV6vQqGQent7J3Z4g2RnZ6u7u9vq\nMdLG5XLJ5/PZLmeJrO3CbjlLZG0nZG0PiZxHte84zzIq06ZNUzAYVCgUUkFBgT7++GOtWrUqZU1H\nR4fy8/PlcDh0/PhxxeNx5eXlSfr67QFnl1pJam1tVTQaTcsxmMDlctnqeBN6e3ttd9xkbQ92zVki\nazshawzGiJKalZWlW265Ra+88opisZgWLlyokpISvf/++5Kkqqoqffrpp9q/f7+cTqfcbne/EgsA\nAIDMYURJlb4+hT979uyUbVVVVcm/L1q0SIsWLUr3WAAAALCAEV9BBQAAAJyJkgoAAADjUFIBAABg\nHEoqAAAAjENJBQAAgHEoqQAAADAOJRUAAADGoaQCAADAOJRUAAAAGIeSCgAAAONQUgEAAGAcSioA\nAACMQ0kFAACAcSipAAAAMA4lFQAAAMahpAIAAMA4lFQAAAAYh5IKAAAA41BSAQAAYBxKKgAAAIxD\nSQUAAIBxKKkAAAAwDiUVAAAAxqGkAgAAwDiUVAAAABiHkgoAAADjUFIBAABgHEc8Ho9bPcREiEQi\nikQiytDDG5DT6VQsFrN6jLRxOBzyeDzq6emxVc4SWduF3XKWyNpOyNoeHA6HioqKRrWva5xnMUZO\nTo7a29sVjUatHiVtcnNz1dXVZfUYaeN2u1VUVKTOzk5b5SyRtV3YLWeJrO2ErO3B7XaPel9O9wMA\nAMA4lFQAAAAYh5IKAAAA41BSAQAAYBxKKgAAAIxDSQUAAIBxKKkAAAAwDiUVAAAAxqGkAgAAwDiU\nVAAAABiHkgoAAADjUFIBAABgHEoqAAAAjENJBQAAgHEoqQAAADAOJRUAAADGoaQCAADAOJRUAAAA\nGIeSCgARJWyRAAATh0lEQVQAAONQUgEAAGAcSioAAACMQ0kFAACAcSipAAAAMA4lFQAAAMahpAIA\nAMA4lFQAAAAYx2X1AAlNTU1qaGhQPB7XwoULtXjx4n5r6uvr1dzcLLfbrRUrVqi0tNSCSQEAADDR\njCipsVhM9fX1Wrt2rQoLC7V582ZVVFSopKQkuaaxsVHBYFA1NTU6fvy4du3apUAgYOHUXwsGg6qt\nrZUkrVq1Slu3bpUkBQIBFRcXD7m2trZWb7/9ti688EKtX79eTz31lCTpb//2b7VhwwaFw2Hl5eXp\n4osv1lNPPaXy8vLk7fzsZz9TfX29vF6vamtrNWvWLL3wwgvq7e1N3veRI0dUU1OjL7/8Utdff73+\n7u/+TsXFxXr33Xd13333KRqN6tvf/rb+8R//UZJUW1ur//u//9N///d/q7e3V9LX2XR1dSkrK0uP\nP/64Dh48qIMHD2r+/Pm666679Pjjj2v37t2KxWK69NJLtXHjRr3++ut6++23lZ+fr1AopEgkoltu\nuUUPPvigXn75ZX3wwQeaM2eOcnJyJEkOh0OSFI/H+13Ozc1N5lxbW6uuri5FIhEdOnRIc+fO1aRJ\nk5KP2dmPd8LZj0MgEOiX00hyPDvTZ555JvmY1NTUpKxP3G4kEkk5nlAopPXr10uSNm7cmJLt008/\nrQ8++EALFizQgw8+OODtRaNR9fX1KScn55wzDjRz4liH2neodcO5jfG4H8AE/IyOHI8ZxoMjnmgG\nFmppadGePXt01113SZJ++9vfSpKuueaa5JqdO3dq1qxZuuyyyyRJzzzzjL73ve/J6/UOerutra2K\nRqMTNncwGNTKlSvV2NgoSfJ4POrp6ZEk+f1+bdu2LfnEPHuty+VKFsHhcLvd+s1vfiOfz6dbbrlF\nLS0tKddfdNFFyW1+v1+PP/64Vq5cmXL8M2fO1COPPKIHHnggZd+pU6fK6/XqyJEjIzp+p9OpWCw2\nYesTEgVuqPnOfrwTjhw5ouuuuy7lcTjzsff7/dqyZYvuvffeYeV4pmAwqBUrVqTMVV5erh07diSL\n75mZJ8ycOVMnTpxIzuTxePT222/L5/ON6vaGmnGgmc+8jcH2HWrdcG5jPO7nTG63WyUlJRP+nDZN\nbm6uurq6rB4jrUzLerg/o2OVSVnzvB5aJmU9HImcRyNrw4YNG8Z3nJE7fvy4Tp8+rYqKCknSqVOn\n9NVXX2n27NnJNQcOHNDs2bN1wQUXSJIOHTqkGTNmqKCgQOFwWCdPnlR7e3vyTzwel8PhkMPhUFZW\n1oT8eeaZZ7R79+7kjH19fcm/nzx5Ujk5Oaqurh5w7UjLWiwW0yeffKKTJ0/q17/+db/rw+Fwyn3v\n2bNHbW1tKWtOnTqlt956q999d3Z2KhQKjWge6S+vfE7U+oRQKHTO+c5+vBN/7rnnnn6F/szjP3ny\npD755BN99NFHyW1D5Xh2/vX19f1mTaw/O/OEU6dOpczQ19eXzHY0tzfUjOf6mR1s36HWDec2xuN+\nzlzncrmUm5urnp6eCX1Om/bH7XYrHo9bPkc6/5iW9XB/Rsl65I+ZaVmn608mZT2cP4mcR8OI0/2J\n07ujdeDAAe3duzdlW3V1tZYuXTqm2z2XvLy8c16f+L+Hc60dDrfbPezbycrKGvP9nW/OfLwT3G73\nOfc715qBbjexfaj1I8l8qGyHc3uDzTjQuuHsO9S64dzGeNzPQHw+34DbkXlMyXqkP6PgeY3xY+zp\nfofDkfLhqZ07d2rmzJm6/PLLJaWe7g+Hw+ro6Ei5Ta/Xq76+vhGdUh+pkydPavny5YOeJn7jjTeS\n75k8e+1oTvfv3btXPp9PN910kz7//POU6y+++OLkNr/fr1/84hdavnx5yimUWbNm6dFHH9X999+f\nsu+FF16o/Pz88/50/5mPd0Jzc7Oqq6tTHge325287Pf79eKLL+qee+4ZVo5nOnnypG699dZ+p+d3\n7dqlSZMm9cs8YdasWTp+/HjK6f49e/bI5/ON6vaGmnGgmc+8jcH2HWrdcG5jPO7nTC6XSz6fT6FQ\naEKf06bJzs5Wd3e31WOklWlZD/dndKwyKWue10PLpKyHI5HzaBhRUvv6+vRv//ZvWrt2rQoKClRb\nW6tVq1b1++DUvn37tGbNGrW0tKihoeGcH5xKx/tc+OAUH5zig1MT/8Ep3rtmHyZmnY4PAWVa1jyv\nB5dpWZ/LWN6TakRJlf7yFVSxWEwLFy7UNddco/fff1+SVFVVJUnavXu3mpub5fF4tHz5ck2bNm3I\n2+QHP7PZ9R84iaztwm45S2RtJ2RtD2MpqUa8J1WSZs+enfJBKekv5TRh2bJl6RwJAAAAFuE3TgEA\nAMA4lFQAAAAYh5IKAAAA41BSAQAAYBxKKgAAAIxDSQUAAIBxKKkAAAAwDiUVAAAAxqGkAgAAwDiU\nVAAAABiHkgoAAADjUFIBAABgHEoqAAAAjENJBQAAgHEoqQAAADAOJRUAAADGoaQCAADAOJRUAAAA\nGIeSCgAAAONQUgEAAGAcSioAAACMQ0kFAACAcSipAAAAMA4lFQAAAMahpAIAAMA4lFQAAAAYh5IK\nAAAA4zji8Xjc6iEmQiQSUSQSUYYe3oCcTqdisZjVY6SNw+GQx+NRT0+PrXKWyNou7JazRNZ2Qtb2\n4HA4VFRUNKp9XeM8izFycnLU3t6uaDRq9Shpk5ubq66uLqvHSBu3262ioiJ1dnbaKmeJrO3CbjlL\nZG0nZG0Pbrd71Ptyuh8AAADGoaQCAADAOJRUAAAAGIeSCgAAAONQUgEAAGAcSioAAACMQ0kFAACA\ncSipAAAAMA4lFQAAAMahpAIAAMA4lFQAAAAYh5IKAAAA41BSAQAAYBxKKgAAAIxDSQUAAIBxKKkA\nAAAwDiUVAAAAxqGkAgAAwDiUVAAAABiHkgoAAADjUFIBAABgHEoqAAAAjENJBQAAgHEoqQAAADAO\nJRUAAADGoaQCAADAOC6rBzh9+rS2bt2qU6dOqaioSHfccYdyc3P7rXvyySeVnZ0tp9Mpp9Op++67\nz4JpAQAAkA6Wl9T33ntPl1xyiRYvXqz33ntP7733nm644YZ+6xwOh+655x7l5eVZMCUAAADSyfLT\n/YcPH9b8+fMlSVdccYUOHTpk8UQAAACwmuWvpHZ2dsrr9UqSvF6vOjs7B1370ksvyeFwqKqqSpWV\nlcnt4XBYHR0dKWu9Xq9cLssPL62ysrLkdrutHiNtEvnaLWeJrO3CbjlLZG0nZG0PY8k3LT8ZL730\nUr8SKUnXXnttymWHwzHobXz/+99XQUGBOjs79dJLL2ny5MkqKyuTJB04cEB79+5NWV9WVqaVK1fK\n5/ONwxHAROFwWO+++64qKyvJOcORtX2QtX2QtT2cmXNhYeGI9k1LSV27du2g1+Xn56u9vV0FBQVq\nb29Xfn7+gOsKCgqS6+fOnasTJ04kS2plZaUqKiqSa1tbW7V9+3Z1dHSM+AHB+aOjo0N79+5VRUUF\nOWc4srYPsrYPsraHseRs+XtSKyoq9OGHH0qSPvjgA82ZM6ffmp6eHnV3dyf/fuTIEU2ZMiV5fWFh\noaZNm5b8U1JSkp7hAQAAMCEsfyPI4sWL9frrr+sPf/hD8iuopK9fHt65c6fuvPNOdXR06NVXX5Uk\nxWIxzZs3T5deeqmVYwMAAGACWV5S8/LydPfdd/fbXlhYqDvvvFOSVFxcrAceeCDdowEAAMAiWRs2\nbNhg9RDjLR6Py+PxaObMmcrOzrZ6HEwQcrYPsrYPsrYPsraHseTsiMfj8QmaCwAAABgVy0/3j0VT\nU5MaGhoUj8e1cOFCLV68uN+a+vp6NTc3y+12a8WKFSotLbVgUozVubI+evSo6urqkl9jMnfuXFVX\nV1sxKsZgx44dampqUn5+vtatWzfgGp7TmeFcWfOczgxtbW3avn178jvQKysrddVVV/Vbx/P6/Dec\nrEf6vD5vS2osFlN9fb3Wrl2rwsJCbd68WRUVFSmf7G9sbFQwGFRNTY2OHz+uXbt2KRAIWDg1RmM4\nWUtffzfu6tWrLZoS42HBggW68sortX379gGv5zmdOc6VtcRzOhM4nU7ddNNNKi0tVXd3tzZv3qzy\n8nL+W52BhpO1NLLnteVfQTVaJ06cUHFxsXw+n7KysnTZZZf1+5WqZ/7K1RkzZigSiQz4SwVgtuFk\njcxQVlamnJycQa/nOZ05zpU1MkNBQUHyVdHs7GxNnjxZ7e3tKWt4XmeG4WQ9UudtSQ2Hw7rggguS\nlwsLC/s9GO3t7SlfHFtYWKhwOJy2GTE+hpO1w+FQS0uLNm3apFdeeUV//vOf0z0m0oDntH3wnM48\noVBIX3zxhaZPn56yned15hks65E+r8/b0/1D/QpVZJbhZF1aWqqHH35YHo9HTU1NqqurU01NTRqm\nAzAReE5nlu7ubr322mu6+eab+SR/hhsq65E+r8/bV1ILCgrU1taWvBwOh/v9uq3hrIH5hpNjdna2\nPB6PJGn27NmKxWI6ffp0WufExOM5bR88pzNHX1+fXnvtNc2bN09z587tdz3P68xxrqxH+rw+b0vq\ntGnTFAwGFQqF1Nvbq48//lgVFRUpa878lastLS3KycmR1+u1YlyMwXCy7ujoUOLb1I4fP654PK68\nvDwrxsUE4jltHzynM0M8Htcbb7yhkpISXX311QOu4XmdGYaT9Uif1+f196QmvpYoFotp4cKFuuaa\na/T+++9LkqqqqiRJu3fvVnNzszwej5YvX65p06ZZOTJG6VxZ79u3T/v375fT6ZTb7dZNN92kiy66\nyOKpMVJbt27VsWPHdPr0aXm9Xi1ZskSxWEwSz+lMc66seU5nhs8++0wvvPCCpk6dmnzr1nXXXZd8\n5ZTndeYYTtYjfV6f1yUVAAAAmem8Pd0PAACAzEVJBQAAgHEoqQAAADAOJRUAAADGOW+/zB8AAAAT\nb8eOHWpqalJ+fr7WrVs35NqGhgYdO3ZMkhSNRtXZ2alHH310VPdLSQUAAMCgFixYoCuvvFLbt28/\n59qbb745+fff//73+uKLL0Z9v5RUAAAADKqsrEyhUChlWzAYVH19vTo7O+V2u3X77bdr8uTJKWv+\n+Mc/6tprrx31/VJSAQAAMCI7d+7UrbfeqkmTJun48ePavXu37r777uT1p06d0qlTpzRr1qxR3wcl\nFQDGSW9vr1wu/lkFkNm6u7vV0tKi119/Pbmtr68vZc3HH3+sv/qrv0r+9qnR4NP9ADAGM2fO1P/7\nf/9P8+bNU0FBgf7nf/5Hf/3Xfy2fz6f58+dr7969kqRXX31V3/zmN1P2ffLJJ7V8+XJJX/+j/+Mf\n/1hlZWW68MIL9cADDygSiUiS9uzZoxkzZuiJJ57Q1KlTNW3aNL344ovJ21myZImef/755OUXX3xR\n11xzTfLyoUOHdMMNN2jSpEmaM2dOyn9YAGCk4vG4cnJy9IMf/CD554c//GHKmo8//liXXXbZmO6H\nkgoAY1RXV6c333xTR44c0fLly/XTn/5UoVBIjz/+uFauXKmTJ0/qtttu0+HDh9Xc3Jzc71e/+pXu\nvPNOSdKjjz6q5uZmffjhh2pubtaJEyf0s5/9LLn2yy+/VDgc1p/+9Cc9//zz+uEPf5j8ndgOh2PQ\nVys6Ozt1ww03aM2aNWptbVVdXZ3WrVun//3f/53ARwRAJsvJyZHP59Mnn3wi6evSeuYHpFpbWxWJ\nRHTRRReN6X4oqQAwBg6HQzU1NZo+fbpefvll3XLLLclPt15//fWqqqrS7t27lZeXp+XLl+s//uM/\nJElNTU06fPiwbr/9dsXjcdXW1uqJJ55QUVGRvF6vHnvsMdXV1SXvx+1266c//amysrL07W9/W16v\nV4cPHz7nfLt27dKsWbN09913y+l0av78+frud7/Lq6kAhm3r1q16/vnn9dVXX+mJJ57QwYMH9d3v\nflcHDx7Upk2b9O///u8p/x598sknY34VVeI9qQAwZolXCz777DO9/vrr2rlzZ/K63t7e5KdbV69e\nrfXr1+snP/mJfvWrX+k73/mOcnJy9Oc//1mnT59WZWVlcr94PK5YLJa8PGnSJDmdf3ldIS8vTx0d\nHeec7bPPPtPvf/97+Xy+lJnWrl07+gMGYCurVq0acPuaNWsG3L5kyZJxuV9KKgCMUeJU+8UXX6y7\n7rpLmzdvHnDd9ddfr9bWVn344Yeqq6vTL37xC0nS5MmTlZubq08//VSlpaUjvv/8/Hx1dnYmL595\n2u3iiy9WdXW13nrrrRHfLgBYidP9ADBO1qxZo507d+qtt95SX1+fIpGI9uzZoxMnTkj6+pT9HXfc\noR//+McKhUK64YYbJElOp1OBQEAPPfSQWltbJUknTpwYdrGcP3++/vM//1NdXV1qbm5O+RDVsmXL\n1NjYqFdeeUXRaFTRaFT79+/XoUOHxvnoAWB8UVIBYJzMmDFDb7zxhv7pn/5JU6ZM0cUXX6yNGzem\nnLZfvXq1fvOb3+iOO+5IOX3/85//XJdeeqmuuuoqXXDBBbrhhhvU2NiYvH6or3F5+OGH5fF4NHXq\nVH3ve9/TmjVrkusLCgr01ltvqa6uTtOnT1dpaakee+wx9fT0TMAjAADjxxGPx+NWDwEAAACciVdS\nAQAAYBxKKgAAAIxDSQUAAIBxKKkAAAAwDiUVAAAAxqGkAgAAwDiUVAAAABiHkgoAAADj/H/kBmOv\ntS+4xAAAAABJRU5ErkJggg==\n", + "text": [ + "" + ], + "metadata": {} + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + }, + { + "output_type": "display_data", + "png": "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\ntcrKypLb7dajjz6qbdu2hffjcrn02GOPKTExUX/2Z38mt9uto0ePDjjf7t27ddVVV2np0qVKSEjQ\n9OnTdd999/GsKICoVVZW6umnn9aZM2e0du1affDBB7rvvvv0wQcfaP369frVr34V8f3oo48+GpZn\nQyXeIwoAA+r+X/8nn3yil19+Wa+++mr4tkAgEP7U6P33369Vq1bpRz/6kX7961/rz//8z5WSkqIv\nvvhCra2tKikpCW8XCoUUDAbDl7Ozs5WQ8OVzA2lpaWpubh5wtk8++UTvvfeePB5PxEwPPPBA7A8Y\ngK0sXry41+vLysp6vX7OnDnDtm+KKAAMoPtl8SlTpujb3/62Nm7c2Ou6efPmqaGhQQcPHtS2bdv0\n1FNPSZImTJig1NRU/e///q9yc3MHvf/09HS1tLSEL1/8EtmUKVM0e/Zs7d27d9D3CwCm8dI8AESp\nrKxMr776qvbu3auuri75/X799re/VX19vaQLL68vWbJEq1evls/n0/z58yVJCQkJKi8v1/e//301\nNDRIkurr66Muj9OnT9crr7yitrY2HTt2LOKDS3fffbdqamq0detWdXZ2qrOzU/v379eRI0eG+dED\nwPCjiAJAlCZPnqxdu3bp8ccf12WXXaYpU6aooqIi4iX2+++/X2+99ZaWLFkS8VL7v/zLv2jq1Km6\n6aabNG7cOM2fP181NTXh2/v7ESg/+MEPlJSUpMsvv1zLli1TWVlZeH1GRob27t2rbdu2adKkScrN\nzdWjjz6qjo6OETgCADC8HKFQKGR6CAAAANgPz4gCAADACIooAAAAjKCIAgAAwAiKKAAAAIygiAIA\nAMAIiigAAACMoIgCAADACIooAAAAjPh/DdHt779+vZgAAAAASUVORK5CYII=\n", + "text": [ + "" + ], + "metadata": {} + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + }, + { + "output_type": "display_data", + "png": "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\n5s2bxx132223TX8xAAAAyDqemAQAAABzhFAAAACYI4QCAADAHCEUAAAA5gihAAAAMEcIBQAAgDlC\nKAAAAMwRQgEAAGCOEAoAAABzhFAAAACYI4QCAADAHCEUAAAA5gihAAAAMEcIBQAAgDlCKAAAAMwR\nQgEAAGCOEAoAAABzhFAAAACYI4QCAADAHCEUAAAA5gihAAAAMEcIBQAAgDlCKAAAAMwRQgEAAGCO\nEAoAAABzhFAAAACYI4QCAADAHCEUAAAA5gihAAAAMOfNdgFIT3Nzsx5++GElEgnV1dUpGAyOOC4W\niykSiUiSwuGwSktLx3yvu7tbHo9H+fn5yWlDl7VlyxYdPHhQVVVV2rhx47Dp5y53POPVt379em3f\nvl2SdN9996msrCyjZU7leKtlzeR1Yvbi8zI+9hGQHZ5EIpHIdhGZamlpUW9vb7bLmHbNzc1avXq1\nzp49K0ny+/164403hgXRWCym2tpaRaNRSVIoFNJzzz2nb37zm2O+NygUCqmhoSEZDNetW6fm5ubk\n9GAwqJ07dyann7uuwXlHk059fr8/uZ2hUEhvvfWWEonEqH2eaB2Z1D2R7cl0WecqKChQd3e36Tqz\nyefzqayszJljeqjRej0VZuLnZab12mofTWefZ6qZ1msrLvd6onI3b968eerLsdHV1aWBgYFslzHt\nvvGNb+jYsWPJ1/39/Tp06JD+9E//NGXc008/rT179iRfnzp1SocOHdK777475ntDp/l8Pl133XV6\n+umn1djYmDK9tbU1Zfq56xqcNpp06uvv70+Z7vf7dc0114za54nWkUndE9meTJd1Lp/Pp76+PtN1\nZlNubq4KCwudOaaHGq3XU2Emfl5mWq+t9tF09nmmmmm9tuJyrydq3GtC33nnHb388ss6ceKEJGnP\nnj164IEH9Nxzz028SgAAAEDjhNBIJKI//uM/Vl1dna666io9//zzevDBB+X1evX9739fjz76qFWd\nTqurq5Pf70++9vv9qqurGzYuHA4rFAolX4dCIdXV1Y373tBp4XA4uaxzT/cHg8GU6ecud3DaaNKp\nb+h2hkIhPfjggxNe5lh1ZFK3xbJm8joxe/F5GR/7CMieMa8JDQaDevnll1VdXa1f/epXqqmp0Xvv\nvadQKKTm5matXLky5TSxNZeuM3H1xqRLL7103D7PxRuTxrqmaC7eROHqtWPS9F8/NtM+LzOx1xb7\n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\n29/+dvKf73znOyljDh06pMsuu2xS6yGEAsA46uvr9dprr6m5uVlr167VY489ptbWVv3TP/2Tamtr\nderUKd1xxx06fPiwjhw5kpzvpz/9qf7sz/5MkvTII4/oyJEjevvtt3XkyBGdOHFCf/d3f5cce/Lk\nSbW1tenjjz/W888/r+985zvJZzJ7PJ5Rv23o7OzUjTfeqA0bNqilpUX19fW6//779T//8z/TuEcA\nzGX5+fkqKSnRe++9J+mzUDr0BqSWlhbF4/ExnwufDkIoAIzB4/Fo48aNWrx4sV588UXdeuutybtD\nV69ererqau3evVvz5s3T2rVr9bOf/UyS1NTUpMOHD2vNmjVKJBKKRCJ64oknNH/+fAUCAT366KOq\nr69Prsfn8+mxxx5Tbm6u/uRP/kSBQECHDx8et75du3bp4osv1te//nXl5OSoqqpKX/nKV/g2FEDa\ntm/frueff17/93//pyeeeEIHDx7UV77yFR08eFDPPPOM/vmf/znl79F777036W9BJa4JBYBxDf7f\n/kcffaSf//znevXVV5PT+vr6kneH3n333dq0aZP+5m/+Rj/96U915513Kj8/X59++qm6urq0fPny\n5HyJREIDAwPJ1+eff75ycv7/9wLz5s1TR0fHuLV99NFH+s1vfqOSkpKUmr72ta9lvsEAnLJ+/foR\n39+wYcOI769cuXJK1ksIBYBxDJ4K/9znPqevfvWr2rp164jjVq9erZaWFr399tuqr6/Xk08+KUm6\n4IILVFBQoPfff1/l5eUTXn9hYaE6OzuTr4eeFvvc5z6nmpoavf766xNeLgBkE6fjASBNGzZs0Kuv\nvqrXX39d/f39isfjevPNN3XixAlJn51Sv+uuu/Twww+rtbVVN954oyQpJydH4XBYDz74oFpaWiRJ\nJ06cSDs4VlVV6d/+7d/U3d2tI0eOpNykdNtttykajeqll15Sb2+vent7tX//fn3wwQdTvPUAMLUI\noQCQpiVLluiVV17R448/rgULFuhzn/uc6urqUk6r33333frlL3+pu+66K+X0+ve//339wR/8ga65\n5hqdd955uvHGGxWNRpPTx/qZk4ceekh+v18LFy7UPffcow0bNiTHFxUV6fXXX1d9fb0WL16s8vJy\nPfroozp79uw07AEAmDqeRCKRyHYRAAAAcAvfhAIAAMAcIRQAAADmCKEAAAAwRwgFAACAOUIoAAAA\nzBFCAQAAYI4QCgAAAHOEUAAAAJj7f2HzhLu/BC8cAAAAAElFTkSuQmCC\n", + "text": [ + "" + ], + "metadata": {} + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + }, + { + "output_type": "display_data", + "png": "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\n+fT8888rGAwuaH+zzTjdzJP3MdO2s62byz6W4n4m83q9qq2tzflz2jTl5eUaHR0t9Bh5ZVrWc/0Z\nXaxiyprn9eyKKeu5SOe8ECU7d+7cubTjzF9fX59GRkbU0NAgSTp58qT+/Oc/a926dZk1Bw8e1Lp1\n63TOOedIkg4dOqTVq1erqqpKAwMDOnHihAYHBzN/HMeRy+WSy+VSSUlJTv48/PDD2r9/f2bGiYmJ\nzN9PnDihsrIyNTc3T7t2vmUtlUrp9ddf14kTJ/Tzn/98yu0DAwNZ9/3iiy/q1KlTWWtOnjyp5557\nbsp9Dw8PKxaLzWse6f9e+czV+rRYLHbG+U5/vNN/PvWpT00p9JOP/8SJE3r99df1u9/9LnPdbDme\nnn9nZ+eUWdPrT8887eTJk1kzTExMZLJdyP5mm/FMP7MzbTvburnsYynuZ/I6j8ej8vJyjY+P5/Q5\nbdofr9crx3EKPkc+/5iW9Vx/Rsl6/o+ZaVnn608xZT2XP+mcF8KI0/3p07sLdfDgQXV3d2dd19zc\nrC1btixqv2dSUVFxxtvT//dwprVz4fV657yfkpKSRd/f2Wby453m9XrPuN2Z1ky33/T1s62fT+az\nZTuX/c0043Tr5rLtbOvmso+luJ/pBIPBaa9H8TEl6/n+jILnNZaOsaf7XS5X1oennnnmGV1wwQW6\n+OKLJWWf7h8YGNDQ0FDWPv1+vyYmJuZ1Sn2+Tpw4oa1bt854mvjpp5/OvGfy9LULOd3f3d2tYDCo\n66+/Xn/4wx+ybj///PMz14VCIX33u9/V1q1bs06hrFmzRvfee6/+5m/+Jmvb97znPaqsrDzrT/dP\nfrzTjhw5oubm5qzHwev1Zi6HQiE9+uij+tSnPjWnHCc7ceKEPvaxj005Pb9v3z4tW7ZsSuZpa9as\nUV9fX9bp/hdffFHBYHBB+5ttxulmnryPmbadbd1c9rEU9zOZx+NRMBhULBbL6XPaNKWlpRobGyv0\nGHllWtZz/RldrGLKmuf17Iop67lI57wQRpTUiYkJ/cu//Ituu+02VVVVqa2tTdu3b5/ywamXXnpJ\nt9xyi3p7e9XV1XXGD07l430ufHCKD07xwancf3CK967Zw8Ss8/EhoGLLmuf1zIot6zNZzHtSjSip\n0v/9CqpUKqVLL71UV155pV5++WVJUlNTkyRp//79OnLkiHw+n7Zu3aqVK1fOuk9+8Iubrf/ASWRt\nC9tylsjaJmRth8WUVCPekypJ69aty/qglPR/5TTtxhtvzOdIAAAAKBC+cQoAAADGoaQCAADAOJRU\nAAAAGIeSCgAAAONQUgEAAGAcSioAAACMQ0kFAACAcSipAAAAMA4lFQAAAMahpAIAAMA4lFQAAAAY\nh5IKAAAA41BSAQAAYBxKKgAAAIxDSQUAAIBxKKkAAAAwDiUVAAAAxqGkAgAAwDiUVAAAABiHkgoA\nAADjUFIBAABgHEoqAAAAjENJBQAAgHFcjuM4hR4iF+LxuOLxuIr08KbldruVSqUKPUbeuFwu+Xw+\njY+PW5WzRNa2sC1niaxtQtZ2cLlcqq6uXtC2niWexRhlZWUaHBxUIpEo9Ch5U15ertHR0UKPkTde\nr1fV1dUaHh62KmeJrG1hW84SWduErO3g9XoXvC2n+wEAAGAcSioAAACMQ0kFAACAcSipAAAAMA4l\nFQAAAMahpAIAAMA4lFQAAAAYh5IKAAAA41BSAQAAYBxKKgAAAIxDSQUAAIBxKKkAAAAwDiUVAAAA\nxqGkAgAAwDiUVAAAABiHkgoAAADjUFIBAABgHEoqAAAAjENJBQAAgHEoqQAAADAOJRUAAADGoaQC\nAADAOJ5CDzAyMqI9e/bo5MmTqq6u1s0336zy8vIp677zne+otLRUbrdbbrdbd9xxRwGmBQAAQD4U\nvKT+6le/0nvf+15dccUV+tWvfqVf/epXuvbaa6esc7lc+tSnPqWKiooCTAkAAIB8Kvjp/sOHD2vD\nhg2SpA984AM6dOhQgScCAABAoRX8ldTh4WH5/X5Jkt/v1/Dw8Ixrf/zjH8vlcqmpqUmNjY2Z6wcG\nBjQ0NJS11u/3y+Mp+OHlVUlJibxeb6HHyJt0vrblLJG1LWzLWSJrm5C1HRaTb15+Mn784x9PKZGS\ndNVVV2VddrlcM+7js5/9rKqqqjQ8PKwf//jHOvfcc1VfXy9JOnjwoLq7u7PW19fXq6WlRcFgcAmO\nACYaGBjQCy+8oMbGRnIucmRtD7K2B1nbYXLOgUBgXtvmpaTedtttM95WWVmpwcFBVVVVaXBwUJWV\nldOuq6qqyqxfv369jh8/nimpjY2NamhoyKzt7+/X3r17NTQ0NO8HBGePoaEhdXd3q6GhgZyLHFnb\ng6ztQdZ2WEzOBX9PakNDg377299Kkl599VVdeOGFU9aMj49rbGws8/ejR49q+fLlmdsDgYBWrlyZ\n+VNbW5uf4QEAAJATBX8jyBVXXKEnn3xSv/nNbzK/gkp69+XhZ555Rp/85Cc1NDSkxx9/XJKUSqV0\nySWX6H3ve18hxwYAAEAOFbykVlRU6Pbbb59yfSAQ0Cc/+UlJUk1Nje688858jwYAAIACKdm5c+fO\nQg+x1BzHkc/n0wUXXKDS0tJCj4McIWd7kLU9yNoeZG2HxeTschzHydFcAAAAwIIU/HT/YvT09Kir\nq0uO4+jSSy/VFVdcMWVNZ2enjhw5Iq/Xq23btqmurq4Ak2KxzpT1sWPH1N7envk1JuvXr1dzc3Mh\nRsUiPPXUU+rp6VFlZaXuuuuuadfwnC4OZ8qa53RxOHXqlPbu3Zv5HeiNjY267LLLpqzjeX32m0vW\n831en7UlNZVKqbOzU7fddpsCgYB2796thoaGrE/2RyIRRaNRtba2qq+vT/v27VM4HC7g1FiIuWQt\nvfu7cXfs2FGgKbEUNm7cqA996EPau3fvtLfznC4eZ8pa4jldDNxut66//nrV1dVpbGxMu3fv1tq1\na/lvdRGaS9bS/J7XBf8VVAt1/Phx1dTUKBgMqqSkRBdddNGUr1Sd/JWrq1evVjwen/ZLBWC2uWSN\n4lBfX6+ysrIZb+c5XTzOlDWKQ1VVVeZV0dLSUp177rkaHBzMWsPzujjMJev5OmtL6sDAgM4555zM\n5UAgMOXBGBwczPrFsYFAQAMDA3mbEUtjLlm7XC719vZq165d+slPfqI//elP+R4TecBz2h48p4tP\nLBbTO++8o1WrVmVdz/O6+MyU9Xyf12ft6f7ZvkIVxWUuWdfV1enuu++Wz+dTT0+P2tvb1dramofp\nAOQCz+niMjY2pieeeEIf+chH+CR/kZst6/k+r8/aV1Krqqp06tSpzOWBgYEpX7c1lzUw31xyLC0t\nlc/nkyStW7dOqVRKIyMjeZ0Tucdz2h48p4vHxMSEnnjiCV1yySVav379lNt5XhePM2U93+f1WVtS\nV65cqWg0qlgspmQyqddee00NDQ1ZayZ/5Wpvb6/Kysrk9/sLMS4WYS5ZDw0NKf3b1Pr6+uQ4jioq\nKgoxLnKI57Q9eE4XB8dx9PTTT6u2tlaXX375tGt4XheHuWQ93+f1Wf17UtO/liiVSunSSy/VlVde\nqZdfflmS1NTUJEnav3+/jhw5Ip/Pp61bt2rlypWFHBkLdKasX3rpJR04cEBut1ter1fXX3+9zjvv\nvAJPjfnas2eP3nzzTY2MjMjv92vz5s1KpVKSeE4XmzNlzXO6OLz11lt65JFHtGLFisxbt66++urM\nK6c8r4vHXLKe7/P6rC6pAAAAKE5n7el+AAAAFC9KKgAAAIxDSQUAAIBxKKkAAAAwzln7y/wBAACQ\ne0899ZR6enpUWVmpu+66a9a1XV1devPNNyVJiURCw8PDuvfeexd0v5RUAAAAzGjjxo360Ic+pL17\n955x7Uc+8pHM33/961/rnXfeWfD9UlIBAAAwo/r6esVisazrotGoOjs7NTw8LK/Xq0984hM699xz\ns9b8/ve/11VXXbXg+6WkAgAAYF6eeeYZfexjH9OyZcvU19en/fv36/bbb8/cfvLkSZ08eVJr1qxZ\n8H1QUgFgiSSTSXk8/LMKoLiNjY2pt7dXTz75ZOa6iYmJrDWvvfaa/uIv/iLz7VMLwaf7AWARLrjg\nAv2///f/dMkll6iqqkr//d//rQ9/+MMKBoPasGGDuru7JUmPP/64PvjBD2Zt+53vfEdbt26V9O4/\n+l/+8pdVX1+v97znPbrzzjsVj8clSS+++KJWr16tBx54QCtWrNDKlSv16KOPZvazefNm/fCHP8xc\nfvTRR3XllVdmLh86dEjXXnutli1bpgsvvDDrPywAMF+O46isrEyf//znM3++8IUvZK157bXXdNFF\nFy3qfiipALBI7e3tevbZZ3X06FFt3bpVX//61xWLxXTfffeppaVFJ06c0Mc//nEdPnxYR44cyWz3\n05/+VJ/85CclSffee6+OHDmi3/72tzpy5IiOHz+ub37zm5m1f/zjHzUwMKC3335bP/zhD/WFL3wh\n853YLpdrxlcrhoeHde211+qWW25Rf3+/2tvbddddd+l//ud/cviIAChmZWVlCgaDev311yW9W1on\nf0Cqv79f8Xhc55133qLuh5IKAIvgcrnU2tqqVatW6bHHHtMNN9yQ+XTrNddco6amJu3fv18VFRXa\nunWr/uM//kOS1NPTo8OHD+sTn/iEHMdRW1ubHnjgAVVXV8vv9+trX/ua2tvbM/fj9Xr19a9/XSUl\nJfroRz8qv9+vw4cPn3G+ffv2ac2aNbr99tvldru1YcMG3XTTTbyaCmDO9uzZox/+8If685//rAce\neECvvPKKbrrpJr3yyivatWuX/u3f/i3r36PXX3990a+iSrwnFQAWLf1qwVtvvaUnn3xSzzzzTOa2\nZDKZ+XTrjh07dM899+gf/uEf9NOf/lR/9Vd/pbKyMv3pT3/SyMiIGhsbM9s5jqNUKpW5vGzZMrnd\n//e6QkVFhYaGhs4421tvvaVf//rXCgaDWTPddtttCz9gAFbZvn37tNffcsst016/efPmJblfSioA\nLFL6VPv555+vW2+9Vbt375523TXXXKP+/n799re/VXt7u7773e9Kks4991yVl5frjTfeUF1d3bzv\nv7KyUsPDw5nLk0+7nX/++WpubtZzzz037/0CQCFxuh8Alsgtt9yiZ555Rs8995wmJiYUj8f14osv\n6vjx45LePWV/880368tf/rJisZiuvfZaSZLb7VY4HNbf/u3fqr+/X5J0/PjxORfLDRs26Gc/+5lG\nR0d15MiRrA9R3XjjjYpEIvrJT36iRCKhRCKhAwcO6NChQ0t89ACwtCipALBEVq9eraefflrf+ta3\ntHz5cp1//vm6//77s07b79ixQ7/4xS908803Z52+/+d//me9733v02WXXaZzzjlH1157rSKRSOb2\n2X6Ny9133y2fz6cVK1bo05/+tG655ZbM+qqqKj333HNqb2/XqlWrVFdXp6997WsaHx/PwSMAAEvH\n5TiOU+ghAAAAgMl4JRUAAADGoaQCAADAOJRUAAAAGIeSCgAAAONQUgEAAGAcSioAAACMQ0kFAACA\ncSipAAAAMM7/B+n7oifrMkpiAAAAAElFTkSuQmCC\n", + "text": [ + "" + ], + "metadata": {} + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + }, + { + "output_type": "display_data", + "png": "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\n1EhKzwAAAABJRU5ErkJggg==\n", + "text": [ + "" + ], + "metadata": {} + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n" + ] + } + ], + "input": [ + "from sklearn.preprocessing import StandardScaler\n", + "X = load_data(\"train\")\n", + "# Applying transforms here\n", + "cols = X.columns.values.tolist()\n", + "cols.remove('revenue')\n", + "cols = ['P8' ,'P10' ,'P12' ,'P15' ,'P17' ,'P18' ,'P22' ,'P28' ,'P32' ,'num_months']\n", + "print \"Applied log(X+1)\"\n", + "for vary in cols:\n", + " X[vary] = X[[vary]].apply(lambda x:np.log(x + 1)) \n", + " print ggplot(aes(x='revenue',y=vary), data=X) + geom_point()" + ], + "language": "python", + "prompt_number": 122 + }, + { + "cell_type": "code", + "metadata": {}, + "outputs": [ + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "0 5653753\n", + "1 6923131\n", + "2 2055379\n", + "3 2675511\n", + "4 4316715\n", + "5 5017319\n", + "6 5166635\n", + "7 4491607\n", + "8 4952497\n", + "9 5444227\n", + "10 3745135\n", + "11 5161370\n", + "12 1734634\n", + "13 4807746\n", + "14 1999097\n", + "15 3218918\n", + "16 19696939\n", + "17 8213524\n", + "18 5337526\n", + "19 2021934\n", + "20 5525735\n", + "21 1149870\n", + "22 3956086\n", + "23 2999068\n", + "24 8904084\n", + "25 3778621\n", + "26 2267425\n", + "27 5435276\n", + "28 4705945\n", + "29 3447890\n", + " ... \n", + "107 3248660\n", + "108 3570392\n", + "109 4219263\n", + "110 2954086\n", + "111 2993069\n", + "112 3784230\n", + "113 2097022\n", + "114 4155435\n", + "115 4882985\n", + "116 8894598\n", + "117 2018785\n", + "118 1847826\n", + "119 3780019\n", + "120 4067566\n", + "121 3445076\n", + "122 4286645\n", + "123 4263629\n", + "124 3810007\n", + "125 4780607\n", + "126 4015749\n", + "127 7592272\n", + "128 2383840\n", + "129 3939804\n", + "130 3376145\n", + "131 3199619\n", + "132 5787594\n", + "133 9262754\n", + "134 2544857\n", + "135 7217634\n", + "136 6363241\n", + "Name: revenue, dtype: float64\n", + "Linear Regressors\n", + "Columns for Linear Regression" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "['P8', 'P10', 'P12', 'P15', 'P17', 'P18', 'P22', 'P28', 'P32', 'num_months']\n", + "Remaining\n", + "['is_big_city', 'Type_MB', 'Type_IL', 'P11', 'P13', 'P14', 'P16', 'P19', 'P30', 'P31', 'P36', 'P37', 'P34', 'P35', 'P2', 'P3', 'P1', 'P6', 'P7', 'P4', 'P5', 'P9', 'Type_FC', 'Type_DT', 'P33', 'P25', 'P24', 'P27', 'P26', 'P21', 'P20', 'P23', 'P29']\n", + "Logistic Regression\n", + "Columns for Logistic Regression" + ] + }, + { + "output_type": "stream", + "stream": "stdout", + "text": [ + "\n", + "['num_months']\n", + "Remaining\n", + "['is_big_city', 'Type_MB', 'Type_IL', 'P10', 'P11', 'P12', 'P13', 'P14', 'P15', 'P16', 'P17', 'P18', 'P19', 'P30', 'P31', 'P36', 'P37', 'P34', 'P35', 'P2', 'P3', 'P1', 'P6', 'P7', 'P4', 'P5', 'P8', 'P9', 'Type_FC', 'Type_DT', 'P32', 'P33', 'P25', 'P24', 'P27', 'P26', 'P21', 'P20', 'P23', 'P22', 'P29', 'P28']\n" + ] + } + ], + "input": [ + "X = load_data(\"train\")\n", + "# Applying transforms here\n", + "cols = X.columns.values.tolist()\n", + "cols.remove('revenue')\n", + "from sklearn.feature_selection import RFECV\n", + "from sklearn.linear_model import Ridge,LogisticRegression\n", + "y = X[\"revenue\"]\n", + "print y\n", + "X = X.drop([\"revenue\"],axis=1)\n", + "X = np.log(X.as_matrix() + 1)\n", + "print \"Linear Regressors\"\n", + "clf_lr = RFECV(Ridge(),scoring=\"mean_squared_error\",cv=137)\n", + "clf_lr.fit(X,np.log(y))\n", + "cols_lr = np.array(cols)[clf_lr.support_].tolist()\n", + "print \"Columns for Linear Regression\"\n", + "print cols_lr\n", + "print \"Remaining\"\n", + "print list(set(cols) - set(cols_lr))\n", + "print \"Logistic Regression\"\n", + "clf_lr = RFECV(LogisticRegression(),scoring=\"mean_squared_error\",cv=137)\n", + "clf_lr.fit(X,np.log(y))\n", + "cols_lr = np.array(cols)[clf_lr.support_].tolist()\n", + "print \"Columns for Logistic Regression\"\n", + "print cols_lr\n", + "print \"Remaining\"\n", + "print list(set(cols) - set(cols_lr))" + ], + "language": "python", + "prompt_number": 123 + }, + { + "cell_type": "code", + "metadata": {}, + "outputs": [], + "input": [ + "" + ], + "language": "python" + } + ] + } + ], + "cells": [], + "metadata": { + "name": "" + }, + "nbformat": 3, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/TFI/batchio.py b/TFI/batchio.py new file mode 100644 index 0000000..0d39f92 --- /dev/null +++ b/TFI/batchio.py @@ -0,0 +1,89 @@ +from extras import load_params +from pandas import read_csv,DataFrame +import os +import numpy as np +from datetime import datetime + +### Approaches +# 1. Using Tfidf Traanform : Give a weight to each class according to its value in a given example + +def sort_restaurant_type(rest_type): + if rest_type == "FC": + return 0 + elif rest_type == "IL": + return 1 + elif rest_type == "MB": + return 1 + elif rest_type == "DT": + return 1 + +def city_hash(cityname): + return hash(cityname) % 57 + +def cal_count(given_date,mode="day"): + current = "1/1/2015" + start_date = datetime.strptime(given_date, "%m/%d/%Y") + end_date = datetime.strptime(current, "%m/%d/%Y") + req_val = (end_date-start_date) + if mode == "day": + return abs(req_val.days) + elif mode == "month": + return int(abs(req_val.days)/12) + elif mode == "year": + return abs(req_val.days)/365 + + + + +def init_transforms(data): + data["City"] = data["City"].apply(lambda x:str(x)) + data["is_big_city"] = data["City Group"].apply(lambda x:int(x=="Big Cities")) + data["start_year"] = data["Open Date"].apply(lambda x:int(x[6:])) + data["start_month"] = data["Open Date"].apply(lambda x:int(x[:2])) + data["start_day"] = data["Open Date"].apply(lambda x:int(x[3:5])) + data["num_years"] = data["start_year"].apply(lambda x:2015 - x) + data["num_years_since_1900"] = data["start_year"].apply(lambda x:x - 1900) + data["num_months"] = data["num_years"].apply(lambda x:x*12) - data["start_month"].apply(lambda x:12-x) + data["num_months_since_1900"] = data["num_years_since_1900"].apply(lambda x:x*12) - data["start_month"].apply(lambda x:12-x) + # data["Type_FC"] = data["Type"].apply(lambda x:int(x=="FC")) + # data["Type_IL"] = data["Type"].apply(lambda x:int(x=="IL")) + # data["Type_DT"] = data["Type"].apply(lambda x:int(x=="DT")) + # data["Type_MB"] = data["Type"].apply(lambda x:int(x=="MB")) + # New Ones + data["Type_Rest"] = data["Type"].apply(sort_restaurant_type) + data["City_Hash"] = data["City"].apply(city_hash) + data = data.drop(["Id","City","City Group","Open Date", + "Type"],axis=1) + # data = data[["num_months","is_big_city","P7"]] + # Xd = data[['num_months','revenue']] + # Xd["num_months"] = Xd["num_months"].apply(np.sqrt) + # print Xd + # data = data[["num_months"]["revenue"]] + # print Xd.head() + return data + +def load_data(data_type,shuffle=True): + assert(data_type == "train" or data_type == "test" or data_type == "cv") + if data_type == "cv": data_type = "train" + path = os.path.join(load_params().data_dir,data_type + ".csv") + data = read_csv(path) + + # print data.columns.values + if data_type != "test": + if shuffle: data = data.reindex(np.random.permutation(data.index)) + y = data.revenue.values + data = data.drop(["revenue"],axis=1) + data = init_transforms(data) + cols = data.columns.values + X = data.as_matrix() + return cols,np.log(X + 1),y + else: + data = init_transforms(data) + X = data.as_matrix() + return np.log(X + 1) + +def make_submission(name,preds): + sub = read_csv(os.path.join(load_params().data_dir,'sampleSubmission.csv')) + # create submission file + sub['Prediction']=preds + sub.to_csv(name, index=False) \ No newline at end of file diff --git a/TFI/classifier.py b/TFI/classifier.py new file mode 100644 index 0000000..2fb8891 --- /dev/null +++ b/TFI/classifier.py @@ -0,0 +1,97 @@ +from sklearn.ensemble import RandomForestRegressor,BaggingRegressor,BaggingClassifier +from sklearn.lda import LDA +from sklearn.linear_model import Ridge,RidgeClassifier +from sklearn.svm import SVR,SVC +import pickle as pkl +import numpy as np +import os + +class RandomForestRegressorWithCoef(RandomForestRegressor): + def fit(self, *args, **kwargs): + super(RandomForestRegressorWithCoef, self).fit(*args, **kwargs) + self.coef_ = self.feature_importances_ + +class RidgeClassifierWithPredProba(RidgeClassifier): + + def predict_proba(self,X): + d = self.decision_function(X) + probs = np.exp(d) / np.sum(np.exp(d)) + return np.vstack((probs,1-probs)).T + + +class SimpleBlendedRegressor: + + def __init__(self,clf_list=[],clf_weights=[],feat_sel=[]): + self.clf_list = clf_list + self.feat_sel = feat_sel + self.clf_weights = clf_weights + + def fit(self,X,y): + for clf_idx in xrange(len(self.clf_list)): + cols_idxs = self.get_cols(self.cols,self.feat_sel[clf_idx]) + Xtrain = X[:,cols_idxs] + self.clf_list[clf_idx].fit(Xtrain,y) + + def predict(self,X): + sum_weights = sum(self.clf_weights) + ypred = np.zeros((X.shape[0])) + for clf_idx in xrange(len(self.clf_list)): + cols_idxs = self.get_cols(self.cols,self.feat_sel[clf_idx]) + Xtest = X[:,cols_idxs] + ypred += self.clf_list[clf_idx].predict(Xtest)*self.clf_weights[clf_idx] + ypred = ypred/sum_weights + return ypred + + def add_all_colnames(self,colnames): + self.cols = colnames + + def get_cols(self,cols,toselect): + final = [] + for i,col in enumerate(cols): + if col in toselect: + final.append(i) + return final + +class SimpleBlendedClassifier: + + def __init__(self,clf_list=[],clf_weights=[],feat_sel=[]): + self.clf_list = clf_list + self.feat_sel = feat_sel + self.clf_weights = clf_weights + + def fit(self,X,y): + self.num_labels = np.unique(y).shape[0] + for clf_idx in xrange(len(self.clf_list)): + cols_idxs = self.get_cols(self.cols,self.feat_sel[clf_idx]) + Xtrain = X[:,cols_idxs] + self.clf_list[clf_idx].fit(Xtrain,y) + + def predict(self,X): + sum_weights = sum(self.clf_weights) + ypred = np.zeros((X.shape[0])) + for clf_idx in xrange(len(self.clf_list)): + cols_idxs = self.get_cols(self.cols,self.feat_sel[clf_idx]) + Xtest = X[:,cols_idxs] + ypred += self.clf_list[clf_idx].predict(Xtest)*self.clf_weights[clf_idx] + ypred = ypred/sum_weights + return ypred + + def predict_proba(self,X): + sum_weights = sum(self.clf_weights) + ypred = np.zeros((X.shape[0],self.num_labels)) + for clf_idx in xrange(len(self.clf_list)): + cols_idxs = self.get_cols(self.cols,self.feat_sel[clf_idx]) + Xtest = X[:,cols_idxs] + ypred += self.clf_list[clf_idx].predict_proba(Xtest)*self.clf_weights[clf_idx] + ypred = ypred/sum_weights + return ypred + + def add_all_colnames(self,colnames): + self.cols = colnames + + def get_cols(self,cols,toselect): + final = [] + for i,col in enumerate(cols): + if col in toselect: + final.append(i) + return final \ No newline at end of file diff --git a/TFI/classifier_bak.py b/TFI/classifier_bak.py new file mode 100644 index 0000000..0e68150 --- /dev/null +++ b/TFI/classifier_bak.py @@ -0,0 +1,77 @@ +from sklearn.ensemble import RandomForestRegressor,BaggingRegressor +from sklearn.lda import LDA +from sklearn.linear_model import Ridge +from sklearn.svm import SVR +import pylibfm +import pickle as pkl +import numpy as np +import os + +def store_pickle(data,path): + f = open(path,"w") + pkl.dump(data,f) + f.close() + +def read_pickle(path): + f = open(path,"r") + data = pkl.load(f) + return data + +class RandomForestRegressorWithCoef(RandomForestRegressor): + def fit(self, *args, **kwargs): + super(RandomForestRegressorWithCoef, self).fit(*args, **kwargs) + self.coef_ = self.feature_importances_ + + +class SimpleBlendedClassifier: + + def __init__(self,clf_list=[],clf_weights=[],feat_sel=[],cache=True): + self.clf_list = clf_list + self.feat_sel = feat_sel + self.clf_weights = clf_weights + self.cache = cache + + def fit(self,X,y): + path = "./cache/%s" % str(self) + if(os.path.isfile(path) and self.cache): + self.clf_list = read_pickle(path) + else: + for clf_idx in xrange(len(self.clf_list)): + cols_idxs = self.get_cols(self.cols,self.feat_sel[clf_idx]) + Xtrain = X[:,cols_idxs] + path_clf = "./cache/%s" % str(self.clf_list[clf_idx]).translate(None,"(,)= ") + if(os.path.isfile(path_clf) and self.cache): + self.clf_list[clf_idx] = read_pickle(path_clf) + else: + self.clf_list[clf_idx].fit(Xtrain,y) + if self.cache: + store_pickle(self.clf_list[clf_idx],path_clf) + if self.cache: + store_pickle(self.clf_list,path) + + def predict(self,X): + sum_weights = sum(self.clf_weights) + ypred = np.zeros((X.shape[0])) + for clf_idx in xrange(len(self.clf_list)): + cols_idxs = self.get_cols(self.cols,self.feat_sel[clf_idx]) + Xtest = X[:,cols_idxs] + ypred += self.clf_list[clf_idx].predict(Xtest)*self.clf_weights[clf_idx] + ypred = ypred/sum_weights + return ypred + + def add_all_colnames(self,colnames): + self.cols = colnames + + def get_cols(self,cols,toselect): + final = [] + for i,col in enumerate(cols): + if col in toselect: + final.append(i) + return final + + def __repr__(self): + base_name = "SimpleBlendedRegModel" + clf_name = '__'.join([str(name).translate(None,"(,)= ") for name in self.clf_list]) + clf_weights = '__'.join([str(wt) for wt in self.clf_weights]) + clf_featsel = '__'.join([''.join([colname for colname in col]) for col in self.feat_sel]) + return '___'.join([str(base_name),str(clf_name),clf_weights,clf_featsel]) \ No newline at end of file diff --git a/TFI/extras.py b/TFI/extras.py new file mode 100644 index 0000000..6299e0c --- /dev/null +++ b/TFI/extras.py @@ -0,0 +1,28 @@ +import json +import numpy as np + +class Params: + """ + Variable used to associate parameters derived from 'settings.json' + Usage + >>> params = Params() + >>> params.var1 = 100 + """ + pass + + +def load_params(): + """ + Load parameters from settings.json and store in Params object variable + :return:set of parameters loaded from settings.json + """ + json_data = open("settings.json") + data = json.load(json_data) + params = Params() + params.data_dir = data["data_dir"] + return params + +def rmse(y_true,y_pred): + assert (y_pred.shape[0] == y_true.shape[0]), "predicted and true values dont match in shape" + num_samples = y_true.shape[0] + return np.sqrt(np.sum(np.square(y_true - y_pred))/num_samples) \ No newline at end of file diff --git a/TFI/settings.json b/TFI/settings.json new file mode 100644 index 0000000..9028a1a --- /dev/null +++ b/TFI/settings.json @@ -0,0 +1,3 @@ +{ + "data_dir" : "/home/tangy/Work/Kaggle/data/TFI" +} \ No newline at end of file diff --git a/TFI/validation.py b/TFI/validation.py new file mode 100644 index 0000000..094bb7c --- /dev/null +++ b/TFI/validation.py @@ -0,0 +1,159 @@ +from batchio import load_data,make_submission +from sklearn.cross_validation import KFold +from sklearn.feature_selection import RFECV +import math +from extras import rmse +from classifier import * +import numpy as np +from sklearn.metrics import accuracy_score + +selector = { + "linear" : ['P8', 'P10', 'P12', 'P15', 'P17', 'P18', 'P22', 'P28', 'P32', 'num_months'], + "lin_svr" : ['P8', 'P10', 'P12', 'P15', 'P16', 'P17', 'P18', 'P22', 'P24', 'P26', 'P28', 'P32', 'start_year', 'num_months'], + "rf" : ['P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7', 'P8', 'P9', 'P10', 'P11', 'P12', 'P13', 'P14', 'P15', 'P16', 'P17', 'P19', 'P20', 'P21', 'P22', 'P24', 'P25', 'P26', 'P27', 'P28', 'P29', 'P30', 'P31', 'P32', 'P33', 'P35', 'P36', 'P37', 'is_big_city', 'start_year', 'start_month', 'start_day', 'num_years', 'num_months', 'Type_Rest'], +} + + +def get_cols(cols,toselect): + final = [] + for i,col in enumerate(cols): + if col in toselect: + final.append(i) + return final + + +def gen_outlier_labels(revenue): + mean = np.mean(revenue) + std = np.std(revenue) + labels = np.zeros(revenue.shape) + upper_lim = mean + std + lower_lim = mean - std + for idx in xrange(revenue.shape[0]): + yrev = revenue[idx] + if yrev > upper_lim: + labels[idx] = 1 + elif yrev < lower_lim: + labels[idx] = -1 + else: + labels[idx] = 0 + return labels + +def run_model_outliers(clf,data_type,data,scoring=accuracy_score): + assert(data_type == "train" or data_type == "test" or data_type == "cv") + if data_type != "test": + (X,y) = data + if data_type == "train": + print "training..." + clf.fit(X,y) + return clf + else: + print "validating..." + num_cv_iters = 30 + score = [] + for iter in xrange(num_cv_iters): + cv_iter = KFold(y.shape[0],n_folds=10,shuffle=True,random_state=iter) + for train_idx,test_idx in cv_iter: + clf.fit(X[train_idx],y[train_idx]) + score.append(scoring(y[test_idx],clf.predict(X[test_idx]))) + print "Mean : %f\nSTD: %f" % (np.mean(score),np.std(score)) + else: + print "testing..." + (X) = data + return clf.predict(X) + +def run_model(clf,data_type,data,scoring="mean_squared_error"): + assert(data_type == "train" or data_type == "test" or data_type == "cv") + if data_type != "test": + (X,y) = data + if data_type == "train": + print "training..." + # clf = BaggingRegressor(base_estimator=clf,n_estimators=1000,n_jobs=-1) + clf.fit(X,np.log(y)) + return clf + else: + print "validating..." + # cv_op = RFECV(clf,scoring=scoring,cv=137) + # X = cv_op.fit_transform(X,np.log(y)) + # clf = BaggingRegressor(base_estimator=clf,n_estimators=1000,n_jobs=-1) + num_cv_iters = 30 + loss = [] + for iter in xrange(num_cv_iters): + cv_iter = KFold(y.shape[0],n_folds=10,shuffle=True,random_state=iter) + for train_idx,test_idx in cv_iter: + clf.fit(X[train_idx],np.log(y[train_idx])) + loss.append(rmse(y[test_idx],np.exp(clf.predict(X[test_idx])))) + print "Log Loss Listing" + print loss + print "Mean : %f" % float(sum(loss)/len(loss)) + # return cv_op + else: + print "testing..." + (X) = data + return np.exp(clf.predict(X)) + +def get_predictions(clf,clf_out): + print clf + cols,Xtrain,ytrain = load_data("train") + Xtest = load_data("test") + cols = cols.tolist() + clf_out.add_all_colnames(cols) + # yout = gen_outlier_labels(ytrain) + # print selector + # sel_idx = get_cols(cols,selector) + # Xtrain = Xtrain[:,sel_idx] + # Xtest = Xtest[:,sel_idx] + # print "getting outliers" + # run_model_outliers(clf_out,"cv",(Xtrain,yout)) + # clf_out = run_model_outliers(clf_out,"train",(Xtrain,yout)) + # yout_pred = run_model_outliers(clf_out,"test",(Xtest)) + print "Running model" + # cols.append("rev_outlier") + clf.add_all_colnames(cols) + # run_model(clf,"cv",(Xtrain,ytrain)) + # Xtrain = np.concatenate((Xtrain,yout.reshape(yout.shape[0],1)),axis=1) + # run_model(clf,"cv",(Xtrain,ytrain)) + clf = run_model(clf,"train",(Xtrain,ytrain)) + # Xtest = np.concatenate((Xtest,yout_pred.reshape(yout_pred.shape[0],1)),axis=1) + ypred = run_model(clf,"test",(Xtest)) + return ypred + +#Notes : 800-1200 estimators seems to work better tho giving a low validation score + +if __name__ == '__main__': + # np.random.seed(5) + clf_blended = SimpleBlendedRegressor( + clf_list=[ + Ridge(), + BaggingRegressor(SVR(C=0.6,degree=5,epsilon=0.2,gamma=0.09),n_estimators=1000,n_jobs=-1), + # SVR(C=0.6,degree=5,epsilon=0.2,gamma=0.09), + ], + clf_weights=[1,1], + feat_sel=[ + selector["linear"], + selector["rf"] + ] + ) + clf_outliers = SimpleBlendedClassifier( + clf_list=[ + RidgeClassifier(), + # RidgeClassifierWithPredProba(), + # BaggingRegressor(SVR(C=0.6,degree=5,epsilon=0.2,gamma=0.09),n_estimators=1000,n_jobs=-1), + # BaggingClassifier(SVC(C=0.6,degree=5,gamma=0.09,probability=True),n_estimators=1000,n_jobs=-1), + SVC(C=0.6,degree=5,gamma=0.09), + ], + clf_weights=[1,1], + feat_sel=[ + selector["linear"], + selector["rf"] + ] + ) + ypred_blendedclf = get_predictions(clf_blended,clf_outliers) + # ypred_ridge = get_predictions(Ridge(),"mean_squared_error",selector["linear"]) + # ypred_rf = get_predictions(RandomForestRegressor(n_estimators=1000,max_depth=5,min_samples_split=5,max_features=1,max_leaf_nodes=18,n_jobs=-1),"mean_squared_error",selector["rf"]) + # ypred_linsvr = get_predictions(LinearSVR(C=0.9,loss='squa red_epsilon_insensitive',epsilon=0.1),"mean_squared_error",selector["lin_svr"]) + # ypred_svr = get_predictions(SVR(C=0.6,degree=5,epsilon=0.2,gamma=0.09),"mean_squared_error",selector["rf"]) + # ypred_svrbagged = get_predictions(BaggingRegressor(SVR(C=0.6,degree=5,epsilon=0.2,gamma=0.09),n_estimators=1000,n_jobs=-1),"mean_squared_error",selector["rf"]) + # fm = pylibfm.FM(num_factors=10, num_iter=50,verbose=False,task="regression", initial_learning_rate=0.02, learning_rate_schedule="constant") + # ypred_svrada = get_predictions(AdaBoostRegressor(SVR(C=0.6,degree=5,epsilon=0.2,gamma=0.09),n_estimators=20,learning_rate=0.5),"mean_squared_error",selector["rf"]) + # ypred = (ypred_ridge + ypred_svrbagged)/2 + make_submission("added_num_years_feat.csv",ypred_blendedclf) diff --git a/TFI/validation_copy.py b/TFI/validation_copy.py new file mode 100644 index 0000000..6cc46e4 --- /dev/null +++ b/TFI/validation_copy.py @@ -0,0 +1,157 @@ +from batchio import load_data,make_submission +from sklearn.cross_validation import KFold +from sklearn.feature_selection import RFECV +import math +from extras import rmse +from classifier import * +import numpy as np +from sklearn.metrics import accuracy_score + +selector = { + "linear" : ['P8', 'P10', 'P12', 'P15', 'P17', 'P18', 'P22', 'P28', 'P32', 'num_months'], + "lin_svr" : ['P8', 'P10', 'P12', 'P15', 'P16', 'P17', 'P18', 'P22', 'P24', 'P26', 'P28', 'P32', 'start_year', 'num_months'], + "rf" : ['P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7', 'P8', 'P9', 'P10', 'P11', 'P12', 'P13', 'P14', 'P15', 'P16', 'P17', 'P19', 'P20', 'P21', 'P22', 'P24', 'P25', 'P26', 'P27', 'P28', 'P29', 'P30', 'P31', 'P32', 'P33', 'P35', 'P36', 'P37', 'is_big_city', 'start_year', 'start_month', 'start_day', 'num_years', 'num_months', 'Type_Rest','rev_outlier'] +} + + +def get_cols(cols,toselect): + final = [] + for i,col in enumerate(cols): + if col in toselect: + final.append(i) + return final + + +def gen_outlier_labels(revenue): + mean = np.mean(revenue) + std = np.std(revenue) + labels = np.zeros(revenue.shape) + upper_lim = mean + std + lower_lim = mean - std + for idx in xrange(revenue.shape[0]): + yrev = revenue[idx] + if yrev > upper_lim or yrev < lower_lim: + labels[idx] = 1 + else: + labels[idx] = 0 + return labels + +def run_model_outliers(clf,data_type,data,scoring=accuracy_score): + print "deriving outliers" + assert(data_type == "train" or data_type == "test" or data_type == "cv") + if data_type != "test": + (X,y) = data + if data_type == "train": + print "training..." + clf.fit(X,y) + return clf + else: + print "validating..." + num_cv_iters = 30 + score = [] + for iter in xrange(num_cv_iters): + cv_iter = KFold(y.shape[0],n_folds=10,shuffle=True,random_state=iter) + for train_idx,test_idx in cv_iter: + clf.fit(X[train_idx],y[train_idx]) + score.append(scoring(y[test_idx],clf.predict(X[test_idx]))) + print "Mean : %f\nSTD: %f" % (np.mean(score),np.std(score)) + else: + print "testing..." + (X) = data + return clf.predict(X) + +def run_model(clf,data_type,data,scoring="mean_squared_error"): + assert(data_type == "train" or data_type == "test" or data_type == "cv") + if data_type != "test": + (X,y) = data + if data_type == "train": + print "training..." + # clf = BaggingRegressor(base_estimator=clf,n_estimators=1000,n_jobs=-1) + clf.fit(X,np.log(y)) + return clf + else: + print "validating..." + # cv_op = RFECV(clf,scoring=scoring,cv=137) + # X = cv_op.fit_transform(X,np.log(y)) + # clf = BaggingRegressor(base_estimator=clf,n_estimators=1000,n_jobs=-1) + num_cv_iters = 30 + loss = [] + for iter in xrange(num_cv_iters): + cv_iter = KFold(y.shape[0],n_folds=10,shuffle=True,random_state=iter) + for train_idx,test_idx in cv_iter: + clf.fit(X[train_idx],np.log(y[train_idx])) + print np.exp(clf.predict(X[test_idx])) + loss.append(rmse(y[test_idx],np.exp(clf.predict(X[test_idx])))) + print "Log Loss Listing" + print loss + print "Mean : %f" % float(sum(loss)/len(loss)) + # return cv_op + else: + print "testing..." + (X) = data + return np.exp(clf.predict(X)) + +def get_predictions(clf,clf_out): + print clf + cols,Xtrain,ytrain = load_data("train") + Xtest = load_data("test") + cols = cols.tolist() + clf_out.add_all_colnames(cols) + yout = gen_outlier_labels(ytrain) + # print selector + # sel_idx = get_cols(cols,selector) + # Xtrain = Xtrain[:,sel_idx] + # Xtest = Xtest[:,sel_idx] + print "getting outliers" + # run_model_outliers(clf_out,"cv",(Xtrain,yout)) + clf_out = run_model_outliers(clf_out,"train",(Xtrain,yout)) + yout_pred = run_model_outliers(clf_out,"test",(Xtest)) + print "Running model" + cols.append("rev_outlier") + clf.add_all_colnames(cols) + # run_model(clf,"cv",(Xtrain,ytrain)) + Xtrain = np.concatenate((Xtrain,yout.reshape(yout.shape[0],1)),axis=1) + clf = run_model(clf,"train",(Xtrain,ytrain)) + Xtest = np.concatenate((Xtest,yout_pred.reshape(yout_pred.shape[0],1)),axis=1) + ypred = run_model(clf,"test",(Xtest)) + return ypred + +#Notes : 800-1200 estimators seems to work better tho giving a low validation score + +if __name__ == '__main__': + # np.random.seed(5) + clf_blended = SimpleBlendedRegressor( + clf_list=[ + Ridge(), + # BaggingRegressor(SVR(C=0.6,degree=5,epsilon=0.2,gamma=0.09),n_estimators=1000,n_jobs=-1), + SVR(C=0.6,degree=5,epsilon=0.2,gamma=0.09), + ], + clf_weights=[1,1], + feat_sel=[ + selector["linear"], + selector["rf"] + ] + ) + clf_outliers = SimpleBlendedClassifier( + clf_list=[ + # RidgeClassifier(), + RidgeClassifierWithPredProba(), + # BaggingRegressor(SVR(C=0.6,degree=5,epsilon=0.2,gamma=0.09),n_estimators=1000,n_jobs=-1), + # SVC(C=0.6,degree=5,gamma=0.09,probability=True), + ], + clf_weights=[1], + feat_sel=[ + selector["linear"], + # selector["rf"] + ] + ) + ypred_blendedclf = get_predictions(clf_blended,clf_outliers) + # ypred_ridge = get_predictions(Ridge(),"mean_squared_error",selector["linear"]) + # ypred_rf = get_predictions(RandomForestRegressor(n_estimators=1000,max_depth=5,min_samples_split=5,max_features=1,max_leaf_nodes=18,n_jobs=-1),"mean_squared_error",selector["rf"]) + # ypred_linsvr = get_predictions(LinearSVR(C=0.9,loss='squa red_epsilon_insensitive',epsilon=0.1),"mean_squared_error",selector["lin_svr"]) + # ypred_svr = get_predictions(SVR(C=0.6,degree=5,epsilon=0.2,gamma=0.09),"mean_squared_error",selector["rf"]) + # ypred_svrbagged = get_predictions(BaggingRegressor(SVR(C=0.6,degree=5,epsilon=0.2,gamma=0.09),n_estimators=1000,n_jobs=-1),"mean_squared_error",selector["rf"]) + # fm = pylibfm.FM(num_factors=10, num_iter=50,verbose=False,task="regression", initial_learning_rate=0.02, learning_rate_schedule="constant") + # ypred_svrada = get_predictions(AdaBoostRegressor(SVR(C=0.6,degree=5,epsilon=0.2,gamma=0.09),n_estimators=20,learning_rate=0.5),"mean_squared_error",selector["rf"]) + # ypred = (ypred_ridge + ypred_svrbagged)/2 + make_submission("baggedsvrnridge.csv",ypred_blendedclf)