--- a +++ b/src/preprocessing.py @@ -0,0 +1,113 @@ +from sklearn.model_selection import train_test_split +from sklearn.preprocessing import StandardScaler +from sklearn.compose import ColumnTransformer +from sklearn.pipeline import Pipeline +from sklearn.impute import SimpleImputer +from sklearn.preprocessing import OneHotEncoder, LabelEncoder +import matplotlib.pyplot as plt +import seaborn as sns + +def preprocess_data(data, target): + X = data.drop(columns=[target]) + y = data[target] + return X, y + +def split_data(data, target, test_size=0.2, val_size=0.1): + X, y = preprocess_data(data, target) + X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=test_size + val_size, stratify=y) + X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=test_size / (test_size + val_size), stratify=y_temp) + return X_train, X_val, X_test, y_train, y_val, y_test + +def create_pipeline(model, numerical_features, categorical_features): + numeric_transformer = Pipeline(steps=[ + ('scaler', StandardScaler())]) + + categorical_transformer = Pipeline(steps=[ + ('imputer', SimpleImputer(strategy='constant', fill_value='missing')), + ('onehot', LabelEncoder(handle_unknown='ignore'))]) + + preprocessor = ColumnTransformer( + transformers=[ + ('num', numeric_transformer, numerical_features), + ('cat', categorical_transformer, categorical_features)]) + + pipeline = Pipeline(steps=[('preprocessor', preprocessor), + ('model', model)]) + return pipeline + +def preprocessor_pipeline(numerical_features, categorical_features): + numeric_transformer = Pipeline(steps=[ + ('scaler', StandardScaler())]) + + categorical_transformer = Pipeline(steps=[ + ('label', LabelEncoder())]) + + preprocessor = ColumnTransformer( + transformers=[ + ('num', numeric_transformer, numerical_features), + ('cat', categorical_transformer, categorical_features)]) + + return preprocessor + + +# Vérifier l'existence de duplications dans le dataset +def check_duplicates(data): + return data.duplicated().sum() + +# Supprimer les duplications dans le dataset +def drop_duplicates(data): + data.drop_duplicates(inplace=True) + return data + +# Fonction pour visualiser les données manquantes dans le dataset avec un heatmap +def plot_missing_data(data): + plt.figure(figsize=(10, 5)) + sns.heatmap(data.isnull(), cbar=False) + plt.title('Missing data in the dataset') + plt.show() + +# Fonction pour enlever les valeurs aberrantes dans le dataset +def remove_outliers(data, column): + Q1 = data[column].quantile(0.25) + Q3 = data[column].quantile(0.75) + IQR = Q3 - Q1 + lower_bound = Q1 - 1.5 * IQR + upper_bound = Q3 + 1.5 * IQR + return data[(data[column] >= lower_bound) & (data[column] <= upper_bound)] + +# Fonction pour visualiser les valeurs aberrantes dans le dataset +def plot_outliers(data, column): + plt.figure(figsize=(10, 5)) + sns.boxplot(x=data[column]) + plt.title('Outliers in the dataset') + plt.show() + +def balance_dataset(data_path, target_column, output_path, random_state=42): + """ + Équilibre le dataset en assurant que chaque classe ait le même nombre de lignes, + basé sur la classe ayant le moins de lignes. + + Parameters: + - data_path (str): Le chemin du fichier CSV à charger. + - target_column (str): Le nom de la colonne cible pour équilibrer les classes. + - output_path (str): Le chemin du fichier CSV où sauvegarder le dataset équilibré. + - random_state (int): La graine aléatoire pour la reproductibilité (par défaut 42). + """ + # Charger les données + df = pd.read_csv(data_path) + + # Trouver la taille de la plus petite classe + min_class_size = df[target_column].value_counts().min() + + # Échantillonner chaque classe pour avoir un nombre égal de lignes + df_balanced = df.groupby(target_column).apply(lambda x: x.sample(min_class_size, random_state=random_state)).reset_index(drop=True) + + # Sauvegarder le nouveau dataset + df_balanced.to_csv(output_path, index=False) + + # Vérifier la distribution des classes dans le nouvel ensemble de données + distribution = df_balanced[target_column].value_counts() + print("Distribution des classes dans le dataset équilibré :") + print(distribution) + + return df_balanced \ No newline at end of file