Caso práctico: ¿Usar algoritmos de aprendizaje automático para predecir si el préstamo de un usuario no cumple?

Hola a todos, recientemente circuló en Internet una captura de pantalla de "Espero retrasar la hipoteca debido a la epidemia", ¡lo que inmediatamente provocó acaloradas discusiones entre los internautas!

Los incumplimientos de pago de préstamos pueden ocurrir cuando un prestatario pide dinero prestado a un prestamista y no paga el préstamo a tiempo. Los préstamos morosos no solo se informarán al crédito, sino que también pueden correr el riesgo de ser demandados.

Con el fin de administrar y controlar mejor los riesgos, las instituciones crediticias generalmente predicen si el préstamo de un usuario no cumple con la información del usuario. Hoy usaré un conjunto de datos de ejemplo para explicar el principio de funcionamiento de la predicción del incumplimiento de un préstamo. No es fácil ser original. Si te gusta este artículo, recuerda dar me gusta, seguir, Colección, datos de la versión completa y código al final del artículo.

[Nota] Se proporciona un grupo de intercambio técnico al final del artículo.

datos

Los datos incluyen los datos demográficos de cada cliente y una variable objetivo que muestra si no pagarán sus préstamos.

Primero, importamos la biblioteca y cargamos el conjunto de datos.

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.set_theme(style = "darkgrid")
data = pd.read_csv("/kaggle/input/loan-prediction-based-on-customer-behavior/Training Data.csv")
data.head()

Explora conjuntos de datos

Primero, comencemos con la comprensión de los datos y su distribución.

rows, columns = data.shape
print('Rows:', rows)
print('Columns:', columns)

producción

Rows: 252000
Columns: 13

Vemos que los datos tienen 252000 filas y 13 características, de las cuales 12 son características de entrada y 1 es una característica de salida.

Ahora verificamos el tipo de datos y otra información.

data.info()

producción

RangeIndex: 252000 entries, 0 to 251999

Data columns (total 13 columns)
 #   Column             Non-Null Count   Dtype 
---  ------             --------------   ----- 
 0   Id                 252000 non-null  int64 
 1   Income             252000 non-null  int64 
 2   Age                252000 non-null  int64 
 3   Experience         252000 non-null  int64 
 4   Married/Single     252000 non-null  object
 5   House_Ownership    252000 non-null  object
 6   Car_Ownership      252000 non-null  object
 7   Profession         252000 non-null  object
 8   CITY               252000 non-null  object
 9   STATE              252000 non-null  object
 10  CURRENT_JOB_YRS    252000 non-null  int64 
 11  CURRENT_HOUSE_YRS  252000 non-null  int64 
 12  Risk_Flag          252000 non-null  int64 
dtypes: int64(7), object(6)
memory usage: 25.0+ MB

Vemos que la mitad de las características son numéricas y la mitad son cadenas, por lo que pueden ser características categóricas.

En ciencia de datos, los datos numéricos se denominan "datos cuantitativos" y los datos categóricos se denominan "datos cualitativos".

Verifiquemos si faltan valores en los datos.

data.isnull().sum()

producción

Id                   0
Income               0
Age                  0
Experience           0
Married/Single       0
House_Ownership      0
Car_Ownership        0
Profession           0
CITY                 0
STATE                0
CURRENT_JOB_YRS      0
CURRENT_HOUSE_YRS    0
Risk_Flag            0
dtype: int64

Revisemos los nombres de las columnas de datos.

data.columns

producción

Index(['Id', 'Income', 'Age', 'Experience', 'Married/Single',
       'House_Ownership', 'Car_Ownership', 'Profession', 'CITY', 'STATE',
       'CURRENT_JOB_YRS', 'CURRENT_HOUSE_YRS', 'Risk_Flag'],
      dtype='object')

Obtenemos los nombres de las características de los datos.

Análisis de columnas numéricas

Primero, comenzamos nuestro análisis con datos numéricos.

data.describe()

producción

Ahora, examinamos la distribución de datos.

data.hist( figsize = (22, 20) )
plt.show()



Ahora, comprobamos el recuento de la variable de destino.

data["Risk_Flag"].value_counts()

producción

0    221004
1     30996
Name: Risk_Flag, dtype: int64

Solo una pequeña fracción de la variable objetivo consiste en personas que no pagan sus préstamos.

Ahora, dibujamos el gráfico de correlación.

fig, ax = plt.subplots( figsize = (12,8) )
corr_matrix = data.corr()
corr_heatmap = sns.heatmap( corr_matrix, cmap = "flare", annot=True, ax=ax, annot_kws={
    
    "size": 14})
plt.show()

Analizar las características de la categoría

Ahora, pasamos al análisis de características categóricas.

Primero, definimos una función para crear la gráfica.

def categorical_valcount_hist(feature):
    print(data[feature].value_counts())
    fig, ax = plt.subplots( figsize = (6,6) )
    sns.countplot(x=feature, ax=ax, data=data)
    plt.show()

Primero, examinamos el número de casados ​​vs. solteros.

categorical_valcount_hist("Married/Single")

Entonces, la mayoría de las personas son solteras.

Ahora, verificamos el número de propietarios de viviendas.

categorical_valcount_hist("House_Ownership")

Ahora, vamos a comprobar el número de estados.

print( "Total categories in STATE:", len( data["STATE"].unique() ) )
print()
print( data["STATE"].value_counts() )

producción

Total categories in STATE: 29
Uttar_Pradesh        28400
Maharashtra          25562
Andhra_Pradesh       25297
West_Bengal          23483
Bihar                19780
Tamil_Nadu           16537
Madhya_Pradesh       14122
Karnataka            11855
Gujarat              11408
Rajasthan             9174
Jharkhand             8965
Haryana               7890
Telangana             7524
Assam                 7062
Kerala                5805
Delhi                 5490
Punjab                4720
Odisha                4658
Chhattisgarh          3834
Uttarakhand           1874
Jammu_and_Kashmir     1780
Puducherry            1433
Mizoram                849
Manipur                849
Himachal_Pradesh       833
Tripura                809
Uttar_Pradesh[5]       743
Chandigarh             656
Sikkim                 608
Name: STATE
dtype: int64

Ahora, comprobamos el número de profesiones.

print( "Total categories in Profession:", len( data["Profession"].unique() ) )
print()
data["Profession"].value_counts()

producción

Total categories in Profession: 51
Physician                     5957
Statistician                  5806
Web_designer                  5397
Psychologist                  5390
Computer_hardware_engineer    5372
Drafter                       5359
Magistrate                    5357
Fashion_Designer              5304
Air_traffic_controller        5281
Comedian                      5259
Industrial_Engineer           5250
Mechanical_engineer           5217
Chemical_engineer             5205
Technical_writer              5195
Hotel_Manager                 5178
Financial_Analyst             5167
Graphic_Designer              5166
Flight_attendant              5128
Biomedical_Engineer           5127
Secretary                     5061
Software_Developer            5053
Petroleum_Engineer            5041
Police_officer                5035
Computer_operator             4990
Politician                    4944
Microbiologist                4881
Technician                    4864
Artist                        4861
Lawyer                        4818
Consultant                    4808
Dentist                       4782
Scientist                     4781
Surgeon                       4772
Aviator                       4758
Technology_specialist         4737
Design_Engineer               4729
Surveyor                      4714
Geologist                     4672
Analyst                       4668
Army_officer                  4661
Architect                     4657
Chef                          4635
Librarian                     4628
Civil_engineer                4616
Designer                      4598
Economist                     4573
Firefighter                   4507
Chartered_Accountant          4493
Civil_servant                 4413
Official                      4087
Engineer                      4048
Name: Profession
dtype: int64

análisis de los datos

Ahora, comenzamos por comprender la relación entre las diferentes características de los datos.

sns.boxplot(x ="Risk_Flag",y="Income" ,data = data)


Ahora, vemos la relación entre la variable marcadora y la edad.

sns.boxplot(x ="Risk_Flag",y="Age" ,data = data)

sns.boxplot(x ="Risk_Flag",y="Experience" ,data = data)

sns.boxplot(x ="Risk_Flag",y="CURRENT_JOB_YRS" ,data = data)

sns.boxplot(x ="Risk_Flag",y="CURRENT_HOUSE_YRS" ,data = data)

fig, ax = plt.subplots( figsize = (8,6) )
sns.countplot(x='Car_Ownership', hue='Risk_Flag', ax=ax, data=data)

fig, ax = plt.subplots( figsize = (8,6) )
sns.countplot( x='Married/Single', hue='Risk_Flag', data=data )

fig, ax = plt.subplots( figsize = (10,8) )
sns.boxplot(x = "Risk_Flag", y = "CURRENT_JOB_YRS", hue='House_Ownership', data = data)

ingeniería de características

Antes del modelado, la preparación de datos es un proceso requerido en el campo de la ciencia de datos. Durante el proceso de preparación de datos, tenemos que completar varias tareas, una de estas responsabilidades clave es la codificación de datos categóricos.

Es bien sabido que la mayoría de los datos en el trabajo diario tienen valores de cadena categóricos, mientras que la mayoría de los modelos de aprendizaje automático solo se ocupan de categorías numéricas.

La codificación de datos categóricos es el proceso de convertir datos categóricos en formato entero para que los datos se puedan introducir en un modelo para mejorar la precisión de la predicción.

Aplicaremos la codificación a las características categóricas.

from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
import category_encoders as ce

label_encoder = LabelEncoder()
for col in ['Married/Single','Car_Ownership']:
    data[col] = label_encoder.fit_transform( data[col] )
onehot_encoder = OneHotEncoder(sparse = False)
data['House_Ownership'] = onehot_encoder.fit_transform(data['House_Ownership'].values.reshape(-1, 1) )

high_card_features = ['Profession', 'CITY', 'STATE']

count_encoder = ce.CountEncoder()

# Transform the features, rename the columns with the _count suffix, and join to dataframe
count_encoded = count_encoder.fit_transform( data[high_card_features] )
data = data.join(count_encoded.add_suffix("_count"))

data= data.drop(labels=['Profession', 'CITY', 'STATE'], axis=1)
data.head()


Una vez finalizada la parte de ingeniería de funciones, dividimos los datos en conjuntos de entrenamiento y prueba.

Dividir los datos en conjuntos de entrenamiento y prueba

Para evaluar la eficiencia de trabajo de nuestro modelo de aprendizaje automático, debemos dividir el conjunto de datos en conjunto de entrenamiento y conjunto de prueba. El conjunto de entrenamiento se usa para entrenar el modelo de aprendizaje automático, cuyas estadísticas se conocen, y el conjunto de datos de prueba se usa para la predicción.

x = data.drop("Risk_Flag", axis=1)
y = data["Risk_Flag"]
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2, stratify = y, random_state = 7)

Establecemos el tamaño del conjunto de prueba en el 20% de todos los datos.

Clasificador de bosque aleatorio

Los algoritmos basados ​​en árboles se utilizan ampliamente en el aprendizaje automático para hacer frente a los desafíos del aprendizaje supervisado. Estos algoritmos son adaptables y pueden resolver casi cualquier problema (clasificación o regresión).

Además, tienen predicciones altamente precisas, estables e interpretables.

Random forest es una técnica común de aprendizaje supervisado basada en árboles que se puede utilizar para resolver problemas de clasificación y regresión. Los bosques aleatorios normalmente combinan cientos de árboles de decisión y luego entrenan cada árbol de decisión en una muestra diferente de datos.

Ahora, entrenamos el modelo y realizamos predicciones.

from sklearn.ensemble import RandomForestClassifier
from imblearn.over_sampling import SMOTE
from imblearn.pipeline import Pipeline

rf_clf = RandomForestClassifier(criterion='gini', bootstrap=True, random_state=100)
smote_sampler = SMOTE(random_state=9)
pipeline = Pipeline(steps = [['smote', smote_sampler],['classifier', rf_clf]])
pipeline.fit(x_train, y_train)
y_pred = pipeline.predict(x_test)

Ahora, comprobamos la puntuación de precisión.

from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score, accuracy_score, roc_auc_score
print("-------------------------TEST SCORES-----------------------") 
print(f"Recall: {
      
       round(recall_score(y_test, y_pred)*100, 4) }")
print(f"Precision: {
      
       round(precision_score(y_test, y_pred)*100, 4) }")
print(f"F1-Score: {
      
       round(f1_score(y_test, y_pred)*100, 4) }")
print(f"Accuracy score: {
      
       round(accuracy_score(y_test, y_pred)*100, 4) }")
print(f"AUC Score: {
      
       round(roc_auc_score(y_test, y_pred)*100, 4) }")

producción

-------------------------TEST SCORES-----------------------
Recall: 54.1378
Precision: 54.3306
F1-Score: 54.234
Accuracy score: 88.7619
AUC Score: 73.8778

En conclusión

Hoy explicaré todo el proceso de predicción de la mora del préstamo de un usuario, hay algunos puntos a los que vale la pena prestar atención:

  • Cuando necesitamos resultados muy precisos y evitar el sobreajuste, los métodos de bosque aleatorio son adecuados para tareas de clasificación y regresión en conjuntos de datos con muchos elementos y características que pueden tener valores faltantes.
  • Además, Random Forest proporciona una importancia relativa de las funciones, lo que le permite seleccionar las funciones más importantes. Es más fácil de interpretar que los modelos de redes neuronales, pero más difícil de interpretar que los árboles de decisión.
  • En el caso de las características categóricas, debemos realizar la codificación para que los algoritmos de ML puedan procesarlas.
  • La predicción de la morosidad de los préstamos depende en gran medida de la demografía, ya que es más probable que las personas con ingresos más bajos no paguen sus préstamos.

adquisición de código

Responda en el fondo de la cuenta pública a continuación: Incumplimiento de crédito , se puede obtener el código de la versión completa

artículo recomendado

Intercambio de Tecnología

¡Bienvenido a reimprimir, coleccionar, dar me gusta y apoyar!

inserte la descripción de la imagen aquí

En la actualidad, se ha abierto un grupo de intercambio técnico, con más de 2000 miembros . La mejor manera de comentar al agregar es: fuente + dirección de interés, que es conveniente para encontrar amigos de ideas afines.

  • Método 1. Envíe la siguiente imagen a WeChat, mantenga presionada para identificarla y responda en segundo plano: agregar grupo;
  • Método ②, agregar microseñal: dkl88191 , nota: de CSDN
  • Método ③, cuenta pública de búsqueda de WeChat: aprendizaje de Python y extracción de datos , respuesta en segundo plano: agregar grupo

pulsación larga seguir

Supongo que te gusta

Origin blog.csdn.net/weixin_38037405/article/details/124090892
Recomendado
Clasificación