Desarrollo de modelo de calificación crediticia basado en Python, con datos y código

El modelo de calificación crediticia se puede representar mediante "cuatro tarjetas", que son tarjeta A (tarjeta de puntuación de aplicación, tarjeta de puntuación de aplicación), tarjeta B (tarjeta de puntuación de comportamiento, tarjeta de puntuación de comportamiento), tarjeta C (tarjeta de puntuación de colección, tarjeta de puntuación de colección) y la tarjeta F (Anti-Fraud Card, tarjeta de puntuación antifraude), que se aplica antes, durante y después del préstamo.

En este artículo, analizamos principalmente el desarrollo de modelos de calificación crediticia basados ​​en Python y adjuntamos códigos relevantes en cada parte.

Flujo del proyecto

En la Figura 1-1 se muestra un modelo típico de calificación crediticia. El principal proceso de desarrollo del modelo de calificación de riesgo de crédito es el siguiente:

1. Adquisición de datos, incluida la adquisición de datos de clientes existentes y clientes potenciales. Los clientes existentes se refieren a clientes que ya han realizado negocios relevantes; los clientes potenciales se refieren a clientes que tienen la intención de realizar negocios relevantes en el futuro.

2. Preprocesamiento de datos , las tareas principales incluyen la limpieza de datos, el procesamiento de valores faltantes y el procesamiento de valores atípicos, principalmente para convertir los datos sin procesar adquiridos en datos formateados que puedan usarse para el desarrollo del modelo.

3. Análisis exploratorio de datos.Este paso es principalmente para obtener la situación general de la muestra.Los indicadores que describen la situación general de la muestra incluyen principalmente histogramas, diagramas de caja, etc.

4. Selección de variables : este paso consiste principalmente en descartar los indicadores que tienen el impacto más significativo en el estado de incumplimiento a través de métodos estadísticos. Existen principalmente métodos de selección de características univariadas y métodos basados ​​en modelos de aprendizaje automático.

5. Desarrollo del modelo , este paso incluye principalmente segmentación de variables, transformación WOE (peso de evidencia) de variables y estimación de regresión logística.

6. Evaluación del modelo : este paso es principalmente para evaluar la capacidad del modelo para distinguir, predecir y estabilidad, y formar un informe de evaluación del modelo para sacar conclusiones sobre si el modelo se puede utilizar.

7. Puntaje crediticio, un método para determinar el puntaje crediticio basado en el coeficiente de regresión logística y WOE, etc. Convierta el modelo logístico en un formulario de puntuación estándar.

8. Establecer un sistema de calificación y establecer un sistema de calificación crediticia automático basado en el método de calificación crediticia.

formato_png 1

Figura 1-1 Proceso de desarrollo del modelo de calificación crediticia

recopilación de datos

Los datos provienen de Give Me Some Credit de Kaggle: https://www.kaggle.com/c/GiveMeSomeCredit/data, con 150.000 datos de muestra. La siguiente figura muestra la situación general de estos datos.

Los datos pertenecen a préstamos de consumo personal, sólo se deben considerar los datos que pueden ser utilizados en la implementación final del scoring crediticio, los datos deben obtenerse de los siguientes aspectos:

– Atributos básicos: incluida la edad del prestatario en ese momento.

– Solvencia de la deuda: incluyendo los ingresos mensuales del prestatario y el ratio de endeudamiento.

– Relación de crédito: 35-59 días de mora en dos años, 60-89 días de mora en dos años, 90 o más de 90 días de mora en dos años.

– Estado de la propiedad: incluye el número de créditos y préstamos abiertos, y el número de préstamos o líneas inmobiliarias.

– Atributos del préstamo: Ninguno por ahora.

– Otros factores: Se incluye el número de dependientes del prestatario (sin incluir a la propia persona).

– Ventana de tiempo: la ventana de observación de la variable independiente son los dos últimos años y la ventana de desempeño de la variable dependiente son los dos años siguientes.

formato_png 2

Figura 2-1 Variables de datos sin procesar

#

Preprocesamiento de datos

Antes del procesamiento de datos, es necesario comprender los valores faltantes y los valores atípicos de los datos. Existe una función describe() en Python, que puede comprender los valores faltantes, la media y la mediana del conjunto de datos.

 
 
  1. #载入数据
  2. data = pd.read_csv('cs-training.csv')
  3. #数据集确实和分布情况
  4. data.describe().to_csv('DataDescribe.csv')

Detalles del conjunto de datos:

formato_png 3

Figura 3-1 Detalles de variables

Como se puede ver en la figura anterior, faltan las variables MonthlyIncome y NumberOfDependents, la variable MonthlyIncome tiene un total de 29731 valores faltantes y NumberOfDependents tiene 3924 valores faltantes.

3.1 Procesamiento de valores faltantes

Esta situación es muy común en problemas prácticos, lo que conducirá a la imposibilidad de aplicar algunos métodos analíticos que no pueden abordar los valores faltantes, por lo que debemos abordar los valores faltantes en el primer paso del desarrollo del modelo de calificación de riesgo crediticio. Los métodos de procesamiento de valores perdidos incluyen los siguientes.

**1. Las muestras con valores faltantes se eliminan directamente.

2. Complete los valores faltantes según la similitud entre muestras.

3. Complete los valores faltantes en función de la correlación entre variables. **

La tasa faltante de la variable MonthlyIncome es relativamente grande, por lo que completamos los valores faltantes de acuerdo con la correlación entre las variables y utilizamos el método de bosque aleatorio:

 
 
  1. # 用随机森林对缺失值预测填充函数
  2. def set_missing(df):
  3. # 把已有的数值型特征取出来
  4. process_df = df.ix[:,[5,0,1,2,3,4,6,7,8,9]]
  5. # 分成已知该特征和未知该特征两部分
  6. known = process_df[process_df.MonthlyIncome.notnull()].as_matrix()
  7. unknown = process_df[process_df.MonthlyIncome.isnull()].as_matrix()
  8. # X为特征属性值
  9. X = known[:, 1:]
  10. # y为结果标签值
  11. y = known[:, 0]
  12. # fit到RandomForestRegressor之中
  13. rfr = RandomForestRegressor(random_state=0,
  14. n_estimators=200,max_depth=3,n_jobs=-1)
  15. rfr.fit(X,y)
  16. # 用得到的模型进行未知特征值预测
  17. predicted = rfr.predict(unknown[:, 1:]).round(0)
  18. print(predicted)
  19. # 用得到的预测结果填补原缺失数据
  20. df.loc[(df.MonthlyIncome.isnull()), 'MonthlyIncome'] = predicted
  21. return df

A la variable NumberOfDependents le faltan relativamente pocos valores y se puede eliminar directamente sin causar mucho impacto en el modelo general. Después de solucionar los valores faltantes, elimine los duplicados.

 
 
  1. data=set_missing(data)#用随机森林填补比较多的缺失值
  2. data=data.dropna()#删除比较少的缺失值
  3. data = data.drop_duplicates()#删除重复项
  4. data.to_csv('MissingData.csv',index=False)

3.2 Procesamiento de valores atípicos

Una vez procesados ​​los valores faltantes, debemos manejar los valores atípicos. Un valor atípico se refiere a un valor que se desvía significativamente de la mayoría de los datos muestreados . Por ejemplo, cuando la edad de un cliente individual es 0, este valor generalmente se considera un valor atípico. Encuentre valores atípicos en la población de muestra, generalmente utilizando el método de detección de valores atípicos.

En primer lugar, encontramos que hay 0 en la variable edad, lo que obviamente es un valor atípico y se elimina directamente:

 
 
  1. # 年龄等于0的异常值进行剔除
  2. data = data[data['age'] > 0]

Para las variables NumberOfTime30-59DaysPastDueNotWorse, NumberOfTimes90DaysLate y NumberOfTime60-89DaysPastDueNotWorse, se puede ver en el siguiente diagrama de caja Figura 3-2 que hay valores anormales y, a partir de la función única, se puede saber que hay dos valores anormales. de valor 96 y 98, por lo que fue eliminado. Al mismo tiempo, se encontrará que si se eliminan los valores 96 y 98 de una de las variables, los valores 96 y 98 de las otras variables también se eliminarán en consecuencia.

formato_png 4

Figura 3-2 Diagrama de caja

Elimine los valores atípicos de las variables NumberOfTime30-59DaysPastDueNotWorse , NumberOfTimes90DaysLate , NumberOfTime60-89DaysPastDueNotWorse . Además, en el conjunto de datos, el buen cliente es 0 y el cliente predeterminado es 1. Considerando el entendimiento normal, el cliente que normalmente puede ejecutar el contrato y pagar el interés es 1, por lo que lo invertimos.

 
 
  1. #剔除异常值
  2. data = data[data['NumberOfTime30-59DaysPastDueNotWorse'] < 90]
  3. #变量SeriousDlqin2yrs取反
  4. data['SeriousDlqin2yrs']=1-data['SeriousDlqin2yrs']

3.3 Segmentación de datos

Para verificar el efecto de ajuste del modelo, necesitamos dividir el conjunto de datos en conjunto de entrenamiento y conjunto de prueba .

 
 
  1. from sklearn.cross_validation import train_test_splitY = data['SeriousDlqin2yrs']
  2. X = data.ix[:, 1:]
  3. #测试集占比30%
  4. X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=0)
  5. # print(Y_train)
  6. train = pd.concat([Y_train, X_train], axis=1)
  7. test = pd.concat([Y_test, X_test], axis=1)
  8. clasTest = test.groupby('SeriousDlqin2yrs')['SeriousDlqin2yrs'].count()
  9. train.to_csv('TrainData.csv',index=False)
  10. test.to_csv('TestData.csv',index=False)

análisis exploratorio

Antes de construir un modelo, generalmente realizamos EDA (análisis de datos exploratorios, análisis de datos exploratorios) en los datos existentes. EDA se refiere a la exploración de datos existentes (especialmente datos sin procesar de encuestas u observaciones) con la menor cantidad posible de suposiciones a priori. Los métodos de análisis de datos exploratorios más utilizados incluyen: histograma, diagrama de dispersión y diagrama de caja, etc.

La distribución por edades de los clientes se muestra en la Figura 4-1. Se puede ver que la variable edad tiene una distribución aproximadamente normal, lo que está en línea con los supuestos del análisis estadístico.

formato_png 5

Figura 4-1 Distribución por edades de los clientes

La distribución del ingreso anual de los clientes se muestra en la Figura 4-2, y el ingreso mensual tiene aproximadamente una distribución normal, lo que satisface las necesidades del análisis estadístico.

formato_png 6

La distribución del ingreso anual de los clientes se muestra en la Figura 4-2, y el ingreso mensual tiene aproximadamente una distribución normal, lo que satisface las necesidades del análisis estadístico.

selección de variables

La selección (clasificación) de variables de características es muy importante para los profesionales del análisis de datos y el aprendizaje automático. Una buena selección de características puede mejorar el rendimiento del modelo y ayudarnos a comprender las características y la estructura subyacente de los datos, lo que juega un papel importante para mejorar aún más el modelo y el algoritmo. En cuanto a la implementación del código de selección de variables de Python, puede consultar la introducción de varios métodos de selección de funciones de uso común combinados con Scikit-learn: https://www.cnblogs.com/hhh5460/p/5186226.html.

En este artículo, utilizamos el método de selección de variables del modelo de calificación crediticia y utilizamos  el método de análisis WOE para determinar si los indicadores cumplen con la importancia económica comparando la probabilidad de incumplimiento de la clasificación del indicador y la clasificación correspondiente . Primero, discretizamos (bin) las variables.

5.1 Procesamiento de agrupamiento

La agrupación de variables es un nombre para la discretización de variables continuas. En el desarrollo de tarjetas de crédito, se utilizan comúnmente segmentos equidistantes, segmentos de igual profundidad y segmentos óptimos.

Entre ellos, intervalos de longitud Equval significa que los intervalos de los segmentos son consistentes, por ejemplo, la edad se toma como un segmento de diez años;

Intervalos de frecuencia iguales consiste en determinar primero el número de segmentos y luego hacer que la cantidad de datos en cada segmento sea aproximadamente igual;

Optimal Binning , también conocido como discretización supervisada, utiliza el particionamiento recursivo (Recursive Partitioning) para dividir variables continuas en segmentos, detrás del cual se encuentra un algoritmo basado en inferencia condicional para encontrar una mejor agrupación.

Primero elegimos la segmentación óptima de la variable continua y luego consideramos la segmentación equidistante de la variable continua cuando la distribución de la variable continua no cumple con los requisitos de la segmentación óptima. El código para la agrupación óptima es el siguiente:

 
 
  1. # 定义自动分箱函数def mono_bin(Y, X, n = 20):
  2. r = 0
  3. good=Y.sum()
  4. bad=Y.count() - good
  5. while np.abs(r) < 1:
  6. d1 = pd.DataFrame({"X": X, "Y": Y, "Bucket": pd.qcut(X, n)})
  7. d2 = d1.groupby('Bucket', as_index = True)
  8. r, p = stats.spearmanr(d2.mean().X, d2.mean().Y)
  9. n = n - 1
  10. d3 = pd.DataFrame(d2.X.min(), columns = ['min'])
  11. d3['min']=d2.min().X
  12. d3['max'] = d2.max().X
  13. d3['sum'] = d2.sum().Y
  14. d3['total'] = d2.count().Y
  15. d3['rate'] = d2.mean().Y
  16. d3['woe']=np.log((d3['rate']/(1-d3['rate']))/(good/bad))
  17. d4 = (d3.sort_index(by = 'min')).reset_index(drop=True)
  18. print("=" * 60)
  19. print(d4)
  20. return d4

Para RevolvingUtilizationOfUnsecuredLines, edad, DebtRatio e MonthlyIncome en el conjunto de datos usaremos la segmentación óptima.

formato_png 7

Figura 5-1 Agrupación de RevolvingUtilizationOfUnsecuredLines

formato_png 8

Figura 5-2 Situación de agrupación por edades

formato_png 9

Figura 5-3 Situación de agrupación del ratio de deuda

formato_png 10

Figura 5-4 Situación de agrupación de ingresos mensuales

Para las variables que no se pueden agrupar de manera óptima, el agrupamiento es el siguiente:

 
 
  1. # 连续变量离散化
  2. cutx3 = [ninf, 0, 1, 3, 5, pinf]
  3. cutx6 = [ninf, 1, 2, 3, 5, pinf]
  4. cutx7 = [ninf, 0, 1, 3, 5, pinf]
  5. cutx8 = [ninf, 0,1,2, 3, pinf]
  6. cutx9 = [ninf, 0, 1, 3, pinf]
  7. cutx10 = [ninf, 0, 1, 2, 3, 5, pinf]

5.2 AY

El análisis WOE consiste en agrupar los indicadores, calcular el valor WOE de cada marcha y observar la tendencia del valor WOE que cambia con los indicadores. La definición matemática de WOE es:

ay=ln(buen atributo/malo atributo)

Al analizar, debemos organizar cada índice de pequeño a grande y calcular el valor WOE del contenedor correspondiente . Cuanto mayor sea el índice positivo, menor será el valor WOE; cuanto mayor sea el índice negativo, mayor será el valor WOE. Cuanto mayor sea la pendiente negativa del valor WOE del índice positivo y mayor la pendiente positiva del índice de respuesta, significa que el índice tiene una buena capacidad de discriminación. Si el valor WOE está cerca de una línea recta, significa que la capacidad de juicio del indicador es débil. Si hay una tendencia de correlación positiva entre el índice positivo y WOE, y una tendencia de correlación negativa entre el índice negativo y WOE, significa que este índice no cumple con la importancia económica y debe eliminarse.

La implementación de la función WOE se incluyó en la función mono_bin() en la sección anterior, por lo que no se repetirá aquí.

5.3 Análisis de correlación y detección intravenosa

A continuación, utilizaremos los datos limpios para observar la correlación entre variables. Tenga en cuenta que el análisis de correlación aquí es solo una verificación preliminar, y el VI (ponderación de la evidencia) del modelo se verifica más a fondo como base para la selección de variables.

Usamos el paquete seaborn en Python para dibujar el gráfico de correlación llamando a la función de dibujo heatmap(). El código de implementación es el siguiente:

 
 
  1. corr = data.corr()
  2. #计算各变量的相关性系数
  3. xticks = ['x0','x1','x2','x3','x4','x5','x6','x7','x8','x9','x10']#x轴标签
  4. yticks = list(corr.index)
  5. #y轴标签
  6. fig = plt.figure()ax1 = fig.add_subplot(1, 1, 1)sns.heatmap(corr, annot=True, cmap='rainbow', ax=ax1, annot_kws={'size': 9, 'weight': 'bold', 'color': 'blue'})
  7. #绘制相关性系数热力图
  8. ax1.set_xticklabels(xticks, rotation=0, fontsize=10)ax1.set_yticklabels(yticks, rotation=0, fontsize=10)plt.show()

formato_png 11

Figura 5-5 Correlación de variables en el conjunto de datos

Como puede verse en la figura anterior, la correlación entre variables es muy pequeña. El coeficiente de correlación para NumberOfOpenCreditLinesAndLoans y NumberRealEstateLoansOrLines es 0,43.

A continuación, calcule más el valor de información (IV) de cada variable. Los indicadores IV se utilizan generalmente para determinar el poder predictivo de variables independientes. Su fórmula es:

IV=suma((atributobueno-atributomalo)*ln(atributobueno/atributomalo))

Los criterios para juzgar la capacidad predictiva de las variables por el valor IV son:

< 0,02: impredecible

0,02 a 0,1: débil

0,1 a 0,3: medio

0,3 a 0,5: fuerte

0.5: sospechoso

La implementación de IV se coloca en la función mono_bin () y el código se implementa de la siguiente manera:

 
 
  1. # 定义自动分箱函数def mono_bin(Y, X, n = 20):
  2. r = 0
  3. good=Y.sum()
  4. bad=Y.count()-good
  5. while np.abs(r) < 1:
  6. d1 = pd.DataFrame({"X": X, "Y": Y, "Bucket": pd.qcut(X, n)})
  7. d2 = d1.groupby('Bucket', as_index = True)
  8. r, p = stats.spearmanr(d2.mean().X, d2.mean().Y)
  9. n = n - 1
  10. d3 = pd.DataFrame(d2.X.min(), columns = ['min'])
  11. d3['min']=d2.min().X
  12. d3['max'] = d2.max().X
  13. d3['sum'] = d2.sum().Y
  14. d3['total'] = d2.count().Y
  15. d3['rate'] = d2.mean().Y
  16. d3['woe']=np.log((d3['rate']/(1-d3['rate']))/(good/bad))
  17. d3['goodattribute']=d3['sum']/good
  18. d3['badattribute']=(d3['total']-d3['sum'])/bad
  19. iv=((d3['goodattribute']-d3['badattribute'])*d3['woe']).sum()
  20. d4 = (d3.sort_index(by = 'min')).reset_index(drop=True)
  21. print("=" * 60)
  22. print(d4)
  23. cut=[]
  24. cut.append(float('-inf'))
  25. for i in range(1,n+1):
  26. qua=X.quantile(i/(n+1))
  27. cut.append(round(qua,4))
  28. cut.append(float('inf'))
  29. woe=list(d4['woe'].round(3))
  30. return d4,iv,cut,woe

Código de diagrama IV generado:

 
 
  1. ivlist=[ivx1,ivx2,ivx3,ivx4,ivx5,ivx6,ivx7,ivx8,ivx9,ivx10]
  2. #各变量
  3. IVindex=['x1','x2','x3','x4','x5','x6','x7','x8','x9','x10']
  4. #x轴的标签
  5. fig1 = plt.figure(1)ax1 = fig1.add_subplot(1, 1, 1)x = np.arange(len(index))+1ax1.bar(x, ivlist, width=0.4)
  6. #生成柱状图
  7. ax1.set_xticks(x)ax1.set_xticklabels(index, rotation=0, fontsize=12)ax1.set_ylabel('IV(Information Value)', fontsize=14)
  8. #在柱状图上添加数字标签
  9. for a, b in zip(x, ivlist):
  10. plt.text(a, b + 0.01, '%.4f' % b, ha='center', va='bottom', fontsize=10)plt.show()

imagen de salida:

formato_png 12

Figura 5-6 Diagrama de salida IV de cada variable

Como puede verse, los valores IV de las variables DebtRatio, MonthlyIncome, NumberOfOpenCreditLinesAndLoans, NumberRealEstateLoansOrLines y NumberOfDependents son significativamente más bajos, por lo que se eliminan.

análisis del modelo

La transformación del peso de la evidencia (WOE) puede transformar un modelo de regresión logística en un formato de cuadro de mando estándar. El propósito de introducir la transformación WOE no es mejorar la calidad del modelo, pero algunas variables no deben incluirse en el modelo, ya sea porque no pueden aumentar el valor del modelo o porque el error relacionado con el coeficiente de correlación del modelo es grande. , el establecimiento de una tarjeta de crédito estándar También es posible no utilizar la conversión WOE.

En este caso, el modelo de regresión logística necesita tratar con una mayor cantidad de variables independientes. Aunque esto aumenta la complejidad del procedimiento de modelado, el cuadro de mando resultante es siempre el mismo.

Antes de construir el modelo, debemos convertir las variables filtradas en valores WOE para la calificación crediticia.

6.1 Conversión AY

Ya hemos obtenido los datos de binning y los datos WOE de cada variable, y solo necesitamos reemplazarlos según los datos de cada variable, el código de implementación es el siguiente:

 
 
  1. #替换成woe函数def replace_woe(series, cut, woe):
  2. list = []
  3. I = 0
  4. while i<len(series):
  5. value=series[i]
  6. j=len(cut) - 2
  7. m=len(cut) - 2
  8. while j >= 0:
  9. if value>=cut[j]:
  10. j = -1
  11. else:
  12. j -= 1
  13. m -= 1
  14. list.append(woe[m])
  15. i += 1
  16. return list

Sustituimos cada variable y la guardamos en el archivo WoeData.csv:

 
 
  1. # 替换成
  2. woedata['RevolvingUtilizationOfUnsecuredLines'] = Series(replace_woe(data['RevolvingUtilizationOfUnsecuredLines'], cutx1, woex1))
  3. data['age'] = Series(replace_woe(data['age'], cutx2, woex2))
  4. data['NumberOfTime30-59DaysPastDueNotWorse'] = Series(replace_woe(data['NumberOfTime30-59DaysPastDueNotWorse'], cutx3, woex3))
  5. data['DebtRatio'] = Series(replace_woe(data['DebtRatio'], cutx4, woex4))
  6. data['MonthlyIncome'] = Series(replace_woe(data['MonthlyIncome'], cutx5, woex5))
  7. data['NumberOfOpenCreditLinesAndLoans'] = Series(replace_woe(data['NumberOfOpenCreditLinesAndLoans'], cutx6, woex6))
  8. data['NumberOfTimes90DaysLate'] = Series(replace_woe(data['NumberOfTimes90DaysLate'], cutx7, woex7))
  9. data['NumberRealEstateLoansOrLines'] = Series(replace_woe(data['NumberRealEstateLoansOrLines'], cutx8, woex8))
  10. data['NumberOfTime60-89DaysPastDueNotWorse'] = Series(replace_woe(data['NumberOfTime60-89DaysPastDueNotWorse'], cutx9, woex9))
  11. data['NumberOfDependents'] = Series(replace_woe(data['NumberOfDependents'], cutx10, woex10))
  12. data.to_csv('WoeData.csv', index=False)

6.2 Establecimiento del modelo logístico

Llamamos directamente al paquete statsmodels para implementar la regresión logística:

 
 
  1. 导入数据data = pd.read_csv('WoeData.csv')
  2. #应变量
  3. Y=data['SeriousDlqin2yrs']
  4. #自变量,剔除对因变量影响不明显的变量
  5. X=data.drop(['SeriousDlqin2yrs','DebtRatio','MonthlyIncome', 'NumberOfOpenCreditLinesAndLoans','NumberRealEstateLoansOrLines','NumberOfDependents'],axis=1)
  6. X1=sm.add_constant(X)
  7. logit=sm.Logit(Y,X1)
  8. result=logit.fit()
  9. print(result.summary())

Resultado de salida:

formato_png 13

Figura 6-1 Resultados del modelo de regresión logística

Se puede ver en la Figura 6-1 que todas las variables de la regresión logística han pasado la prueba de significancia y cumplen con los requisitos.

6.3 Comprobación del modelo

En este punto, nuestra parte de modelado básicamente ha terminado. Necesitamos verificar qué tan predictivo es el modelo. Utilizamos los datos de prueba reservados al comienzo de la etapa de modelado para la inspección. La capacidad de ajuste del modelo se evaluó mediante la curva ROC y el AUC.

En Python, puede usar sklearn.metrics, que puede comparar fácilmente dos clasificadores y calcular automáticamente ROC y AUC.

Código de implementación:

 
 
  1. #应变量
  2. Y_test = test['SeriousDlqin2yrs']
  3. #自变量,剔除对因变量影响不明显的变量,与模型变量对应
  4. X_test = test.drop(['SeriousDlqin2yrs', 'DebtRatio', 'MonthlyIncome', 'NumberOfOpenCreditLinesAndLoans','NumberRealEstateLoansOrLines', 'NumberOfDependents'], axis=1)
  5. X3 = sm.add_constant(X_test)
  6. resu = result.predict(X3)
  7. #进行预测
  8. fpr, tpr, threshold = roc_curve(Y_test, resu)
  9. rocauc = auc(fpr, tpr)
  10. #计算
  11. AUCplt.plot(fpr, tpr, 'b', label='AUC = %0.2f' % rocauc)
  12. #生成ROC曲线
  13. plt.legend(loc='lower right')
  14. plt.plot([0, 1], [0, 1], 'r--')
  15. plt.xlim([0, 1])
  16. plt.ylim([0, 1])
  17. plt.ylabel('真正率')
  18. plt.xlabel('假正率')
  19. plt.show()

Resultado de salida:

formato_png 14

Figura 6-2 Curva ROC

Como se puede ver en la figura anterior, el valor AUC es 0,85, lo que indica que el efecto de predicción del modelo sigue siendo bueno y la tasa de precisión es alta.

puntuación de crédito

Básicamente hemos completado el trabajo relacionado con el modelado y verificado la capacidad predictiva del modelo con la curva ROC. El siguiente paso es convertir el modelo logístico en un cuadro de mando estándar.

7.1 Criterios de puntuación

formato_png 15

Según los trabajos anteriores se obtiene:

a=log(p_bueno/P_malo)

Puntuación = compensación + factor * log(probabilidades)

Antes de crear un cuadro de mando estándar, debemos elegir algunos parámetros del cuadro de mando: puntos base, PDO (porcentaje de puntos de duplicación) y relación bueno/malo. Aquí, tomamos 600 como puntaje base, PDO es 20 (cada 20 puntos más que el doble de la proporción de bueno a malo) y la proporción de bueno a malo es 20.

 
 
  1. # 我们取600分为基础分值,PDO为20(每高20分好坏比翻一倍),好坏比取20。
  2. z = 20 / math.log(2)
  3. q = 600 - 20 * math.log(20) / math.log(2)
  4. baseScore = round(q + p * coe[0], 0)

Puntuación total personal = puntuación básica + puntuaciones de cada parte

7.2 Puntuación de partes

Las puntuaciones para cada sección variable se calculan a continuación. Función de puntuación para cada parte:

 
 
  1. #计算分数函数 def get_score(coe,woe,factor):
  2. scores=[]
  3. for w in woe:
  4. score=round(coe*w*factor,0)
  5. scores.append(score)
  6. return scores

Calcule la puntuación de cada variable:

 
 
  1. # 各项部分分数
  2. x1 = get_score(coe[1], woex1, p)
  3. x2 = get_score(coe[2], woex2, p)
  4. x3 = get_score(coe[3], woex3, p)
  5. x7 = get_score(coe[4], woex7, p)
  6. x9 = get_score(coe[5], woex9, p)

Podemos obtener la tarjeta de puntuación de cada parte como se muestra en la Figura 7-1:

formato_png 16

Figura 7-1 Criterios de puntuación para cada variable

#

sistema de puntuación automatizado

Para calcular la puntuación según la variable la implementación es la siguiente:

 
 
  1. #根据变量计算分数
  2. def compute_score(series,cut,score):
  3. list = []
  4. i = 0
  5. while i < len(series):
  6. value = series[i]
  7. j = len(cut) - 2
  8. m = len(cut) - 2
  9. while j >= 0:
  10. if value >= cut[j]:
  11. j = -1
  12. else:
  13. j -= 1
  14. m -= 1
  15. list.append(score[m])
  16. i += 1
  17. return list

Calculemos la puntuación en la prueba:

 
 
  1. test1 = pd.read_csv('TestData.csv')
  2. test1['BaseScore']=Series(np.zeros(len(test1)))+baseScore
  3. test1['x1'] = Series(compute_score(test1['RevolvingUtilizationOfUnsecuredLines'], cutx1, x1))
  4. test1['x2'] = Series(compute_score(test1['age'], cutx2, x2))
  5. test1['x3'] = Series(compute_score(test1['NumberOfTime30-59DaysPastDueNotWorse'], cutx3, x3))
  6. test1['x7'] = Series(compute_score(test1['NumberOfTimes90DaysLate'], cutx7, x7)
  7. test1['x9'] = Series(compute_score(test1['NumberOfTime60-89DaysPastDueNotWorse'], cutx9, x9))
  8. test1['Score'] = test1['x1'] + test1['x2'] + test1['x3'] + test1['x7'] +test1['x9'] + baseScore
  9. test1.to_csv('ScoreData.csv', index=False)

Resultados parciales del cálculo por lotes:

formato_png 17

Figura 8-1 Resultados parciales de los cálculos por lotes

Resumen y perspectivas

En este artículo, a través de la extracción y el análisis de los datos de Give Me Some Credit en kaggle, combinados con el principio de establecimiento de la tarjeta de puntuación de crédito, se crea un sistema de puntuación de crédito simple a partir del preprocesamiento de datos, la selección de variables y el análisis de modelos para crear puntuaciones de crédito. .

El sistema de cuadro de mando de aprendizaje automático basado en IA puede hacer que el sistema sea más potente al eliminar datos antiguos (después de un cierto momento, como 2 años) antes de realizar el modelado automático, la evaluación del modelo y la optimización continua de las variables de características.

Enlace del artículo | https://zhuanlan.zhihu.com/p/35284849

[Python] Aquí se presenta el uso de Python para desarrollar tarjetas de puntaje de crédito. Casos prácticos más relevantes en "Modelo de tarjeta de puntaje de control de riesgos financieros de Python y análisis de datos (edición mejorada)"

Supongo que te gusta

Origin blog.csdn.net/fulk6667g78o8/article/details/132305977
Recomendado
Clasificación