-
-
Save hdary85/36b32bc0e7bcafdbed51dc9ea35b4fe6 to your computer and use it in GitHub Desktop.
nmar
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 1. Import des librairies nécessaires | |
| import numpy as np | |
| import pandas as pd | |
| import matplotlib.pyplot as plt | |
| from matplotlib import colors | |
| from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV | |
| from sklearn.linear_model import LogisticRegression | |
| from sklearn.ensemble import RandomForestClassifier | |
| from sklearn.metrics import classification_report, confusion_matrix, roc_curve, auc | |
| from sklearn.preprocessing import StandardScaler, OneHotEncoder | |
| from sklearn.compose import ColumnTransformer | |
| from sklearn.pipeline import Pipeline | |
| # Pour afficher les graphiques dans un notebook (si besoin) | |
| %matplotlib inline | |
| # 2. Création du DataFrame avec quelques exemples | |
| data = { | |
| # Groupe 1: Informations sur l'alerte | |
| 'ALERT_ID': [1, 1, 1], | |
| 'ALERT_DATE': ['2024-02-01', '2024-02-01', '2024-02-01'], | |
| # Groupe 2: Informations sur le party_key | |
| 'PARTY_RISK': [2, 2, 2], | |
| 'PARTY_KEY': [1234, 1234, 1234], | |
| 'PARTY_POPULATION_GROUP': ['VSB', 'VSB', 'VSB'], | |
| # Groupe 3: Détails des transactions | |
| 'TRX_AMOUNT': [100, 150, 1000], | |
| 'TRX_DATE': ['2024-01-12', '2024-01-20', '2024-01-25'], | |
| 'TRX_TYPE': ['VMM', 'VNN', 'ESP'], # 'ESP' = transaction en espèces | |
| 'TRX_C_D': ['C', 'C', 'C'], | |
| # Groupe 4: Informations sur les contreparties | |
| # Pour les transactions en espèces (TRX_TYPE = 'ESP'), on mettra des NaN | |
| 'CP_PK': [432, 289, None], | |
| 'CP_RISK': [7, 5, None], | |
| 'CP_SCORE': [2345, 1243, None], | |
| # Groupe 5: Agrégations | |
| # Ici, TOTAL_CP et TOTAL_CASH représentent le total des transactions de contreparties ou en espèces | |
| # par alert et party_key. Pour les transactions en espèces, TOTAL_CP prendra la valeur totalisée | |
| # sur les autres transactions si c'est pertinent. | |
| 'NBR_CP_TRX': [2, 2, 2], # Ici, même en espèces, on peut comptabiliser le total si besoin | |
| 'NBR_CP': [2, 2, 2], | |
| 'TOTAL_CP': [250, 250, 250], | |
| 'TOTAL_CASH': [1000, 1000, 1000], | |
| # Groupe 6: ISSUE (variable cible binaire) | |
| 'ISSUE': [1, 1, 1] | |
| } | |
| df = pd.DataFrame(data) | |
| # 3. Préparation et nettoyage des données | |
| # Conversion des colonnes de date en datetime | |
| df['ALERT_DATE'] = pd.to_datetime(df['ALERT_DATE']) | |
| df['TRX_DATE'] = pd.to_datetime(df['TRX_DATE']) | |
| # Pour les transactions en espèces, s'assurer que les informations de contrepartie sont bien NaN | |
| df.loc[df['TRX_TYPE'] == 'ESP', ['CP_PK', 'CP_RISK', 'CP_SCORE']] = np.nan | |
| # Affichage des premières lignes pour vérification | |
| print("Aperçu du DataFrame:") | |
| print(df.head()) | |
| # 4. Analyse exploratoire (EDA) | |
| # Statistiques descriptives globales | |
| print("\nStatistiques descriptives globales:") | |
| print(df.describe(include='all')) | |
| # Statistiques par groupe (par exemple: par PARTY_POPULATION_GROUP) | |
| print("\nStatistiques par groupe de 'PARTY_POPULATION_GROUP':") | |
| print(df.groupby('PARTY_POPULATION_GROUP').describe()) | |
| # ----------------------- | |
| # Visualisations | |
| # ----------------------- | |
| # 4.1 Histogramme pour PARTY_RISK | |
| plt.figure(figsize=(6,4)) | |
| plt.hist(df['PARTY_RISK'], bins=range(1, 11), edgecolor='black') | |
| plt.xlabel("Niveau de risque du party") | |
| plt.ylabel("Fréquence") | |
| plt.title("Distribution du PARTY_RISK") | |
| plt.grid(True) | |
| plt.show() | |
| # 4.2 Histogramme pour CP_RISK (uniquement pour transactions avec contrepartie renseignée) | |
| plt.figure(figsize=(6,4)) | |
| plt.hist(df['CP_RISK'].dropna(), bins=range(0, 11), edgecolor='black') | |
| plt.xlabel("Niveau de risque de la contrepartie") | |
| plt.ylabel("Fréquence") | |
| plt.title("Distribution du CP_RISK") | |
| plt.grid(True) | |
| plt.show() | |
| # 4.3 Boxplot de TRX_AMOUNT selon TRX_TYPE | |
| plt.figure(figsize=(6,4)) | |
| types = df['TRX_TYPE'].unique() | |
| data_box = [df.loc[df['TRX_TYPE'] == t, 'TRX_AMOUNT'] for t in types] | |
| plt.boxplot(data_box, labels=types) | |
| plt.xlabel("Type de transaction") | |
| plt.ylabel("Montant de la transaction") | |
| plt.title("Boxplot du TRX_AMOUNT par TRX_TYPE") | |
| plt.grid(True) | |
| plt.show() | |
| # 4.4 Heatmap de corrélation entre les variables numériques | |
| # Sélection des colonnes numériques pertinentes | |
| numerical_cols = ['PARTY_RISK', 'TRX_AMOUNT', 'CP_RISK', 'CP_SCORE', 'NBR_CP_TRX', 'NBR_CP', 'TOTAL_CP', 'TOTAL_CASH', 'ISSUE'] | |
| corr = df[numerical_cols].corr() | |
| plt.figure(figsize=(8,6)) | |
| plt.imshow(corr, cmap='viridis', interpolation='none', aspect='auto') | |
| plt.colorbar() | |
| plt.xticks(range(len(numerical_cols)), numerical_cols, rotation=45, ha='right') | |
| plt.yticks(range(len(numerical_cols)), numerical_cols) | |
| plt.title("Heatmap de corrélation entre variables numériques") | |
| plt.tight_layout() | |
| plt.show() | |
| # 4.5 Scatter plot : TRX_AMOUNT vs. CP_SCORE (pour transactions avec CP_SCORE non-null) | |
| plt.figure(figsize=(6,4)) | |
| mask = df['CP_SCORE'].notnull() | |
| plt.scatter(df.loc[mask, 'TRX_AMOUNT'], df.loc[mask, 'CP_SCORE'], alpha=0.7) | |
| plt.xlabel("TRX_AMOUNT") | |
| plt.ylabel("CP_SCORE") | |
| plt.title("Scatter plot: TRX_AMOUNT vs CP_SCORE") | |
| plt.grid(True) | |
| plt.show() | |
| # ----------------------- | |
| # 5. Préparation pour le modèle prédictif | |
| # ----------------------- | |
| # Pour la prédiction, nous utiliserons les variables jugées pertinentes. | |
| # Ici, nous utilisons toutes les variables numériques et nous encodons la variable catégorielle PARTY_POPULATION_GROUP. | |
| # Nous retirons les colonnes d'identifiants ou dates qui ne servent pas directement à la prédiction. | |
| # On peut conserver : PARTY_RISK, TRX_AMOUNT, CP_RISK, CP_SCORE, NBR_CP_TRX, NBR_CP, TOTAL_CP, TOTAL_CASH | |
| # Et on encode : PARTY_POPULATION_GROUP | |
| # On peut aussi éventuellement calculer des features temporels (par exemple, délai entre ALERT_DATE et TRX_DATE) si pertinent. | |
| # Calcul d'une nouvelle feature : délai (en jours) entre ALERT_DATE et TRX_DATE | |
| df['DELAY_DAYS'] = (df['ALERT_DATE'] - df['TRX_DATE']).dt.days | |
| # Sélection des features à utiliser pour le modèle | |
| features = ['PARTY_RISK', 'TRX_AMOUNT', 'CP_RISK', 'CP_SCORE', | |
| 'NBR_CP_TRX', 'NBR_CP', 'TOTAL_CP', 'TOTAL_CASH', 'DELAY_DAYS', 'PARTY_POPULATION_GROUP'] | |
| target = 'ISSUE' | |
| # Conserver uniquement les lignes nécessaires (si des données manquent, vous pouvez aussi choisir d'imputer) | |
| df_model = df[features + [target]].copy() | |
| # Traitement des valeurs manquantes : ici nous imputons par la médiane pour les variables numériques | |
| for col in ['CP_RISK', 'CP_SCORE']: | |
| df_model[col] = df_model[col].fillna(df_model[col].median()) | |
| # Encodage de la variable catégorielle PARTY_POPULATION_GROUP | |
| # Nous utilisons OneHotEncoder pour transformer cette colonne. | |
| # Nous allons construire un pipeline pour le prétraitement. | |
| categorical_features = ['PARTY_POPULATION_GROUP'] | |
| numerical_features = [col for col in features if col not in categorical_features] | |
| preprocessor = ColumnTransformer( | |
| transformers=[ | |
| ('num', StandardScaler(), numerical_features), | |
| ('cat', OneHotEncoder(drop='first'), categorical_features) # drop_first pour éviter la redondance | |
| ]) | |
| # Séparation des données en ensembles d'entraînement et de test (70% train, 30% test) | |
| X = df_model[features] | |
| y = df_model[target] | |
| X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) | |
| # 6. Construction et évaluation des modèles | |
| # 6.1 Pipeline pour la régression logistique | |
| pipeline_lr = Pipeline(steps=[('preprocessor', preprocessor), | |
| ('classifier', LogisticRegression(max_iter=1000, random_state=42))]) | |
| # Entraînement du modèle de régression logistique | |
| pipeline_lr.fit(X_train, y_train) | |
| # Prédictions | |
| y_pred_lr = pipeline_lr.predict(X_test) | |
| print("\n--- Régression Logistique ---") | |
| print("Classification Report :") | |
| print(classification_report(y_test, y_pred_lr)) | |
| # Validation croisée (par exemple 5-fold) sur l'ensemble d'entraînement | |
| cv_scores_lr = cross_val_score(pipeline_lr, X_train, y_train, cv=5, scoring='accuracy') | |
| print("Scores de validation croisée (Logistique):", cv_scores_lr) | |
| print("Score moyen (Logistique): {:.2f}".format(cv_scores_lr.mean())) | |
| # 6.2 Pipeline pour une forêt aléatoire | |
| pipeline_rf = Pipeline(steps=[('preprocessor', preprocessor), | |
| ('classifier', RandomForestClassifier(random_state=42))]) | |
| # Entraînement du modèle forêt aléatoire | |
| pipeline_rf.fit(X_train, y_train) | |
| # Prédictions | |
| y_pred_rf = pipeline_rf.predict(X_test) | |
| print("\n--- Forêt Aléatoire ---") | |
| print("Classification Report :") | |
| print(classification_report(y_test, y_pred_rf)) | |
| # Validation croisée sur la forêt aléatoire | |
| cv_scores_rf = cross_val_score(pipeline_rf, X_train, y_train, cv=5, scoring='accuracy') | |
| print("Scores de validation croisée (RF):", cv_scores_rf) | |
| print("Score moyen (RF): {:.2f}".format(cv_scores_rf.mean())) | |
| # 6.3 Matrice de confusion et courbe ROC (pour le modèle de régression logistique) | |
| cm = confusion_matrix(y_test, y_pred_lr) | |
| plt.figure(figsize=(4,4)) | |
| plt.imshow(cm, interpolation='nearest', cmap='Blues') | |
| plt.title("Matrice de confusion - Régression Logistique") | |
| plt.colorbar() | |
| tick_marks = np.arange(2) | |
| plt.xticks(tick_marks, ['0', '1']) | |
| plt.yticks(tick_marks, ['0', '1']) | |
| plt.xlabel("Prédiction") | |
| plt.ylabel("Réalité") | |
| for i in range(2): | |
| for j in range(2): | |
| plt.text(j, i, format(cm[i, j], 'd'), | |
| horizontalalignment="center", color="red") | |
| plt.tight_layout() | |
| plt.show() | |
| # Courbe ROC | |
| y_prob_lr = pipeline_lr.predict_proba(X_test)[:, 1] | |
| fpr, tpr, thresholds = roc_curve(y_test, y_prob_lr) | |
| roc_auc = auc(fpr, tpr) | |
| plt.figure(figsize=(6,4)) | |
| plt.plot(fpr, tpr, label="AUC = {:.2f}".format(roc_auc)) | |
| plt.plot([0, 1], [0, 1], linestyle='--') | |
| plt.xlabel("Taux de faux positifs") | |
| plt.ylabel("Taux de vrais positifs") | |
| plt.title("Courbe ROC - Régression Logistique") | |
| plt.legend(loc='lower right') | |
| plt.grid(True) | |
| plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment