Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
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.
Ejemplo n.º 3
0
    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))