CoolFace
Apppublic

sma-nas/credit-scoring-api

sourceHugging Faceupdated 7mo agoView on Hugging Face
0likes
data_processing.py242 linesDownload Raw Back to src
1"""2Module de traitement et préparation des données pour le scoring de crédit.3"""4 5import pandas as pd6import numpy as np7from sklearn.preprocessing import LabelEncoder, StandardScaler8from sklearn.impute import SimpleImputer9import warnings10warnings.filterwarnings('ignore')11 12 13def load_data(file_path):14    """15    Charge un fichier de données.16    17    Args:18        file_path (str): Chemin vers le fichier19        20    Returns:21        pd.DataFrame: Données chargées22    """23    try:24        if file_path.endswith('.csv'):25            return pd.read_csv(file_path)26        elif file_path.endswith('.xlsx'):27            return pd.read_excel(file_path)28        else:29            raise ValueError("Format de fichier non supporté. Utiliser .csv ou .xlsx")30    except Exception as e:31        print(f"Erreur lors du chargement : {e}")32        return None33 34 35def explore_data(df, name="Dataset"):36    """37    Affiche un résumé exploratoire du dataset.38    39    Args:40        df (pd.DataFrame): Dataset à explorer41        name (str): Nom du dataset42    """43    print(f"\n{'='*60}")44    print(f"Exploration : {name}")45    print(f"{'='*60}")46    print(f"\nDimensions : {df.shape[0]} lignes x {df.shape[1]} colonnes")47    print(f"\nTypes de colonnes :")48    print(df.dtypes.value_counts())49    print(f"\nValeurs manquantes :")50    missing = df.isnull().sum()51    if missing.sum() > 0:52        missing_pct = (missing / len(df)) * 10053        missing_df = pd.DataFrame({54            'Colonnes': missing.index,55            'Manquants': missing.values,56            'Pourcentage': missing_pct.values57        })58        print(missing_df[missing_df['Manquants'] > 0].sort_values('Manquants', ascending=False))59    else:60        print("Aucune valeur manquante")61    print(f"\nDoublons : {df.duplicated().sum()}")62 63 64def check_duplicates(df):65    """66    Vérifie et supprime les doublons.67    68    Args:69        df (pd.DataFrame): Dataset70        71    Returns:72        pd.DataFrame: Dataset sans doublons73    """74    n_duplicates = df.duplicated().sum()75    if n_duplicates > 0:76        print(f"⚠️  {n_duplicates} doublons trouvés et supprimés")77        return df.drop_duplicates()78    print("✓ Aucun doublon trouvé")79    return df80 81 82def merge_datasets(df_list, keys, how='inner'):83    """84    Fusionne plusieurs datasets.85    86    Args:87        df_list (list): Liste de DataFrames88        keys (list): Liste des clés de fusion89        how (str): Type de jointure90        91    Returns:92        pd.DataFrame: Dataset fusionné93    """94    if len(df_list) < 2:95        return df_list[0] if df_list else None96    97    result = df_list[0]98    for i, df in enumerate(df_list[1:], 1):99        before = len(result)100        result = result.merge(df, on=keys[i-1] if isinstance(keys, list) else keys, how=how)101        after = len(result)102        print(f"Fusion {i}: {before} lignes → {after} lignes")103    104    return result105 106 107def handle_missing_values(df, strategy='auto', threshold=0.5):108    """109    Gère les valeurs manquantes avec différentes stratégies.110    111    Args:112        df (pd.DataFrame): Dataset113        strategy (str): Stratégie ('auto', 'drop', 'mean', 'median', 'mode')114        threshold (float): Seuil de suppression de colonnes (% de valeurs manquantes)115        116    Returns:117        pd.DataFrame: Dataset avec valeurs manquantes traitées118    """119    df_clean = df.copy()120    121    # Colonnes avec trop de valeurs manquantes122    missing_pct = df_clean.isnull().sum() / len(df_clean)123    cols_to_drop = missing_pct[missing_pct > threshold].index.tolist()124    125    if cols_to_drop:126        print(f"⚠️  Suppression de {len(cols_to_drop)} colonnes avec >{threshold*100}% de valeurs manquantes:")127        print(cols_to_drop)128        df_clean = df_clean.drop(columns=cols_to_drop)129    130    # Imputation pour les colonnes restantes131    if strategy == 'auto':132        # Colonnes numériques : médiane133        numeric_cols = df_clean.select_dtypes(include=[np.number]).columns134        if len(numeric_cols) > 0:135            imputer_num = SimpleImputer(strategy='median')136            df_clean[numeric_cols] = imputer_num.fit_transform(df_clean[numeric_cols])137        138        # Colonnes catégorielles : mode139        cat_cols = df_clean.select_dtypes(include=['object', 'category']).columns140        if len(cat_cols) > 0:141            imputer_cat = SimpleImputer(strategy='most_frequent')142            df_clean[cat_cols] = imputer_cat.fit_transform(df_clean[cat_cols])143    144    print(f"✓ Valeurs manquantes traitées. Colonnes restantes : {df_clean.shape[1]}")145    return df_clean146 147 148def encode_categorical(df, method='label', target_col=None):149    """150    Encode les variables catégorielles.151    152    Args:153        df (pd.DataFrame): Dataset154        method (str): Méthode d'encodage ('label', 'onehot')155        target_col (str): Colonne cible à ne pas encoder156        157    Returns:158        pd.DataFrame: Dataset avec variables encodées159    """160    df_encoded = df.copy()161    cat_cols = df_encoded.select_dtypes(include=['object', 'category']).columns.tolist()162    163    if target_col and target_col in cat_cols:164        cat_cols.remove(target_col)165    166    if method == 'label':167        for col in cat_cols:168            le = LabelEncoder()169            df_encoded[col] = le.fit_transform(df_encoded[col].astype(str))170        print(f"✓ {len(cat_cols)} colonnes encodées (Label Encoding)")171    172    elif method == 'onehot':173        df_encoded = pd.get_dummies(df_encoded, columns=cat_cols, drop_first=True)174        print(f"✓ {len(cat_cols)} colonnes encodées (One-Hot Encoding)")175    176    return df_encoded177 178 179def create_features(df):180    """181    Crée de nouvelles features à partir des variables existantes.182    183    Args:184        df (pd.DataFrame): Dataset185        186    Returns:187        pd.DataFrame: Dataset avec nouvelles features188    """189    df_features = df.copy()190    191    # Exemple : ajouter des features de date si présentes192    date_cols = df_features.select_dtypes(include=['datetime64']).columns193    for col in date_cols:194        df_features[f'{col}_year'] = df_features[col].dt.year195        df_features[f'{col}_month'] = df_features[col].dt.month196        df_features[f'{col}_dayofweek'] = df_features[col].dt.dayofweek197    198    print(f"✓ Features créées. Nouvelles dimensions : {df_features.shape}")199    return df_features200 201 202def scale_features(df, target_col=None):203    """204    Normalise les features numériques.205    206    Args:207        df (pd.DataFrame): Dataset208        target_col (str): Colonne cible à ne pas normaliser209        210    Returns:211        pd.DataFrame: Dataset avec features normalisées212        StandardScaler: Scaler ajusté213    """214    df_scaled = df.copy()215    numeric_cols = df_scaled.select_dtypes(include=[np.number]).columns.tolist()216    217    if target_col and target_col in numeric_cols:218        numeric_cols.remove(target_col)219    220    if len(numeric_cols) > 0:221        scaler = StandardScaler()222        df_scaled[numeric_cols] = scaler.fit_transform(df_scaled[numeric_cols])223        print(f"✓ {len(numeric_cols)} features numériques normalisées")224        return df_scaled, scaler225    226    return df_scaled, None227 228 229def save_processed_data(df, file_path):230    """231    Sauvegarde les données préparées.232    233    Args:234        df (pd.DataFrame): Dataset à sauvegarder235        file_path (str): Chemin de sauvegarde236    """237    try:238        df.to_csv(file_path, index=False)239        print(f"✓ Données sauvegardées : {file_path}")240    except Exception as e:241        print(f"❌ Erreur lors de la sauvegarde : {e}")242