TP3 Payment Fraud

This commit is contained in:
valentin 2020-04-08 18:32:34 +02:00
parent 0cfe0822aa
commit 388ac8ec41
3 changed files with 39452 additions and 2 deletions

View File

@ -205,9 +205,40 @@ lin_rmse_scores = np.sqrt(-score)
print("CV Scores Mean [lin_reg]: ", lin_rmse_scores.mean()) print("CV Scores Mean [lin_reg]: ", lin_rmse_scores.mean())
# ---- CV Score over forest_reg ---- # ---- CV Score over forest_reg ----
forest_reg = RandomForestRegressor() forest_reg = RandomForestRegressor(n_jobs=-1)
#forest_reg = RandomForestRegressor()
print("Training model [...]")
forest_reg.fit(housing_prepared, housing_labels) forest_reg.fit(housing_prepared, housing_labels)
print("Training model [DONE]")
score = cross_val_score(forest_reg, housing_prepared, housing_labels, scoring="neg_mean_squared_error", cv=10)
print("Testing model [...]")
score = cross_val_score(forest_reg, housing_prepared, housing_labels, scoring="neg_mean_squared_error", cv=10, n_jobs=-1)
#score = cross_val_score(forest_reg, housing_prepared, housing_labels, scoring="neg_mean_squared_error", cv=10)
print("Testing model [DONE]")
print("--- Scores on Validation set --- ")
forest_rmse_scores = np.sqrt(-score) forest_rmse_scores = np.sqrt(-score)
print("CV Scores Mean [forest_reg]: ", forest_rmse_scores.mean()) print("CV Scores Mean [forest_reg]: ", forest_rmse_scores.mean())
print("CV Scores Standard deviation [forest_reg]: ", forest_rmse_scores.std())
housing_predictions = forest_reg.predict(housing_prepared)
forest_mse = mean_squared_error(housing_labels, housing_predictions)
forest_rmse = np.sqrt(forest_mse)
print("Error rate [forest_reg] (less is best): ", forest_rmse)
print("Predictions: ", forest_reg.predict(some_data_prepared))
print("Labels: ", list(some_labels))
# ============== TestSet ============
print("=========== TestSet ===========")
X_test = strat_test_set.drop("median_house_value", axis=1)
y_test = strat_test_set["median_house_value"].copy()
X_test_prepared = full_pipeline.transform(X_test)
X_test_prepared_5 = full_pipeline.transform(X_test.iloc[:5])
y_test_5 = y_test.iloc[:5]
final_prediction = forest_reg.predict(X_test_prepared)
final_mse = mean_squared_error(y_test, final_prediction)
final_rmse = np.sqrt(final_mse)
print("Final Error rate (less is best): ", final_rmse)
print("Predictions: ", forest_reg.predict(X_test_prepared_5))
print("Labels: ", list(y_test_5))

197
tp3_ex_fraud/main.py Normal file
View File

@ -0,0 +1,197 @@
# === Imports ===
# - La base -
import pandas as pd
import numpy as np
# - Pour le plot
import matplotlib.pyplot as plt
# - Pour la séparation train/test stratifiée
from sklearn.model_selection import StratifiedShuffleSplit
# - Pour le OneHotEncoder (categories) -
from sklearn.preprocessing import OneHotEncoder
# - Pour le pipeline et le std-scaler -
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
# - Pour le ColumnTransformer (fullPipeline) -
from sklearn.compose import ColumnTransformer
# - Pour les modèles -
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsRegressor
# - Pour la mesure d'erreur sur la prediction -
from sklearn.metrics import mean_squared_error
# =-=-=-=-=-=-= Récupération du dataset =-=-=-=-=-=-=
payment = pd.read_csv('payment_fraud.csv',delimiter=',')
# =-=-=-=-=-=-=-= Comprendre la structure du dataset =-=-=-=-=-=-=
# - Affichage des cinq premiers exemples d'entrainement -
print("\n - Payment Head - ")
print(payment.head())
# - Informations sur le dataset -
print("\n - Payment Info - ")
payment.info()
# -> Le dataset comporte 39 221 lignes
# -> Il va falloir faire attention au feature 'paymentMethod' qui est un objet
# -> Le reste des features sont soit des int soit des float
# -> Mais pas de valeurs nulles
# - A quoi resemble le feature 'paymentMethod' -
print("\n - paymentMethod Sample - ")
print(payment['paymentMethod'].sample(10))
# - Nombre d'occurences 'paymentMethod' -
print("\n - paymentMethod ValueCounts - ")
print(payment['paymentMethod'].value_counts())
# -> Visiblement nous sommes face à des catégorires
# - Distribution Statistique -
print("\n - Payment Describe - ")
print(payment.describe())
# -> Ici je remarque 2 choses:
# -> 1 - Les labels de fraudes effectives représentent seulement moins de 25% du dataset
# -> 2 - Plusieurs valeurs sont très inégales aux quartiles (numItem max 29 pour +75% à 1), (paymentMethodAgeDays max 1999.58 pour +50% à 0 et 25% à 87.5)
# -> Il faudrait vérifier s'il s'agit que d'une seule valeur à chaque fois qui perturbe le dataset ou si elles sont plusieurs à s'écarter du reste du dataset
# - Analyse de la distribution (Histogramme) -
payment.hist(bins=50, figsize=(20,15))
# - Uncomment the next line to display the graph -
#plt.show()
# -> Grace aux histogrammes, on peut voir qu'il n'y a pas qu'une valeur à 1999.58 mais bien une fine population
# -- qui part de 0 pour aller s'écraser vers 2000. Avec tout de même un grand pique en 0 qui monte à plus de 25 000 de population
# -> Concernant le feature 'numItem' c'est pareil, il y a quelques valeurs qui tentent de se rapprocher de 29 avec tout de même
# -- une grande concentration autour de 1.
# =-=-=-=-=-=-= Création de l'ensemble d'entrainement et de test =-=-=-=-=-=-=
# -> Ici test_size représente la proportion du dataset consacrée au set d'entrainement.
# -> Et random_state représente la graine de séparation "aléatoire". Cela nous permet d'avoir
# -- toujours la même répartition si l'on utilise la même graine.
# -> Nous allons séparer notre en dataset en Train_Set et Test_Set. Mais nous allons
# -- directement procéder à une séparation stratifiée afin d'obtenir une proportion
# -- équivalente de paiements frauduleux et légitimes.
split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
for train_index, test_index in split.split(payment, payment['label']):
strat_train_set = payment.loc[train_index]
strat_test_set = payment.loc[test_index]
# =-=-=-=-=-=-= Analyse de la corrélation des données =-=-=-=-=-=-=-=
corr_matrix = payment.corr()
print("\n - Payment Correlation Matrix - ")
print(corr_matrix["label"].sort_values(ascending=False))
# =-=-=-=-=-=-= Selection des features =-=-=-=-=-=-=
# -> Nous sommes en présence d'un dataset qui ne compte que 5 features
# -> On va garder tous les features car nous n'en avons pas beaucoup
# =-=-=-=-=-=-= Extraction des Labels =-=-=-=-=-=-=
payment = strat_train_set.drop("label", axis=1)
labels = strat_train_set['label'].copy()
# =-=-=-=-=-=-= Nettoyage du dataset =-=-=-=-=-=-=
# - Verification de la présence potentielle de valeurs nulles -
print("\n - Valeurs nulles ? - ")
print(payment.isnull().sum())
# -> Toutes les valeurs sont nulles, on continue
# - On ne va pas faire d'imputer car nous n'avons pas de valeurs manquantes -
# =-=-=-=-=-=-= Attribut sous forme de catégorie =-=-=-=-=-=-=
payment_cat = payment[['paymentMethod']]
cat_encoder = OneHotEncoder()
payment_cat_1hot = cat_encoder.fit_transform(payment_cat)
# =-=-=-=-=-=-= Transformation en Pipelines =-=-=-=-=-=-=
# - On ne va pas mettre d'imputer dans le pipeline car on ne s'en est pas servi -
num_pipeline = Pipeline([
('std_scaler', StandardScaler()),
])
payment_num = payment.drop("paymentMethod", axis=1)
payment_num_tr = num_pipeline.fit_transform(payment_num)
num_attribs = list(payment_num)
cat_attribs = ["paymentMethod"]
full_pipeline = ColumnTransformer([
("num", num_pipeline, num_attribs),
("cat", OneHotEncoder(), cat_attribs),
])
payment_prepared = full_pipeline.fit_transform(payment)
# =-=-=-=-=-=-= Entraînement et évaluation sur l'ensemble d'entraînement =-=-=-=-=-=-=
# - Entrainement 1 (LogisticRegressor) -
log_reg = LogisticRegression()
log_reg.fit(payment_prepared, labels)
# - Prediction -
print("\n - Prediction on some data - ")
some_data = payment.iloc[:5]
some_labels = labels.iloc[:5]
some_data_prepared = full_pipeline.transform(some_data)
print("Predictions:", log_reg.predict(some_data_prepared))
print("Real values:", some_labels)
print("\n - Mesure d'erreur sur la prediction (Train_Set) [LogisticRegressor] -")
payment_predictions = log_reg.predict(payment_prepared)
log_mse = mean_squared_error(labels, payment_predictions)
log_rmse = np.sqrt(log_mse)
print(log_rmse)
# - Entrainement 2 (Knn -> k-nearest neighbors) -
knn_reg = KNeighborsRegressor()
knn_reg.fit(payment_prepared, labels)
# - Prediction -
print("\n - Prediction on some data - ")
some_data = payment.iloc[:5]
some_labels = labels.iloc[:5]
some_data_prepared = full_pipeline.transform(some_data)
print("Predictions:", knn_reg.predict(some_data_prepared))
print("Real values:", some_labels)
print("\n - Mesure d'erreur sur la prediction (Train_set) [KnnRegressor] -")
payment_predictions = knn_reg.predict(payment_prepared)
knn_mse = mean_squared_error(labels, payment_predictions)
knn_rmse = np.sqrt(knn_mse)
print(knn_rmse)
# -> On obtient de meilleurs résultats avec Knn, on va tout de même vérifier que l'on n'est pas face à de l'overfitting
# =-=-=-=-=-=-= Evaluation du modèle sur le Test_Set =-=-=-=-=-=-=
# Ensemble de test
X_test = strat_test_set.drop("label", axis=1)
# Les étiquettes
y_test = strat_test_set["label"].copy()
X_test_prepared = full_pipeline.transform(X_test)
# - Mesure de performance sur le Test_Set -
print("\n - Mesure d'erreur sur la prediction (Test_Set) [LogisticRegressor] -")
payment_predictions = log_reg.predict(X_test_prepared)
log_mse = mean_squared_error(y_test, payment_predictions)
log_rmse = np.sqrt(log_mse)
print(log_rmse)
print("\n - Mesure d'erreur sur la prediction (Test_Set) [KnnRegressor] -")
payment_predictions = knn_reg.predict(X_test_prepared)
knn_mse = mean_squared_error(y_test, payment_predictions)
knn_rmse = np.sqrt(knn_mse)
print(knn_rmse)
# -> Visiblement nous ne sommes pas face à de l'overfitting, en effet les scores sont proches de ceux
# -- obtenus avec le Train_Set. Ils sont certes légèrement moins satisfaisants mais restent respectables.
# -> Je confirme les meilleurs résultats en utilisant le modèle basé sur l'algorithme Knn.

39222
tp3_ex_fraud/payment_fraud.csv Normal file

File diff suppressed because it is too large Load Diff