def script(): # Get a list of activity ids to use as targets. # activities = ["Walking", "Jogging", "Cycling", "Idle"] # activities = ["Walking", "Jogging", "Cycling", "Writing", "Typing", "Idle"] activities = [ "Walking", "Jogging", "Cycling", "Writing", "Typing", "Sitting", "Standing", "On Phone (sit)", "On Phone (stand)" ] activity_ids = [name_id_map[activity] for activity in activities] targets = ["Idle", "Low", "Medium", "High"] # Get a connection to the database. database_conn = get_database() cursor = database_conn.cursor() # Get the features relating to these activities. features = get_features(cursor, activity_ids) # Shuffle the features to distribute them more randomly between users and trials. shuffle(features) # Split the features into training and testing. x_train, x_test, y_train, y_test = get_train_test_data( features, range(0, 6), 6) # Update the target values. y_train = [ energy_id_map[name_id_map[activity_id]] for activity_id in y_train ] y_test = [ energy_id_map[name_id_map[activity_id]] for activity_id in y_test ] # Train the classifiers. trained_classifiers = get_trained_classifiers(x_train, y_train) # Plot confusion matrices. conf_matrix = None for classifier in trained_classifiers: cnf = plot_confusion(classifier, targets, x_test, y_test) if conf_matrix is None: conf_matrix = cnf else: conf_matrix += cnf # Plot the total conf matrix. plot_confusion(None, targets, x_test, y_test, conf_matrix) # Measure their accuracies using the testing data. accuracies = [ get_accuracy(classifier, x_test, y_test) for classifier in trained_classifiers ] # Print the accuracies of each algorithm. for classifier, accuracy in zip(trained_classifiers, accuracies): print("{} is {}% accurate".format(classifier.__class__.__name__, accuracy)) # Get the best classifier for these features. classifier, accuracy = trained_classifiers[accuracies.index( max(accuracies))], max(accuracies) # Print result. print("Best classifier is: {}, with accuracy {}".format( classifier.__class__.__name__, accuracy)) # Plot the confusion matrix of the best performing. plot_confusion(classifier, targets, x_test, y_test) idle_accuracy = conf_matrix[0][0] / sum(conf_matrix[0]) * 100 low_accuracy = conf_matrix[1][1] / sum(conf_matrix[1]) * 100 med_accuracy = conf_matrix[2][2] / sum(conf_matrix[2]) * 100 high_accuracy = conf_matrix[3][3] / sum(conf_matrix[3]) * 100 cnf_encoded = pickle.dumps(conf_matrix) classifier_encoded = pickle.dumps(classifier) accuracies_encoded = pickle.dumps({ "Idle": idle_accuracy, "Low": low_accuracy, "Medium": med_accuracy, "High": high_accuracy }) cursor.execute( """ INSERT INTO public."Model" (data, name, description, target_accuracies, confusion_matrix) VALUES (%s, %s, %s, %s, %s) ON CONFLICT (name) DO UPDATE SET data = %s, target_accuracies = %s, confusion_matrix = %s; """, (classifier_encoded, model_name, description, accuracies_encoded, cnf_encoded, classifier_encoded, accuracies_encoded, cnf_encoded)) database_conn.commit() # Close the database connections. cursor.close() database_conn.close()
cursor.execute(""" SELECT "meanXYZ", "stdXYZ", dom_hand, watch_hand FROM public."Featureset_1" feature, public."Participant" ptct, public."Trial" trial WHERE trial.participant_id = ptct.id AND trial.id = feature.trial_id; """) # Create a matrix of feature data. features = [[attrs[0][0], attrs[0][1], attrs[0][2], attrs[1][0], attrs[1][1], attrs[1][2], attrs[2] == attrs[3]] for attrs in cursor.fetchall()] # Shuffle the features to distribute them more randomly between users and trials. shuffle(features) # Create training data for classifying a user's dominant hand. x_train, x_test, y_train, y_test = get_train_test_data(features, range(0, 6), 6) # # Update the target to a numerical value. # for index, hand in enumerate(y_train): # if hand[0] == 'r': # y_train[index] = RIGHT_TARGET # else: # y_train[index] = LEFT_TARGET # # for index, hand in enumerate(y_test): # if hand[0] == 'r': # y_test[index] = RIGHT_TARGET # else: # y_test[index] = LEFT_TARGET # # We're saved doing this manipulation of data through the boolean comparator in the list comprehension above.
def test_improved_accuracy(self): # Get the "same hand" activity classifying model. self.cursor.execute( """ SELECT data FROM public."Model" WHERE name = %s; """, ("same_hand_activity_set_1", )) data = self.cursor.fetchone() # Check for existence. if data is None: self.fail( "There is no model with the name same_hand_activity_set_1.") # Decode the classifier. data = data[0] same_hand_classifier = pickle.loads(data) # Get the "diff hand" activity classifying model. self.cursor.execute( """ SELECT data FROM public."Model" WHERE name = %s; """, ("diff_hand_activity_set_1", )) data = self.cursor.fetchone() # Check for existence. if data is None: self.fail( "There is no model with the name diff_hand_activity_set_1.") # Decode the classifier. data = data[0] diff_hand_classifier = pickle.loads(data) # Get the general activity classifying model for comparison. self.cursor.execute( """ SELECT data FROM public."Model" WHERE name = %s; """, ("activity_set_1", )) data = self.cursor.fetchone() # Check for existence. if data is None: self.fail("There is no model with the name activity_set_1.") # Decode the classifier. data = data[0] general_classifier = pickle.loads(data) # Get features for users that wear their watch on their dominant hand. same_features = self.get_features(dom_hand_is_watch_hand=True) # Get features for users that don't wear their watch on their dominant hand. diff_features = self.get_features(dom_hand_is_watch_hand=False) # Get the activity classification accuracy when the user wears the watch on their dominant hand. _, x_test, _, y_test = get_train_test_data(same_features, range(0, 6), 6) same_accuracy = get_accuracy(same_hand_classifier, x_test, y_test) # Get the activity classification accuracy when the user wears the watch on their non-dominant hand. _, x_test, _, y_test = get_train_test_data(diff_features, range(0, 6), 6) diff_accuracy = get_accuracy(diff_hand_classifier, x_test, y_test) # Get the accuracy for all watch / arm configurations. same_features.append(diff_features) _, x_test, _, y_test = get_train_test_data(same_features, range(0, 6), 6) general_accuracy = get_accuracy(general_classifier, x_test, y_test) self.assertTrue( general_accuracy < same_accuracy, "The targeted classifier did not improve accuracy " "for those who wear a watch on their dominant hand.\n" "General: {}%. Same: {}%. Diff: {}%.".format( general_accuracy, same_accuracy, diff_accuracy)) self.assertTrue( general_accuracy < diff_accuracy, "The targeted classifier did not improve accuracy " "for those who wear a watch on their non-dominant hand.\n" "General: {}%. Same: {}%. Diff: {}%.".format( general_accuracy, same_accuracy, diff_accuracy))