├── .DS_Store ├── .gitignore ├── AccelerometerFeatureExtractionScript.py ├── ArtifactClassifiers.py ├── EDA-Artifact-Detection-Script.py ├── EDA-Peak-Detection-Script.py ├── LICENSE.txt ├── README.md ├── classify.py ├── load_files.py └── requirements.txt /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MITMediaLabAffectiveComputing/eda-explorer/fdfde39ad576668a59429aec100b2bcc0942d318/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | .idea 3 | env-python2 4 | env-python3 5 | tests -------------------------------------------------------------------------------- /AccelerometerFeatureExtractionScript.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | import scipy.signal as scisig 4 | import os 5 | import matplotlib.pyplot as plt 6 | 7 | from load_files import getInputLoadFile, getOutputPath, get_user_input 8 | 9 | DEBUG = True 10 | 11 | SAMPLING_RATE = 8 12 | 13 | ONE_MINUTE_S = 60 14 | THIRTY_MIN_S = ONE_MINUTE_S*30 15 | SECONDS_IN_DAY = 24*60*60 16 | 17 | STILLNESS_MOTION_THRESHOLD = .1 18 | PERCENT_STILLNESS_THRESHOLD = .95 19 | 20 | STEP_DIFFERENCE_THRESHOLD = 0.3 21 | 22 | 23 | 24 | def computeAllAccelerometerFeatures(data, time_frames): 25 | if DEBUG: print("\t\tcomputing motion...") 26 | motion = computeMotion(data['AccelX'], data['AccelY'], data['AccelZ']) 27 | 28 | if DEBUG: print("\t\tcomputing steps...") 29 | steps = computeSteps(motion) 30 | 31 | if DEBUG: print("\t\tcomputing stillness...") 32 | stillness = computeStillness(motion) 33 | 34 | features = [] 35 | 36 | for time_frame in time_frames: 37 | start = time_frame[0] 38 | end = time_frame[1] 39 | start1Hz = int(start / SAMPLING_RATE) 40 | end1Hz = end if end == -1 else int(end / SAMPLING_RATE) 41 | if DEBUG: print("\t\tcomputing features for time frame. Start index: "+ str(start)+ " end index: "+ str(end)) 42 | 43 | time_frame_feats = computeAccelerometerFeaturesOverOneTimeFrame(motion[start:end], 44 | steps[start:end], 45 | stillness[start1Hz:end1Hz]) 46 | features.append(time_frame_feats) 47 | 48 | return features, steps, motion 49 | 50 | def computeMotion(acc1, acc2, acc3): 51 | '''Aggregates 3-axis accelerometer signal into a single motion signal''' 52 | return np.sqrt(np.array(acc1)**2 + np.array(acc2)**2 + np.array(acc3)**2) 53 | 54 | def computeSteps(motion): 55 | '''Determines the location of steps from the aggregated accelerometer signal. 56 | Signal is low-pass filtered, then minimums are located in the signal. For each 57 | min, if the max absolute derivative (first difference) immediately surrounding 58 | it is greater than a threshold, it is counted as a step. 59 | 60 | Args: 61 | motion: root mean squared 3 axis acceleration 62 | Returns: 63 | steps: binary array at 8Hz which is 1 everywhere there is a step''' 64 | 65 | filtered_signal = filterSignalFIR(motion, 2, 256) 66 | diff = filtered_signal[1:]-filtered_signal[:-1] 67 | 68 | mins = scisig.argrelextrema(filtered_signal, np.less)[0] 69 | 70 | steps = [0] * len(filtered_signal) 71 | for m in mins: 72 | if m <= 4 or m >= len(diff) - 4: 73 | continue 74 | if max(abs(diff[m-4:m+4])) > STEP_DIFFERENCE_THRESHOLD: 75 | steps[m] = 1.0 76 | 77 | return steps 78 | 79 | def filterSignalFIR(eda, cutoff=0.4, numtaps=64): 80 | f = cutoff/(SAMPLING_RATE/2.0) 81 | FIR_coeff = scisig.firwin(numtaps,f) 82 | 83 | return scisig.lfilter(FIR_coeff,1,eda) 84 | 85 | def computeStillness(motion): 86 | '''Locates periods in which the person is still or motionless. 87 | Total acceleration must be less than a threshold for 95 percent of one 88 | minute in order for that minute to count as still 89 | 90 | Args: 91 | motion: an array containing the root mean squared acceleration 92 | Returns: 93 | A 1Hz array that is 1 for each second belonging to a still period, 0 otherwise 94 | ''' 95 | diff = motion[1:]-motion[:-1] 96 | momentary_stillness = diff < STILLNESS_MOTION_THRESHOLD 97 | np.append(momentary_stillness,0) # to ensure list is the same size as the full day signal 98 | num_minutes_in_day = 24*60 99 | 100 | #create array indicating whether person was still or not for each second of the day 101 | #to be still the momentary_stillness signal must be true for more than 95% of the minute 102 | #containing that second 103 | second_stillness = [0]*SECONDS_IN_DAY 104 | 105 | for i in range(num_minutes_in_day): 106 | hours_start = int(i / 60) 107 | mins_start = i % 60 108 | hours_end = int((i+1) / 60) 109 | mins_end = (i+1) % 60 110 | 111 | start_idx = getIndexFromTimestamp(hours_start, mins_start) 112 | end_idx = getIndexFromTimestamp(hours_end, mins_end) 113 | 114 | this_minute = momentary_stillness[start_idx:end_idx] 115 | minute_stillness = sum(this_minute) > PERCENT_STILLNESS_THRESHOLD*(60*SAMPLING_RATE) 116 | 117 | second_idx = int(start_idx/8) 118 | for si in range(second_idx,second_idx+60): 119 | second_stillness[si] = float(minute_stillness) 120 | 121 | return second_stillness 122 | 123 | def computeAccelerometerFeaturesOverOneTimeFrame(motion, steps, stillness): 124 | ''' Computes all available features for a time period. Incoming signals are assumed to be from 125 | only that time period. 126 | 127 | Args: 128 | motion: 8Hz root mean squared 3 axis acceleration 129 | steps: 8Hz binary signal that is 1 if there is a step 130 | stillness: 1Hz 1 if the person was still during this second, 0 otherwise 131 | Returns: 132 | A list of features containing (in order): 133 | -Step count number of steps detected 134 | -mean step time during movement average number of samples between two steps (aggregated first to 1 minute, 135 | then we take the mean of only the parts of this signal occuring during movement) 136 | -percent stillness percentage of time the person spent nearly motionless 137 | ''' 138 | 139 | features = [] 140 | 141 | features.extend(computeStepFeatures(steps,stillness)) 142 | features.append(countStillness(stillness)) 143 | 144 | return features 145 | 146 | def computeStepFeatures(steps,stillness): 147 | '''Counts the total number of steps over a given period, 148 | as well as the average time between steps (meant to approximate walking speed) 149 | 150 | Args: 151 | steps: an binary array at 8 Hz that is 1 every time there is a step 152 | Returns: 153 | sum: the number of steps in a period 154 | median time: average number of samples between two steps''' 155 | 156 | sum_steps = float(sum(steps)) 157 | 158 | step_indices = np.nonzero(steps)[0] 159 | diff = step_indices[1:]-step_indices[:-1] 160 | 161 | #ensure length of step difference array is the same so we can get the actual locations of step differences 162 | timed_step_diff = np.empty(len(steps)) * np.nan 163 | timed_step_diff[step_indices[:len(diff)]] = diff 164 | 165 | signal_length_1s = len(stillness) 166 | signal_length_1min = int(signal_length_1s / 60) 167 | 168 | # if there aren't enough steps during this period, cannot accurately compute mean step diff 169 | if len(timed_step_diff) < signal_length_1min: 170 | return [sum_steps, np.nan] 171 | 172 | agg_stillness = aggregateSignal(stillness, signal_length_1min, 'max') 173 | agg_step_diff = aggregateSignal(timed_step_diff, signal_length_1min, 'mean') 174 | 175 | movement_indices = [i for i in range(len(agg_stillness)) if agg_stillness[i] == 0.0] 176 | step_diff_during_movement = agg_step_diff[movement_indices] 177 | 178 | return [sum_steps,round(np.nanmean(step_diff_during_movement),10)] 179 | 180 | def countStillness(stillness): 181 | '''Counts the total percentage of time spent still over a period 182 | 183 | Args: 184 | stillness: an binary array at 1Hz that is 1 if that second is part of a still period 185 | Returns: 186 | the percentage time spent still over a period''' 187 | 188 | return float(sum(stillness)) / float(len(stillness)) 189 | 190 | def aggregateSignal(signal, new_signal_length, agg_method='sum'): 191 | new_signal = np.zeros(new_signal_length) 192 | samples_per_bucket = int(len(signal) / new_signal_length) 193 | 194 | #the new signal length must be large enough that there is at least 1 sample per bucket 195 | assert(samples_per_bucket > 0) 196 | 197 | for i in range(new_signal_length): 198 | if agg_method == 'sum': 199 | new_signal[i] = np.nansum(signal[i*samples_per_bucket:(i+1)*samples_per_bucket]) 200 | elif agg_method == 'percent': 201 | new_signal[i] = np.nansum(signal[i*samples_per_bucket:(i+1)*samples_per_bucket]) / samples_per_bucket 202 | elif agg_method == 'mean': 203 | new_signal[i] = np.nanmean(signal[i*samples_per_bucket:(i+1)*samples_per_bucket]) 204 | elif agg_method == 'max': 205 | new_signal[i] = np.nanmax(signal[i*samples_per_bucket:(i+1)*samples_per_bucket]) 206 | return new_signal 207 | 208 | def getIndexFromTimestamp(hours, mins=0): 209 | return ((hours * 60) + mins) * 60 * SAMPLING_RATE 210 | 211 | def inputTimeFrames(): 212 | '''Allows user to choose the time frames over which they compute accelerometer features.''' 213 | 214 | time_frames = [] 215 | print("Accelerometer features can be extracted over different time periods.") 216 | cont = get_user_input("If you would like to enter a time period over which to compute features, enter 'y', or press enter to compute features over the entire file.") 217 | while cont == 'y' or cont == 'Y': 218 | start = int(get_user_input("Enter the starting hour of the time period (hour 0 is when the file starts):")) 219 | end = int(get_user_input("Enter the ending hour of the time period (hour 0 is when the file starts; use -1 for the end of the file):")) 220 | start = getIndexFromTimestamp(int(start)) 221 | if end != -1: 222 | end = getIndexFromTimestamp(int(end)) 223 | time_frames.append([start,end]) 224 | print("Great! Now computing features for the following time periods:"+ str(time_frames)) 225 | cont = get_user_input("To add another time period, enter 'y'. To finish, press enter.") 226 | 227 | if len(time_frames) == 0: 228 | time_frames = [[0,-1]] # the whole file 229 | 230 | return time_frames 231 | 232 | def saveFeaturesToFile(features, time_frames, output_file): 233 | of = open(output_file, 'w') 234 | of.write("Time period start hour, Time period end hour, Step count, Mean step time during movement, Percent stillness\n") 235 | tf_i = 0 236 | for tf in time_frames: 237 | output_str = str(tf[0]) + ' , ' + str(tf[1]) 238 | for feat in features[tf_i]: 239 | output_str += ' , ' + str(feat) 240 | tf_i += 1 241 | of.write(output_str + '\n') 242 | of.close() 243 | print("Saved features to file"+ output_file) 244 | 245 | # draws a graph of the data with the peaks marked on it 246 | # assumes that 'data' dataframe already contains the 'peaks' column 247 | def plotSteps(data, x_seconds, sampleRate = SAMPLING_RATE): 248 | if x_seconds: 249 | time_m = np.arange(0,len(data))/float(sampleRate) 250 | realign = 128/(sampleRate) 251 | else: 252 | time_m = np.arange(0,len(data))/(sampleRate*60.) 253 | realign = 128/(sampleRate*60.) 254 | 255 | data_min = data['motion'].min() 256 | data_max = data['motion'].max() 257 | 258 | #Plot the data with the Peaks marked 259 | plt.figure(1,figsize=(20, 5)) 260 | 261 | plt.plot(time_m,data['motion']) 262 | 263 | for i in range(len(data)): 264 | if data.iloc[i]["steps"]==1: 265 | x_loc = time_m[i] - realign 266 | plt.plot([x_loc,x_loc],[data_min,data_max],"k") 267 | step_height = data_max * 1.15 268 | #data['steps_plot'] = data['steps'] * step_height 269 | #plt.plot(time_m,data['steps_plot'],'k') 270 | 271 | plt.xlim([0,time_m[-1]]) 272 | plt.ylim([data_min-.1,data_max+.1]) 273 | plt.title('Motion with Detected "Steps" marked') 274 | plt.ylabel('g') 275 | if x_seconds: 276 | plt.xlabel('Time (s)') 277 | else: 278 | plt.xlabel('Time (min)') 279 | 280 | plt.show() 281 | 282 | if __name__ == "__main__": 283 | print("This script will extract features related to accelerometer data.") 284 | 285 | data, filepath_confirm = getInputLoadFile() 286 | 287 | output_path = getOutputPath() 288 | 289 | time_frames = inputTimeFrames() 290 | 291 | features, steps, motion = computeAllAccelerometerFeatures(data, time_frames) 292 | 293 | data["steps"] = steps 294 | data["motion"] = motion 295 | 296 | saveFeaturesToFile(features, time_frames, output_path) 297 | 298 | print("") 299 | plot_ans = get_user_input("Do you want to plot the detected steps? (y/n): ") 300 | if 'y' in plot_ans: 301 | secs_ans = get_user_input("Would you like the x-axis to be in seconds or minutes? (sec/min): ") 302 | if 'sec' in secs_ans: 303 | x_seconds=True 304 | else: 305 | x_seconds=False 306 | plotSteps(data, x_seconds) 307 | else: 308 | print("\tOkay, script will not produce a plot") 309 | 310 | -------------------------------------------------------------------------------- /ArtifactClassifiers.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from sklearn.metrics.pairwise import rbf_kernel 3 | 4 | 5 | def predict_binary_classifier(X): 6 | '''' 7 | X: num test data by 13 features 8 | ''' 9 | 10 | # Get params 11 | params = binary_classifier() 12 | 13 | # compute kernel for all data points 14 | K = rbf_kernel(params['support_vec'], X, gamma=params['gamma']) 15 | 16 | # Prediction = sign((sum_{i=1}^n y_i*alpha*K(x_i,x)) + rho) 17 | predictions = np.zeros(X.shape[0]) 18 | for i in range(X.shape[0]): 19 | predictions[i] = np.sign(np.sum(params['dual_coef']*K[:, i]) + params['intercept']) 20 | 21 | return predictions 22 | 23 | 24 | def predict_multiclass_classifier(X): 25 | ''' 26 | X: num test data by 10 features 27 | ''' 28 | # Get params 29 | params = multiclass_classifier() 30 | 31 | K = rbf_kernel(params['support_vec'], X, gamma=params['gamma']) 32 | 33 | # define the start and end index for support vectors for each class 34 | nv = params['num_support_vec'] 35 | start = [sum(nv[:i]) for i in range(len(nv))] 36 | end = [start[i] + nv[i] for i in range(len(nv))] 37 | 38 | # calculate: sum(a_p * k(x_p, x)) between every 2 classes 39 | dual_coef = params['dual_coef'].T 40 | predictions_0_1 = np.zeros(X.shape[0]) 41 | for i in range(X.shape[0]): 42 | temp_prediction = np.sum(dual_coef[start[0]:end[0], 0] * K[start[0]:end[0], i]) + \ 43 | np.sum(dual_coef[start[1]:end[1], 0] * K[start[1]:end[1], i]) + params['intercept'][0] 44 | predictions_0_1[i] = 0 if temp_prediction > 0 else 1 45 | 46 | predictions_0_2 = np.zeros(X.shape[0]) 47 | for i in range(X.shape[0]): 48 | temp_prediction = np.sum(dual_coef[start[0]:end[0], 1] * K[start[0]:end[0], i]) + \ 49 | np.sum(dual_coef[start[2]:end[2], 0] * K[start[2]:end[2], i]) + params['intercept'][1] 50 | predictions_0_2[i] = 0 if temp_prediction > 0 else 2 51 | 52 | predictions_1_2 = np.zeros(X.shape[0]) 53 | for i in range(X.shape[0]): 54 | temp_prediction = np.sum(dual_coef[start[1]:end[1], 1] * K[start[1]:end[1], i]) + \ 55 | np.sum(dual_coef[start[2]:end[2], 1] * K[start[2]:end[2], i]) + params['intercept'][2] 56 | predictions_1_2[i] = 1 if temp_prediction > 0 else 2 57 | 58 | decision_function = np.vstack([predictions_0_1, predictions_0_2, predictions_1_2]).T 59 | 60 | # Majority Vote to find the best class 61 | predictions = np.zeros(X.shape[0]) 62 | for i in range(X.shape[0]): 63 | lst = decision_function[i,:].tolist() 64 | predictions[i] = max(set(lst), key=lst.count)-1 65 | 66 | return predictions 67 | 68 | 69 | 70 | def binary_classifier(): 71 | gamma = 0.1 72 | 73 | # dual coef = y_i*alpha_i 74 | dual_coef = np.array([[-1.12775599e+02, -1.00000000e+03, -1.00000000e+03, 75 | -1.00000000e+03, -1.00000000e+03, -1.00000000e+03, 76 | -1.00000000e+03, -1.00000000e+03, -1.00000000e+03, 77 | -1.00000000e+03, -1.00000000e+03, -1.00000000e+03, 78 | -4.65947457e+02, -1.00000000e+03, -1.00000000e+03, 79 | -1.00000000e+03, -1.17935400e+02, -1.00000000e+03, 80 | -1.00000000e+03, -1.00000000e+03, -1.00000000e+03, 81 | -1.00000000e+03, -1.00000000e+03, -1.00000000e+03, 82 | -1.00000000e+03, -2.92534132e+02, -1.00000000e+03, 83 | -1.00000000e+03, -3.69965631e+01, -1.00000000e+03, 84 | -1.00000000e+03, -1.00000000e+03, -1.00000000e+03, 85 | -1.00000000e+03, -1.00000000e+03, -1.00000000e+03, 86 | -1.00000000e+03, -1.00000000e+03, 1.00000000e+03, 87 | 1.00000000e+03, 1.00000000e+03, 1.00000000e+03, 88 | 7.92366387e+02, 3.00553142e+02, 2.22950860e-01, 89 | 1.00000000e+03, 1.00000000e+03, 5.58636056e+02, 90 | 1.21751544e+02, 1.00000000e+03, 1.00000000e+03, 91 | 2.61920652e+00, 9.96570403e+02, 1.00000000e+03, 92 | 1.00000000e+03, 1.00000000e+03, 1.00000000e+03, 93 | 1.00000000e+03, 1.00000000e+03, 1.02270060e+02, 94 | 5.41288840e+01, 1.91650287e+02, 1.00000000e+03, 95 | 1.00000000e+03, 1.00000000e+03, 1.00000000e+03, 96 | 1.00000000e+03, 2.45152637e+02, 7.53766346e+02, 97 | 1.00000000e+03, 1.00000000e+03, 3.63211198e+00, 98 | 1.00000000e+03, 3.31675798e+01, 5.64620367e+02, 99 | 1.00000000e+03, 1.00000000e+03, 1.00000000e+03, 100 | 2.66900636e+02, 1.00000000e+03, 6.54763900e+02, 101 | 3.38216549e+02, 6.86434772e+01, 2.78998678e+02, 102 | 6.97557950e+02, 1.00000000e+03]]) 103 | 104 | # intercept = rho 105 | intercept = np.array([-2.63232929]) 106 | 107 | # support vectors = x_i 108 | support_vec = np.array([[0.02809756, 0.0455, 0.025, 0.00866667, 0.03799132, -0.00799413, 0.01061208, 0.016263, 0.00671743, 0.00572262, 0.00578504, 0.00542415, 0.00318195], 109 | [0.00060976, 0.0035, 0.007, 0.00087179, 0.00024191, -0.0005069, 0.0005069, 0.0070711, 0.00306413, 0.0031833, 0.0107827, 0.0066959, 0.0022981], 110 | [3.49731707, 0.092, 0.054, 0.01923077, 3.53815367, -0.02236652, 0.02659884, 0.062225, 0.0316782, 0.01818914, 0.06607571, 0.03342241, 0.099702], 111 | [2.52643902, 0.058, 0.055, 0.0114359, 2.54031008, -0.01070662, 0.01296803, 0.043134, 0.01649923, 0.01579683, 0.03326171, 0.05004163, 0.013965], 112 | [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, -2.74622599e-18, -2.42947453e-17, 3.36047450e-17, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], 113 | [3.89758537, 0.167, 0.27, 0.06717949, 3.87923565, -0.04130143, 0.05403825, 0.047376, 0.0328098, 0.01255584, 0.03676955, 0.14237773, 0.11031], 114 | [0.93326829, 0.0855, 0.106, 0.01169231, 0.92669874, -0.02740927, 0.02740927, 0.043841, 0.01131377, 0.01595008, 0.0231871, 0.02414775, 0.0139655], 115 | [4.64253659, 0.106, 0.13, 0.03661538, 4.63806066, -0.03168223, 0.03168223, 0.10182, 0.0559785, 0.03369301, 0.06341563, 0.08583294, 0.0251025], 116 | [0.29312195, 0.028, 0.039, 0.00682051, 0.28575076, -0.00648365, 0.00648365, 0.0056569, 0.00367694, 0.00126494, 0.00364005, 0.01814984, 0.006364], 117 | [3.08187805, 0.0615, 0.123, 0.03435897, 3.11862292, -0.02260403, 0.02260403, 0.053033, 0.0397394, 0.01570345, 0.0338851, 0.10069204, 0.16652], 118 | [2.43902439e-05, 5.00000000e-04, 1.00000000e-03, 1.02564103e-04, 2.43769719e-05, -7.19856842e-05, 7.19856842e-05, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], 119 | [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, -4.05052739e-10, -2.77557303e-09, 5.77955577e-09, 7.07110000e-04, 1.17851667e-04, 2.88676449e-04, 2.04124145e-04, 1.44336183e-04, 0.00000000e+00], 120 | [0.83290244, 0.099, 0.172, 0.02610256, 0.82408369, -0.0168393, 0.0168393, 0.13011, 0.02875613, 0.04987211, 0.03786379, 0.02684837, 0.0155565], 121 | [0.92597561, 0.017, 0.009, 0.00369231, 0.92583814, -0.00670974, 0.00670974, 0.012021, 0.00506763, 0.00420523, 0.01259266, 0.0115391, 0.00265165], 122 | [2.43902439e-05, 5.00000000e-04, 1.00000000e-03, 2.56410256e-05, 2.18000765e-04, -5.56411248e-04, 5.56411248e-04, 9.19240000e-03, 2.71058333e-03, 4.25246049e-03, 2.49833278e-03, 7.64311464e-03, 0.00000000e+00], 123 | [0.88760976, 0.0205, 0.022, 0.00489744, 0.88799505, -0.00346772, 0.00461828, 0.011314, 0.00447838, 0.00394135, 0.01327278, 0.01434142, 0.00406585], 124 | [9.21263415, 0.118, 0.472, 0.0695641, 9.19153391, -0.02181738, 0.02181738, 0.16688, 0.07130037, 0.06135461, 0.04328934, 0.04277416, 0.0829085], 125 | [0.48378049, 0.017, 0.026, 0.00794872, 0.48333175, -0.00337375, 0.00350864, 0.016971, 0.0089568, 0.00472601, 0.01168189, 0.01629524, 0.0226275], 126 | [0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 9.65026603e-122, -2.00921455e-120, 4.22507597e-120, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000], 127 | [0.10897561, 0.03, 0.033, 0.00553846, 0.12761266, -0.00442938, 0.00556735, 0.025456, 0.00872107, 0.00870258, 0.01130487, 0.01554551, 0.0123745], 128 | [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, -1.38812548e-09, -2.34438020e-08, 2.34438020e-08, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], 129 | [0.66663415, 0.052, 0.05, 0.00510256, 0.66182973, -0.01361869, 0.01361869, 0.0049497, 0.00296982, 0.00208565, 0.00424264, 0.00961131, 0.012374], 130 | [3.74146341e+00, 6.60000000e-02, 7.00000000e-02, 2.41025641e-02, 3.72790310e+00, -1.65194036e-02, 1.65194036e-02, 2.33350000e-02, 2.29102000e-02, 3.87787571e-04, 7.25086202e-03, 8.04828002e-03, 2.26270000e-02], 131 | [2.43902439e-05, 5.00000000e-04, 1.00000000e-03, 1.02564103e-04, 2.44149661e-05, -7.19856850e-05, 7.19856850e-05, 7.07110000e-04, 1.17851667e-04, 2.88676449e-04, 2.04124145e-04, 1.44336183e-04, 0.00000000e+00], 132 | [1.14713659e+01, 1.68000000e-01, 3.24000000e-01, 8.83589744e-02, 1.13977278e+01, -4.35202063e-02, 4.35202063e-02, 1.20920000e-01, 1.15826000e-01, 5.32593935e-03, 4.29825546e-02, 1.11681949e-01, 1.82080000e-01], 133 | [1.63631707, 0.0825, 0.138, 0.02410256, 1.65473267, -0.02914746, 0.02927458, 0.074953, 0.02899134, 0.03271076, 0.02718317, 0.09610564, 0.012728], 134 | [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 6.01460518e-42, -2.71490067e-40, 2.71490067e-40, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], 135 | [0.52358537, 0.038, 0.03, 0.00769231, 0.52319376, -0.01066405, 0.01066405, 0.026163, 0.01025307, 0.00912966, 0.02678697, 0.04011893, 0.00866185], 136 | [0.10931707, 0.103, 0.407, 0.04461538, 0.13188551, -0.01686662, 0.02506229, 0.1492, 0.0384195, 0.06327203, 0.06411448, 0.05508901, 0], 137 | [0.0444878, 0.0245, 0.04, 0.00984615, 0.03577326, -0.00573919, 0.00573919, 0.013435, 0.0078961, 0.00418135, 0.01136515, 0.01291603, 0.0134352], 138 | [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.03127202e-08, -2.56175141e-07, 5.37317466e-07, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00], 139 | [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 140 | [0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 3.27917545e-05, -7.79437718e-04, 7.79437718e-04, 3.04060000e-02, 5.06766667e-03, 1.24131975e-02, 1.34721936e-02, 5.34029589e-02, 0.00000000e+00], 141 | [2.43902439e-05, 5.00000000e-04, 1.00000000e-03, 1.02564103e-04, 2.60691650e-05, -7.19856850e-05, 7.19856850e-05, 7.07110000e-04, 1.17851667e-04, 2.88676449e-04, 2.04124145e-04, 1.44336183e-04, 0.00000000e+00], 142 | [0.46446341, 0.033, 0.03, 0.00933333, 0.46299034, -0.00866364, 0.00866364, 0.033941, 0.01357644, 0.01214903, 0.02164486, 0.02701617, 0.012374], 143 | [5.89978049, 0.117, 0.112, 0.04453846, 5.88525247, -0.02253416, 0.02253416, 0.084146, 0.0492146, 0.01985341, 0.06802812, 0.09041259, 0.045255], 144 | [0.01317073, 0.0195, 0.015, 0.00538462, 0.00829287, -0.00622806, 0.00622806, 0.026163, 0.01145514, 0.00926554, 0.00690652, 0.02540613, 0.018031], 145 | [1.16509756, 0.028, 0.02, 0.01051282, 1.16338281, -0.01379371, 0.01379371, 0.020506, 0.01461345, 0.00563317, 0.01416569, 0.01971055, 0.0281075], 146 | [3.67914634, 0.1235, 0.126, 0.02676923, 3.67052968, -0.04266586, 0.04266586, 0.041719, 0.0233342, 0.0106888, 0.03232337, 0.07260248, 0.050912], 147 | [0.11331707, 0.0015, 0.004, 0.0014359, 0.11329803, -0.00042144, 0.00042144, 0.0021213, 0.0014142, 0.00109543, 0.00124164, 0.00053231, 0.00070713], 148 | [1.11256098, 0.026, 0.016, 0.00561538, 1.09093248, -0.00174647, 0.00490015, 0.02192, 0.01272782, 0.00816993, 0.02111102, 0.04921207, 0.012021], 149 | [0.06846341, 0.007, 0.01, 0.00307692, 0.06774886, -0.00179795, 0.00190969, 0.0056569, 0.00311126, 0.00162791, 0.00195576, 0.00721732, 0.01096], 150 | [1.16454634e+01, 1.78500000e-01, 3.20000000e-01, 8.94615385e-02, 1.15869935e+01, -1.15451745e-02, 1.59897956e-02, 1.37890000e-01, 1.23393333e-01, 1.01170444e-02, 3.66151153e-02, 1.46607419e-01, 1.94455000e-01], 151 | [3.45158537, 0.1375, 0.052, 0.01676923, 3.44594643, -0.03141983, 0.03141983, 0.038184, 0.0272946, 0.00958649, 0.01698014, 0.06290749, 0.1393], 152 | [3.12563415, 0.0535, 0.111, 0.02897436, 3.17337638, -0.02835417, 0.02835417, 0.054447, 0.0278601, 0.0188188, 0.00755315, 0.03628251, 0.055154], 153 | [8.50975610e-02, 1.00000000e-03, 4.00000000e-03, 8.20512821e-04, 8.50491997e-02, -1.84870042e-04, 2.35933619e-04, 1.41420000e-03, 1.41420000e-03, 2.60312573e-11, 4.08248290e-04, 2.88668284e-04, 7.07110000e-04], 154 | [0.82373171, 0.048, 0.121, 0.01853846, 0.82149219, -0.0053288, 0.00684639, 0.041012, 0.0208598, 0.01423898, 0.02609294, 0.02676908, 0.01078335], 155 | [4.39680488, 0.223, 0.354, 0.09258974, 4.35973108, -0.03206468, 0.03450864, 0.20506, 0.0971572, 0.07235446, 0.13713059, 0.23019854, 0.32138], 156 | [5.66058537, 0.0285, 0.093, 0.01282051, 5.66682734, -0.00633008, 0.00633008, 0.040305, 0.01513214, 0.01889847, 0.01503912, 0.03383458, 0], 157 | [0.13329268, 0.011, 0.021, 0.00338462, 0.13419267, -0.00262455, 0.00262455, 0.0035355, 0.00226272, 0.00092195, 0.00772172, 0.00411547, 0.0038891], 158 | [0.15463415, 0.0325, 0.065, 0.01617949, 0.15422134, -0.00766504, 0.00766504, 0.067882, 0.02286322, 0.02270081, 0.02939288, 0.0224428, 0.017501], 159 | [1.47902439e-01, 1.50000000e-03, 2.00000000e-03, 3.84615385e-04, 1.48269290e-01, -1.36058722e-04, 1.36058722e-04, 2.12130000e-03, 8.24950000e-04, 9.39849132e-04, 5.16397779e-04, 5.91603500e-04, 0.00000000e+00], 160 | [2.76797561, 0.071, 0.17, 0.03212821, 2.84223399, -0.01692731, 0.01692731, 0.04879, 0.03441267, 0.00934515, 0.03221283, 0.05768286, 0.092806], 161 | [1.30939024, 0.044, 0.066, 0.0165641, 1.2967273, -0.01727205, 0.01727205, 0.03182, 0.01456652, 0.01056655, 0.00732632, 0.02987207, 0.038891], 162 | [0.0914878, 0.038, 0.028, 0.00364103, 0.08295897, -0.00877545, 0.00877545, 0.032527, 0.00648182, 0.01277828, 0.01289089, 0.01040763, 0.0042426], 163 | [0.13621951, 0.0015, 0.006, 0.00174359, 0.13689296, -0.00036169, 0.00040731, 0.0021213, 0.00153205, 0.00082663, 0.00058452, 0.00069522, 0.00088391], 164 | [0.05692683, 0.007, 0.006, 0.00189744, 0.05532006, -0.00145672, 0.00145672, 0.0056569, 0.00311126, 0.00184393, 0.00420714, 0.00465287, 0.0070711], 165 | [0.07460976, 0.002, 0.006, 0.00097436, 0.07430141, -0.00035004, 0.00038011, 0.0028284, 0.00113136, 0.0011832, 0.00070711, 0.0005916, 0.00070711], 166 | [0.04782927, 0.006, 0.011, 0.00353846, 0.04406202, -0.00232859, 0.00232859, 0.012021, 0.00438408, 0.00442728, 0.00363318, 0.00540593, 0.0091924], 167 | [4.443, 0.141, 0.076, 0.02310256, 4.40858239, -0.03710778, 0.03710778, 0.03182, 0.0271528, 0.00465324, 0.03506173, 0.07970664, 0.11278], 168 | [8.79678049, 0.057, 0.208, 0.04194872, 8.784878, -0.01132933, 0.01132933, 0.08061, 0.04695182, 0.039817, 0.0405623, 0.01937402, 0.033234], 169 | [2.58236585, 0.063, 0.128, 0.02112821, 2.5705713, -0.0079298, 0.01979542, 0.062225, 0.0309712, 0.02172778, 0.02949491, 0.02741888, 0.02687], 170 | [0.08992683, 0.0015, 0.006, 0.00030769, 0.09000535, -0.00020308, 0.00020308, 0.0021213, 0.00106065, 0.00116188, 0.0007746, 0.00086603, 0.00053035], 171 | [0.09085366, 0.0175, 0.037, 0.00694872, 0.09607742, -0.00456388, 0.00456388, 0.0098995, 0.00523258, 0.00310646, 0.01357571, 0.0133944, 0.0056569], 172 | [1.34473171, 0.0255, 0.022, 0.00953846, 1.37010789, -0.00558419, 0.00558419, 0.030406, 0.0134351, 0.00877511, 0.00929516, 0.03188089, 0.0265165], 173 | [0.14253659, 0.001, 0.004, 0.00097436, 0.14237889, -0.0002998, 0.0002998, 0.0014142, 0.0011785, 0.00057734, 0.0005164, 0.00069521, 0.00106066], 174 | [0.07617073, 0.001, 0.004, 0.00179487, 0.07597272, -0.00025949, 0.00025949, 0.0014142, 0.0011785, 0.00057734, 0.0005164, 0.00063245, 0.00070711], 175 | [0.28502439, 0.0025, 0.01, 0.00241026, 0.28596915, -0.000355, 0.000355, 0.12869, 0.02333393, 0.05162999, 0.0313152, 0.13233722, 0.0044194], 176 | [5.97658537, 0.0645, 0.106, 0.02925641, 5.95365623, -0.01454886, 0.01454886, 0.045962, 0.02913296, 0.02145587, 0.04602717, 0.06410626, 0.053033], 177 | [4.19787805, 0.0405, 0.072, 0.02764103, 4.21230508, -0.01456906, 0.01468492, 0.030406, 0.02206174, 0.01003006, 0.02031748, 0.03873656, 0.034295], 178 | [0.06904878, 0.0025, 0.005, 0.00117949, 0.06819891, -0.00023428, 0.00033805, 0.0035355, 0.00098994, 0.00154918, 0.001, 0.0007071, 0.00070711], 179 | [2.07410488e+01, 1.10000000e-02, 4.40000000e-02, 1.24102564e-02, 2.07288498e+01, -5.11402880e-02, 5.11402880e-02, 1.55560000e-02, 1.55560000e-02, 0.00000000e+00, 5.68037557e-03, 3.17543685e-03, 7.77820000e-03], 180 | [0.15141463, 0.0025, 0.008, 0.00161538, 0.15286961, -0.00066236, 0.00066236, 0.0049497, 0.0021213, 0.00180276, 0.00235584, 0.01268589, 0.0021213], 181 | [1.07970732, 0.0275, 0.046, 0.00725641, 1.0819483, -0.0025949, 0.00261392, 0.026163, 0.00754248, 0.00945165, 0.01400506, 0.00566908, 0.011137], 182 | [1.45278049e+00, 2.50000000e-02, 3.40000000e-02, 8.23076923e-03, 1.46401853e+00, -5.22375992e-03, 7.56803574e-03, 8.48530000e-03, 6.71755000e-03, 1.39641061e-03, 4.14024959e-03, 1.47976972e-02, 2.03295000e-02], 183 | [1.18829268e-01, 1.00000000e-03, 4.00000000e-03, 1.17948718e-03, 1.18657803e-01, -3.33958979e-04, 3.55599268e-04, 1.41420000e-03, 1.41420000e-03, 2.60312573e-11, 6.32455532e-04, 5.32284214e-04, 7.07110000e-04], 184 | [0.09217073, 0.0085, 0.007, 0.00258974, 0.07952256, -0.00104703, 0.00138337, 0.006364, 0.00466692, 0.00203719, 0.00509166, 0.01307342, 0.021213], 185 | [0.06936585, 0.0095, 0.015, 0.00394872, 0.06837444, -0.00205373, 0.00205373, 0.0084853, 0.00296984, 0.0030984, 0.00234521, 0.00419839, 0.0017678], 186 | [5.05807317, 0.049, 0.082, 0.02402564, 5.06327737, -0.01120311, 0.01120311, 0.031113, 0.0239, 0.01338272, 0.01117139, 0.04351642, 0.020506], 187 | [0.26421951, 0.04, 0.068, 0.00902564, 0.2587529, -0.01040894, 0.01040894, 0.025456, 0.01060666, 0.00890233, 0.01111643, 0.04563416, 0.011314], 188 | [3.59336585, 0.0575, 0.054, 0.02094872, 3.58195886, -0.01804095, 0.01838506, 0.043134, 0.0336584, 0.01240579, 0.01683523, 0.04717173, 0.038184], 189 | [1.29187805, 0.026, 0.016, 0.00689744, 1.27916244, -0.00322078, 0.00490015, 0.025456, 0.01032378, 0.00861112, 0.01863263, 0.0636921, 0.038537], 190 | [6.28670732, 0.1245, 0.127, 0.03102564, 6.35501978, -0.01747513, 0.02813757, 0.084146, 0.04690465, 0.0254467, 0.06541464, 0.18275149, 0.15008], 191 | [10.64578049, 0.079, 0.284, 0.04564103, 10.64447668, -0.01946271, 0.01947497, 0.10889, 0.04186, 0.05739752, 0.06891299, 0.05417812, 0.050205], 192 | [3.32470732, 0.092, 0.046, 0.01687179, 3.32977984, -0.02794509, 0.02794509, 0.072125, 0.0288498, 0.02428699, 0.06277798, 0.10343739, 0.061518], 193 | [0.07358537, 0.001, 0.004, 0.00153846, 0.0735262, -0.00027514, 0.00027514, 0.0014142, 0.0009428, 0.00073029, 0.00075277, 0.00053228, 0.00070711]]) 194 | 195 | return {'dual_coef': dual_coef, 196 | 'support_vec': support_vec, 197 | 'intercept': intercept, 198 | 'gamma': gamma} 199 | 200 | 201 | def multiclass_classifier(): 202 | gamma = 0.1 203 | 204 | # dual coef = y_i*alpha_i 205 | dual_coef = np.array([[1.00000000e+02, 0.00000000e+00, 0.00000000e+00, 1.00000000e+02, 2.19164051e-01, 206 | 1.00000000e+02, 1.00000000e+02, 0.00000000e+00, 0.00000000e+00, 1.00000000e+02, 207 | 2.73972798e+00, 1.00000000e+02, 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 208 | 1.00000000e+02, 0.00000000e+00, 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 209 | 1.00000000e+02, 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 5.78184818e+01, 210 | 1.00000000e+02, 1.00000000e+02, 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 211 | 1.00000000e+02, 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 212 | 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 4.43824790e+01, 213 | 0.00000000e+00, 0.00000000e+00, 8.90021137e+01, 1.00000000e+02, 3.38829336e+01, 214 | 1.00000000e+02, 7.35308055e+01, 5.00832282e+01, 1.00000000e+02, 1.00000000e+02, 215 | 1.00000000e+02, 9.04295253e+01, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 216 | 1.00000000e+02, 1.00000000e+02, 7.37255035e+01, 1.00000000e+02, 0.00000000e+00, 217 | 1.00000000e+02, -1.00000000e+02, -4.59726588e+01, -9.10060871e+01, -0.00000000e+00, 218 | -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, 219 | -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, -0.00000000e+00, 220 | -1.00000000e+02, -0.00000000e+00, -0.00000000e+00, -1.00000000e+02, -0.00000000e+00, 221 | -0.00000000e+00, -1.00000000e+02, -0.00000000e+00, -1.00000000e+02, -1.00000000e+02, 222 | -1.00000000e+02, -1.00000000e+02, -2.32473120e-01, -1.00000000e+02, -0.00000000e+00, 223 | -0.00000000e+00, -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, 224 | -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -1.00000000e+02, -0.00000000e+00, 225 | -2.01478019e-01, -1.00000000e+02, -5.32795432e+01, -0.00000000e+00, -0.00000000e+00, 226 | -1.00000000e+02, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, 227 | -1.00000000e+02, -2.05233000e+01, -0.00000000e+00, -9.58435547e-02, -0.00000000e+00, 228 | -0.00000000e+00, -0.00000000e+00, -1.00000000e+02, -0.00000000e+00, -1.00000000e+02, 229 | -1.00000000e+02, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, 230 | -1.00000000e+02, -0.00000000e+00, -1.14900102e+01, -7.73085905e+01, -1.00000000e+02, 231 | -0.00000000e+00, -1.00000000e+02, -0.00000000e+00, -1.00000000e+02, -0.00000000e+00, 232 | -0.00000000e+00, -8.64770605e+01, -1.00000000e+02, -1.18090663e-01, -1.00000000e+02, 233 | -1.00000000e+02, -0.00000000e+00, -0.00000000e+00, -1.00000000e+02, -0.00000000e+00, 234 | -0.00000000e+00, -6.27523608e+01, -0.00000000e+00, -4.38003436e+01, -0.00000000e+00, 235 | -0.00000000e+00, -5.36807440e-02, -0.00000000e+00, -0.00000000e+00, -1.00000000e+02, 236 | -0.00000000e+00, -1.51862509e-01, -2.23505792e+01, -0.00000000e+00, -1.71549400e+00, 237 | -0.00000000e+00, -0.00000000e+00, -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, 238 | -1.00000000e+02, -0.00000000e+00, -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, 239 | -6.48908553e+01, -5.45079781e+01, -0.00000000e+00, -1.00000000e+02, -1.00000000e+02, 240 | -1.00000000e+02, -4.15526000e+01, -1.00000000e+02, -0.00000000e+00, -0.00000000e+00, 241 | -3.97322757e+01, -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, -1.00000000e+02, 242 | -1.00000000e+02, -8.51452564e+01, -1.00000000e+02, -0.00000000e+00, -0.00000000e+00, 243 | -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -1.00000000e+02, -1.00000000e+02, 244 | -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, -1.00000000e+02, -1.00000000e+02, 245 | -1.00000000e+02, -1.36707150e+01, -2.28944671e+00, -1.00000000e+02, -1.00000000e+02, 246 | -0.00000000e+00, -1.00000000e+02, -0.00000000e+00, -1.00000000e+02, -9.70237576e+01, 247 | -0.00000000e+00, -1.00000000e+02, -8.98901380e+00, -1.00000000e+02, -0.00000000e+00, 248 | -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, -0.00000000e+00, -1.00000000e+02, 249 | -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -2.31872364e+00, -0.00000000e+00, 250 | -1.00000000e+02, -1.00000000e+02, -6.81207558e+01, -0.00000000e+00, -1.00000000e+02, 251 | -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, -0.00000000e+00, -1.00000000e+02, 252 | -1.25804913e+01, -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, -1.00000000e+02, 253 | -0.00000000e+00, -0.00000000e+00, -5.79636185e+01, -0.00000000e+00, -3.60349193e+01, 254 | -1.00000000e+02, -1.00000000e+02], 255 | [1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 0.00000000e+00, 256 | 1.00000000e+02, 0.00000000e+00, 1.22133880e+01, 1.00000000e+02, 1.00000000e+02, 257 | 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 258 | 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 0.00000000e+00, 1.00000000e+02, 259 | 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 5.45699567e+01, 0.00000000e+00, 260 | 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 261 | 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 262 | 1.00000000e+02, 1.00000000e+02, 0.00000000e+00, 1.00000000e+02, 0.00000000e+00, 263 | 1.00000000e+02, 1.00000000e+02, 5.30198194e+01, 1.00000000e+02, 0.00000000e+00, 264 | 8.10028022e+01, 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 8.57299348e+01, 265 | 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 266 | 1.00000000e+02, 0.00000000e+00, 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 267 | 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 268 | 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 269 | 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 6.98226850e+00, 1.00000000e+02, 270 | 1.00000000e+02, 2.28942244e+00, 1.00000000e+02, 0.00000000e+00, 3.10951756e+00, 271 | 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 0.00000000e+00, 2.43965458e+01, 272 | 5.54247795e+01, 4.89715327e+01, 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 273 | 1.00000000e+02, 0.00000000e+00, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 274 | 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 8.77648862e-01, 275 | 1.41352297e+00, 1.00000000e+02, 0.00000000e+00, 1.00000000e+02, 5.87399500e+01, 276 | 1.00000000e+02, 7.89673831e+01, 7.17216921e-01, 7.08622898e+01, 1.00000000e+02, 277 | 1.00000000e+02, 0.00000000e+00, 1.00000000e+02, 0.00000000e+00, 7.08652210e+01, 278 | 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 2.28740165e+00, 1.00000000e+02, 279 | 1.00000000e+02, 1.00000000e+02, 6.26644343e+01, 1.51915932e+01, 9.33156003e+01, 280 | 1.00000000e+02, 5.73480226e-01, 0.00000000e+00, 0.00000000e+00, 1.00000000e+02, 281 | 6.51947143e+01, 0.00000000e+00, 1.00000000e+02, 3.61854680e+01, 1.50700439e+00, 282 | 3.93114839e+01, 1.00000000e+02, 1.00000000e+02, 0.00000000e+00, 0.00000000e+00, 283 | 1.00000000e+02, 1.62942145e+01, 1.00000000e+02, 1.00000000e+02, 3.65697187e+01, 284 | 3.32328741e+01, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 1.00000000e+02, 285 | 1.00000000e+02, 0.00000000e+00, 3.84017861e-02, 3.27497129e+00, 1.00000000e+02, 286 | 1.00000000e+02, 0.00000000e+00, 1.00000000e+02, -1.00000000e+02, -1.00000000e+02, 287 | -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, -7.87287696e+01, 288 | -1.00000000e+02, -2.17133274e+01, -1.00000000e+02, -0.00000000e+00, -1.00000000e+02, 289 | -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, -1.00000000e+02, 290 | -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, 291 | -1.00000000e+02, -4.03561653e+01, -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, 292 | -1.00000000e+02, -0.00000000e+00, -0.00000000e+00, -8.73885349e+01, -1.00000000e+02, 293 | -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, 294 | -0.00000000e+00, -0.00000000e+00, -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, 295 | -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, 296 | -1.00000000e+02, -0.00000000e+00, -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, 297 | -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, -1.00000000e+02, 298 | -0.00000000e+00, -1.00000000e+02, -1.00000000e+02, -7.69821289e+01, -0.00000000e+00, 299 | -1.00000000e+02, -8.28241499e+01, -1.00000000e+02, -6.27852100e+00, -8.74723914e+01, 300 | -0.00000000e+00, -0.00000000e+00, -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, 301 | -0.00000000e+00, -0.00000000e+00, -1.00000000e+02, -1.00000000e+02, -0.00000000e+00, 302 | -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, -2.15412985e+01, -0.00000000e+00, 303 | -2.97074994e+01, -9.62658735e+01, -1.00000000e+02, -1.00000000e+02, -1.00000000e+02, 304 | -1.00000000e+02, -0.00000000e+00]]) 305 | 306 | # intercept = rho 307 | intercept = np.array([-0.62674907, 1.31994877, 0.67252991]) 308 | 309 | # support vectors = x_i 310 | support_vec = np.array([[5.49570019e-07, -2.58632551e-07, 3.16229206e-02, 0.00000000e+00, 0.00000000e+00, 7.07110000e-02, 0.00000000e+00, 0.00000000e+00, 5.49570019e-07,-1.79132036e-08], 311 | [0.01061208, -0.00799413, 0.00572262, 0.025, 0.02809756,0.016263, 0.058, 0.00866667, 0.01061208, 0.03799132], 312 | [0.0005069, -0.0005069, 0.0031833, 0.007, 0.00060976,0.0070711, 0.014, 0.00087179, 0.00039282, 0.00024191], 313 | [0.02659884, -0.02236652, 0.01818914, 0.054, 3.49731707,0.062225, 0.063, 0.01923077, 0.02659884, 3.53815367], 314 | [0.1959552, -0.19377234, 0.49935644, 2.567, 0.212,1.2473, 4.086, 0.27730769, 0.1959552, 0.21128449], 315 | [0.01296803, -0.01070662, 0.01579683, 0.055, 2.52643902,0.043134, 0.057, 0.0114359, 0.01296803, 2.54031008], 316 | [0.04634941, -0.03616377, 0.03342396, 0.285, 1.25278049,0.11031, 0.285, 0.05482051, 0.04634941, 1.24439126], 317 | [0.01161685, -0.01161685, 0.01472225, 0.061, 0.00495122,0.036062, 0.131, 0.00758974, 0.00936955, 0.00494698], 318 | [3.36047450e-17, -2.42947453e-17, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 3.36047450e-17,-2.74622599e-18], 319 | [0.05403825, -0.04130143, 0.01255584, 0.27, 3.89758537,0.047376, 0.27, 0.06717949, 0.05403825, 3.87923565], 320 | [0.06322635, -0.0450853, 0.0069893, 0.107, 0.52617073,0.019799, 0.166, 0.01469231, 0.06322635, 0.51547654], 321 | [0.02740927, -0.02740927, 0.01595008, 0.106, 0.93326829,0.043841, 0.106, 0.01169231, 0.01663183, 0.92669874], 322 | [0.02181645, -0.02181645, 0.00031623, 0.045, 0.04685366,0.00070711, 0.045, 0.00605128, 0.01964941, 0.05939633], 323 | [0.03168223, -0.03168223, 0.03369301, 0.13, 4.64253659,0.10182, 0.13, 0.03661538, 0.02589546, 4.63806066], 324 | [0.00648365, -0.00648365, 0.00126494, 0.039, 0.29312195,0.0056569, 0.039, 0.00682051, 0.0043318, 0.28575076], 325 | [0.02260403, -0.02260403, 0.01570345, 0.123, 3.08187805,0.053033, 0.123, 0.03435897, 0.01139526, 3.11862292], 326 | [7.19856842e-05, -7.19856842e-05, 0.00000000e+00, 1.00000000e-03, 2.43902439e-05, 0.00000000e+00, 2.00000000e-03, 1.02564103e-04, 5.59639155e-05, 2.43769719e-05], 327 | [5.77955577e-09, -2.77557303e-09, 2.88676449e-04, 0.00000000e+00, 0.00000000e+00, 7.07110000e-04, 0.00000000e+00, 0.00000000e+00, 5.77955577e-09,-4.05052739e-10], 328 | [0.0168393, -0.0168393, 0.04987211, 0.172, 0.83290244,0.13011, 0.287, 0.02610256, 0.01063438, 0.82408369], 329 | [0.00670974, -0.00670974, 0.00420523, 0.009, 0.92597561,0.012021, 0.012, 0.00369231, 0.00394705, 0.92583814], 330 | [0.04881422, -0.04881422, 0.06039519, 0.128, 0.84173171,0.15274, 0.166, 0.0145641, 0.02705203, 0.83114509], 331 | [5.56411248e-04, -5.56411248e-04, 4.25246049e-03, 1.00000000e-03, 2.43902439e-05, 9.19240000e-03, 1.00000000e-03, 2.56410256e-05, 4.16114259e-04, 2.18000765e-04], 332 | [0.00461828, -0.00346772, 0.00394135, 0.022, 0.88760976,0.011314, 0.022, 0.00489744, 0.00461828, 0.88799505], 333 | [0.02181738, -0.02181738, 0.06135461, 0.472, 9.21263415,0.16688, 0.472, 0.0695641, 0.01361679, 9.19153391], 334 | [0.18064104, -0.18064104, 0.02243327, 0.141, 1.74753659,0.065761, 0.141, 0.02587179, 0.08614869, 1.89288442], 335 | [0.04502684, -0.04502684, 0.03092595, 0.075, 0.66726829,0.070004, 0.075, 0.01507692, 0.02703687, 0.6524218 ], 336 | [0.00350864, -0.00337375, 0.00472601, 0.026, 0.48378049,0.016971, 0.038, 0.00794872, 0.00350864, 0.48333175], 337 | [4.22507597e-120, -2.00921455e-120, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 0.00000000e+000, 4.22507597e-120, 9.65026603e-122], 338 | [0.0511954, -0.0511954, 0.00917865, 0.032, 1.50741463,0.028284, 0.056, 0.00958974, 0.01612377, 1.43087637], 339 | [0.0504243, -0.03682241, 0.03693438, 0.147, 3.4434878,0.086267, 0.147, 0.02051282, 0.0504243, 3.49633275], 340 | [0.00556735, -0.00442938, 0.00870258, 0.033, 0.10897561,0.025456, 0.033, 0.00553846, 0.00556735, 0.12761266], 341 | [2.34438020e-08, -2.34438020e-08, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.15475168e-08,-1.38812548e-09], 342 | [0.01361869, -0.01361869, 0.00208565, 0.05, 0.66663415,0.0049497, 0.05, 0.00510256, 0.0087315, 0.66182973], 343 | [0.00526982, -0.00287197, 0.016589, 0.06, 0.02595122,0.042426, 0.06, 0.00515385, 0.00526982, 0.02530658], 344 | [1.65194036e-02, -1.65194036e-02, 3.87787571e-04, 7.00000000e-02, 3.74146341e+00, 2.33350000e-02, 1.06000000e-01, 2.41025641e-02, 1.58008422e-02, 3.72790310e+00], 345 | [7.19856850e-05, -7.19856850e-05, 2.88676449e-04, 1.00000000e-03, 2.43902439e-05, 7.07110000e-04, 2.00000000e-03, 1.02564103e-04, 5.59639159e-05, 2.44149661e-05], 346 | [4.35202063e-02, -4.35202063e-02, 5.32593935e-03, 3.24000000e-01, 1.14713659e+01, 1.20920000e-01, 3.24000000e-01, 8.83589744e-02, 3.31111507e-02, 1.13977278e+01], 347 | [0.0767267, -0.0767267, 0.07121201, 0.446, 8.87180488,0.24324, 0.446, 0.10620513, 0.0720187, 8.83162683], 348 | [0.02927458, -0.02914746, 0.03271076, 0.138, 1.63631707,0.074953, 0.138, 0.02410256, 0.02927458, 1.65473267], 349 | [0.02124579, -0.00660226, 0.05683001, 0.218, 0.16541463,0.13718, 0.241, 0.04171795, 0.02124579, 0.07039812], 350 | [2.71490067e-40, -2.71490067e-40, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.26462710e-40, 6.01460518e-42], 351 | [0.0147575, -0.0147575, 0.016589, 0.06, 0.03368293,0.042426, 0.06, 0.00917949, 0.01001548, 0.03172037], 352 | [0.05563514, -0.05003055, 0.0377493, 0.474, 3.34209756,0.10819, 0.474, 0.04441026, 0.05563514, 3.34310614], 353 | [0.01066405, -0.01066405, 0.00912966, 0.03, 0.52358537,0.026163, 0.042, 0.00769231, 0.00753237, 0.52319376], 354 | [0.02506229, -0.01686662, 0.06327203, 0.407, 0.10931707,0.1492, 0.407, 0.04461538, 0.02506229, 0.13188551], 355 | [0.05540528, -0.05540528, 0.05916798, 0.36, 5.93456098,0.18526, 0.36, 0.14474359, 0.03879351, 5.91696978], 356 | [0.05114493, -0.04906722, 0.03169166, 0.444, 1.59946341,0.089803, 0.444, 0.051, 0.05114493, 1.39984371], 357 | [1.87455177e-04, -8.82323678e-05, 3.60629601e-02, 0.00000000e+00, 0.00000000e+00, 7.63680000e-02, 0.00000000e+00, 0.00000000e+00, 1.87455177e-04,-1.21670239e-05], 358 | [0.00573919, -0.00573919, 0.00418135, 0.04, 0.0444878,0.013435, 0.04, 0.00984615, 0.00463094, 0.03577326], 359 | [0.02921642, -0.02921642, 0.06455675, 0.145, 1.28114634,0.15486, 0.145, 0.0314359, 0.00907076, 1.30595106], 360 | [0.08101569, -0.05496349, 0.03591274, 0.557, 5.79265854,0.1294, 0.557, 0.10274359, 0.08101569, 5.7521422 ], 361 | [5.37317466e-07, -2.56175141e-07, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 5.37317466e-07, 1.03127202e-08], 362 | [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 363 | [7.79437718e-04, -7.79437718e-04, 1.24131975e-02, 0.00000000e+00, 0.00000000e+00, 3.04060000e-02, 0.00000000e+00, 0.00000000e+00, 3.70210952e-04, 3.27917545e-05], 364 | [7.19856850e-05, -7.19856850e-05, 2.88676449e-04, 1.00000000e-03, 2.43902439e-05, 7.07110000e-04, 2.00000000e-03, 1.02564103e-04, 4.31188798e-05, 2.60691650e-05], 365 | [0.00866364, -0.00866364, 0.01214903, 0.03, 0.46446341,0.033941, 0.048, 0.00933333, 0.00584264, 0.46299034], 366 | [0.03683296, -0.03683296, 0.07256353, 0.2, 0.89,0.18385, 0.353, 0.0225641, 0.02517257, 0.88537216], 367 | [0.03602508, -0.03342342, 0.05528397, 0.172, 0.12058537,0.14991, 0.173, 0.05969231, 0.03602508, 0.10686173], 368 | [0.02253416, -0.02253416, 0.01985341, 0.112, 5.89978049,0.084146, 0.12, 0.04453846, 0.01958278, 5.88525247], 369 | [0.00622806, -0.00622806, 0.00926554, 0.015, 0.01317073,0.026163, 0.036, 0.00538462, 0.00320484, 0.00829287], 370 | [0.01379371, -0.01379371, 0.00563317, 0.02, 1.16509756,0.020506, 0.043, 0.01051282, 0.0134218, 1.16338281], 371 | [0.01159407, -0.01159407, 0.01052999, 0.058, 1.19278049,0.028991, 0.058, 0.00697436, 0.0092909, 1.19462633], 372 | [0.01666124, -0.01508531, 0.01591668, 0.15, 4.25739024,0.057276, 0.15, 0.02835897, 0.01666124, 4.23504838], 373 | [0.02791508, -0.02791508, 0.00861704, 0.059, 2.72943902,0.031113, 0.059, 0.01371795, 0.02720056, 2.66137841], 374 | [0.02677122, -0.02677122, 0.00984899, 0.043, 4.52929268,0.051619, 0.074, 0.02512821, 0.02513023, 4.52779804], 375 | [0.00820856, -0.00820856, 0.04182701, 0.229, 0.85280488,0.12374, 0.229, 0.02958974, 0.00626605, 0.8738938 ], 376 | [0.00660789, -0.00533542, 0.00713786, 0.049, 0.06365854,0.027577, 0.049, 0.01835897, 0.00660789, 0.05446593], 377 | [0.00553774, -0.00553774, 0.00491419, 0.026, 3.13085366,0.014849, 0.026, 0.00651282, 0.0033944, 3.12413464], 378 | [7.01018256e-03, -7.01018256e-03, 2.29380976e-02, 1.26000000e-01, 6.56448780e+00, 4.45480000e-02, 1.26000000e-01, 1.09743590e-02, 5.16783812e-03, 6.55718858e+00], 379 | [0.01903315, -0.01903315, 0.02305625, 0.102, 4.03021951,0.073539, 0.127, 0.04748718, 0.01826975, 4.03932544], 380 | [0.010121, -0.00916936, 0.01151868, 0.072, 0.54807317,0.037477, 0.072, 0.02423077, 0.010121, 0.56664269], 381 | [0.02477958, -0.02477958, 0.00811683, 0.072, 2.91585366,0.033941, 0.106, 0.01771795, 0.02394629, 2.93431172], 382 | [0.01211938, -0.01211938, 0.01493102, 0.059, 1.22153659,0.038891, 0.059, 0.0164359, 0.00614063, 1.21761274], 383 | [2.29049895e-02, -2.29049895e-02, 6.47077661e-03, 3.14000000e-01, 1.10041220e+01, 1.23740000e-01, 3.27000000e-01, 1.18076923e-01, 2.12905216e-02, 1.09333661e+01], 384 | [0.01060994, -0.01060994, 0.01007483, 0.034, 3.8605122,0.024042, 0.034, 0.01323077, 0.00897269, 3.85004794], 385 | [0.00627491, -0.00627491, 0.00093988, 0.022, 0.77860976,0.0056569, 0.022, 0.00546154, 0.0034974, 0.77367652], 386 | [0.05803024, -0.0551299, 0.10802924, 0.289,15.55358537, 0.20435, 0.289, 0.05861538, 0.05803024, 15.56158018], 387 | [0.01871651, -0.01186601, 0.0663762, 0.171,11.80826829, 0.13011, 0.171, 0.02697436, 0.01871651, 11.8298579 ], 388 | [0.05996643, -0.05996643, 0.01671762, 0.244, 0.87841463,0.042426, 0.244, 0.02264103, 0.03965289, 0.87488872], 389 | [4.98711743e-02, -4.98711743e-02, 3.65041596e-03, 5.28000000e-01, 1.48976098e+01, 1.90920000e-01, 5.28000000e-01, 1.90358974e-01, 3.84779140e-02, 1.48525928e+01], 390 | [0.01136134, -0.01136134, 0.00951859, 0.069, 3.72480488,0.043841, 0.132, 0.02179487, 0.00932468, 3.66845001], 391 | [0.03194417, -0.03194417, 0.00795281, 0.026, 1.34785366,0.028284, 0.028, 0.00864103, 0.03178111, 1.33144448], 392 | [2.64572119e-02, -2.21160394e-02, 7.74479696e-04, 7.50000000e-02, 4.26239024e+00, 2.82840000e-02, 7.50000000e-02, 2.74358974e-02, 2.64572119e-02, 4.25156996e+00], 393 | [0.02750577, -0.0258611, 0.04753049, 0.27, 9.51297561,0.092631, 0.27, 0.06833333, 0.02750577, 9.52726146], 394 | [0.00866709, -0.00541625, 0.06576809, 0.186, 0.70678049,0.15415, 0.186, 0.01346154, 0.00866709, 0.70474759], 395 | [0.03066446, -0.02713743, 0.02467478, 0.232, 4.49546341,0.097581, 0.35, 0.08861538, 0.03066446, 4.52324303], 396 | [0.03264028, -0.03264028, 0.06438005, 0.102, 0.34746341,0.15415, 0.2, 0.01420513, 0.02531656, 0.31306559], 397 | [0.10027745, -0.10027745, 0.24027297, 2.921,19.25053659, 0.87257, 2.921, 0.42974359, 0.095849, 19.15442972], 398 | [0.00700114, -0.00699188, 0.00745196, 0.051, 0.07097561,0.028991, 0.056, 0.01948718, 0.00700114, 0.07004534], 399 | [0.02156914, -0.02156914, 0.00709096, 0.037, 2.22063415,0.028284, 0.055, 0.01587179, 0.01496926, 2.2271266 ], 400 | [0.04052342, -0.04052342, 0.01554335, 0.088, 4.43229268,0.060104, 0.088, 0.02589744, 0.02803208, 4.44932817], 401 | [0.03391535, -0.03391535, 0.03559771, 0.18, 0.57178049,0.13576, 0.236, 0.08284615, 0.0298453, 0.61786751], 402 | [0.01311557, -0.01311557, 0.01651455, 0.096, 5.56714634,0.034648, 0.098, 0.02623077, 0.01097477, 5.57445898], 403 | [0.02984218, -0.02984218, 0.04015245, 0.156, 0.49970732,0.11384, 0.162, 0.05010256, 0.02111739, 0.50149962], 404 | [0.00525823, -0.00525823, 0.0044271, 0.017, 1.22795122,0.014849, 0.024, 0.00615385, 0.00431849, 1.2262395 ], 405 | [0.01034227, -0.0064927, 0.00905154, 0.054, 3.7145122,0.022627, 0.059, 0.01389744, 0.01034227, 3.71109431], 406 | [0.01480054, -0.01480054, 0.01288003, 0.1, 4.24504878,0.04879, 0.1, 0.03451282, 0.01429233, 4.26818139], 407 | [0.02487982, -0.02487982, 0.04157097, 0.238, 9.47917073,0.084146, 0.238, 0.06812821, 0.02178416, 9.4506215 ], 408 | [0.0519567, -0.0519567, 0.03125581, 0.244, 3.01041463,0.10394, 0.244, 0.04551282, 0.03842769, 3.00134531], 409 | [0.11461199, -0.11461199, 0.18484777, 1.671,15.49843902, 0.63498, 1.671, 0.38930769, 0.10481226, 15.48006191], 410 | [0.07299834, -0.06491022, 0.18753433, 0.99,21.14187805, 0.35002, 0.99, 0.19264103, 0.07299834, 21.11450374], 411 | [0.00637064, -0.00336012, 0.05694093, 0.131, 1.2014878,0.13647, 0.175, 0.01325641, 0.00637064, 1.18082784], 412 | [3.20491472e-02, -3.20491472e-02, 5.58137707e-03, 3.42000000e-01, 1.17296585e+01, 1.27280000e-01, 3.52000000e-01, 8.53589744e-02, 2.53251481e-02, 1.17137294e+01], 413 | [0.02781479, -0.02778159, 0.02039015, 0.06, 4.47456098,0.060811, 0.06, 0.02194872, 0.02781479, 4.48594928], 414 | [2.46837687e-02, -2.46837687e-02, 5.41311894e-03, 5.08000000e-01, 1.48384390e+01, 1.92330000e-01, 5.44000000e-01, 1.59897436e-01, 2.11520468e-02, 1.48894277e+01], 415 | [0.00868918, -0.00474268, 0.05575972, 0.069, 0.05356098,0.13576, 0.069, 0.00579487, 0.00868918, 0.02191644], 416 | [0.04526781, -0.04408048, 0.07762039, 0.253,13.55292683, 0.16405, 0.461, 0.10697436, 0.04526781, 13.52730947], 417 | [0.05879119, -0.05879119, 0.13295615, 0.455,18.92917073, 0.30759, 0.83, 0.13789744, 0.04592195, 18.93763555], 418 | [0.02189384, -0.01216995, 0.05066665, 0.246, 9.98273171,0.098995, 0.28, 0.06220513, 0.02189384, 9.99516767], 419 | [0.02539376, -0.02539376, 0.01551926, 0.07, 4.18487805,0.048083, 0.07, 0.01479487, 0.01839075, 4.18516621], 420 | [0.03555225, -0.02731574, 0.02814509, 0.204, 3.88414634,0.099702, 0.235, 0.08258974, 0.03555225, 3.93872613], 421 | [0.0582598, -0.04036336, 0.04616096, 0.319,11.37339024, 0.11455, 0.337, 0.06123077, 0.0582598, 11.34920676], 422 | [0.01981077, -0.01981077, 0.03330417, 0.106, 8.0285122,0.062933, 0.188, 0.03092308, 0.01455206, 8.03116754], 423 | [0.05959746, -0.04430587, 0, 0.99,21.09304878, 0.35002, 0.99, 0.43153846, 0.05959746, 21.13322117], 424 | [3.21965997e-02, -3.21965997e-02, 4.40061045e-03, 2.82000000e-01, 1.03585610e+01, 1.06070000e-01, 2.82000000e-01, 1.04769231e-01, 3.08413155e-02, 1.03278009e+01], 425 | [1.61063213e-02, -1.61063213e-02, 5.67556300e-02, 3.14000000e-01, 1.12777805e+01, 1.14550000e-01, 3.14000000e-01, 4.11025641e-02, 1.10897848e-02, 1.12605687e+01], 426 | [0.02189384, -0.01179437, 0.05216424, 0.151,10.04721951, 0.098995, 0.151, 0.04297436, 0.02189384, 10.08818858], 427 | [0.00238657, -0.00238657, 0.0034182, 0.014, 0.77714634,0.011314, 0.016, 0.00351282, 0.00232057, 0.77743005], 428 | [0.06433761, -0.06083287, 0.14957506, 0.946,20.62917073, 0.33446, 0.946, 0.37597436, 0.06433761, 20.61320173], 429 | [1.39575245e-04, -6.63125529e-05, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.39575245e-04, 8.37811140e-07], 430 | [2.78771985e-10, -2.78771985e-10, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 2.70507545e-10, 2.56354866e-11], 431 | [1.17302985e-02, -7.71146815e-03, 2.53259440e-02, 1.64000000e-01, 7.73348780e+00, 6.50540000e-02, 1.74000000e-01, 4.20000000e-02, 1.17302985e-02, 7.74824436e+00], 432 | [0.01495479, -0.01495479, 0.05647272, 0.306,11.12082927, 0.11455, 0.306, 0.03379487, 0.01350048, 11.13703625], 433 | [0.06224454, -0.06224454, 0.10018563, 0.528,14.96365854, 0.19799, 0.528, 0.08512821, 0.04174687, 14.9855656 ], 434 | [1.50784174e-02, -1.50784174e-02, 5.75469303e-02, 3.14000000e-01, 1.12202439e+01, 1.11020000e-01, 3.14000000e-01, 8.52051282e-02, 8.68754010e-03, 1.12353267e+01], 435 | [0.00507143, -0.00507143, 0.00379475, 0.017, 0.02482927,0.0098995, 0.023, 0.00358974, 0.00308139, 0.023151 ], 436 | [0.02900558, -0.02900558, 0.09336675, 0.528,14.83170732, 0.18668, 0.528, 0.08441026, 0.0267984, 14.78693574], 437 | [0.01743156, -0.01634197, 0.06142791, 0.354,11.68380488, 0.13011, 0.355, 0.09658974, 0.01743156, 11.6854788 ], 438 | [0.06157537, -0.04061912, 0.09114882, 0.434, 8.39795122,0.31396, 0.878, 0.17061538, 0.06157537, 8.3171658 ], 439 | [0.01157586, -0.00787553, 0.00781547, 0.103, 3.28846341,0.034648, 0.103, 0.02582051, 0.01157586, 3.29875571], 440 | [7.33132616e-03, -6.81397261e-03, 3.00898494e-02, 1.88000000e-01, 7.75687805e+00, 6.64680000e-02, 1.88000000e-01, 4.87179487e-02, 7.33132616e-03, 7.75743580e+00], 441 | [0.0325806, -0.02489858, 0.06056313, 0.347, 1.96856098,0.17678, 0.347, 0.09082051, 0.0325806, 1.93503196], 442 | [0.02057271, -0.02057271, 0.03637653, 0.168, 7.91641463,0.070004, 0.168, 0.03194872, 0.0175232, 7.87590288], 443 | [0.02488661, -0.02177646, 0.01564241, 0.205, 0.40578049,0.087681, 0.205, 0.05994872, 0.02488661, 0.41578688], 444 | [0.07366755, -0.07366755, 0.13654436, 0.99,20.81831707, 0.35002, 0.99, 0.11958974, 0.04818856, 20.83153348], 445 | [0.02708256, -0.02708256, 0.08111137, 0.224,13.16290244, 0.15839, 0.42, 0.09841026, 0.02505871, 13.18839945], 446 | [0.00958152, -0.00958152, 0.02217553, 0.12, 6.09365854,0.045255, 0.12, 0.02551282, 0.00690841, 6.10985475], 447 | [0.02958837, -0.01655602, 0.0402901, 0.206, 4.10741463,0.1393, 0.276, 0.05653846, 0.02958837, 4.02902721], 448 | [0.07592541, -0.07592541, 0.19758112, 1.738,16.99126829, 0.50275, 1.738, 0.51812821, 0.06254254, 16.89231623], 449 | [0.03172265, -0.0218731, 0.0643494, 0.611, 6.06187805,0.21567, 0.611, 0.11628205, 0.03172265, 6.03346158], 450 | [0.00524933, -0.00425262, 0.00617516, 0.022, 0.88902439,0.015556, 0.022, 0.00415385, 0.00524933, 0.88950276], 451 | [2.94223481e-02, -1.75922046e-02, 1.93346063e-03, 3.24000000e-01, 1.13452439e+01, 1.14550000e-01, 3.24000000e-01, 1.01076923e-01, 2.94223481e-02, 1.14096319e+01], 452 | [0.04812244, -0.03838389, 0.06461018, 0.461,13.97795122, 0.1789, 0.461, 0.13925641, 0.04812244, 13.95949649], 453 | [0.03621849, -0.03433152, 0.03043904, 0.165, 1.58258537,0.08556, 0.184, 0.03061538, 0.03621849, 1.53392771], 454 | [0.02373659, -0.02277035, 0.05867974, 0.434,13.38863415, 0.16405, 0.434, 0.07953846, 0.02373659, 13.34239253], 455 | [0.02111005, -0.02111005, 0.07987431, 0.224,13.04126829, 0.15839, 0.224, 0.04605128, 0.02028668, 13.05917311], 456 | [0.03671861, -0.03671861, 0.01580834, 0.064, 3.6292439,0.060811, 0.084, 0.03615385, 0.03589838, 3.59330461], 457 | [0.03538591, -0.03538591, 0.05734932, 0.175,11.07687805, 0.11738, 0.175, 0.04389744, 0.02528186, 11.06401646], 458 | [0.01139907, -0.01139907, 0.0404773, 0.256, 9.43263415,0.09051, 0.256, 0.04312821, 0.01139243, 9.44721736], 459 | [2.21139985e-02, -2.21139985e-02, 7.74479696e-04, 1.13000000e-01, 4.05441463e+00, 2.68700000e-02, 1.13000000e-01, 3.17948718e-02, 1.83677482e-02, 4.02531967e+00], 460 | [0.03887186, -0.02634328, 0.0509491, 0.189,11.66063415, 0.13364, 0.189, 0.07851282, 0.03887186, 11.63597796], 461 | [4.18064577e-02, -4.18064577e-02, 7.74589241e-03, 3.82000000e-01, 1.81040000e+01, 1.41420000e-02, 7.64000000e-01, 7.98974359e-02, 2.37616498e-02, 1.81240583e+01], 462 | [0.0610875, -0.05055225, 0.17753526, 1.452,16.057, 0.49144, 1.452, 0.30223077, 0.0610875, 15.96984146], 463 | [0.04722622, -0.02572493, 0.06540382, 0.494,14.07109756, 0.17466, 0.494, 0.16689744, 0.04722622, 14.02996765], 464 | [0.00210856, -0.00193237, 0.01084809, 0.048, 0.28902439,0.028284, 0.053, 0.00574359, 0.00210856, 0.28286954], 465 | [0.01251112, -0.01153534, 0.03329564, 0.094, 7.72314634,0.066468, 0.178, 0.04507692, 0.01251112, 7.71739425], 466 | [0.07891577, -0.05286848, 0.10496868, 0.385,17.73741463, 0.2588, 0.751, 0.13687179, 0.07891577, 17.7611277 ], 467 | [2.57691246e-03, -1.65339484e-03, 1.37839166e-03, 1.00000000e-02, 1.53980488e+00, 9.19240000e-03, 1.00000000e-02, 4.35897436e-03, 2.57691246e-03, 1.52310545e+00], 468 | [1.65446780e-02, -1.65446780e-02, 5.91533656e-02, 1.30000000e-02, 1.14603171e+01, 1.14550000e-01, 1.30000000e-02, 1.33333333e-03, 1.26380521e-02, 1.14674074e+01], 469 | [4.11400031e-02, -3.79141831e-02, 6.84964646e-03, 5.12000000e-01, 1.48432683e+01, 1.97990000e-01, 5.28000000e-01, 1.59692308e-01, 4.11400031e-02, 1.47993898e+01], 470 | [0.02155868, -0.01887666, 0.07962665, 0.238,13.24478049, 0.15344, 0.238, 0.04825641, 0.02155868, 13.22587027], 471 | [0.00599973, -0.00599973, 0.00697133, 0.034, 0.63663415,0.019799, 0.034, 0.00594872, 0.00480282, 0.61555439], 472 | [0.04266586, -0.04266586, 0.0106888, 0.126, 3.67914634,0.041719, 0.132, 0.02676923, 0.03469959, 3.67052968], 473 | [0.00042144, -0.00042144, 0.00109543, 0.004, 0.11331707,0.0021213, 0.006, 0.0014359, 0.00027545, 0.11329803], 474 | [0.02663118, -0.02639755, 0.01336405, 0.07, 4.36412195,0.054447, 0.079, 0.025, 0.02663118, 4.359373 ], 475 | [0.00730426, -0.00730426, 0.00435895, 0.072, 0.61409756,0.012728, 0.096, 0.00930769, 0.00603133, 0.60116405], 476 | [0.01877031, -0.00838677, 0.02480503, 0.068, 2.56031707,0.077075, 0.068, 0.02294872, 0.01877031, 2.4790144 ], 477 | [0.01901328, -0.01785507, 0.0129973, 0.155, 2.71221951,0.047376, 0.155, 0.03697436, 0.01901328, 2.68282596], 478 | [0.00190969, -0.00179795, 0.00162791, 0.01, 0.06846341,0.0056569, 0.01, 0.00307692, 0.00190969, 0.06774886], 479 | [0.02343739, -0.02343739, 0.06043373, 0.17,10.8854878, 0.11172, 0.17, 0.07266667, 0.01923799, 10.87016693], 480 | [1.59897956e-02, -1.15451745e-02, 1.01170444e-02, 3.20000000e-01, 1.16454634e+01, 1.37890000e-01, 3.47000000e-01, 8.94615385e-02, 1.59897956e-02, 1.15869935e+01], 481 | [0.01774385, -0.01578744, 0.03231943, 0.085, 2.70382927,0.12233, 0.133, 0.03161538, 0.01774385, 2.68325119], 482 | [0.02835417, -0.02835417, 0.0188188, 0.111, 3.12563415,0.054447, 0.111, 0.02897436, 0.01213407, 3.17337638], 483 | [2.35933619e-04, -1.84870042e-04, 2.60312573e-11, 4.00000000e-03, 8.50975610e-02, 1.41420000e-03, 4.00000000e-03, 8.20512821e-04, 2.35933619e-04, 8.50491997e-02], 484 | [0.00684639, -0.0053288, 0.01423898, 0.121, 0.82373171,0.041012, 0.121, 0.01853846, 0.00684639, 0.82149219], 485 | [0.00656202, -0.00298516, 0.00525832, 0.04, 0.32917073,0.013435, 0.04, 0.00435897, 0.00656202, 0.32469572], 486 | [0.03061193, -0.01830022, 0.02278918, 0.083, 3.852,0.07566, 0.083, 0.02366667, 0.03061193, 3.82389036], 487 | [0.03450864, -0.03206468, 0.07235446, 0.354, 4.39680488,0.20506, 0.354, 0.09258974, 0.03450864, 4.35973108], 488 | [1.33757941e-03, -1.33757941e-03, 1.81681257e-02, 1.60000000e-02, 6.81234146e+00, 4.73760000e-02, 1.60000000e-02, 5.74358974e-03, 7.88662159e-04, 6.81237822e+00], 489 | [0.05408959, -0.05408959, 0.07739115, 0.232,13.12702439, 0.16263, 0.46, 0.12551282, 0.02715891, 13.09196866], 490 | [0.01414166, -0.01414166, 0, 0.214, 9.05543902,0, 0.214, 0.01707692, 0.01284695, 9.04209973], 491 | [0.00262455, -0.00262455, 0.00092195, 0.021, 0.13329268,0.0035355, 0.021, 0.00338462, 0.00176235, 0.13419267], 492 | [0.00766504, -0.00766504, 0.02270081, 0.065, 0.15463415,0.067882, 0.065, 0.01617949, 0.00760269, 0.15422134], 493 | [0.01601326, -0.01601326, 0.00953142, 0.044, 4.34658537,0.029698, 0.082, 0.02784615, 0.0152717, 4.34824852], 494 | [1.36058722e-04, -1.36058722e-04, 9.39849132e-04, 2.00000000e-03, 1.47902439e-01, 2.12130000e-03, 4.00000000e-03, 3.84615385e-04, 1.20873351e-04, 1.48269290e-01], 495 | [0.01692731, -0.01692731, 0.00934515, 0.17, 2.76797561,0.04879, 0.17, 0.03212821, 0.00804809, 2.84223399], 496 | [0.00021792, -0.00016886, 0.00077459, 0.002, 0.16504878,0.0014142, 0.004, 0.00020513, 0.00021792, 0.16495962], 497 | [0.0025624, -0.0017206, 0.00242901, 0.013, 0.22082927,0.0084853, 0.015, 0.00476923, 0.0025624, 0.21293887], 498 | [0.00825234, -0.00825234, 0.00915876, 0.068, 4.30339024,0.028284, 0.073, 0.02058974, 0.00762434, 4.32659455], 499 | [0.03004306, -0.02691667, 0.04972124, 0.152,10.16087805, 0.10324, 0.158, 0.07189744, 0.03004306, 10.1129346 ], 500 | [0.02155975, -0.02155975, 0.04474389, 0.129, 8.92531707,0.084146, 0.236, 0.07838462, 0.02002646, 8.88551601], 501 | [1.14268607e-02, -9.73097720e-03, 7.75027419e-04, 6.40000000e-02, 3.79953659e+00, 2.40420000e-02, 6.40000000e-02, 1.87692308e-02, 1.14268607e-02, 3.80236594e+00], 502 | [0.02707888, -0.02707888, 0.01880556, 0.076, 4.34395122,0.053033, 0.076, 0.02764103, 0.02459437, 4.34208839], 503 | [0.01727205, -0.01727205, 0.01056655, 0.066, 1.30939024,0.03182, 0.066, 0.0165641, 0.01633014, 1.2967273 ], 504 | [0.00877545, -0.00877545, 0.01277828, 0.028, 0.0914878,0.032527, 0.037, 0.00364103, 0.00682708, 0.08295897], 505 | [0.00040731, -0.00036169, 0.00082663, 0.006, 0.13621951,0.0021213, 0.006, 0.00174359, 0.00040731, 0.13689296], 506 | [0.00145672, -0.00145672, 0.00184393, 0.006, 0.05692683,0.0056569, 0.008, 0.00189744, 0.00103611, 0.05532006], 507 | [0.00539013, -0.00539013, 0.01083511, 0.025, 0.60539024,0.02687, 0.052, 0.00476923, 0.00387435, 0.60237517], 508 | [0.00576748, -0.00576748, 0.01658765, 0.082, 2.201,0.045962, 0.082, 0.01251282, 0.00554347, 2.2021353 ], 509 | [0.00038011, -0.00035004, 0.0011832, 0.006, 0.07460976,0.0028284, 0.006, 0.00097436, 0.00038011, 0.07430141], 510 | [0.00232859, -0.00232859, 0.00442728, 0.011, 0.04782927,0.012021, 0.012, 0.00353846, 0.00200706, 0.04406202], 511 | [0.03710778, -0.03710778, 0.00465324, 0.076, 4.443,0.03182, 0.086, 0.02310256, 0.03407041, 4.40858239], 512 | [1.13293306e-02, -1.13293306e-02, 3.98170020e-02, 2.08000000e-01, 8.79678049e+00, 8.06100000e-02, 2.08000000e-01, 4.19487179e-02, 8.02841512e-03, 8.78487800e+00], 513 | [0.00241135, -0.00186458, 0.0089488, 0.059, 1.06817073,0.02192, 0.059, 0.00302564, 0.00241135, 1.06816635], 514 | [0.01979542, -0.0079298, 0.02172778, 0.128, 2.58236585,0.062225, 0.128, 0.02112821, 0.01979542, 2.5705713 ], 515 | [0.02311331, -0.02311331, 0.01137534, 0.062, 4.10326829,0.048083, 0.076, 0.02253846, 0.02280474, 4.08634796], 516 | [0.00020308, -0.00020308, 0.00116188, 0.006, 0.08992683,0.0021213, 0.006, 0.00030769, 0.0001032, 0.09000535], 517 | [0.02430024, -0.01198259, 0.05125066, 0.284,10.61465854, 0.10041, 0.284, 0.04492308, 0.02430024, 10.68180335], 518 | [0.00456388, -0.00456388, 0.00310646, 0.037, 0.09085366,0.0098995, 0.037, 0.00694872, 0.00379939, 0.09607742], 519 | [0.0258999, -0.02057017, 0.03178882, 0.123, 5.97997561,0.086974, 0.123, 0.02774359, 0.0258999, 5.91008859], 520 | [0.02995729, -0.02995729, 0.02248653, 0.065, 3.89078049,0.067175, 0.072, 0.02235897, 0.02419343, 3.84855841], 521 | [0.03168889, -0.01073342, 0.02388286, 0.091, 4.27865854,0.08061, 0.091, 0.02253846, 0.03168889, 4.27815091], 522 | [0.00558419, -0.00558419, 0.00877511, 0.022, 1.34473171,0.030406, 0.026, 0.00953846, 0.00182773, 1.37010789], 523 | [0.0002998, -0.0002998, 0.00057734, 0.004, 0.14253659,0.0014142, 0.004, 0.00097436, 0.00028829, 0.14237889], 524 | [0.00219221, -0.00094528, 0.01264908, 0.057, 0.64868293,0.027577, 0.057, 0.00864103, 0.00219221, 0.63404688], 525 | [0.00025949, -0.00025949, 0.00057734, 0.004, 0.07617073,0.0014142, 0.004, 0.00179487, 0.00015403, 0.07597272], 526 | [3.54995192e-04, -3.54995192e-04, 5.16299928e-02, 1.00000000e-02, 2.85024390e-01, 1.28690000e-01, 1.00000000e-02, 2.41025641e-03, 2.75611646e-04, 2.85969148e-01], 527 | [0.01468492, -0.01456906, 0.01003006, 0.072, 4.19787805,0.030406, 0.072, 0.02764103, 0.01468492, 4.21230508], 528 | [0.02925993, -0.02564169, 0.0243944, 0.069, 3.981,0.081317, 0.069, 0.01961538, 0.02925993, 3.88386281], 529 | [0.00033805, -0.00023428, 0.00154918, 0.005, 0.06904878,0.0035355, 0.005, 0.00117949, 0.00033805, 0.06819891], 530 | [0.02167887, -0.01716068, 0.03000235, 0.167, 7.68443902,0.068589, 0.176, 0.05779487, 0.02167887, 7.62067289], 531 | [0.00860053, -0.00687122, 0.00984125, 0.028, 1.9362439,0.032527, 0.028, 0.01158974, 0.00860053, 1.85928806], 532 | [1.62829923e-02, -1.27782612e-02, 5.03488484e-03, 2.93000000e-01, 1.10292927e+01, 9.19240000e-03, 2.93000000e-01, 4.98717949e-02, 1.62829923e-02, 1.10624738e+01], 533 | [5.11402880e-02, -5.11402880e-02, 0.00000000e+00, 4.40000000e-02, 2.07410488e+01, 1.55560000e-02, 4.40000000e-02, 1.24102564e-02, 2.17468552e-02, 2.07288498e+01], 534 | [0.02048881, -0.01983837, 0.01785776, 0.068, 3.90980488,0.045255, 0.068, 0.02412821, 0.02048881, 3.92262256], 535 | [0.00066236, -0.00066236, 0.00180276, 0.008, 0.15141463,0.0049497, 0.008, 0.00161538, 0.00045688, 0.15286961], 536 | [0.00060837, -0.00053966, 0.00036514, 0.006, 0.15390244,0.0021213, 0.006, 0.00184615, 0.00060837, 0.1543969 ], 537 | [0.00261392, -0.0025949, 0.00945165, 0.046, 1.07970732,0.026163, 0.046, 0.00725641, 0.00261392, 1.0819483 ], 538 | [2.21525541e-02, -2.09299114e-02, 4.55533610e-03, 1.75000000e-01, 7.59114634e+00, 6.50540000e-02, 1.75000000e-01, 4.90256410e-02, 2.21525541e-02, 7.58764892e+00], 539 | [7.56803574e-03, -5.22375992e-03, 1.39641061e-03, 3.40000000e-02, 1.45278049e+00, 8.48530000e-03, 3.90000000e-02, 8.23076923e-03, 7.56803574e-03, 1.46401853e+00], 540 | [0.00042417, -0.00042417, 0.00109543, 0.003, 0.16736585,0.0021213, 0.006, 0.00123077, 0.00031221, 0.16745186], 541 | [3.55599268e-04, -3.33958979e-04, 2.60312573e-11, 4.00000000e-03, 1.18829268e-01, 1.41420000e-03, 4.00000000e-03, 1.17948718e-03, 3.55599268e-04, 1.18657803e-01], 542 | [8.49163246e-03, -7.36645573e-03, 1.26472005e-03, 4.00000000e-02, 4.19334146e+00, 2.82840000e-02, 8.00000000e-02, 2.64615385e-02, 8.49163246e-03, 4.21478989e+00], 543 | [0.04132153, -0.04132153, 0.08233984, 0.491,13.82968293, 0.1789, 0.491, 0.09758974, 0.02614823, 13.93101321], 544 | [0.00138337, -0.00104703, 0.00203719, 0.007, 0.09217073,0.006364, 0.007, 0.00258974, 0.00138337, 0.07952256], 545 | [0.02013966, -0.02013966, 0.06794402, 0.35,11.46958537, 0.12728, 0.35, 0.09010256, 0.01988961, 11.45768721], 546 | [0.00205373, -0.00205373, 0.0030984, 0.015, 0.06936585,0.0084853, 0.017, 0.00394872, 0.00152146, 0.06837444], 547 | [0.01040894, -0.01040894, 0.00890233, 0.068, 0.26421951,0.025456, 0.068, 0.00902564, 0.00546137, 0.2587529 ], 548 | [8.19684883e-03, -8.19684883e-03, 2.09202670e-02, 6.30000000e-02, 6.51109756e+00, 4.45480000e-02, 6.30000000e-02, 1.66153846e-02, 5.80672162e-03, 6.50965345e+00], 549 | [0.00023369, -0.00023369, 0.00246646, 0.007, 0.16326829,0.006364, 0.007, 0.00079487, 0.00019522, 0.1627248 ], 550 | [0.00490015, -0.00322078, 0.00861112, 0.016, 1.29187805,0.025456, 0.016, 0.00689744, 0.00490015, 1.27916244], 551 | [0.0134886, -0.00766548, 0.0189313, 0.109, 6.21553659,0.041012, 0.109, 0.03533333, 0.0134886, 6.22416714], 552 | [0.02813757, -0.01747513, 0.0254467, 0.127, 6.28670732,0.084146, 0.127, 0.03102564, 0.02813757, 6.35501978], 553 | [0.02044022, -0.02044022, 0.03488198, 0.176, 8.10602439,0.065761, 0.176, 0.04466667, 0.01777938, 8.12759058], 554 | [0.01947497, -0.01946271, 0.05739752, 0.284,10.64578049, 0.10889, 0.296, 0.04564103, 0.01947497, 10.64447668], 555 | [0.01922614, -0.01922614, 0.02849813, 0.097, 4.29178049,0.08061, 0.097, 0.02720513, 0.01556252, 4.30987745], 556 | [0.00027514, -0.00027514, 0.00073029, 0.004, 0.07358537,0.0014142, 0.004, 0.00153846, 0.0002546, 0.0735262]]) 557 | 558 | num_support_vec = [61, 97, 89] 559 | 560 | return {'dual_coef': dual_coef, 561 | 'support_vec': support_vec, 562 | 'intercept': intercept, 563 | 'gamma': gamma, 564 | 'num_support_vec': num_support_vec} 565 | 566 | 567 | if __name__ == '__main__': 568 | 569 | binary_test_data = np.array([ 570 | [0., 0., 0., 0., 0., 0., 0., 0.14212846, 0.02368808, 0.0580237, 0.06960633, 0.04921911, 0.], 571 | [0.21073171, 0.794, 0.922, 0.14076923, 0.20974742, -0.32312654, 0.32312654, 0.88741901, 0.17300546, 0.3544437, 0.39891235, 0.5271785, 0.0076014], 572 | [0.04058537, 0.009, 0.008, 0.00225641, 0.03362015, -0.00420592, 0.00420592, 0.00565685, 0.00235702, 0.00193218, 0.00581951, 0.00861878, 0.00671751], 573 | [0.07887805, 0.0035, 0.007, 0.00179487, 0.07598638, -0.00096018, 0.00113304, 0.00494975, 0.00235702, 0.00177012, 0.00098742, 0.00128452, 0.00335876], 574 | [0.10126829, 0.0015, 0.004, 0.00174359, 0.09954269, -0.00034342, 0.00034342, 0.00212132, 0.00153206, 0.00028868, 0.00075829, 0.00064872, 0.00212132] 575 | ]) 576 | binary_predictions = predict_binary_classifier(binary_test_data) 577 | 578 | import pickle 579 | f2 = open('/Users/sarataylor/Dev/eda-explorer-public/SVMBinary.p', 'rb') 580 | s2 = f2.read() 581 | clf = pickle.loads(s2) 582 | 583 | assert(len([1 for i in range(5) if binary_predictions[i] != clf.predict(binary_test_data)[i]]) == 0) 584 | 585 | # Test multiclass 586 | test_data = np.array([[3.11141105e-02, -3.11136868e-02, 2.42079822e-02, 7.49220000e-02, 1.15335178e+01, 8.37681119e-02, 7.49220000e-02, 1.03606795e-02, 3.11141105e-02, 1.15205823e+01], 587 | [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], 588 | [0.10255266, -0.10255266, 0.03827904, 0.328471, 6.61645195, 0.26352986, 0.406695, 0.02494941, 0.05696297, 7.64941098], 589 | [0.1095642, -0.1095642, 0.08589464, 0.113983, 11.49373772, 0.26352986, 0.113983, 0.01375942, 0.03753318, 11.51816541], 590 | [0.15404637, -0.08878016, 0.1020834, 0.768917, 11.40673696, 0.28606288, 0.768917, 0.08697605, 0.15404637, 11.46339086]]) 591 | 592 | multi_predictions = predict_multiclass_classifier(test_data) 593 | 594 | f2 = open('/Users/sarataylor/Dev/eda-explorer-public/SVMMulticlass.p', 'rb') 595 | s2 = f2.read() 596 | clf = pickle.loads(s2) 597 | 598 | assert (len([1 for i in range(5) if multi_predictions[i] != clf.predict(test_data)[i]]) == 0) 599 | 600 | 601 | 602 | -------------------------------------------------------------------------------- /EDA-Artifact-Detection-Script.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | import matplotlib 4 | import matplotlib.pyplot as plt 5 | import pywt 6 | import os 7 | import datetime 8 | 9 | from load_files import getInputLoadFile, get_user_input 10 | from ArtifactClassifiers import predict_binary_classifier, predict_multiclass_classifier 11 | 12 | matplotlib.rcParams['ps.useafm'] = True 13 | matplotlib.rcParams['pdf.use14corefonts'] = True 14 | matplotlib.rcParams['text.usetex'] = True 15 | 16 | 17 | def getWaveletData(data): 18 | ''' 19 | This function computes the wavelet coefficients 20 | 21 | INPUT: 22 | data: DataFrame, index is a list of timestamps at 8Hz, columns include EDA, filtered_eda 23 | 24 | OUTPUT: 25 | wave1Second: DateFrame, index is a list of timestamps at 1Hz, columns include OneSecond_feature1, OneSecond_feature2, OneSecond_feature3 26 | waveHalfSecond: DateFrame, index is a list of timestamps at 2Hz, columns include HalfSecond_feature1, HalfSecond_feature2 27 | ''' 28 | startTime = data.index[0] 29 | 30 | # Create wavelet dataframes 31 | oneSecond = pd.date_range(start=startTime, periods=len(data), freq='1s') 32 | halfSecond = pd.date_range(start=startTime, periods=len(data), freq='500L') 33 | 34 | # Compute wavelets 35 | cA_n, cD_3, cD_2, cD_1 = pywt.wavedec(data['EDA'], 'Haar', level=3) #3 = 1Hz, 2 = 2Hz, 1=4Hz 36 | 37 | # Wavelet 1 second window 38 | N = int(len(data)/8) 39 | coeff1 = np.max(abs(np.reshape(cD_1[0:4*N],(N,4))), axis=1) 40 | coeff2 = np.max(abs(np.reshape(cD_2[0:2*N],(N,2))), axis=1) 41 | coeff3 = abs(cD_3[0:N]) 42 | wave1Second = pd.DataFrame({'OneSecond_feature1':coeff1,'OneSecond_feature2':coeff2,'OneSecond_feature3':coeff3}) 43 | wave1Second.index = oneSecond[:len(wave1Second)] 44 | 45 | # Wavelet Half second window 46 | N = int(np.floor((len(data)/8.0)*2)) 47 | coeff1 = np.max(abs(np.reshape(cD_1[0:2*N],(N,2))),axis=1) 48 | coeff2 = abs(cD_2[0:N]) 49 | waveHalfSecond = pd.DataFrame({'HalfSecond_feature1':coeff1,'HalfSecond_feature2':coeff2}) 50 | waveHalfSecond.index = halfSecond[:len(waveHalfSecond)] 51 | 52 | return wave1Second,waveHalfSecond 53 | 54 | 55 | def getDerivatives(eda): 56 | deriv = (eda[1:-1] + eda[2:])/ 2. - (eda[1:-1] + eda[:-2])/ 2. 57 | second_deriv = eda[2:] - 2*eda[1:-1] + eda[:-2] 58 | return deriv,second_deriv 59 | 60 | 61 | def getDerivStats(eda): 62 | deriv, second_deriv = getDerivatives(eda) 63 | maxd = max(deriv) 64 | mind = min(deriv) 65 | maxabsd = max(abs(deriv)) 66 | avgabsd = np.mean(abs(deriv)) 67 | max2d = max(second_deriv) 68 | min2d = min(second_deriv) 69 | maxabs2d = max(abs(second_deriv)) 70 | avgabs2d = np.mean(abs(second_deriv)) 71 | 72 | return maxd,mind,maxabsd,avgabsd,max2d,min2d,maxabs2d,avgabs2d 73 | 74 | 75 | def getStats(data): 76 | eda = data['EDA'].values 77 | filt = data['filtered_eda'].values 78 | maxd,mind,maxabsd,avgabsd,max2d,min2d,maxabs2d,avgabs2d = getDerivStats(eda) 79 | maxd_f,mind_f,maxabsd_f,avgabsd_f,max2d_f,min2d_f,maxabs2d_f,avgabs2d_f = getDerivStats(filt) 80 | amp = np.mean(eda) 81 | amp_f = np.mean(filt) 82 | return amp, maxd,mind,maxabsd,avgabsd,max2d,min2d,maxabs2d,avgabs2d,amp_f,maxd_f,mind_f,maxabsd_f,avgabsd_f,max2d_f,min2d_f,maxabs2d_f,avgabs2d_f 83 | 84 | 85 | def computeWaveletFeatures(waveDF): 86 | maxList = waveDF.max().tolist() 87 | meanList = waveDF.mean().tolist() 88 | stdList = waveDF.std().tolist() 89 | medianList = waveDF.median().tolist() 90 | aboveZeroList = (waveDF[waveDF>0]).count().tolist() 91 | 92 | return maxList,meanList,stdList,medianList,aboveZeroList 93 | 94 | 95 | def getWavelet(wave1Second,waveHalfSecond): 96 | max_1,mean_1,std_1,median_1,aboveZero_1 = computeWaveletFeatures(wave1Second) 97 | max_H,mean_H,std_H,median_H,aboveZero_H = computeWaveletFeatures(waveHalfSecond) 98 | return max_1,mean_1,std_1,median_1,aboveZero_1,max_H,mean_H,std_H,median_H,aboveZero_H 99 | 100 | 101 | def getFeatures(data,w1,wH): 102 | # Get DerivStats 103 | amp,maxd,mind,maxabsd,avgabsd,max2d,min2d,maxabs2d,avgabs2d,amp_f,maxd_f,mind_f,maxabsd_f,avgabsd_f,max2d_f,min2d_f,maxabs2d_f,avgabs2d_f = getStats(data) 104 | statFeat = np.hstack([amp,maxd,mind,maxabsd,avgabsd,max2d,min2d,maxabs2d,avgabs2d,amp_f,maxd_f,mind_f,maxabsd_f,avgabsd_f,max2d_f,min2d_f,maxabs2d_f,avgabs2d_f]) 105 | 106 | # Get Wavelet Features 107 | max_1,mean_1,std_1,median_1,aboveZero_1,max_H,mean_H,std_H,median_H,aboveZero_H = getWavelet(w1,wH) 108 | waveletFeat = np.hstack([max_1,mean_1,std_1,median_1,aboveZero_1,max_H,mean_H,std_H,median_H,aboveZero_H]) 109 | 110 | all_feat = np.hstack([statFeat,waveletFeat]) 111 | 112 | if np.Inf in all_feat: 113 | print("Inf") 114 | 115 | if np.NaN in all_feat: 116 | print("NaN") 117 | 118 | return list(all_feat) 119 | 120 | 121 | def createFeatureDF(data): 122 | ''' 123 | INPUTS: 124 | filepath: string, path to input file 125 | OUTPUTS: 126 | features: DataFrame, index is a list of timestamps for each 5 seconds, contains all the features 127 | data: DataFrame, index is a list of timestamps at 8Hz, columns include AccelZ, AccelY, AccelX, Temp, EDA, filtered_eda 128 | ''' 129 | # Load data from q sensor 130 | wave1sec,waveHalf = getWaveletData(data) 131 | 132 | # Create 5 second timestamp list 133 | timestampList = data.index.tolist()[0::40] 134 | 135 | # feature names for DataFrame columns 136 | allFeatureNames = ['raw_amp','raw_maxd','raw_mind','raw_maxabsd','raw_avgabsd','raw_max2d','raw_min2d','raw_maxabs2d','raw_avgabs2d','filt_amp','filt_maxd','filt_mind', 137 | 'filt_maxabsd','filt_avgabsd','filt_max2d','filt_min2d','filt_maxabs2d','filt_avgabs2d','max_1s_1','max_1s_2','max_1s_3','mean_1s_1','mean_1s_2','mean_1s_3', 138 | 'std_1s_1','std_1s_2','std_1s_3','median_1s_1','median_1s_2','median_1s_3','aboveZero_1s_1','aboveZero_1s_2','aboveZero_1s_3','max_Hs_1','max_Hs_2','mean_Hs_1', 139 | 'mean_Hs_2','std_Hs_1','std_Hs_2','median_Hs_1','median_Hs_2','aboveZero_Hs_1','aboveZero_Hs_2'] 140 | 141 | # Initialize Feature Data Frame 142 | features = pd.DataFrame(np.zeros((len(timestampList),len(allFeatureNames))),columns=allFeatureNames,index=timestampList) 143 | 144 | # Compute features for each 5 second epoch 145 | for i in range(len(features)-1): 146 | start = features.index[i] 147 | end = features.index[i+1] 148 | this_data = data[start:end] 149 | this_w1 = wave1sec[start:end] 150 | this_w2 = waveHalf[start:end] 151 | features.iloc[i] = getFeatures(this_data,this_w1,this_w2) 152 | return features 153 | 154 | 155 | def classifyEpochs(features,featureNames,classifierName): 156 | ''' 157 | This function takes the full features DataFrame and classifies each 5 second epoch into artifact, questionable, or clean 158 | 159 | INPUTS: 160 | features: DataFrame, index is a list of timestamps for each 5 seconds, contains all the features 161 | featureNames: list of Strings, subset of feature names needed for classification 162 | classifierName: string, type of SVM (binary or multiclass) 163 | 164 | OUTPUTS: 165 | labels: Series, index is a list of timestamps for each 5 seconds, values of -1, 0, or 1 for artifact, questionable, or clean 166 | ''' 167 | # Only get relevant features 168 | features = features[featureNames] 169 | X = features[featureNames].values 170 | 171 | # Classify each 5 second epoch and put into DataFrame 172 | if 'Binary' in classifierName: 173 | featuresLabels = predict_binary_classifier(X) 174 | elif 'Multi' in classifierName: 175 | featuresLabels = predict_multiclass_classifier(X) 176 | 177 | return featuresLabels 178 | 179 | 180 | def getSVMFeatures(key): 181 | ''' 182 | This returns the list of relevant features 183 | 184 | INPUT: 185 | key: string, either "Binary" or "Multiclass" 186 | 187 | OUTPUT: 188 | featureList: list of Strings, subset of feature names needed for classification 189 | ''' 190 | if key == "Binary": 191 | return ['raw_amp','raw_maxabsd','raw_max2d','raw_avgabs2d','filt_amp','filt_min2d','filt_maxabs2d','max_1s_1', 192 | 'mean_1s_1','std_1s_1','std_1s_2','std_1s_3','median_1s_3'] 193 | elif key == "Multiclass": 194 | return ['filt_maxabs2d','filt_min2d','std_1s_1','raw_max2d','raw_amp','max_1s_1','raw_maxabs2d','raw_avgabs2d', 195 | 'filt_max2d','filt_amp'] 196 | else: 197 | print('Error!! Invalid key, choose "Binary" or "Multiclass"\n\n') 198 | return 199 | 200 | 201 | def classify(classifierList): 202 | ''' 203 | This function wraps other functions in order to load, classify, and return the label for each 5 second epoch of Q sensor data. 204 | 205 | INPUT: 206 | classifierList: list of strings, either "Binary" or "Multiclass" 207 | OUTPUT: 208 | featureLabels: Series, index is a list of timestamps for each 5 seconds, values of -1, 0, or 1 for artifact, questionable, or clean 209 | data: DataFrame, only output if fullFeatureOutput=1, index is a list of timestamps at 8Hz, columns include AccelZ, AccelY, AccelX, Temp, EDA, filtered_eda 210 | ''' 211 | # Constants 212 | oneHour = 8*60*60 # 8(samp/s)*60(s/min)*60(min/hour) = samp/hour 213 | fiveSec = 8*5 214 | 215 | # Load data 216 | data, _ = getInputLoadFile() 217 | 218 | # Get pickle List and featureNames list 219 | featureNameList = [[]]*len(classifierList) 220 | for i in range(len(classifierList)): 221 | featureNames = getSVMFeatures(classifierList[i]) 222 | featureNameList[i]=featureNames 223 | 224 | # Get the number of data points, hours, and labels 225 | rows = len(data) 226 | num_labels = int(np.ceil(float(rows)/fiveSec)) 227 | hours = int(np.ceil(float(rows)/oneHour)) 228 | 229 | # Initialize labels array 230 | labels = -1*np.ones((num_labels,len(classifierList))) 231 | 232 | for h in range(hours): 233 | # Get a data slice that is at most 1 hour long 234 | start = h*oneHour 235 | end = min((h+1)*oneHour,rows) 236 | cur_data = data[start:end] 237 | 238 | features = createFeatureDF(cur_data) 239 | 240 | for i in range(len(classifierList)): 241 | # Get correct feature names for classifier 242 | classifierName = classifierList[i] 243 | featureNames = featureNameList[i] 244 | 245 | # Label each 5 second epoch 246 | temp_labels = classifyEpochs(features, featureNames, classifierName) 247 | labels[(h*12*60):(h*12*60+temp_labels.shape[0]),i] = temp_labels 248 | 249 | return labels,data 250 | 251 | 252 | def plotData(data,labels,classifierList,filteredPlot=0,secondsPlot=0): 253 | ''' 254 | This function plots the Q sensor EDA data with shading for artifact (red) and questionable data (grey). 255 | Note that questionable data will only appear if you choose a multiclass classifier 256 | 257 | INPUT: 258 | data: DataFrame, indexed by timestamps at 8Hz, columns include EDA and filtered_eda 259 | labels: array, each row is a 5 second period and each column is a different classifier 260 | filteredPlot: binary, 1 for including filtered EDA in plot, 0 for only raw EDA on the plot, defaults to 0 261 | secondsPlot: binary, 1 for x-axis in seconds, 0 for x-axis in minutes, defaults to 0 262 | 263 | OUTPUT: 264 | [plot] the resulting plot has N subplots (where N is the length of classifierList) that have linked x and y axes 265 | and have shading for artifact (red) and questionable data (grey) 266 | 267 | ''' 268 | 269 | # Initialize x axis 270 | if secondsPlot: 271 | scale = 1.0 272 | else: 273 | scale = 60.0 274 | time_m = np.arange(0,len(data))/(8.0*scale) 275 | 276 | # Initialize Figure 277 | plt.figure(figsize=(10,5)) 278 | 279 | # For each classifier, label each epoch and plot 280 | for k in range(np.shape(labels)[1]): 281 | key = classifierList[k] 282 | 283 | # Initialize Subplots 284 | if k==0: 285 | ax = plt.subplot(len(classifierList),1,k+1) 286 | else: 287 | ax = plt.subplot(len(classifierList),1,k+1,sharex=ax,sharey=ax) 288 | 289 | # Plot EDA 290 | ax.plot(time_m,data['EDA']) 291 | 292 | # For each epoch, shade if necessary 293 | for i in range(0,len(labels)-1): 294 | if labels[i,k]==-1: 295 | # artifact 296 | start = i*40/(8.0*scale) 297 | end = start+5.0/scale 298 | ax.axvspan(start, end, facecolor='red', alpha=0.7, edgecolor ='none') 299 | elif labels[i,k]==0: 300 | # Questionable 301 | start = i*40/(8.0*scale) 302 | end = start+5.0/scale 303 | ax.axvspan(start, end, facecolor='.5', alpha=0.5,edgecolor ='none') 304 | 305 | # Plot filtered data if requested 306 | if filteredPlot: 307 | ax.plot(time_m-.625/scale,data['filtered_eda'], c='g') 308 | plt.legend(['Raw SC','Filtered SC'],loc=0) 309 | 310 | # Label and Title each subplot 311 | plt.ylabel('$\mu$S') 312 | plt.title(key) 313 | 314 | # Only include x axis label on final subplot 315 | if secondsPlot: 316 | plt.xlabel('Time (s)') 317 | else: 318 | plt.xlabel('Time (min)') 319 | 320 | # Display the plot 321 | plt.subplots_adjust(hspace=.3) 322 | plt.show() 323 | return 324 | 325 | 326 | if __name__ == "__main__": 327 | numClassifiers = int(get_user_input('Would you like 1 classifier (Binary or Multiclass) or both (enter 1 or 2): ')) 328 | 329 | # Create list of classifiers 330 | if numClassifiers==1: 331 | temp_clf = int(get_user_input("Select a classifier:\n1: Binary\n2: Multiclass\n:")) 332 | while temp_clf != 1 and temp_clf !=2: 333 | temp_clf = get_user_input("Something went wrong. Enter the number 1 or 2.\n Select a classifier:\n1: Binary\n2: Multiclass):") 334 | if temp_clf == 1: 335 | print('Binary Classifier selected') 336 | classifierList = ['Binary'] 337 | elif temp_clf == 2: 338 | print('Multiclass Classifier selected') 339 | classifierList = ['Multiclass'] 340 | else: 341 | classifierList = ['Binary', 'Multiclass'] 342 | 343 | # Classify the data 344 | labels, data = classify(classifierList) 345 | 346 | # Plotting the data 347 | plotDataInput = get_user_input('Do you want to plot the labels? (y/n): ') 348 | 349 | if plotDataInput=='y': 350 | # Include filter plot? 351 | filteredPlot = get_user_input('Would you like to include filtered data in your plot? (y/n): ') 352 | if filteredPlot=='y': 353 | filteredPlot=1 354 | else: 355 | filteredPlot=0 356 | 357 | # X axis in seconds? 358 | secondsPlot = get_user_input('Would you like the x-axis to be in seconds or minutes? (sec/min): ') 359 | if secondsPlot=='sec': 360 | secondsPlot=1 361 | else: 362 | secondsPlot=0 363 | 364 | # Plot Data 365 | plotData(data,labels,classifierList,filteredPlot,secondsPlot) 366 | 367 | print("Remember! Red is for epochs with artifact, grey is for epochs that are questionable, and no shading is for clean epochs") 368 | 369 | 370 | # Saving the data 371 | saveDataInput = get_user_input('Do you want to save the labels? (y/n): ') 372 | 373 | if saveDataInput=='y': 374 | outputPath = get_user_input('Output directory: ') 375 | outputLabelFilename= get_user_input('Output filename: ') 376 | 377 | # Save labels 378 | fullOutputPath = os.path.join(outputPath,outputLabelFilename) 379 | if fullOutputPath[-4:] != '.csv': 380 | fullOutputPath = fullOutputPath+'.csv' 381 | 382 | featureLabels = pd.DataFrame(labels, index=pd.date_range(start=data.index[0], periods=len(labels), freq='5s'), 383 | columns=classifierList) 384 | 385 | featureLabels.reset_index(inplace=True) 386 | featureLabels.rename(columns={'index':'StartTime'}, inplace=True) 387 | featureLabels['EndTime'] = featureLabels['StartTime']+datetime.timedelta(seconds=5) 388 | featureLabels.index.name = 'EpochNum' 389 | 390 | cols = ['StartTime', 'EndTime'] 391 | cols.extend(classifierList) 392 | 393 | featureLabels = featureLabels[cols] 394 | featureLabels.rename(columns={'Binary': 'BinaryLabels', 'Multiclass': 'MulticlassLabels'}, 395 | inplace=True) 396 | 397 | featureLabels.to_csv(fullOutputPath) 398 | 399 | print("Labels saved to " + fullOutputPath) 400 | print("Remember! The first column is timestamps and the second column is the labels (-1 for artifact, 0 for questionable, 1 for clean)") 401 | 402 | print('--------------------------------') 403 | print("Please also cite this project:") 404 | print("Taylor, S., Jaques, N., Chen, W., Fedor, S., Sano, A., & Picard, R. Automatic identification of artifacts in electrodermal activity data. In Engineering in Medicine and Biology Conference. 2015") 405 | print('--------------------------------') 406 | 407 | 408 | 409 | 410 | 411 | 412 | -------------------------------------------------------------------------------- /EDA-Peak-Detection-Script.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | import os 4 | import matplotlib.pyplot as plt 5 | import pprint 6 | 7 | from load_files import getInputLoadFile, get_user_input, getOutputPath 8 | 9 | SAMPLE_RATE = 8 10 | 11 | def findPeaks(data, offset, start_WT, end_WT, thres=0, sampleRate=SAMPLE_RATE): 12 | ''' 13 | This function finds the peaks of an EDA signal and returns basic properties. 14 | Also, peak_end is assumed to be no later than the start of the next peak. (Is this okay??) 15 | 16 | ********* INPUTS ********** 17 | data: DataFrame with EDA as one of the columns and indexed by a datetimeIndex 18 | offset: the number of rising samples and falling samples after a peak needed to be counted as a peak 19 | start_WT: maximum number of seconds before the apex of a peak that is the "start" of the peak 20 | end_WT: maximum number of seconds after the apex of a peak that is the "rec.t/2" of the peak, 50% of amp 21 | thres: the minimum uS change required to register as a peak, defaults as 0 (i.e. all peaks count) 22 | sampleRate: number of samples per second, default=8 23 | 24 | ********* OUTPUTS ********** 25 | peaks: list of binary, 1 if apex of SCR 26 | peak_start: list of binary, 1 if start of SCR 27 | peak_start_times: list of strings, if this index is the apex of an SCR, it contains datetime of start of peak 28 | peak_end: list of binary, 1 if rec.t/2 of SCR 29 | peak_end_times: list of strings, if this index is the apex of an SCR, it contains datetime of rec.t/2 30 | amplitude: list of floats, value of EDA at apex - value of EDA at start 31 | max_deriv: list of floats, max derivative within 1 second of apex of SCR 32 | 33 | ''' 34 | EDA_deriv = data['filtered_eda'][1:].values - data['filtered_eda'][:-1].values 35 | peaks = np.zeros(len(EDA_deriv)) 36 | peak_sign = np.sign(EDA_deriv) 37 | for i in range(int(offset), int(len(EDA_deriv) - offset)): 38 | if peak_sign[i] == 1 and peak_sign[i + 1] < 1: 39 | peaks[i] = 1 40 | for j in range(1, int(offset)): 41 | if peak_sign[i - j] < 1 or peak_sign[i + j] > -1: 42 | #if peak_sign[i-j]==-1 or peak_sign[i+j]==1: 43 | peaks[i] = 0 44 | break 45 | 46 | # Finding start of peaks 47 | peak_start = np.zeros(len(EDA_deriv)) 48 | peak_start_times = [''] * len(data) 49 | max_deriv = np.zeros(len(data)) 50 | rise_time = np.zeros(len(data)) 51 | 52 | for i in range(0, len(peaks)): 53 | if peaks[i] == 1: 54 | temp_start = max(0, i - sampleRate) 55 | max_deriv[i] = max(EDA_deriv[temp_start:i]) 56 | start_deriv = .01 * max_deriv[i] 57 | 58 | found = False 59 | find_start = i 60 | # has to peak within start_WT seconds 61 | while found == False and find_start > (i - start_WT * sampleRate): 62 | if EDA_deriv[find_start] < start_deriv: 63 | found = True 64 | peak_start[find_start] = 1 65 | peak_start_times[i] = data.index[find_start] 66 | rise_time[i] = get_seconds_and_microseconds(data.index[i] - pd.to_datetime(peak_start_times[i])) 67 | 68 | find_start = find_start - 1 69 | 70 | # If we didn't find a start 71 | if found == False: 72 | peak_start[i - start_WT * sampleRate] = 1 73 | peak_start_times[i] = data.index[i - start_WT * sampleRate] 74 | rise_time[i] = start_WT 75 | 76 | # Check if amplitude is too small 77 | if thres > 0 and (data['EDA'].iloc[i] - data['EDA'][peak_start_times[i]]) < thres: 78 | peaks[i] = 0 79 | peak_start[i] = 0 80 | peak_start_times[i] = '' 81 | max_deriv[i] = 0 82 | rise_time[i] = 0 83 | 84 | # Finding the end of the peak, amplitude of peak 85 | peak_end = np.zeros(len(data)) 86 | peak_end_times = [''] * len(data) 87 | amplitude = np.zeros(len(data)) 88 | decay_time = np.zeros(len(data)) 89 | half_rise = [''] * len(data) 90 | SCR_width = np.zeros(len(data)) 91 | 92 | for i in range(0, len(peaks)): 93 | if peaks[i] == 1: 94 | peak_amp = data['EDA'].iloc[i] 95 | start_amp = data['EDA'][peak_start_times[i]] 96 | amplitude[i] = peak_amp - start_amp 97 | 98 | half_amp = amplitude[i] * .5 + start_amp 99 | 100 | found = False 101 | find_end = i 102 | # has to decay within end_WT seconds 103 | while found == False and find_end < (i + end_WT * sampleRate) and find_end < len(peaks): 104 | if data['EDA'].iloc[find_end] < half_amp: 105 | found = True 106 | peak_end[find_end] = 1 107 | peak_end_times[i] = data.index[find_end] 108 | decay_time[i] = get_seconds_and_microseconds(pd.to_datetime(peak_end_times[i]) - data.index[i]) 109 | 110 | # Find width 111 | find_rise = i 112 | found_rise = False 113 | while found_rise == False: 114 | if data['EDA'].iloc[find_rise] < half_amp: 115 | found_rise = True 116 | half_rise[i] = data.index[find_rise] 117 | SCR_width[i] = get_seconds_and_microseconds(pd.to_datetime(peak_end_times[i]) - data.index[find_rise]) 118 | find_rise = find_rise - 1 119 | 120 | elif peak_start[find_end] == 1: 121 | found = True 122 | peak_end[find_end] = 1 123 | peak_end_times[i] = data.index[find_end] 124 | find_end = find_end + 1 125 | 126 | # If we didn't find an end 127 | if found == False: 128 | min_index = np.argmin(data['EDA'].iloc[i:(i + end_WT * sampleRate)].tolist()) 129 | peak_end[i + min_index] = 1 130 | peak_end_times[i] = data.index[i + min_index] 131 | 132 | peaks = np.concatenate((peaks, np.array([0]))) 133 | peak_start = np.concatenate((peak_start, np.array([0]))) 134 | max_deriv = max_deriv * sampleRate # now in change in amplitude over change in time form (uS/second) 135 | 136 | return peaks, peak_start, peak_start_times, peak_end, peak_end_times, amplitude, max_deriv, rise_time, decay_time, SCR_width, half_rise 137 | 138 | def get_seconds_and_microseconds(pandas_time): 139 | return pandas_time.seconds + pandas_time.microseconds * 1e-6 140 | 141 | def calcPeakFeatures(data,outfile,offset,thresh,start_WT,end_WT): 142 | returnedPeakData = findPeaks(data, offset*SAMPLE_RATE, start_WT, end_WT, thresh, SAMPLE_RATE) 143 | data['peaks'] = returnedPeakData[0] 144 | data['peak_start'] = returnedPeakData[1] 145 | data['peak_end'] = returnedPeakData[3] 146 | 147 | data['peak_start_times'] = returnedPeakData[2] 148 | data['peak_end_times'] = returnedPeakData[4] 149 | data['half_rise'] = returnedPeakData[10] 150 | # Note: If an SCR doesn't decrease to 50% of amplitude, then the peak_end = min(the next peak's start, 15 seconds after peak) 151 | data['amp'] = returnedPeakData[5] 152 | data['max_deriv'] = returnedPeakData[6] 153 | data['rise_time'] = returnedPeakData[7] 154 | data['decay_time'] = returnedPeakData[8] 155 | data['SCR_width'] = returnedPeakData[9] 156 | 157 | # To keep all filtered data remove this line 158 | featureData = data[data.peaks==1][['EDA','rise_time','max_deriv','amp','decay_time','SCR_width']] 159 | 160 | # Replace 0s with NaN, this is where the 50% of the peak was not found, too close to the next peak 161 | featureData[['SCR_width','decay_time']]=featureData[['SCR_width','decay_time']].replace(0, np.nan) 162 | featureData['AUC']=featureData['amp']*featureData['SCR_width'] 163 | 164 | featureData.to_csv(outfile) 165 | 166 | return data 167 | 168 | # draws a graph of the data with the peaks marked on it 169 | # assumes that 'data' dataframe already contains the 'peaks' column 170 | def plotPeaks(data, x_seconds, sampleRate = SAMPLE_RATE): 171 | if x_seconds: 172 | time_m = np.arange(0,len(data))/float(sampleRate) 173 | else: 174 | time_m = np.arange(0,len(data))/(sampleRate*60.) 175 | 176 | data_min = min(data['EDA']) 177 | data_max = max(data['EDA']) 178 | 179 | #Plot the data with the Peaks marked 180 | plt.figure(1,figsize=(20, 5)) 181 | peak_height = data_max * 1.15 182 | data['peaks_plot'] = data['peaks'] * peak_height 183 | plt.plot(time_m,data['peaks_plot'],'#4DBD33') 184 | #plt.plot(time_m,data['EDA']) 185 | plt.plot(time_m,data['filtered_eda']) 186 | plt.xlim([0,time_m[-1]]) 187 | y_min = min(0, data_min) - (data_max - data_min) * 0.1 188 | plt.ylim([min(y_min, data_min),peak_height]) 189 | plt.title('EDA with Peaks marked') 190 | plt.ylabel('$\mu$S') 191 | if x_seconds: 192 | plt.xlabel('Time (s)') 193 | else: 194 | plt.xlabel('Time (min)') 195 | 196 | plt.show() 197 | 198 | def chooseValueOrDefault(str_input, default): 199 | if str_input == "": 200 | return default 201 | else: 202 | return float(str_input) 203 | 204 | if __name__ == "__main__": 205 | 206 | data, filepath_confirm = getInputLoadFile() 207 | 208 | fullOutputPath = getOutputPath() 209 | 210 | print("") 211 | print("Please choose settings for the peak detection algorithm. For default values press return") 212 | thresh_str = get_user_input('\tMinimum peak amplitude (default = .02):') 213 | thresh = chooseValueOrDefault(thresh_str,.02) 214 | offset_str = get_user_input('\tOffset (default = 1): ') 215 | offset = chooseValueOrDefault(offset_str,1) 216 | start_WT_str = get_user_input('\tMax rise time (s) (default = 4): ') 217 | start_WT = chooseValueOrDefault(start_WT_str,4) 218 | end_WT_str = get_user_input('\tMax decay time (s) (default = 4): ') 219 | end_WT = chooseValueOrDefault(end_WT_str,4) 220 | 221 | settings_dict = {'threshold':thresh, 222 | 'offset':offset, 223 | 'rise time':start_WT, 224 | 'decay time':end_WT} 225 | 226 | print("") 227 | print("Okay, finding peaks in file "+ filepath_confirm + " using the following parameters") 228 | pprint.pprint(settings_dict) 229 | peakData = calcPeakFeatures(data,fullOutputPath,offset,thresh,start_WT,end_WT) 230 | print("Features computed and saved to " + fullOutputPath) 231 | 232 | # Plotting the data 233 | print("") 234 | plot_ans = get_user_input("Do you want to plot the detected peaks? (y/n): ") 235 | if 'y' in plot_ans: 236 | secs_ans = get_user_input("Would you like the x-axis to be in seconds or minutes? (sec/min): ") 237 | if 'sec' in secs_ans: 238 | x_seconds=True 239 | else: 240 | x_seconds=False 241 | plotPeaks(peakData,x_seconds) 242 | else: 243 | print("\tOkay, script will not produce a plot") 244 | 245 | print("") 246 | print('--------------------------------') 247 | print("Please also cite this project:") 248 | print("Taylor, S., Jaques, N., Chen, W., Fedor, S., Sano, A., & Picard, R. Automatic identification of artifacts in electrodermal activity data. In Engineering in Medicine and Biology Conference. 2015") 249 | print('--------------------------------') 250 | 251 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | EDA-Explorer is an open-source project under the MIT License 2 | 3 | Copyright (c) 2016 Sara Taylor and Natasha Jaques 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | eda-explorer 2 | ============ 3 | 4 | Scripts to detect artifacts and in electrodermal activity (EDA) data. Note that these scripts are written for Python 2.7 and Python 3.7 5 | 6 | 7 | Version 1.0 8 | 9 | Please also cite this project: 10 | Taylor, S., Jaques, N., Chen, W., Fedor, S., Sano, A., & Picard, R. Automatic identification of artifacts in electrodermal activity data. In Engineering in Medicine and Biology Conference. 2015. 11 | 12 | 13 | Required python packages can be found in requirements.txt 14 | 15 | To run artifact detection from the command line: 16 | == 17 | python EDA-Artifact-Detection-Script.py 18 | 19 | Currently there are only 2 classifiers to choose from: Binary or Multiclass 20 | 21 | To run peak detection: 22 | == 23 | python EDA-Peak-Detection-Script.py 24 | 25 | Descriptions of the algorithm settings can be found at http://eda-explorer.media.mit.edu/info/ 26 | 27 | To run accelerometer feature extraction: 28 | == 29 | python AccelerometerFeatureExtractionScript.py 30 | 31 | This file works slightly differently than the others in that it gives summary information over periods of time. 32 | 33 | Notes: 34 | === 35 | 36 | 1. Currently, these files are written with the assumption that the sample rate is an integer power of 2. 37 | 38 | 2. Please visit [eda-explorer.media.mit.edu](https://eda-explorer.media.mit.edu) 39 | to use the web-based version 40 | -------------------------------------------------------------------------------- /classify.py: -------------------------------------------------------------------------------- 1 | from sklearn.svm import SVC 2 | import pickle 3 | 4 | 5 | #docs: http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC 6 | class SVM: 7 | def __init__(self, C=1.0,beta=0.0, kernel='linear', poly_degree=3, max_iter=-1, tol=0.001): 8 | #possible kernels: linear, 'poly', 'rbf', 'sigmoid', 'precomputed' or a callable 9 | 10 | #data features 11 | self.n_features = None 12 | self.train_X = [] 13 | self.train_Y = [] 14 | self.val_X = [] 15 | self.val_Y = [] 16 | self.test_X = [] 17 | self.test_Y = [] 18 | 19 | #classifier features 20 | self.C = C 21 | self.beta = beta 22 | self.kernel = kernel 23 | self.poly_degree = poly_degree 24 | self.max_iter = max_iter 25 | self.tolerance = tol 26 | 27 | self.classifier = None 28 | 29 | 30 | #SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, 31 | # gamma=0.0, kernel='rbf', max_iter=-1, probability=False, 32 | # random_state=None, shrinking=True, tol=0.001, verbose=False) 33 | 34 | def setTrainData(self, X, Y): 35 | self.train_X = X 36 | self.train_Y = Y 37 | 38 | self.n_features = self.train_X.shape[1] 39 | 40 | def setTestData(self, X, Y): 41 | self.test_X = X 42 | self.test_Y = Y 43 | 44 | def setC(self, c): 45 | self.C = c 46 | 47 | def setBeta(self, beta): 48 | if beta is None: 49 | self.beta = 0.0 50 | else: 51 | self.beta=beta 52 | 53 | def setKernel(self, kernel, poly_degree=3): 54 | self.kernel = kernel 55 | self.poly_degree = poly_degree 56 | 57 | def setValData(self, X, Y): 58 | self.val_X = X 59 | self.val_Y = Y 60 | 61 | def train(self): 62 | self.classifier = SVC(C=self.C, kernel=self.kernel, gamma=self.beta, degree=self.poly_degree, max_iter=self.max_iter, 63 | tol=self.tolerance) 64 | self.classifier.fit(self.train_X, self.train_Y) 65 | 66 | def predict(self, X): 67 | return self.classifier.predict(X) 68 | 69 | def getScore(self, X, Y): 70 | #returns accuracy 71 | return self.classifier.score(X, Y) 72 | 73 | def getNumSupportVectors(self): 74 | return self.classifier.n_support_ 75 | 76 | def getHingeLoss(self,X,Y): 77 | preds = self.predict(X) 78 | hinge_inner_func = 1.0 - preds*Y 79 | hinge_inner_func = [max(0,x) for x in hinge_inner_func] 80 | return sum(hinge_inner_func) 81 | 82 | def saveClassifierToFile(self, filepath): 83 | s = pickle.dumps(self.classifier) 84 | f = open(filepath, 'wb') 85 | f.write(s) 86 | 87 | def loadClassifierFromFile(self, filepath): 88 | f2 = open(filepath, 'rb') 89 | s2 = f2.read() 90 | self.classifier = pickle.loads(s2) 91 | -------------------------------------------------------------------------------- /load_files.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import scipy.signal as scisig 3 | import os 4 | import numpy as np 5 | 6 | 7 | def get_user_input(prompt): 8 | try: 9 | return raw_input(prompt) 10 | except NameError: 11 | return input(prompt) 12 | 13 | 14 | def getInputLoadFile(): 15 | '''Asks user for type of file and file path. Loads corresponding data. 16 | 17 | OUTPUT: 18 | data: DataFrame, index is a list of timestamps at 8Hz, columns include 19 | AccelZ, AccelY, AccelX, Temp, EDA, filtered_eda 20 | ''' 21 | print("Please enter information about your EDA file... ") 22 | dataType = get_user_input("\tData Type (e4, q, shimmer, or misc): ") 23 | if dataType=='q': 24 | filepath = get_user_input("\tFile path: ") 25 | filepath_confirm = filepath 26 | data = loadData_Qsensor(filepath) 27 | elif dataType=='e4': 28 | filepath = get_user_input("\tPath to E4 directory: ") 29 | filepath_confirm = os.path.join(filepath,"EDA.csv") 30 | data = loadData_E4(filepath) 31 | elif dataType=='shimmer': 32 | filepath = get_user_input("\tFile path: ") 33 | filepath_confirm = filepath 34 | data = loadData_shimmer(filepath) 35 | elif dataType=="misc": 36 | filepath = get_user_input("\tFile path: ") 37 | filepath_confirm = filepath 38 | data = loadData_misc(filepath) 39 | else: 40 | print("Error: not a valid file choice") 41 | 42 | return data, filepath_confirm 43 | 44 | def getOutputPath(): 45 | print("") 46 | print("Where would you like to save the computed output file?") 47 | outfile = get_user_input('\tFile name: ') 48 | outputPath = get_user_input('\tFile directory (./ for this directory): ') 49 | fullOutputPath = os.path.join(outputPath,outfile) 50 | if fullOutputPath[-4:] != '.csv': 51 | fullOutputPath = fullOutputPath+'.csv' 52 | return fullOutputPath 53 | 54 | def loadData_Qsensor(filepath): 55 | ''' 56 | This function loads the Q sensor data, uses a lowpass butterworth filter on the EDA signal 57 | Note: currently assumes sampling rate of 8hz, 16hz, 32hz; if sampling rate is 16hz or 32hz the signal is downsampled 58 | 59 | INPUT: 60 | filepath: string, path to input file 61 | 62 | OUTPUT: 63 | data: DataFrame, index is a list of timestamps at 8Hz, columns include AccelZ, AccelY, AccelX, Temp, EDA, filtered_eda 64 | ''' 65 | # Get header info 66 | try: 67 | header_info = pd.io.parsers.read_csv(filepath, nrows=5) 68 | except IOError: 69 | print("Error!! Couldn't load file, make sure the filepath is correct and you are using a csv from the q sensor software\n\n") 70 | return 71 | 72 | # Get sample rate 73 | sampleRate = int((header_info.iloc[3,0]).split(":")[1].strip()) 74 | 75 | # Get the raw data 76 | data = pd.io.parsers.read_csv(filepath, skiprows=7) 77 | data = data.reset_index() 78 | 79 | # Reset the index to be a time and reset the column headers 80 | data.columns = ['AccelZ','AccelY','AccelX','Battery','Temp','EDA'] 81 | 82 | # Get Start Time 83 | startTime = pd.to_datetime(header_info.iloc[4,0][12:-10]) 84 | 85 | # Make sure data has a sample rate of 8Hz 86 | data = interpolateDataTo8Hz(data,sampleRate,startTime) 87 | 88 | # Remove Battery Column 89 | data = data[['AccelZ','AccelY','AccelX','Temp','EDA']] 90 | 91 | # Get the filtered data using a low-pass butterworth filter (cutoff:1hz, fs:8hz, order:6) 92 | data['filtered_eda'] = butter_lowpass_filter(data['EDA'], 1.0, 8, 6) 93 | 94 | return data 95 | 96 | def _loadSingleFile_E4(filepath,list_of_columns, expected_sample_rate,freq): 97 | # Load data 98 | data = pd.read_csv(filepath) 99 | 100 | # Get the startTime and sample rate 101 | startTime = pd.to_datetime(float(data.columns.values[0]),unit="s") 102 | sampleRate = float(data.iloc[0][0]) 103 | data = data[data.index!=0] 104 | data.index = data.index-1 105 | 106 | # Reset the data frame assuming expected_sample_rate 107 | data.columns = list_of_columns 108 | if sampleRate != expected_sample_rate: 109 | print('ERROR, NOT SAMPLED AT {0}HZ. PROBLEMS WILL OCCUR\n'.format(expected_sample_rate)) 110 | 111 | # Make sure data has a sample rate of 8Hz 112 | data = interpolateDataTo8Hz(data,sampleRate,startTime) 113 | 114 | return data 115 | 116 | 117 | def loadData_E4(filepath): 118 | # Load EDA data 119 | eda_data = _loadSingleFile_E4(os.path.join(filepath,'EDA.csv'),["EDA"],4,"250L") 120 | # Get the filtered data using a low-pass butterworth filter (cutoff:1hz, fs:8hz, order:6) 121 | eda_data['filtered_eda'] = butter_lowpass_filter(eda_data['EDA'], 1.0, 8, 6) 122 | 123 | # Load ACC data 124 | acc_data = _loadSingleFile_E4(os.path.join(filepath,'ACC.csv'),["AccelX","AccelY","AccelZ"],32,"31250U") 125 | # Scale the accelometer to +-2g 126 | acc_data[["AccelX","AccelY","AccelZ"]] = acc_data[["AccelX","AccelY","AccelZ"]]/64.0 127 | 128 | # Load Temperature data 129 | temperature_data = _loadSingleFile_E4(os.path.join(filepath,'TEMP.csv'),["Temp"],4,"250L") 130 | 131 | data = eda_data.join(acc_data, how='outer') 132 | data = data.join(temperature_data, how='outer') 133 | 134 | # E4 sometimes records different length files - adjust as necessary 135 | min_length = min(len(acc_data), len(eda_data), len(temperature_data)) 136 | 137 | return data[:min_length] 138 | 139 | def loadData_shimmer(filepath): 140 | data = pd.read_csv(filepath, sep='\t', skiprows=(0,1)) 141 | 142 | orig_cols = data.columns 143 | rename_cols = {} 144 | 145 | for search, new_col in [['Timestamp','Timestamp'], 146 | ['Accel_LN_X', 'AccelX'], ['Accel_LN_Y', 'AccelY'], ['Accel_LN_Z', 'AccelZ'], 147 | ['Skin_Conductance', 'EDA']]: 148 | orig = [c for c in orig_cols if search in c] 149 | if len(orig) == 0: 150 | continue 151 | rename_cols[orig[0]] = new_col 152 | 153 | data.rename(columns=rename_cols, inplace=True) 154 | 155 | # TODO: Assuming no temperature is recorded 156 | data['Temp'] = 0 157 | 158 | # Drop the units row and unnecessary columns 159 | data = data[data['Timestamp'] != 'ms'] 160 | data.index = pd.to_datetime(data['Timestamp'], unit='ms') 161 | data = data[['AccelZ', 'AccelY', 'AccelX', 'Temp', 'EDA']] 162 | 163 | for c in ['AccelZ', 'AccelY', 'AccelX', 'Temp', 'EDA']: 164 | data[c] = pd.to_numeric(data[c]) 165 | 166 | # Convert to 8Hz 167 | data = data.resample("125L").mean() 168 | data.interpolate(inplace=True) 169 | 170 | # Get the filtered data using a low-pass butterworth filter (cutoff:1hz, fs:8hz, order:6) 171 | data['filtered_eda'] = butter_lowpass_filter(data['EDA'], 1.0, 8, 6) 172 | 173 | return data 174 | 175 | 176 | def loadData_getColNames(data_columns): 177 | print("Here are the data columns of your file: ") 178 | print(data_columns) 179 | 180 | # Find the column names for each of the 5 data streams 181 | colnames = ['EDA data','Temperature data','Acceleration X','Acceleration Y','Acceleration Z'] 182 | new_colnames = ['','','','',''] 183 | 184 | for i in range(len(new_colnames)): 185 | new_colnames[i] = get_user_input("Column name that contains "+colnames[i]+": ") 186 | while (new_colnames[i] not in data_columns): 187 | print("Column not found. Please try again") 188 | print("Here are the data columns of your file: ") 189 | print(data_columns) 190 | 191 | new_colnames[i] = get_user_input("Column name that contains "+colnames[i]+": ") 192 | 193 | # Get user input on sample rate 194 | sampleRate = get_user_input("Enter sample rate (must be an integer power of 2): ") 195 | while (sampleRate.isdigit()==False) or (np.log(int(sampleRate))/np.log(2) != np.floor(np.log(int(sampleRate))/np.log(2))): 196 | print("Not an integer power of two") 197 | sampleRate = get_user_input("Enter sample rate (must be a integer power of 2): ") 198 | sampleRate = int(sampleRate) 199 | 200 | # Get user input on start time 201 | startTime = pd.to_datetime(get_user_input("Enter a start time (format: YYYY-MM-DD HH:MM:SS): ")) 202 | while type(startTime)==str: 203 | print("Not a valid date/time") 204 | startTime = pd.to_datetime(get_user_input("Enter a start time (format: YYYY-MM-DD HH:MM:SS): ")) 205 | 206 | 207 | return sampleRate, startTime, new_colnames 208 | 209 | 210 | def loadData_misc(filepath): 211 | # Load data 212 | data = pd.read_csv(filepath) 213 | 214 | # Get the correct colnames 215 | sampleRate, startTime, new_colnames = loadData_getColNames(data.columns.values) 216 | 217 | data.rename(columns=dict(zip(new_colnames,['EDA','Temp','AccelX','AccelY','AccelZ'])), inplace=True) 218 | data = data[['AccelZ','AccelY','AccelX','Temp','EDA']] 219 | 220 | # Make sure data has a sample rate of 8Hz 221 | data = interpolateDataTo8Hz(data,sampleRate,startTime) 222 | 223 | # Get the filtered data using a low-pass butterworth filter (cutoff:1hz, fs:8hz, order:6) 224 | data['filtered_eda'] = butter_lowpass_filter(data['EDA'], 1.0, 8, 6) 225 | 226 | return data 227 | 228 | def interpolateDataTo8Hz(data,sample_rate,startTime): 229 | if sample_rate<8: 230 | # Upsample by linear interpolation 231 | if sample_rate==2: 232 | data.index = pd.date_range(start=startTime, periods=len(data), freq='500L') 233 | elif sample_rate==4: 234 | data.index = pd.date_range(start=startTime, periods=len(data), freq='250L') 235 | data = data.resample("125L").mean() 236 | else: 237 | if sample_rate>8: 238 | # Downsample 239 | idx_range = list(range(0,len(data))) # TODO: double check this one 240 | data = data.iloc[idx_range[0::int(int(sample_rate)/8)]] 241 | # Set the index to be 8Hz 242 | data.index = pd.date_range(start=startTime, periods=len(data), freq='125L') 243 | 244 | # Interpolate all empty values 245 | data = interpolateEmptyValues(data) 246 | return data 247 | 248 | def interpolateEmptyValues(data): 249 | cols = data.columns.values 250 | for c in cols: 251 | data.loc[:, c] = data[c].interpolate() 252 | 253 | return data 254 | 255 | def butter_lowpass(cutoff, fs, order=5): 256 | # Filtering Helper functions 257 | nyq = 0.5 * fs 258 | normal_cutoff = cutoff / nyq 259 | b, a = scisig.butter(order, normal_cutoff, btype='low', analog=False) 260 | return b, a 261 | 262 | def butter_lowpass_filter(data, cutoff, fs, order=5): 263 | # Filtering Helper functions 264 | b, a = butter_lowpass(cutoff, fs, order=order) 265 | y = scisig.lfilter(b, a, data) 266 | return y -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==1.16.2 2 | scipy==1.2.1 3 | pandas==0.24.1 4 | scikit-learn==0.20.3 5 | matplotlib>=2.1.2 6 | PyWavelets==1.0.2 --------------------------------------------------------------------------------