from google.colab import drive
import os
drive.mount('/content/gdrive')
# Establecer ruta de acceso en dr
import os
print(os.getcwd())
os.chdir("/content/gdrive/My Drive")
Mounted at /content/gdrive /content
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
import xgboost as xgb
from sklearn.metrics import mean_squared_error
from sklearn.metrics import accuracy_score
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import RandomizedSearchCV
from sklearn.experimental import enable_halving_search_cv
from sklearn.model_selection import HalvingGridSearchCV
from sklearn.model_selection import HalvingRandomSearchCV
Datos
https://www.kaggle.com/datasets/mlg-ulb/creditcardfraudv
Contexto
Es importante que las compañías de tarjetas de crédito puedan reconocer las transacciones de tarjetas de crédito fraudulentas para que a los clientes no se les cobre por artículos que no compraron.
Contenido
El conjunto de datos contiene transacciones realizadas con tarjetas de crédito en septiembre de 2013 por titulares de tarjetas europeos.
Este conjunto de datos presenta transacciones que ocurrieron en dos días, donde tenemos 492 fraudes de 284,807 transacciones. El conjunto de datos está muy desequilibrado, la clase positiva (fraudes) representa el 0,172 % de todas las transacciones.
Contiene solo variables de entrada numéricas que son el resultado de una transformación PCA.
Desafortunadamente, debido a problemas de confidencialidad, no se pueden proporcionar las características originales ni más información general sobre los datos. Las características V1, V2, … V28 son los principales componentes obtenidos con PCA, las únicas características que no han sido transformadas con PCA son Time y Amount.
La característica Time contiene los segundos transcurridos entre cada transacción y la primera transacción en el conjunto de datos. La variable Amount es la cantidad de la transacción, esta función se puede utilizar para el aprendizaje sensible a los costos dependiente del ejemplo. Class es la variable de respuesta y toma valor 1 en caso de fraude y 0 en caso contrario.
# Lectura de DF
df=pd.read_csv('creditcard.csv')
# Vamos a eliminar la columna tiempo
df= df.drop(columns='Time')
# Estandarizamos la columna Amount
df['Amount']=(df['Amount']- np.mean(df['Amount']))/np.std(df.Amount)
df.head()
# El problema es muy desbalanceado tranajaremos con una muestra para resolver el problema
df_ones=df[df['Class']==1] # Filtro de caracteristica
print(df_ones.shape)
df_zeros=df[df['Class']==0] # Filtro de NO caracteristica
df_zeros= df_zeros.sample(3*df_ones.shape[0]) # Tamaño de muestra 3 veces el de la caracteristica
print(df_zeros.shape)
# Concatenar
df_final=pd.DataFrame(np.concatenate([df_ones, df_zeros],axis=0), columns=df.columns)
print(df_final.shape)
df_final.head()
(492, 30) (1476, 30) (1968, 30)
V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 | ... | V21 | V22 | V23 | V24 | V25 | V26 | V27 | V28 | Amount | Class | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | -2.312227 | 1.951992 | -1.609851 | 3.997906 | -0.522188 | -1.426545 | -2.537387 | 1.391657 | -2.770089 | -2.772272 | ... | 0.517232 | -0.035049 | -0.465211 | 0.320198 | 0.044519 | 0.177840 | 0.261145 | -0.143276 | -0.353229 | 1.0 |
1 | -3.043541 | -3.157307 | 1.088463 | 2.288644 | 1.359805 | -1.064823 | 0.325574 | -0.067794 | -0.270953 | -0.838587 | ... | 0.661696 | 0.435477 | 1.375966 | -0.293803 | 0.279798 | -0.145362 | -0.252773 | 0.035764 | 1.761758 | 1.0 |
2 | -2.303350 | 1.759247 | -0.359745 | 2.330243 | -0.821628 | -0.075788 | 0.562320 | -0.399147 | -0.238253 | -1.525412 | ... | -0.294166 | -0.932391 | 0.172726 | -0.087330 | -0.156114 | -0.542628 | 0.039566 | -0.153029 | 0.606031 | 1.0 |
3 | -4.397974 | 1.358367 | -2.592844 | 2.679787 | -1.128131 | -1.706536 | -3.496197 | -0.248778 | -0.247768 | -4.801637 | ... | 0.573574 | 0.176968 | -0.436207 | -0.053502 | 0.252405 | -0.657488 | -0.827136 | 0.849573 | -0.117342 | 1.0 |
4 | 1.234235 | 3.019740 | -4.304597 | 4.732795 | 3.624201 | -1.357746 | 1.713445 | -0.496358 | -1.282858 | -2.447469 | ... | -0.379068 | -0.704181 | -0.656805 | -1.632653 | 1.488901 | 0.566797 | -0.010016 | 0.146793 | -0.349231 | 1.0 |
5 rows × 30 columns
df_final.shape
(1968, 30)
df_final.isnull().sum()
V1 0 V2 0 V3 0 V4 0 V5 0 V6 0 V7 0 V8 0 V9 0 V10 0 V11 0 V12 0 V13 0 V14 0 V15 0 V16 0 V17 0 V18 0 V19 0 V20 0 V21 0 V22 0 V23 0 V24 0 V25 0 V26 0 V27 0 V28 0 Amount 0 Class 0 dtype: int64
# Separar en X y y
y= df_final.Class
X= df_final.drop(columns='Class', axis=1)
print(X.shape, y.shape)
(1968, 29) (1968,)
# Separar en train y test
X_train,X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
print(X_train.shape, X_test.shape)
(1377, 29) (591, 29)
model= xgb.XGBClassifier(learning_rate=0.001)
# Lista de hiperparametros
params_1 = {'criterion': 'gini', 'splitter': 'best', 'max_depth': 5}
params_2 = {'criterion': 'entropy', 'splitter': 'random', 'max_depth': 7}
params_3 = {'criterion': 'gini', 'splitter': 'random', 'max_depth': 10}
# Modelo 1
model.set_params(**params_1).fit(X_train, y_train)
print(f'Accuracy para Modelo 1 = {round(accuracy_score(y_test, model.predict(X_test)), 5)}')
# Modelo 2
model.set_params(**params_2).fit(X_train, y_train)
print(f'Accuracy para Modelo 2 = {round(accuracy_score(y_test, model.predict(X_test)), 5)}')
# Modelo 3
model.set_params(**params_3).fit(X_train, y_train)
print(f'Accuracy para Modelo 3 = {round(accuracy_score(y_test, model.predict(X_test)), 5)}')
Accuracy para Modelo 1 = 0.95431 Accuracy para Modelo 2 = 0.95431 Accuracy para Modelo 3 = 0.94924
params_grid = {
'min_child_weight': [1, 5, 10],
'gamma': [0.5, 1, 1.5, 2, 5],
'subsample': [0.6, 0.8, 1.0],
'colsample_bytree': [0.6, 0.8, 1.0],
'max_depth': [5,6,7],
'criterion':['entropy','gini']
}
# tiempo de ejecucuon 424 seg
grid_cv = GridSearchCV(model, params_grid, scoring="accuracy", n_jobs=-1, cv=3)
grid_cv.fit(X_train, y_train)
print("Mejores Parametros", grid_cv.best_params_)
print("Mejor CV score", grid_cv.best_score_)
print(f'Accuracy del modelo = {round(accuracy_score(y_test, grid_cv.predict(X_test)), 5)}')
Mejores Parametros {'colsample_bytree': 0.6, 'criterion': 'entropy', 'gamma': 0.5, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 1.0} Mejor CV score 0.9600580973129992 Accuracy del modelo = 0.96277
# tiempo de ejecucuon 7 seg
grid_cv = RandomizedSearchCV(model, params_grid, scoring="accuracy", n_jobs=-1, cv=3)
grid_cv.fit(X_train, y_train)
print("Mejores parametros", grid_cv.best_params_)
print("Mejor score de CV", grid_cv.best_score_)
print(f'Accuracy del modelo = {round(accuracy_score(y_test, grid_cv.predict(X_test)), 5)}')
Mejores parametros {'subsample': 0.8, 'min_child_weight': 5, 'max_depth': 5, 'gamma': 2, 'criterion': 'gini', 'colsample_bytree': 0.6} Mejor score de CV 0.9578794480755265 Accuracy del modelo = 0.95939
# tiempo de ejecucuon 125 seg
halving_cv = HalvingGridSearchCV(model, params_grid, scoring="accuracy", factor=3)
halving_cv.fit(X_train, y_train)
print("Mejores parametros", halving_cv.best_params_)
print("Mejor Score CV", halving_cv.best_score_)
print(f'Accuracy del modelo = {round(accuracy_score(y_test, halving_cv.predict(X_test)), 5)}')
Mejores parametros {'colsample_bytree': 0.6, 'criterion': 'gini', 'gamma': 2, 'max_depth': 5, 'min_child_weight': 1, 'subsample': 0.8} Mejor Score CV 0.9702319141571479 Accuracy del modelo = 0.96616
# tiempo de ejecucuon 13 seg
halving_cv = HalvingRandomSearchCV(model, params_grid, scoring="accuracy", factor=3)
halving_cv.fit(X_train, y_train)
print("Mejores parametros", halving_cv.best_params_)
print("Mejor CV score", halving_cv.best_score_)
print(f'Accuracy del modelo = {round(accuracy_score(y_test, halving_cv.predict(X_test)), 5)}')
Mejores parametros {'subsample': 0.8, 'min_child_weight': 1, 'max_depth': 7, 'gamma': 1, 'criterion': 'entropy', 'colsample_bytree': 0.6} Mejor CV score 0.9516787815853236 Accuracy del modelo = 0.96616