Exemplo n.º 1
0
def manipulate_features(
        features: np.ndarray,
        file_data: np.ndarray,
        view_individual_paths=False) -> (np.ndarray, np.ndarray):
    """
Return the features manipulated in a way as to make the algorithm for separating the data more accurate.
    :param features: the features to use
    :param file_data: the log file's data
    :return: the manipulated features array, the outliers of the data set and the data scaler
    :param view_individual_paths:
    """

    if contains_key(file_data, "motionState"):
        moving_mask = file_data["motionState"] == "MOVING"
        features = features[moving_mask]
        file_data = file_data[moving_mask]

    new_features = None
    scalers = {}
    if contains_key(file_data, "pathNumber"):

        for pathNumber in np.unique(file_data["pathNumber"]):
            min_max_scaler = MinMaxScaler()

            path_number = file_data["pathNumber"] == pathNumber
            scalers[min_max_scaler] = path_number

            features_at_path = features[path_number]

            half = features_at_path.shape[0] // 2
            coefficient, _ = find_linear_best_fit_line(
                features_at_path[:half, 2], features_at_path[:half, 0])

            if coefficient < 0:
                features_at_path[:, 0] *= -1

            features_at_path = min_max_scaler.fit_transform(features_at_path)
            outliers_free_features = features_at_path

            if view_individual_paths:
                fig = plt.figure()

                fig.gca().scatter(features_at_path[:, 0], features_at_path[:,
                                                                           1])

            if new_features is None:
                new_features = outliers_free_features
            else:
                new_features = np.concatenate(
                    (new_features, outliers_free_features), 0)
    else:
        min_max_scaler = MinMaxScaler()
        scalers[min_max_scaler] = np.full(features.shape[0], True)
        new_features = min_max_scaler.fit_transform(features)

    features = reverse_scaling(new_features, scalers)
    return new_features, features
def manipulate_features(features: np.ndarray,
                        file_data: np.ndarray) -> (np.ndarray, np.ndarray):
    """
Return the features manipulated in a way as to make the algorithm for separating the data more accurate.
    :param features: the features to use
    :param file_data: the log file's data
    :return: the manipulated features array, the outliers of the data set and the data scaler
    """

    if contains_key(file_data, "motionState"):
        moving_mask = file_data["motionState"] == "MOVING"
        features = features[moving_mask]
        file_data = file_data[moving_mask]

    new_features = None
    scalers = {}
    if contains_key(file_data, "pathNumber"):

        for i in range(file_data["pathNumber"].min(),
                       file_data["pathNumber"].max() + 1):
            min_max_scaler = MinMaxScaler()

            path_number = file_data["pathNumber"] == i
            scalers[min_max_scaler] = path_number

            features_at_path = features[path_number]

            half = features_at_path.shape[0] // 2
            coefficient, _ = find_linear_best_fit_line(
                features_at_path[:half, 2], features_at_path[:half, 0])

            if coefficient < 0:
                features_at_path[:, 0] *= -1

            features_at_path = min_max_scaler.fit_transform(features_at_path)
            outliers_free_features = features_at_path

            if new_features is None:
                new_features = outliers_free_features
            else:
                new_features = np.concatenate(
                    (new_features, outliers_free_features), 0)
    else:
        min_max_scaler = MinMaxScaler()
        scalers[min_max_scaler] = np.full(features.shape[0], True)
        new_features = min_max_scaler.fit_transform(features)

    # outlier_detector = OneClassSVM(gamma=10)  # Seems to work best

    # outlier_detector.fit(new_features)
    # outlier_prediction = outlier_detector.predict(new_features)
    # outliers = new_features[outlier_prediction == -1]
    # new_features = new_features[outlier_prediction == 1]

    # features = reverse_scalling(new_features, scalers, outlier_prediction)

    return new_features, features
    def show_constants_graph(self, features, file_data, labels, c=None):
        """
    Creates an addition figure that will display the a graph with the constants on it and also the lines of best fit of
    the accelerating portion of it, the decelerating portion of it and the average of both of those lines
        :param features: the features to use to show the graph and find the constants from
        :param file_data: the whole file data
        :param labels: the labels to say if a data point is accelerating or not
        :param c: the color to plot the points
        :return the constants for the motion profiling kV, kK and kAcc
        """
        if is_straight_line(file_data):
            easygui.msgbox("It was determined that the robot was trying to go straight. "
                           "As an ongoing feature the program will be able detect kLag, etc... "
                           "however for the instance this features has not been added")

        figure = plt.figure("Constants graph")
        constants_plot = figure.gca()
        constants_plot.set_xlabel("Velocity")
        constants_plot.set_ylabel("Average Power")

        fig_manager = plt.get_current_fig_manager()
        fig_manager.window.showMaximized()

        x = features[:, 1]
        y = features[:, 0]

        constants_plot.scatter(x, y, c=labels if c is None else c)

        acceleration_mask = labels == visualize.ACCELERATING
        coef_accelerating, intercept_accelerating = find_linear_best_fit_line(x[acceleration_mask],
                                                                              y[acceleration_mask])
        deceleration_mask = labels == visualize.DECELERATING
        coef_decelerating, intercept_decelerating = find_linear_best_fit_line(x[deceleration_mask],
                                                                              y[deceleration_mask])

        x_lim = np.array(constants_plot.get_xlim())
        y_lim = np.array(constants_plot.get_ylim())

        x, y = get_xy_limited(intercept_accelerating, coef_accelerating, x_lim, y_lim)
        constants_plot.plot(x, y)
        x, y = get_xy_limited(intercept_decelerating, coef_decelerating, x_lim, y_lim)
        constants_plot.plot(x, y)
        # constants_plot.plot(x_lim, coef_accelerating * x_lim + intercept_accelerating)
        # constants_plot.plot(x_lim, coef_decelerating * x_lim + intercept_decelerating)

        average_coef = (coef_accelerating + coef_decelerating) / 2
        average_intercept = (intercept_accelerating + intercept_decelerating) / 2
        # constants_plot.plot(x_lim, average_coef * x_lim + average_intercept)

        x, y = get_xy_limited(average_intercept, average_coef, x_lim, y_lim)
        constants_plot.plot(x, y)

        acceleration_coefficient = (coef_accelerating - average_coef)
        acceleration_intercept = (intercept_accelerating - average_intercept)
        k_acc = ((x.max() + x.min()) / 2) * acceleration_coefficient + acceleration_intercept

        bbox_props = dict(boxstyle="round,pad=0.3", fc="cyan", ec="b", lw=2)
        constants_plot.text(x_lim[0], y_lim[1],
                            "kV: {}\nkK: {}\nkAcc: {}".format(average_coef, average_intercept, k_acc), ha="left",
                            va="top", bbox=bbox_props)

        return average_coef, average_intercept, k_acc
def find_gain(clf, file_data, is_data=False, ax3d=None, ax2d=None):
    """

    :param clf:
    :param file_data:
    :param is_data:
    :param ax3d:
    :param ax2d:
    :return:
    """
    if not is_data:
        file_data = np.genfromtxt(file_data, delimiter=',', dtype=DTYPE, names=True)

    x, _ = get_features(file_data)
    x = x[file_data["motionState"] == 'MOVING']

    out = IsolationForest(n_jobs=-1, random_state=0)
    out.fit(x)
    predicted = out.predict(x)
    x = x[predicted == 1]
    x_scaled = MinMaxScaler().fit_transform(x)
    predicted = clf.predict(x_scaled)

    acceleration = x[predicted == 0]
    average_power_accelerating = acceleration[:, 0]
    velocity_accelerating = acceleration[:, 1]

    deceleration = x[predicted == 1]
    average_power_decelerating = deceleration[:, 0]
    velocity_decelerating = deceleration[:, 1]

    accelerating_coefficient, accelerating_intercept = find_linear_best_fit_line(velocity_accelerating,
                                                                                 average_power_accelerating)
    decelerating_coefficient, decelerating_intercept = find_linear_best_fit_line(velocity_decelerating,
                                                                                 average_power_decelerating)
    k_v = (accelerating_coefficient + decelerating_coefficient) / 2
    k_k = (accelerating_intercept + decelerating_intercept) / 2

    acceleration_coefficient = (accelerating_coefficient - k_v)
    acceleration_intercept = (accelerating_intercept - k_k)
    k_acc = ((x[:, 1].max() - x[:, 1].min()) / 2) * acceleration_coefficient + acceleration_intercept

    if ax3d or ax2d:
        colors = ["red" if i == 0 else "blue" for i in predicted]

        if ax3d:
            ax3d.set_xlabel('Velocity')
            ax3d.set_ylabel('Average motor power')
            ax3d.set_zlabel('Scaled Time')

            scaled_average_power = np.hstack(x_scaled[:, 1])
            scaled_velocity = np.hstack(x_scaled[:, 0])
            time = np.hstack(x_scaled[:, 2])
            ax3d.scatter(scaled_velocity, scaled_average_power, time, c=colors)

        if ax2d:
            ax2d.set_xlabel('Velocity')
            ax2d.set_ylabel('Average motor power')
            velocity = x[:, 1]
            average_power = x[:, 0]
            ax2d.scatter(velocity, average_power, c=colors)

            y_lim = np.array(ax2d.get_ylim())
            # TODO make the lines not exceed the x limit as well

            for c, i in zip([k_v, accelerating_coefficient, decelerating_coefficient],
                            [k_k, accelerating_intercept, decelerating_intercept]):
                ax2d.plot((y_lim - i) / c, y_lim)

    return k_v, k_k, k_acc