66import numpy as np
77from sklearn .decomposition import PCA
88from sklearn .preprocessing import StandardScaler , LabelEncoder
9- < << << << HEAD
10- from reinforcementLearning import run_rl
11- == == == =
129from backend .reinforcementLearning import run_rl
13- > >> >> >> frontend
1410
1511
1612backend_data = {"df" : None ,
@@ -58,8 +54,6 @@ def clean_data(df):
5854
5955###### FEATURE SELECTION & FIND ANOMALIES #####
6056
61- < << << << HEAD
62- == == == =
6357#############TESTING PURPOSES ONLY START #############
6458
6559def find_anomalies (query , uid , num_feat , start = None , end = None , source_ip = None ):
@@ -94,96 +88,11 @@ def find_anomalies(query, uid, num_feat, start=None, end=None, source_ip=None):
9488 return mock_table
9589
9690#############TESTING PURPOSES ONLY END #############
97- > >> >> >> frontend
9891'''
9992Summary: Takes the user query, performs feature selection and RL. Updates all global data.
10093Input:
10194Output:
10295'''
103- < << << << HEAD
104- def find_anomalies (query , uid , num_feat ):
105-
106- ## FEATURE SELECTION
107- main_identifiers = [uid ] # TODO: could later add option for additional headings to ignore, otherwise switch to just UID
108- backend_data ["uid" ] = uid
109- df = backend_data ["df" ]
110- num_entries = df .shape [0 ]
111- drop = []
112- for i in df :
113- if df [i ].dtype == 'O' and i not in main_identifiers : # qualitative
114- qual_to_quant (df , i )
115- if df [i ].nunique () > (num_entries / 2 ) or df [i ].nunique () == 1 : # if more than 1/2 of data points have a unique label OR all have same label, drop the column. can change this!
116- drop .append (i )
117- # print(drop)
118- cleaned_df = df .drop (columns = drop )
119- qual_to_quant (cleaned_df , main_identifiers [0 ])
120- backend_data ["df" ] = cleaned_df
121- # print("Final Columns:", str(cleaned_df.shape[1]))
122- # print(cleaned_df.head())
123-
124- pca , features = get_features (cleaned_df , num_feat , main_identifiers )
125- backend_data ["features" ] = features
126-
127- ## REINFORCEMENT LEARNING
128- anomalies , cluster_sizes , final_features = run_rl (backend_data ) #TODO: others for output data
129- backend_data ["anomalies" ] = anomalies
130- return anomalies
131-
132- '''Converts the qualitative column col in df to quantitative values'''
133- def qual_to_quant (df , col ):
134- le = LabelEncoder ()
135- df [col ] = le .fit_transform (df [col ])
136-
137- "Returns an array with the indexes of the top n values in arr"
138- def get_top_n_idx (n , arr ):
139- arr = np .abs (arr )
140- top = np .argpartition (arr , - n )[- n :]
141- return top
142-
143- '''
144- Returns a numpy array of the selected features from data using PCA.
145-
146- PCA: develops unspecified number of components to represent data
147- Feature Selection: getting the top_n features that have the highest weighted
148- importance across all components
149- '''
150- def get_features (data , top_n , main_identifiers ):
151- copy = data .copy (deep = True ) # Make a copy of the original data to avoid modifying it
152- feat_options = copy .drop (columns = main_identifiers ).copy (deep = True ) # Drop columns like unique IDs that shouldn't be scaled
153-
154- # Standardize the data
155- scaler = StandardScaler ()
156- scaler .fit (feat_options )
157- scaled_data = scaler .transform (feat_options )
158-
159- pca = PCA (n_components = 0.95 ) # should represent at least 95% of overall trends in data
160- pca .fit (scaled_data )
161-
162- ### USE ABSOLUTE VALUE OF LOADINGS ONLY FOR FEATURE IMPORTANCE
163- loadings = np .abs (pca .components_ ) # Get importance for each feature in each component
164- # feature_importance = np.sum(loadings, axis=0) # Sum the absolute loadings for each feature across all components
165-
166- ### USE WEIGHTED LOADINGS BY EXPLAINED VARIANCE FOR FEATURE IMPORTANCE
167- weighted_loadings = np .abs (pca .components_ ) * pca .explained_variance_ratio_ .reshape (- 1 , 1 )
168- feature_importance = np .sum (weighted_loadings , axis = 0 )
169-
170-
171- # Get the indexes of the top n most important features based on summed importance
172- top = get_top_n_idx (top_n , feature_importance )
173-
174- # Get the feature names for the most important features
175- most_important_names = feat_options .columns [top ]
176-
177- # Print the selected important features
178- print ("Most Important Features:" , most_important_names .tolist ())
179-
180- # Return the unique top features
181- unique_feats = np .unique (most_important_names )
182- print ("Unique Features:" , unique_feats .tolist ())
183-
184- # Return the selected unique features
185- return pca , unique_feats
186- == == == =
18796# def find_anomalies(query, uid, num_feat, start=None, end=None, source_ip=None):
18897
18998# ## FEATURE SELECTION
@@ -266,7 +175,6 @@ def get_features(data, top_n, main_identifiers):
266175
267176# # Return the selected unique features
268177# return pca, unique_feats
269- >> >> >> > frontend
270178
271179
272180##### GET OUTPUT #####
@@ -277,9 +185,6 @@ def get_features(data, top_n, main_identifiers):
277185Output:
278186'''
279187def get_output ():
280- < << << << HEAD
281- return ("Returning results" )
282- == == == =
283188 ######## JUST FOR TESTING PURPOSES ########
284189 return {
285190 "ok" : True ,
@@ -288,4 +193,3 @@ def get_output():
288193 "summary" : "Returning test results"
289194 }
290195 }
291- >> >> >> > frontend
0 commit comments