# Scale features

Students need to implement the `scale()` method to scale features in the `feature_matrix`. The method takes the `matrix` and, optionally `minimum` and `maximum` values as input. Students should compute the `minimum` and `maximum` values of each feature in this matrix if these values are not given as input, i.e., when they are `None`. Next, the (computed or given) `minimum` and `maximum` should be used to apply min-max scaling for the feature matrix.

`Assignment.``scale`(matrix, minimum=None, maximum=None)

  Scale features in matrix.

  Parameters

    - matrix (np.array of shape=(n_samples, n_features)) – Matrix to scale.

    - minimum (array-like of shape=(n_features,), optional) – If given, should contain the minimum values for each feature to scale with.

    - maximum (array-like of shape=(n_features,), optional) – If given, should contain the maximum values for each feature to scale with.

  Returns

    - scaled_matrix (array-like of shape=(n_samples, n_features)) – Scaled matrix.

    - minimum (array-like of shape=(n_features,)) – The minimum values for each feature used for scaling.

    - maximum (array-like of shape=(n_features,)) – The maximum values for each feature used for scaling.

Students are not required to return a numpy array. To ensure that everything still works when students return a list we use the `scale_numpy` function that transforms their output of `scale` to numpy arrays.

`Assignment.``scale_numpy`(matrix, minimum=None, maximum=None)

  Scale features in matrix to numpy arrays.

  Parameters

    - matrix (np.array of shape=(n_samples, n_features)) – Matrix to scale.

    - minimum (array-like of shape=(n_features,), optional) – If given, should contain the minimum values for each feature to scale with.

    - maximum (array-like of shape=(n_features,), optional) – If given, should contain the maximum values for each feature to scale with.

  Returns

    - scaled_matrix (np.array of shape=(n_samples, n_features)) – Scaled matrix.

    - minimum (np.array of shape=(n_features,)) – The minimum values for each feature used for scaling.

    - maximum (np.array of shape=(n_features,)) – The maximum values for each feature used for scaling.

## Testing

We test the implementation of scale using the `test_scale()` method. `test_scale()` runs defines various test cases, each case is handled by the `test_scale_single()` method. `test_scale_single()` passes the test case through your implementation of `scale()` and checks if the output contains any errors using the `assert_scale()` method.

`Assignment.``test_scale`(verbose=True)

  Method that runs some tests on data scaling.

  Parameters

    verbose (boolean, default=True) – If True, print test cases.

`Assignment.``test_scale_single`(scaled_input, minimum_input, maximum_input, scaled_target, minimum_target, maximum_target, verbose=False)

  Perform a single test case of input and target.

  Parameters

    - scaled_input (np.array of shape=(n_samples, n_features)) – matrix input given to scale function.

    - minimum_input (np.array of shape=(n_features), optional) – minimum input given to scale function.

    - maximum_input (np.array of shape=(n_features), optional) – maximum input given to scale function.

    - scaled_target (np.array of shape=(n_samples, n_features)) – Target scaled matrix if scale is implemented correctly.

    - minimum_target (np.array of shape=(n_features)) – Target minimum of features if scale is implemented correctly.

    - maximum_target (np.array of shape=(n_features)) – Target maximum of features if scale is implemented correctly.

    - verbose (boolean, default=False) – If True, print information on test case.

`Assignment.``assert_scale`(scaled_target, minimum_target, maximum_target, scaled_output=None, minimum_output=None, maximum_output=None)

  Performs checks comparing a computed output and target output.

  Parameters

    - scaled_target (array-like of shape=(n_samples, n_features)) – Target scaled matrix if scale is implemented correctly.

    - minimum_target (array-like of shape=(n_features)) – Target minimum of features if scale is implemented correctly.

    - maximum_target (array-like of shape=(n_features)) – Target maximum of features if scale is implemented correctly.

    - scaled_output (array-like of shape=(n_samples, n_features)) – Scaled output by running it through the scale implementation.

    - minimum_output (array-like of shape=(n_features)) – Minimum of features computed by scale implementation.

    - maximum_output (array-like of shape=(n_features)) – Maximum of features computed by scale implementation.

## Visualisation

We visualise the scaled `feature_matrix` as a table using the `show_scaled()` method. This produces a pandas.DataFrame of the scaled `feature_matrix` that is automatically displayed nicely in Jupyter notebook.

`Assignment.``show_scaled`()

  Shows the scaled feature matrix for benign flows.

  1. Extracts the feature matrix.

  2. Scales the data.

  3. Turns it into a pd.DataFrame.

Additionally, we want to compare the unscaled and scaled data for both the `benign.csv` and `unknown.csv` data. We plot this data using the `plot_scaled` method (which in turn uses the `plot_data` helper method).

Note

As we may have an arbitrary number of features that we want to plot in a 2D space, we use PCA to compress the data into two dimensions. We basically only show the two principal components with the highest eigenvalues. See the PCA wikipedia article for a full explanation on this technique.

`Assignment.``plot_scaled`()

  Plot scaled vs unscaled.

  1. Computes feature matrix for both benign.csv and unknown.csv.

  2. Applies scaling to both benign and unknown feature matrix.

  3. Plots the differences.

`Assignment.``plot_data`(ax, X, y)

  Plots the feature vectors given by X and labelled by y.

  Parameters

    - ax (matplotlib.axis) – Axis on which to plot data.

    - X (array-like of shape=(n_samples, n_features)) – Feature vectors to plot.

    - y (array-like of shape=(n_features,)) – Labels corresponding to the feature vectors.