# Librerias
import pandas as pd # Manejo de DataFrame
import matplotlib.pyplot as plt # Libreria gráfica
import seaborn as sns # Libreria gráfica
import numpy as np # Libreria de algebra lineal
import pylab as pl # Módulo que proporciona un espacio de nombres similar a Matlab
from sklearn import metrics # Validar nuestro metodo
from sklearn.model_selection import train_test_split # Entrenar y divir la información
from sklearn.tree import DecisionTreeClassifier # Arboles de decisión
from sklearn.ensemble import RandomForestClassifier # Bosques aleatorios
from sklearn.linear_model import LogisticRegression # Regresión logistica
from sklearn.svm import SVC # Máquinas de vectores de soporte
# Lectura el dataset
credit_risk = pd.read_csv("/work/credit_data.csv")
# Primeras 5 filas del dataset
credit_risk.head()
Unnamed: 0int64
Ageint64
0
0
67
1
1
22
2
2
49
3
3
45
4
4
53
# ¿Que columnas tienen los datos?
credit_risk.columns
# ¿Que tamaño tiene el dataset?
credit_risk.shape
# ¿Hay datos nulos?
credit_risk.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 11 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Unnamed: 0 1000 non-null int64
1 Age 1000 non-null int64
2 Sex 1000 non-null object
3 Job 1000 non-null int64
4 Housing 1000 non-null object
5 Saving accounts 817 non-null object
6 Checking account 606 non-null object
7 Credit amount 1000 non-null int64
8 Duration 1000 non-null int64
9 Purpose 1000 non-null object
10 Risk 1000 non-null object
dtypes: int64(5), object(6)
memory usage: 86.1+ KB
# ¿Como se distribuyen las variables númericas?
credit_risk.describe()
Unnamed: 0float64
Agefloat64
count
1000
1000
mean
499.5
35.546
std
288.8194361
11.37546857
min
0
19
25%
249.75
27
50%
499.5
33
75%
749.25
42
max
999
75
# ¿Como se comportan las variables categoricas?
credit_risk.describe(include="O")
Sexobject
Housingobject
count
1000
1000
unique
2
3
top
male
own
freq
690
713
credit_risk.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 11 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Unnamed: 0 1000 non-null int64
1 Age 1000 non-null int64
2 Sex 1000 non-null object
3 Job 1000 non-null int64
4 Housing 1000 non-null object
5 Saving accounts 817 non-null object
6 Checking account 606 non-null object
7 Credit amount 1000 non-null int64
8 Duration 1000 non-null int64
9 Purpose 1000 non-null object
10 Risk 1000 non-null object
dtypes: int64(5), object(6)
memory usage: 86.1+ KB
# Renombramos las columnas
credit_risk = credit_risk.rename(columns={"Age":"Edad",
"Sex":"Género",
"Job":"Trabajo",
"Housing":"Alojamiento",
"Saving accounts":"Cuentas de ahorro",
"Checking account":"Cuenta de cheques",
"Credit amount":"Monto de crédito",
"Duration":"Duración",
"Purpose":"Propósito",
"Risk":"Riesgo"})
# Observamos el cambio de nombres de las columnas
credit_risk.columns
# Procedemos a eliminar una columna
credit_risk = credit_risk.drop(["Unnamed: 0"], axis=1)
credit_risk.drop(['Género', 'Alojamiento', 'Cuentas de ahorro', 'Cuenta de cheques', 'Propósito', 'Riesgo'],axis=1).hist(bins=30, figsize=(15,15))
pl.suptitle("Histogramas para las variables númericas")
plt.show()
# Gráfica de riesgo crediticio
plt.figure(figsize=(8,5))
sns.countplot(credit_risk['Riesgo'])
plt.title("Personas con o sin riesgo crediticio")
plt.xlabel("Riesgo crediticio")
plt.show()
/shared-libs/python3.7/py/lib/python3.7/site-packages/seaborn/_decorators.py:43: FutureWarning: Pass the following variable as a keyword arg: x. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.
FutureWarning
# Riesgo en función del género
plt.figure(figsize=(8,5))
sns.histplot(data = credit_risk, x = "Riesgo",
hue = "Género", palette = "rocket", multiple = "dodge")
plt.title("Riesgo en función del género")
plt.xlabel("Riesgo crediticio")
plt.show()
# Riesgo en función de la cantidad de trabajos
plt.figure(figsize=(8,5))
sns.histplot(data = credit_risk, x = "Riesgo",
hue = "Trabajo", palette = "Set2", multiple = "dodge")
plt.title("Riesgo en función de la cantidad de trabajos")
plt.xlabel("Riesgo crediticio")
plt.show()
# Riesgo en función del tipo de alojamiento
plt.figure(figsize=(8,5))
sns.histplot(data = credit_risk, x = "Riesgo",
hue = "Alojamiento", palette = "viridis", multiple = "dodge")
plt.title("Riesgo en función del tipo de alojamiento")
plt.xlabel("Riesgo crediticio")
plt.show()
# Riesgo en función de cuentas de ahorro
plt.figure(figsize=(8,5))
sns.histplot(data = credit_risk, x = "Riesgo",
hue = "Cuentas de ahorro", palette = "cubehelix", multiple = "dodge")
plt.title("Riesgo en función de cuentas de ahorro")
plt.xlabel("Riesgo crediticio")
plt.show()
# Riesgo en función de cuenta de cheques
plt.figure(figsize=(8,5))
sns.histplot(data = credit_risk, x = "Riesgo",
hue = "Cuenta de cheques", palette = "dark:salmon_r", multiple = "dodge")
plt.title("Riesgo en función de cuenta de cheques")
plt.xlabel("Riesgo crediticio")
plt.show()
# Riesgo en función del proposito del credito
plt.figure(figsize=(8,5))
sns.histplot(data = credit_risk, x = "Riesgo",
hue = "Propósito", palette = "icefire", multiple = "dodge")
plt.title("Riesgo en función del proposito del credito")
plt.xlabel("Riesgo crediticio")
plt.show()
credit_risk.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 10 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Edad 1000 non-null int64
1 Género 1000 non-null object
2 Trabajo 1000 non-null int64
3 Alojamiento 1000 non-null object
4 Cuentas de ahorro 817 non-null object
5 Cuenta de cheques 606 non-null object
6 Monto de crédito 1000 non-null int64
7 Duración 1000 non-null int64
8 Propósito 1000 non-null object
9 Riesgo 1000 non-null object
dtypes: int64(4), object(6)
memory usage: 78.2+ KB
# Observamos los valores unicos de las variables
print("Edad: ", credit_risk['Edad'].unique())
print("Género: ", credit_risk["Género"].unique())
print("Trabajo: ",credit_risk["Trabajo"].unique())
print("Alojamiento: ",credit_risk["Alojamiento"].unique())
print("Cuentas de ahorro: ",credit_risk["Cuentas de ahorro"].unique())
print("Cuenta de cheques: ",credit_risk["Cuenta de cheques"].unique())
print("Duración: ",credit_risk["Duración"].unique())
print("Propósito: ",credit_risk["Propósito"].unique())
print("Riesgo: ",credit_risk["Riesgo"].unique())
Edad: [67 22 49 45 53 35 61 28 25 24 60 32 44 31 48 26 36 39 42 34 63 27 30 57
33 37 58 23 29 52 50 46 51 41 40 66 47 56 54 20 21 38 70 65 74 68 43 55
64 75 19 62 59]
Género: ['male' 'female']
Trabajo: [2 1 3 0]
Alojamiento: ['own' 'free' 'rent']
Cuentas de ahorro: [nan 'little' 'quite rich' 'rich' 'moderate']
Cuenta de cheques: ['little' 'moderate' nan 'rich']
Duración: [ 6 48 12 42 24 36 30 15 9 10 7 60 18 45 11 27 8 54 20 14 33 21 16 4
47 13 22 39 28 5 26 72 40]
Propósito: ['radio/TV' 'education' 'furniture/equipment' 'car' 'business'
'domestic appliances' 'repairs' 'vacation/others']
Riesgo: ['good' 'bad']
# Convertimos riesgo a dummy
credit_risk["Riesgo"] = credit_risk.Riesgo.map({"bad":0,
"good":1})
# Terminamos de convertir el resto de variables categoricas a dummy
credit_risk = credit_risk.merge(pd.get_dummies(credit_risk["Género"], drop_first=True, prefix="Género"), left_index=True, right_index=True)
credit_risk = credit_risk.merge(pd.get_dummies(credit_risk["Alojamiento"], drop_first=True, prefix="Alojamiento"), left_index=True, right_index=True)
credit_risk = credit_risk.merge(pd.get_dummies(credit_risk["Cuentas de ahorro"], drop_first=True, prefix="Cuentas de ahorro"), left_index=True, right_index=True)
credit_risk = credit_risk.merge(pd.get_dummies(credit_risk["Cuenta de cheques"], drop_first=True, prefix="Cuenta de cheques"), left_index=True, right_index=True)
credit_risk = credit_risk.merge(pd.get_dummies(credit_risk["Propósito"], drop_first=True, prefix = "Propósito"),left_index=True, right_index=True)
# Observamos las variables
credit_risk.head()
Edadint64
Géneroobject
0
67
male
1
22
female
2
49
male
3
45
male
4
53
male
# Eliminamos las variables categoricas
credit_risk = credit_risk.drop(["Género",
"Alojamiento",
"Cuentas de ahorro",
"Cuenta de cheques",
"Propósito"], axis = 1)
# Obtenemos la información nuevamente de nuestras variables
credit_risk.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 20 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Edad 1000 non-null int64
1 Trabajo 1000 non-null int64
2 Monto de crédito 1000 non-null int64
3 Duración 1000 non-null int64
4 Riesgo 1000 non-null int64
5 Género_male 1000 non-null uint8
6 Alojamiento_own 1000 non-null uint8
7 Alojamiento_rent 1000 non-null uint8
8 Cuentas de ahorro_moderate 1000 non-null uint8
9 Cuentas de ahorro_quite rich 1000 non-null uint8
10 Cuentas de ahorro_rich 1000 non-null uint8
11 Cuenta de cheques_moderate 1000 non-null uint8
12 Cuenta de cheques_rich 1000 non-null uint8
13 Propósito_car 1000 non-null uint8
14 Propósito_domestic appliances 1000 non-null uint8
15 Propósito_education 1000 non-null uint8
16 Propósito_furniture/equipment 1000 non-null uint8
17 Propósito_radio/TV 1000 non-null uint8
18 Propósito_repairs 1000 non-null uint8
19 Propósito_vacation/others 1000 non-null uint8
dtypes: int64(5), uint8(15)
memory usage: 53.8 KB
# Matriz de correlación
credit_risk.corr()
Edadfloat64
-0.21262041600292306 - 1.0
Trabajofloat64
-0.09275113085259033 - 1.0
Edad
1
0.01567316007
Trabajo
0.01567316007
1
Monto de crédito
0.03271641667
0.2853853331
Duración
-0.03613637402
0.2109097349
Riesgo
0.09112740932
-0.03273500138
Género_male
0.1616941535
0.07029833765
Alojamiento_own
0.006552664341
-0.05939321467
Alojamiento_rent
-0.212620416
-0.03919515542
Cuentas de ahorro_moderate
-0.0753015368
0.004471920427
Cuentas de ahorro_quite rich
0.03098787549
-0.0374989224
# Gráfica de matriz de correlación
plt.figure(figsize=(10,6))
sns.heatmap(credit_risk.corr(), vmax = 0.9, square= True)
plt.title("Matriz de correlación de Pearson")
plt.show()
# Creamos nuestra varible dependiente y independientes
X = credit_risk.drop(["Riesgo"],axis=1) # Varibles independientes o explicativas
Y = credit_risk["Riesgo"] # Variable dependiente riesgo crediticio
# Dividimos nuestros datos
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size= 0.2, random_state= 0)
# Procedemos a aplicar nuestro algoritmo
arbol_decisión = DecisionTreeClassifier(criterion= "entropy")
arbol_decisión.fit(X_train, Y_train) # Ejecución del modelo
Y_pred_arbol = arbol_decisión.predict(X_test)
# Creamos la matriz de confusión
matriz_arbol = metrics.confusion_matrix(Y_test, Y_pred_arbol)
matriz_arbol
# Gráficamos la matriz de confusión
class_names = [0, 1]
fig, ax = plt.subplots()
tick_marks = np.arange(len(class_names))
plt.xticks(tick_marks, class_names)
plt.yticks(tick_marks, class_names)
sns.heatmap(pd.DataFrame(matriz_arbol), annot = True, cmap = "rocket", fmt = "g")
ax.xaxis.set_label_position("top")
plt.tight_layout()
plt.title("Matriz de confusión", y = 1.1)
plt.ylabel("Etiqueta actual")
plt.xlabel("Etiqueta de predicción")
# Exactitud del modelo
print("Exactitud", metrics.accuracy_score(Y_test, Y_pred_arbol))
Exactitud 0.625
# Procedemos a aplicar nuestro algoritmo
bosques_aleatorios = RandomForestClassifier(n_estimators=10, criterion="entropy")
bosques_aleatorios.fit(X_train, Y_train) # Ejecución del modelo
Y_pred_bosques = bosques_aleatorios.predict(X_test)
# Creamos la matriz de confusión
matriz_bosques = metrics.confusion_matrix(Y_test, Y_pred_bosques)
matriz_bosques
# Gráficamos la matriz de confusión
class_names = [0, 1]
fig, ax = plt.subplots()
tick_marks = np.arange(len(class_names))
plt.xticks(tick_marks, class_names)
plt.yticks(tick_marks, class_names)
sns.heatmap(pd.DataFrame(matriz_bosques), annot = True, cmap = "viridis", fmt = "g")
ax.xaxis.set_label_position("top")
plt.tight_layout()
plt.title("Matriz de confusión", y = 1.1)
plt.ylabel("Etiqueta actual")
plt.xlabel("Etiqueta de predicción")
# Exactitud del modelo
print("Exactitud", metrics.accuracy_score(Y_test, Y_pred_bosques))
Exactitud 0.7
# Procedemos aplicar nuestro algoritmo
logreg = LogisticRegression()
logreg.fit(X_train, Y_train) # Ejecución del modelo
Y_pred_log = logreg.predict(X_test)
/shared-libs/python3.7/py/lib/python3.7/site-packages/sklearn/linear_model/_logistic.py:818: ConvergenceWarning: lbfgs failed to converge (status=1):
STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.
Increase the number of iterations (max_iter) or scale the data as shown in:
https://scikit-learn.org/stable/modules/preprocessing.html
Please also refer to the documentation for alternative solver options:
https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
extra_warning_msg=_LOGISTIC_SOLVER_CONVERGENCE_MSG,
# Creamos una matriz de confusión
matriz_log = metrics.confusion_matrix(Y_test, Y_pred_log)
matriz_log
# Gráficamos la matriz de confusión
class_names = [0, 1]
fig, ax = plt.subplots()
tick_marks = np.arange(len(class_names))
plt.xticks(tick_marks, class_names)
plt.yticks(tick_marks, class_names)
sns.heatmap(pd.DataFrame(matriz_log), annot = True, cmap = "Blues_r", fmt = "g")
ax.xaxis.set_label_position("top")
plt.tight_layout()
plt.title("Matriz de confusión", y = 1.1)
plt.ylabel("Etiqueta actual")
plt.xlabel("Etiqueta de predicción")
# Exactitud del modelo
print("Exactitud", metrics.accuracy_score(Y_test, Y_pred_log))
Exactitud 0.705
# Procedemos aplicar nuestro algoritmo
vcs = SVC(kernel="linear")
vcs.fit(X_train, Y_train) # Ejecución del modelo
Y_pred_vcs = vcs.predict(X_test)
# Creamos una matriz de confusión
matriz_vcs = metrics.confusion_matrix(Y_test, Y_pred_vcs)
matriz_vcs
# Gráficamos la matriz de confusión
class_names = [0, 1]
fig, ax = plt.subplots()
tick_marks = np.arange(len(class_names))
plt.xticks(tick_marks, class_names)
plt.yticks(tick_marks, class_names)
sns.heatmap(pd.DataFrame(matriz_vcs), annot = True, cmap = "Spectral", fmt = "g")
ax.xaxis.set_label_position("top")
plt.tight_layout()
plt.title("Matriz de confusión", y = 1.1)
plt.ylabel("Etiqueta actual")
plt.xlabel("Etiqueta de predicción")
# Exactitud del modelo
print("Exactitud", metrics.accuracy_score(Y_test, Y_pred_vcs))
Exactitud 0.72