Estás leyendo la publicación: Random_Forest_Medium_Article – Hacia la IA
Publicado originalmente en Hacia la IA, la empresa líder mundial en noticias y medios de IA y tecnología. Si está creando un producto o servicio relacionado con la IA, lo invitamos a considerar convertirse en patrocinador de la IA. En Hacia la IA, ayudamos a escalar las empresas emergentes de IA y tecnología. Permítanos ayudarlo a dar rienda suelta a su tecnología a las masas.
Modelado de incumplimiento crediticio mediante árboles de decisión
Detección de la solvencia mediante técnicas basadas en árboles
Históricamente, los algoritmos de aprendizaje automático se han utilizado en el espacio de crédito y fraude. Con el aumento en el poder computacional, la industria ha pasado de modelos Logit basados en árboles a técnicas de aprendizaje automático más avanzadas que involucran embolsado y potenciación. industria. El artículo está diseñado para proporcionar a los lectores una visión matemática de los árboles de decisión, el embolsado y los algoritmos de bosques aleatorios. En la sección final, el escritor analiza cómo usar estas técnicas para la prevención de incumplimiento crediticio y fraude utilizando datos de LendingClub.
Árboles de decisión
1. Introducción
La intuición básica detrás de los árboles de decisión es mapear todas las rutas de decisión posibles en forma de un árbol binario. Mostrando lo mismo con el ejemplo de identificar el tipo de flor (y) usando la relación entre la longitud y el ancho del sépalo (x1) y la relación entre la longitud y el ancho del pétalo (x2)
La división inicial en x1>1.7 ayuda a identificar el tipo de flor y=1
La siguiente división del nodo en x2>2.8 ayuda a identificar y=2 e y=3
Matemáticamente, un Árbol de decisión entradas de mapas x ∈ R^d a la salida y usando reglas de decisión binarias:
Cada nodo en el árbol tiene una regla de división
- División basada en el algoritmo codicioso de arriba hacia abajo
- Cada nodo hoja está asociado con un valor de salida
Cada regla de división es de la forma
2. Criterios de división
3. Vista geométrica
Motivación :
- Particionar el espacio para que los datos en una región tengan la misma predicción
- Cada partición representa una línea vertical u horizontal en el plano 2-D
4. Desafíos
- Los árboles de decisión no pueden extrapolarse
- Alta Varianza o Inestabilidad al cambio en los datos: Por cambio menor en los datos vemos la variación en la Estructura del Árbol de Decisión
- La razón de la alta varianza en los árboles de decisión radica en el hecho de que se basan en un algoritmo codicioso. Se enfoca en optimizar para la división de nodos en cuestión, en lugar de tener en cuenta cómo esa división afecta a todo el árbol. Un enfoque codicioso hace que los árboles de decisión se ejecuten más rápido pero los hace propensos a sobreajuste.
En las próximas secciones, discutiremos cómo superar estos desafíos.
Agregador Bootstrap
1. Motivación
2. Algoritmo
Bosque aleatorio
1. Motivación
2. Algoritmo
Otra ventaja de Random Forest es que no requiere un conjunto de datos reservado y, por lo tanto, puede funcionar de manera efectiva en conjuntos de datos más pequeños. En lugar de errores de prueba, podemos calcular errores fuera de bolsa (OOB). El marco para esto se muestra a continuación:
3. Error de bolsa agotada
Laboratorio Jupyter
Aquí exploramos datos de LendingClub.com
Dados muchos factores diferentes, incluido el puntaje FICO del prestatario, la tasa de interés e incluso el propósito del préstamo, intentamos hacer predicciones sobre si un préstamo en particular se pagará en su totalidad.
¿Por qué árboles de decisión/bosques aleatorios?
Los árboles de decisión son una gran técnica de ML “aproximada y lista” que se puede aplicar a muchos escenarios diferentes. Son intuitivos, rápidos y pueden tratar tanto datos numéricos como categóricos. El mayor inconveniente de los árboles de decisión es su tendencia a sobreajustar los datos dados, lo que genera errores en la varianza o el sesgo. Los bosques aleatorios combaten este problema empleando muchos árboles de decisión diferentes en muestras aleatorias de los datos y, por lo tanto, suelen ser una opción más sensata al elegir un modelo de ML.
Importaciones
importar pandas como pd
importar numpy como np
importar seaborn como sns
importar matplotlib.pyplot como plt
% matplotlib en línea
Análisis exploratorio
préstamos = pd.read_csv(‘loan_data.csv’) préstamos.head()
La columna ‘no.totalmente.pagada’ es la que nos interesa predecir.
préstamos.info()
RangeIndex: 9578 entradas, 0 a 9577
Columnas de datos (total 14 columnas):
# Columna Recuento no nulo Dtype
— —— ————– —–
0 credit.policy 9578 no nulo int64
1 propósito 9578 objeto no nulo
2 int.rate 9578 non-null float64
3 cuotas 9578 flotación no nula64
4 log.annual.inc 9578 no nulo float64
5 dti 9578 no nulo float64
6 fico 9578 int64 no nulo
7 días.con.cr.line 9578 non-null float64
8 revol.bal 9578 no nulo int64
9 revol.util 9578 no nulo float64
10 inq.last.6mths 9578 no nulo int64
11 delinq.2yrs 9578 no nulo int64
12 pub.rec 9578 int64 no nulo
13 no.totalmente.pagado 9578 no nulo int64
tipos de datos: float64(6), int64(7), objeto(1)
uso de memoria: 1.0+ MB préstamos.describe()
Algunas columnas Información
- credit.policy: 1 si el cliente cumple con los criterios de suscripción de crédito de LendingClub.com y 0 en caso contrario.
- Propósito: el propósito del préstamo (toma los valores “tarjeta_de_crédito”, “consolidación_de_deuda”, “educativo”, “compra_mayor”, “pequeña_empresa” y “todo_otro”).
- int.rate: La tasa de interés del préstamo, como una proporción (una tasa del 11% se almacenaría como 0,11). A los prestatarios que LendingClub.com considera más riesgosos se les asignan tasas de interés más altas.
- cuota: Las cuotas mensuales adeudadas por el prestatario si el préstamo está financiado.
- log.annual.inc: El logaritmo natural del ingreso anual autoinformado del prestatario.
- dti: La relación deuda-ingreso del prestatario (cantidad de deuda dividida por el ingreso anual).
- fico: El puntaje de crédito FICO del prestatario.
- days.with.cr.line: El número de días que el prestatario ha tenido una línea de crédito.
- revol.bal: Saldo revolvente del prestatario (importe impago al final del ciclo de facturación de la tarjeta de crédito).
- revol.util: la tasa de utilización de la línea renovable del prestatario (la cantidad de la línea de crédito utilizada en relación con el crédito total disponible).
- inq.last.6mths: Número de consultas del prestatario por parte de los acreedores en los últimos 6 meses.
- delinq.2yrs: la cantidad de veces que el prestatario estuvo más de 30 días atrasado en un pago en los últimos 2 años.
- pub.rec: el número de registros públicos despectivos del prestatario (declaraciones de quiebra, gravámenes fiscales o sentencias).
Visualización de datos
plt.figure(figsize=(11,7))
sns.countplot(préstamos[‘purpose’]tono = préstamos[‘not.fully.paid’]) Dividimos nuestra función objetivo con respecto al propósito para el cual se tomó un préstamo. new_df = préstamos.groupby(‘propósito’)[‘not.fully.paid’].value_counts(normalizar=Verdadero)
nuevo_df = nuevo_df.mul(100).rename(‘Porcentaje’).reset_index() nuevo_df1 = nuevo_df[new_df[“not.fully.paid”]==1]new_df1=new_df1.sort_values(“Porcentaje”) g=sns.catplot(x=”propósito”, y=’Porcentaje’, kind=’barra’, data=new_df1, aspecto=2)
g.ax.set_ylim(0,30)
para p en g.ax.parches:
txt = str(p.get_height().round(1)) + ‘%’
txt_x = p.get_x()
txt_y = p.get_height()
g.ax.text(txt_x,txt_y,txt,fontsize=18,verticalalignment=’bottom’,multialignment=’right’)
Nos gustaría entender el riesgo como un porcentaje, por lo que analizamos la proporción de préstamos impagos en cada tipo de propósito sns.boxplot(data =loans, x =’purpose’, y=[‘int.rate’]).legend().set_visible(False) Dado el conocimiento del propósito de la base de riesgo, nos gustaría entender si la APR ofrecida a un cliente tiene en cuenta el propósito. df=préstamos
f,(ax1,ax2,ax3)=plt.subparcelas(1,3,tamañofig=(25,10))
sns.distplot(df[‘int.rate’]bandejas= 30,ax=ax1)
sns.boxplot(data =df, x =’credit.policy’, y= df[‘int.rate’],ax=ax2).leyenda().set_visible(Falso)
sns.boxplot(datos = df[‘int.rate’]ax=ax3)
print(“Distribución de la Tasa de Interés, Rango de la Póliza de Crédito basado en la Póliza de Crédito, Tasa de Interés General”)
Distribución de la Tasa de Interés, Rango de la Póliza de Crédito en función de la Póliza de Crédito, Tasa de Interés General
plt.figure(figsize=(10,6))
prestamos[loans[‘credit.policy’]==1][‘fico’].hist(alfa=0.5,color=’azul’,
contenedores = 30, etiqueta = ‘Crédito.Política = 1’)
prestamos[loans[‘credit.policy’]==0][‘fico’].hist(alfa=0.5,color=’rojo’,
contenedores = 30, etiqueta = ‘Crédito.Política = 0’)
plt.leyenda()
plt.xlabel(‘FICO’) Text(0.5, 0, ‘FICO’) Para comprender si la suscripción de pólizas de crédito de Lending Club tiene un límite basado en FICO para aplicar a los clientes, observamos el siguiente histograma. sns.boxplot(datos =préstamos, x =’crédito.política’, y= préstamos[‘fico’]).legend().set_visible(False) La política de crédito promueve a las personas con FICO más alto
Tracemos un gráfico de pares marinos entre los datos numéricos:
sns.pairplot(préstamos.drop([‘credit.policy’, ‘purpose’,
‘inq.last.6mths’, ‘delinq.2yrs’, ‘pub.rec’, ‘not.fully.paid’]eje=1))
Limpieza
Transformemos la columna ‘propósito’ en variables ficticias para que podamos incluirlas en nuestro análisis:
datos_finales = pd.get_dummies(préstamos,columnas = [‘purpose’]drop_first=True) final_data.head() from sklearn.model_selection import train_test_split X= final_data.drop(‘not.fully.paid’, axis=1)
y= datos_finales[‘not.fully.paid’]
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size = 0.3, random_state = 101)
Árbol de decisión:
from sklearn.tree import DecisionTreeClassifier dtree = DecisionTreeClassifier(class_weight=Ninguno, criterio=’gini’, max_ depth=Ninguno,
max_features=Ninguno, max_leaf_nodes=Ninguno,
min_impurity_decrease=0.0, min_impurity_split=Ninguno,
min_muestras_hoja=1, min_muestras_split=2,
min_weight_fraction_leaf=0.0, random_state=Ninguno,
splitter=’mejor’) dtree.fit(X_tren, y_tren) DecisionTreeClassifier() pred = dtree.predict(X_test)
Evaluación
np.array((pred==y_test)).sum() 2104 de sklearn.metrics import Classification_report, confusion_matrix print(classification_report(y_test,pred)) recuperación de precisión compatibilidad con puntaje f1
0 0,86 0,82 0,84 2431
1 0,19 0,23 0,21 443
precisión 0,73 2874
promedio macro 0.52 0.53 0.53 2874
promedio ponderado 0,75 0,73 0,74 2874
imprimir (confusion_matrix (y_test, pred))
[[2000 431]
[ 339 104]]
Bosque aleatorio:
from sklearn.ensemble import RandomForestClassifier dfor = RandomForestClassifier() dfor.fit(X_train, y_train) RandomForestClassifier() pred2 = dfor.predict(X_test)
Evaluación
(y_test == pred2).sum() 2427
Podemos ver que esto ha hecho una mejor predicción que un solo árbol
print(classification_report(y_test,pred2)) recuperación de precisión compatibilidad con puntaje f1
0 0,85 0,99 0,92 2431
1 0,42 0,02 0,05 443
precisión 0,84 2874
promedio macro 0.64 0.51 0.48 2874
promedio ponderado 0,78 0,84 0,78 2874
imprimir (confusion_matrix (y_test, pred2))
[[2416 15]
[ 432 11]]
Ajuste de hiperparámetros ~ Bosque aleatorio
- n_estimators : Número de árboles en Random Forest
- max_features : Número máximo de características a considerar en cada división
- max_ depth : Profundidad máxima de cada estimador
- min_sample_split: muestras mínimas requeridas para división válida
- min_samples_leaf: Muestras mínimas requeridas en cada nodo hoja
de sklearn.model_selection importar RandomizedSearchCV
# Número de árboles en bosque aleatorio
n_estimadores = [int(x) for x in np.linspace(start = 200, stop = 2000, num = 10)]
# Número de características a considerar en cada división
max_features = [‘auto’, ‘sqrt’]
# Número máximo de niveles en el árbol
profundidad_máxima = [int(x) for x in np.linspace(10, 110, num = 11)]
max_ depth.append(Ninguno)
# Número mínimo de muestras requeridas para dividir un nodo
min_samples_split = [2, 5, 10]
# Número mínimo de muestras requeridas en cada nodo hoja
min_muestras_hoja = [1, 2, 4]
# Crea la grilla aleatoria
random_grid = {‘n_estimadores’: n_estimadores,
‘max_features’: max_features,
‘profundidad_máxima’: profundidad_máxima,
‘min_samples_split’: min_samples_split,
‘min_samples_leaf’: min_samples_leaf,
}
imprimir (cuadrícula_aleatoria) {‘n_estimadores’: [200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]’max_features’: [‘auto’, ‘sqrt’]’máxima profundidad’: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, None]’min_samples_split’: [2, 5, 10]’min_muestras_hoja’: [1, 2, 4]}
Validación cruzada de K-Fold
La técnica de validación cruzada (CV) se explica mejor con un ejemplo usando el método más común, K-Fold CV. Cuando abordamos un problema de aprendizaje automático, nos aseguramos de dividir nuestros datos en un conjunto de entrenamiento y otro de prueba. En K-Fold CV, dividimos aún más nuestro conjunto de entrenamiento en un número K de subconjuntos, llamados pliegues. Luego ajustamos iterativamente el modelo K veces, cada vez entrenando los datos en K-1 de los pliegues y evaluando en el K-ésimo pliegue (llamado datos de validación).
# Use la cuadrícula aleatoria para buscar los mejores hiperparámetros
# Primero cree el modelo base para ajustar
rf = ClasificadorBosqueAleatorio()
# Búsqueda aleatoria de parámetros, usando validación cruzada de 3 veces,
# busque en 100 combinaciones diferentes y use todos los núcleos disponibles
rf_random = RandomizedSearchCV(estimador = rf, param_distributions = random_grid, n_iter = 100, cv = 3, detallado=2, random_state=42, n_jobs = -1)
# Ajustar el modelo de búsqueda aleatoria
rf_random.fit(X_train, y_train) Ajuste de 3 pliegues para cada uno de los 100 candidatos, con un total de 300 ajustes
RandomizedSearchCV(cv=3, estimador=RandomForestClassifier(), n_iter=100, n_jobs=-1,
param_distributions={‘máx_profundidad’: [10, 20, 30, 40, 50, 60,
70, 80, 90, 100, 110,None]’max_features’: [‘auto’, ‘sqrt’],
‘min_samples_leaf’: [1, 2, 4],
‘min_samples_split’: [2, 5, 10],
‘n_estimadores’: [200, 400, 600, 800,1000, 1200, 1400, 1600,
1800, 2000]}, estado_aleatorio=42, detallado=2)
rf_random.best_params_ {‘n_estimadores’: 200,
‘min_samples_split’: 10,
‘min_samples_leaf’: 2,
‘max_features’: ‘raíz cuadrada’,
‘profundidad_máxima’: 110}
Referencias
- https://www.kaggle.com/bdmj12/random-forest-lendingclub-project/notebook
- https://www.kaggle.com/megr25/lending-club-decision-tree-and-random-forest
- https://www.kaggle.com/megr25/lending-club-loans/version/1
- http://www.cs.columbia.edu/~amueller/comsw4995s18/schedule/
- https://medium.com/@appaloosastore/string-similarity-algorithms-compared-3f7b4d12f0ff
- https://stanford.edu/~shervine/teaching/cs-229/cheatsheet-deep-learning
- https://towardsdatascience.com/random-forests-algorithm-explained-with-a-real-life-example-and-some-python-code-affbfa5a942c
- https://www.kdnuggets.com/2017/08/machine-learning-abstracts-decision-trees.html
- Clements, JM, Xu, D., Yousefi, N. y Efimov, D. Aprendizaje profundo secuencial para el seguimiento del riesgo crediticio con datos financieros tabulares. preimpresión de arXiv arXiv:2012.15330, 2020
Random_Forest_Medium_Article se publicó originalmente en Hacia la IA en Medium, donde las personas continúan la conversación destacando y respondiendo a esta historia.
Publicado a través de Hacia la IA