1
1
# Copyright (c) 2023 Diego Gasco ([email protected] ), Diegomangasco on GitHub
2
2
3
- import logging
3
+ import logging # noqa: I001
4
4
import numpy as np
5
5
import scipy
6
6
7
7
logging .basicConfig (level = logging .INFO , format = '%(message)s' )
8
8
9
9
10
- def column_reshape (input_array : np .ndarray ) -> np .ndarray :
10
+ def _column_reshape (input_array : np .ndarray ) -> np .ndarray :
11
11
"""Function to reshape a row Numpy array into a column Numpy array"""
12
12
13
13
return input_array .reshape ((input_array .size , 1 ))
14
14
15
15
16
- def covariance_within_classes (features : np .ndarray , labels : np .ndarray , classes : int ) -> np .ndarray :
16
+ def _covariance_within_classes (features : np .ndarray , labels : np .ndarray , classes : int ) -> np .ndarray :
17
17
"""Function to compute the covariance matrix inside each class"""
18
18
19
19
covariance_sum = np .nan
20
20
for i in range (classes ):
21
21
data = features [:, labels == i ]
22
22
data_mean = data .mean (1 )
23
23
# Centralize the data of class i
24
- centered_data = data - column_reshape (data_mean )
24
+ centered_data = data - _column_reshape (data_mean )
25
25
if i > 0 :
26
26
# If covariance_sum is not None
27
27
covariance_sum += np .dot (centered_data , centered_data .T )
@@ -32,7 +32,7 @@ def covariance_within_classes(features: np.ndarray, labels: np.ndarray, classes:
32
32
return covariance_sum / features .shape [1 ]
33
33
34
34
35
- def covariance_between_classes (features : np .ndarray , labels : np .ndarray , classes : int ) -> np .ndarray :
35
+ def _covariance_between_classes (features : np .ndarray , labels : np .ndarray , classes : int ) -> np .ndarray :
36
36
"""Function to compute the covariance matrix between multiple classes"""
37
37
38
38
general_data_mean = features .mean (1 )
@@ -43,23 +43,25 @@ def covariance_between_classes(features: np.ndarray, labels: np.ndarray, classes
43
43
data_mean = data .mean (1 )
44
44
if i > 0 :
45
45
# If covariance_sum is not None
46
- covariance_sum += device_data * np .dot (column_reshape (data_mean ) - column_reshape (general_data_mean ),
47
- (column_reshape (data_mean ) - column_reshape (general_data_mean )).T )
46
+ covariance_sum += device_data * np .dot (_column_reshape (data_mean ) - _column_reshape (general_data_mean ),
47
+ (_column_reshape (data_mean ) - _column_reshape (general_data_mean )).T )
48
48
else :
49
49
# If covariance_sum is np.nan (i.e. first loop)
50
- covariance_sum = device_data * np .dot (column_reshape (data_mean ) - column_reshape (general_data_mean ),
51
- (column_reshape (data_mean ) - column_reshape (general_data_mean )).T )
50
+ covariance_sum = device_data * np .dot (_column_reshape (data_mean ) - _column_reshape (general_data_mean ),
51
+ (_column_reshape (data_mean ) - _column_reshape (general_data_mean )).T )
52
52
53
53
return covariance_sum / features .shape [1 ]
54
54
55
55
56
- def PCA (features : np .ndarray , dimensions : int ) -> np .ndarray :
57
- """Principal Component Analysis. \n
58
- For more details, see here: https://en.wikipedia.org/wiki/Principal_component_analysis \n
59
- Parameters: \n
60
- * features: the features extracted from the dataset
61
- * labels: the class labels of the features
62
- * dimensions: to filter the projected data for the desired dimension"""
56
+ def principal_component_analysis (features : np .ndarray , dimensions : int ) -> np .ndarray :
57
+ """
58
+ Principal Component Analysis.
59
+
60
+ For more details, see here: https://en.wikipedia.org/wiki/Principal_component_analysis.
61
+ Parameters:
62
+ * features: the features extracted from the dataset
63
+ * dimensions: to filter the projected data for the desired dimension
64
+ """
63
65
64
66
# Check if the features have been loaded
65
67
if features .any ():
@@ -81,23 +83,26 @@ def PCA(features: np.ndarray, dimensions: int) -> np.ndarray:
81
83
raise AssertionError
82
84
83
85
84
- def LDA (features : np .ndarray , labels : np .ndarray , classes : int , dimensions : int ) -> np .ndarray :
85
- """Linear Discriminant Analysis. \n
86
- For more details, see here: https://en.wikipedia.org/wiki/Linear_discriminant_analysis \n
87
- Parameters: \n
88
- * features: the features extracted from the dataset
89
- * labels: the class labels of the features
90
- * classes: the number of classes present in the dataset
91
- * dimensions: to filter the projected data for the desired dimension"""
86
+ def linear_discriminant_analysis (features : np .ndarray , labels : np .ndarray , classes : int , dimensions : int ) -> np .ndarray :
87
+ """
88
+ Linear Discriminant Analysis.
89
+
90
+ For more details, see here: https://en.wikipedia.org/wiki/Linear_discriminant_analysis.
91
+ Parameters:
92
+ * features: the features extracted from the dataset
93
+ * labels: the class labels of the features
94
+ * classes: the number of classes present in the dataset
95
+ * dimensions: to filter the projected data for the desired dimension
96
+ """
92
97
93
98
# Check if the dimension desired is less than the number of classes
94
99
assert classes > dimensions
95
100
96
101
# Check if features have been already loaded
97
102
if features .any :
98
103
_ , eigenvectors = scipy .linalg .eigh (
99
- covariance_between_classes (features , labels , classes ),
100
- covariance_within_classes (features , labels , classes ))
104
+ _covariance_between_classes (features , labels , classes ),
105
+ _covariance_within_classes (features , labels , classes ))
101
106
filtered_eigenvectors = eigenvectors [:, ::- 1 ][:, :dimensions ]
102
107
svd_matrix , _ , _ = np .linalg .svd (filtered_eigenvectors )
103
108
filtered_svd_matrix = svd_matrix [:, 0 :dimensions ]
0 commit comments