Implementación en SAS del Population Stability Index (PSI)

Introducción

En el mundo dinámico de la banca y las finanzas, el análisis de riesgo es una piedra angular para la toma de decisiones informadas. Uno de los instrumentos más valiosos en este análisis es el Population Stability Index (PSI), una medida que permite a las instituciones financieras evaluar la estabilidad de sus modelos predictivos a lo largo del tiempo. En la sección de Estadística hemos explorado a fondo el PSI, proporcionando una comprensión teórica y práctica de esta herramienta (puedes revisar todo el contenido en Population Stability Index).

Ahora, nos adentramos en el análisis del PSI utilizando código SAS, una habilidad crucial para los analistas y científicos de datos en el sector financiero. Aunque existen múltiples plataformas para ejecutar código SAS, recomendamos Altair SLCTM, por aquí os dejamos una guía detallada sobre cómo instalar de forma gratuita Altair SLCTM en tu PC. Todos los códigos que se muestran en esta web funcionan perfectamente en cualquier software que tenga la capacidad de compilar el lenguaje de programación SAS.

Este ejemplo ha sido cuidadosamente diseñado para mostrarte cómo realizar el análisis de PSI de manera eficiente utilizando el lenguaje de programación SAS. Para ilustrar esto, exploraremos dos ejemplos prácticos: la variable categórica «Motor de decisión» y la variable continua «PD». Ambas son esenciales en la evaluación del riesgo de impago. Únete a nosotros en este recorrido técnico y descubre cómo maximizar las capacidades de SAS para tus análisis de PSI.

Ejemplo Práctico

Imagina que te han contratado en una entidad financiera para realizar un chequeo de salud del modelo predictivo que usan para evaluar el riesgo de impago de sus clientes. La entidad está interesada en saber si el modelo todavía es fiable o si ha llegado el momento de actualizarlo con nueva información o, incluso, diseñar uno nuevo. Hay dos variables que les preocupan especialmente: «Motor de decisión» y «PD». La razón es que estas variables son clave en la toma de decisiones y, por tanto, es crucial que sus distribuciones no hayan variado significativamente desde que se desarrolló el modelo.

Por un lado, nos han facilitado la base de datos con la que se desarrolló el modelo predictivo, que cuenta con 78.760 observaciones, a partir de ahora nos referiremos a ella como base o referencia. Por otro lado, nos han proporcionado la base de datos de validación, también conocida como Oot (Out of time), que cuenta con 62.544 observaciones, a partir de ahora la llamaremos actual.

Variable categórica: «Motor de decisión»

La variable «motor_de_decision» categoriza las decisiones de préstamo en cinco grupos:

  1. Resto
  2. Empresa
  3. Préstamo Joven (menores de 30 años)
  4. Préstamo a Empleados
  5. Préstamo Preconcedido

Nuestro objetivo es evaluar si la distribución de estas categorías ha permanecido constante o ha cambiado con el tiempo.

¡Comencemos!

Cargar las BBDD

La entidad nos proporciona dos archivos Excel en formato .xlsx:

Lo primero que haremos será importar los conjuntos de datos a SAS:

/*Lectura del archivo BBDD_MODELO.xlsx*/
PROC IMPORT OUT=BBDD_MODELO
    DATAFILE = "C:\Users\user\Desktop\BBDD_MODELO.xlsx"
    DBMS = XLSX;
    GETNAMES = YES;
RUN;

/*Lectura del archivo BBDD_OOT.xlsx*/
PROC IMPORT OUT=BBDD_OOT
    DATAFILE = "C:\Users\user\Desktop\BBDD_OOT.xlsx"
    DBMS = XLSX;
    GETNAMES = YES;
RUN;
SAS
👇🏻¿Dudas con alguna parte del código?
PROC IMPORT
Este código SAS es una instrucción para importar datos de un archivo Excel a SAS.
1. PROC IMPORT: Este es el comando principal que le indica a SAS que vas a realizar una importación de datos. PROC IMPORT es utilizado para leer datos de fuentes externas y convertirlos en un conjunto de datos de SAS.
2. OUT=BBDD_MODELO: Este parámetro especifica el nombre del conjunto de datos de SAS que se creará a partir del archivo importado. En este caso, el conjunto de datos se llamará BBDD_MODELO.
3. DATAFILE = «C:\Users\user\Desktop\BBDD_MODELO.xlsx»: Este parámetro indica la ruta y el nombre del archivo que deseas importar. Aquí, se está importando un archivo llamado BBDD_MODELO.xlsx, que se encuentra en el escritorio del usuario.
4. DBMS = XLSX: Este parámetro especifica el tipo de base de datos del archivo que se va a importar. En este caso, XLSX indica que el archivo es un Excel en formato de Microsoft Office 2007 o posterior.
5. GETNAMES = YES: Este parámetro le dice a SAS que las primeras filas del archivo Excel contienen los nombres de las variables. Al establecer GETNAMES en YES, SAS utiliza la primera fila del archivo Excel para los nombres de las variables en el conjunto de datos de SAS.
6. RUN;: Finaliza la instrucción de PROC IMPORT y ejecuta el procedimiento.

Recuentos y Proporciones

A continuación, calculamos las frecuencias y los porcentajes de los distintos valores que toma la variable «motor_de_decision» en la base del modelo. También obtenemos el total de observaciones, almacenando el número en la macro variable «TOT_RECUENTO_BASE».

/*Recuentos y Proporciones de la tabla base (BBDD_MODELO)*/
/*Obtenemos las frecuencias de los distintos valores de la variable MOTOR_DE_DECISION*/
PROC SQL;
	CREATE TABLE BASE_AUX AS SELECT
		MOTOR_DE_DECISION,
		COUNT(*) AS RECUENTO_BASE
	FROM BBDD_MODELO
	GROUP BY MOTOR_DE_DECISION;
QUIT;

/*Sumamos todas las frecuencias de cada categoría para obtener el total de observaciones*/
PROC SQL NOPRINT;
	SELECT SUM(RECUENTO_BASE) INTO :TOT_RECUENTO_BASE
	FROM BASE_AUX;
QUIT;

/*Calculamos la proporción de cada categoría*/
DATA BASE;
	SET BASE_AUX;
	PROPORCION_BASE = (RECUENTO_BASE/&TOT_RECUENTO_BASE);
RUN;

/*Sumamos todas las proporciones de cada categoría. Esta suma tiene que ser igual a 1*/
PROC SQL NOPRINT;
	SELECT SUM(PROPORCION_BASE) INTO :TOT_PROPORCION_BASE
	FROM BASE;
QUIT;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. PROC SQL;
    • Inicia un procedimiento SQL en SAS para realizar consultas y manipulaciones de datos.
  2. CREATE TABLE BASE_AUX AS SELECT
    • CREATE TABLE BASE_AUX: Crea una nueva tabla llamada BASE_AUX.
    • AS SELECT: Indica que la estructura y contenido de BASE_AUX se basará en el resultado de la consulta SELECT que sigue.
  3. MOTOR_DE_DECISION, COUNT(*) AS RECUENTO_BASE
    • MOTOR_DE_DECISION: Columna seleccionada del conjunto de datos BBDD_MODELO.
    • COUNT(*): Función de agregación que cuenta todas las filas.
    • AS RECUENTO_BASE: Renombra el resultado de COUNT(*) a RECUENTO_BASE.
  4. FROM BBDD_MODELO
    • Especifica que los datos provienen del conjunto de datos BBDD_MODELO.
  5. GROUP BY MOTOR_DE_DECISION;
    • Agrupa los datos por cada valor único en la columna MOTOR_DE_DECISION.
  6. QUIT;
    • Finaliza el bloque PROC SQL.
  7. PROC SQL NOPRINT;
    • Inicia otro bloque PROC SQL sin mostrar los resultados (output).
  8. SELECT SUM(RECUENTO_BASE) INTO :TOT_RECUENTO_BASE FROM BASE_AUX;
    • SELECT SUM(RECUENTO_BASE): Calcula la suma total de RECUENTO_BASE.
    • INTO :TOT_RECUENTO_BASE: Almacena el resultado en una macro variable llamada TOT_RECUENTO_BASE.
    • FROM BASE_AUX: Especifica que la suma se realiza sobre los datos de BASE_AUX.
  9. DATA BASE;
    • Crea un conjunto de datos llamado BASE.
  10. SET BASE_AUX;
    • Lee y utiliza los datos del conjunto de datos BASE_AUX.
  11. PROPORCION_BASE = (RECUENTO_BASE / &TOT_RECUENTO_BASE);
    • Calcula la proporción de cada valor de RECUENTO_BASE con respecto al total en TOT_RECUENTO_BASE.
  12. RUN;
    • Ejecuta las instrucciones del bloque DATA.
  13. SELECT SUM(PROPORCION_BASE) INTO :TOT_PROPORCION_BASE FROM BASE;
    • Calcula la suma de PROPORCION_BASE en el conjunto de datos BASE y almacena el resultado en la macro variable TOT_PROPORCION_BASE.

Una vez hemos calculado los valores que nos interesan, la tabla Base queda con la siguiente estructura:

Tabla Base: Recuento y Proporciones de la variable «motor_de_decision»

Ahora hacemos lo mismo para la base Oot (out of time).

/*Recuentos y Proporciones de la tabla actual (BBDD_OOT)*/
/*Obtenemos las frecuencias de los distintos valores de la variable MOTOR_DE_DECISION*/
PROC SQL;
	CREATE TABLE ACTUAL_AUX AS SELECT
		MOTOR_DE_DECISION,
		COUNT(*) AS RECUENTO_ACTUAL
	FROM BBDD_OOT
	GROUP BY MOTOR_DE_DECISION;
QUIT;

/*Sumamos todas las frecuencias de cada categoría para obtener el total de observaciones*/
PROC SQL NOPRINT;
	SELECT SUM(RECUENTO_ACTUAL) INTO :TOT_RECUENTO_ACTUAL
	FROM ACTUAL_AUX;
QUIT;

/*Calculamos la proporción de cada categoría*/
DATA ACTUAL;
	SET ACTUAL_AUX;
	PROPORCION_ACTUAL = (RECUENTO_ACTUAL/&TOT_RECUENTO_ACTUAL);
RUN;

/*Sumamos todas las proporciones de cada categoría. Esta suma tiene que ser igual a 1*/
PROC SQL NOPRINT;
	SELECT SUM(PROPORCION_ACTUAL) INTO :TOT_PROPORCION_ACTUAL
	FROM ACTUAL;
QUIT;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. PROC SQL;
    • Inicia un procedimiento SQL en SAS para realizar consultas y manipulaciones de datos.
  2. CREATE TABLE ACTUAL_AUX AS SELECT
    • CREATE TABLE ACTUAL_AUX: Crea una nueva tabla llamada ACTUAL_AUX.
    • AS SELECT: Indica que la estructura y contenido de ACTUAL_AUX se basará en el resultado de la consulta SELECT que sigue.
  3. MOTOR_DE_DECISION, COUNT(*) AS RECUENTO_ACTUAL
    • MOTOR_DE_DECISION: Columna seleccionada del conjunto de datos BBDD_OOT.
    • COUNT(*): Función de agregación que cuenta todas las filas.
    • AS RECUENTO_ACTUAL: Renombra el resultado de COUNT(*) a RECUENTO_ACTUAL.
  4. FROM BBDD_MODELO
    • Especifica que los datos provienen del conjunto de datos BBDD_OOT.
  5. GROUP BY MOTOR_DE_DECISION;
    • Agrupa los datos por cada valor único en la columna MOTOR_DE_DECISION.
  6. QUIT;
    • Finaliza el bloque PROC SQL.
  7. PROC SQL NOPRINT;
    • Inicia otro bloque PROC SQL sin mostrar los resultados (output).
  8. SELECT SUM(RECUENTO_ACTUAL) INTO :TOT_RECUENTO_ACTUAL FROM ACTUAL_AUX;
    • SELECT SUM(RECUENTO_ACTUAL): Calcula la suma total de RECUENTO_ACTUAL.
    • INTO :TOT_RECUENTO_ACTUAL: Almacena el resultado en una macro variable llamada TOT_RECUENTO_ACTUAL.
    • FROM ACTUAL_AUX: Especifica que la suma se realiza sobre los datos de ACTUAL_AUX.
  9. DATA ACTUAL;
    • Crea un conjunto de datos llamado ACTUAL.
  10. SET ACTUAL_AUX;
    • Lee y utiliza los datos del conjunto de datos ACTUAL_AUX.
  11. PROPORCION_ACTUAL = (RECUENTO_ACTUAL / &TOT_RECUENTO_ACTUAL);
    • Calcula la proporción de cada valor de RECUENTO_ACTUAL con respecto al total en TOT_RECUENTO_ACTUAL.
  12. RUN;
    • Ejecuta las instrucciones del bloque DATA.
  13. SELECT SUM(PROPORCION_ACTUAL) INTO :TOT_PROPORCION_ACTUAL FROM ACTUAL;
    • Calcula la suma de PROPORCION_ACTUAL en el conjunto de datos ACTUAL y almacena el resultado en la macro variable TOT_PROPORCION_ACTUAL.

La tabla Actual queda de la siguiente manera:

Tabla Actual: Recuento y Proporciones de la variable «motor_de_decision»

Cálculo del PSI

El siguiente código está diseñado para calcular el PSI de cada categoría de «motor_de_decision». Fíjate que antes de utilizar la fórmula general del PSI en la línea 9 se aplica la corrección manual de las proporciones nulas. Recuerda que el PSI tiene una deficiencia cuando se trata de proporciones nulas o cero, ya sea en las proporciones de la base o actuales. Por eso asignamos el valor 0 a las frecuencias que cuentan con valores vacíos y posteriormente recalculamos su proporción de forma manual añadiendo una observación ficticia, para que más adelante sea posible calcular el logaritmo.

/*Cálculo del PSI*/
DATA RESUMEN;
	MERGE BASE ACTUAL;
	BY MOTOR_DE_DECISION;
	IF RECUENTO_BASE = . THEN RECUENTO_BASE = 0;
	IF RECUENTO_ACTUAL = . THEN RECUENTO_ACTUAL = 0;
	IF RECUENTO_BASE = 0 THEN PROPORCION_BASE = (1/&TOT_RECUENTO_BASE);
	IF RECUENTO_ACTUAL = 0 THEN PROPORCION_ACTUAL = (1/&TOT_RECUENTO_ACTUAL);
	PSI = (PROPORCION_ACTUAL-PROPORCION_BASE)*LOG(PROPORCION_ACTUAL/PROPORCION_BASE);
RUN;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. DATA RESUMEN;
    • Crea un conjunto de datos llamado RESUMEN.
  2. MERGE BASE ACTUAL;
    • Combina los conjuntos de datos BASE y ACTUAL en uno solo. Esta operación alinea las filas de ambos conjuntos de datos basándose en las columnas comunes especificadas en la cláusula BY que sigue.
  3. BY MOTOR_DE_DECISION;
    • Especifica que la fusión de BASE y ACTUAL debe realizarse en base a la columna MOTOR_DE_DECISION. Esto significa que las filas de ambos conjuntos de datos se alinearán según los valores coincidentes en esta columna.
  4. IF RECUENTO_BASE = . THEN RECUENTO_BASE = 0;
    • Reemplaza los valores faltantes (representados por . en SAS) en la columna RECUENTO_BASE con cero.
  5. IF RECUENTO_ACTUAL = . THEN RECUENTO_ACTUAL = 0;
    • Reemplaza los valores faltantes en la columna RECUENTO_ACTUAL con cero.
  6. IF RECUENTO_BASE = 0 THEN PROPORCION_BASE = (1/&TOT_RECUENTO_BASE);
    • Si RECUENTO_BASE es igual a 0, se calcula PROPORCION_BASE como 1 dividido entre el total de recuentos de base (almacenado en la macro variable &TOT_RECUENTO_BASE).
  7. IF RECUENTO_ACTUAL = 0 THEN PROPORCION_ACTUAL = (1/&TOT_RECUENTO_ACTUAL);
    • Si RECUENTO_ACTUAL es igual a 0, se calcula PROPORCION_ACTUAL como 1 dividido entre el total de recuentos actuales (almacenado en la macro variable &TOT_RECUENTO_ACTUAL).
  8. PSI = (PROPORCION_ACTUAL – PROPORCION_BASE) * LOG(PROPORCION_ACTUAL / PROPORCION_BASE);
    • Calcula el Population Stability Index (PSI) utilizando la fórmula dada. Esta fórmula mide la diferencia en las distribuciones de la población base y actual, utilizando el logaritmo natural de la proporción actual dividida por la proporción base, multiplicado por la diferencia entre estas proporciones.
  9. RUN;
    • Ejecuta el bloque de código DATA.

La tabla resultante del código anterior es la siguiente:

Tabla Resumen

Sumamos los PSIs de todas las categorías de la variable «motor_de_decision» y almacenamos el resultado final en la macro variable PSI.

/*Guardamos el valor del PSI en la macro variable PSI*/
PROC SQL NOPRINT;
	SELECT SUM(PSI) INTO :PSI
	FROM RESUMEN;
QUIT;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. PROC SQL NOPRINT;
    • PROC SQL: Inicia un procedimiento SQL, permitiendo la ejecución de consultas y comandos SQL en SAS.
    • NOPRINT: Esta opción evita que los resultados de la consulta SQL se muestren en la salida. Se utiliza cuando solo se necesita realizar una acción (como crear una macro variable) sin necesidad de visualizar los resultados.
  2. SELECT SUM(PSI) INTO :PSI FROM RESUMEN;
    • SELECT SUM(PSI): Esta instrucción calcula la suma total de la columna PSI en el conjunto de datos RESUMEN. El PSI es un valor calculado previamente en cada fila, representando el índice de estabilidad para cada valor de MOTOR_DE_DECISION.
    • INTO :PSI: El resultado de la suma se almacena en una macro variable llamada PSI. Las macro variables en SAS se utilizan para almacenar valores que pueden ser referenciados posteriormente en el código SAS. El prefijo : indica que se trata de una macro variable.
    • FROM RESUMEN: Especifica que la suma se realiza sobre los datos del conjunto RESUMEN.
  3. QUIT;
    • Finaliza el bloque PROC SQL.

Creamos la tabla de Totales, que contará con un único registro formado por las sumas de cada una de las columnas y el RAG correspondiente (es una de las métricas más utilizadas en la interpretación de resultados, que se refiere a «Red», «Amber» y «Green», puedes consultarlo en el apartado Interpretación de resultados de la explicación teórica del PSI).

/*Se crea la fila de totales*/
DATA TOTALES;
	MOTOR_DE_DECISION = "TOTAL";
	PSI = Ψ
	RECUENTO_BASE = &TOT_RECUENTO_BASE;
	RECUENTO_ACTUAL = &TOT_RECUENTO_ACTUAL;
	PROPORCION_BASE = &TOT_PROPORCION_BASE;
	PROPORCION_ACTUAL = &TOT_PROPORCION_ACTUAL;
	IF PSI <= 0.1 THEN RAG = "G";
		ELSE IF 0.1 < PSI <= 0.25 THEN RAG = "A";
		ELSE IF PSI > 0.25 THEN RAG = "R";
RUN;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. DATA TOTALES;
    • Crea un conjunto de datos llamado TOTALES.
  2. MOTOR_DE_DECISION = «TOTAL»;
    • Asigna el valor «TOTAL» a la variable MOTOR_DE_DECISION. Esto indica que la fila representa los totales de la tabla.
  3. PSI = &PSI;
    • Asigna a la variable PSI el valor almacenado en la macro variable PSI. Esta macro variable contiene el valor acumulado del PSI calculado en pasos anteriores del programa.
  4. RECUENTO_BASE = &TOT_RECUENTO_BASE;
    • Asigna a la variable RECUENTO_BASE el valor almacenado en la macro variable TOT_RECUENTO_BASE, que representa el total de recuentos de la base.
  5. RECUENTO_ACTUAL = &TOT_RECUENTO_ACTUAL;
    • Asigna a la variable RECUENTO_ACTUAL el valor almacenado en la macro variable TOT_RECUENTO_ACTUAL, que representa el total de recuentos actuales.
  6. PROPORCION_BASE = &TOT_PROPORCION_BASE;
    • Asigna a la variable PROPORCION_BASE el valor almacenado en la macro variable TOT_PROPORCION_BASE, que representa la proporción total en la base.
  7. PROPORCION_ACTUAL = &TOT_PROPORCION_ACTUAL;
    • Asigna a la variable PROPORCION_ACTUAL el valor almacenado en la macro variable TOT_PROPORCION_ACTUAL, que representa la proporción total actual.
  8. IF PSI <= 0.1 THEN RAG = «G»;
    • Si el valor de PSI es menor o igual a 0.1, asigna «G» (verde) a la variable RAG. Esto indica una estabilidad aceptable en el modelo o la población.
  9. ELSE IF 0.1 < PSI <= 0.25 THEN RAG = «A»;
    • Si el valor de PSI está entre 0.1 y 0.25, asigna «A» (ámbar) a RAG. Esto indica una estabilidad moderada.
  10. ELSE IF PSI > 0.25 THEN RAG = «R»;
    • Si el valor de PSI es mayor a 0.25, asigna «R» (rojo) a RAG. Esto sugiere una inestabilidad significativa.
  11. RUN;
    • Ejecuta el bloque de código DATA.

La tabla que genera el código anterior es la siguiente:

Tabla Totales: Suma acumulada y RAG

Por último, unimos las tablas Resumen y Totales en una única tabla llamada Resultado. Ordenamos las columnas en el orden deseado y le ponemos 4 decimales a las proporciones.

/*Añadimos los totales a la tabla resumen*/
DATA RESULTADO;
	RETAIN MOTOR_DE_DECISION RECUENTO_BASE RECUENTO_ACTUAL PROPORCION_BASE PROPORCION_ACTUAL PSI RAG;
	SET RESUMEN TOTALES;
	FORMAT PROPORCION_BASE 6.4;
	FORMAT PROPORCION_ACTUAL 6.4;
RUN;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. DATA RESULTADO;
    • Crea un conjunto de datos llamado RESULTADO.
  2. RETAIN MOTOR_DE_DECISION RECUENTO_BASE RECUENTO_ACTUAL PROPORCION_BASE PROPORCION_ACTUAL PSI RAG;
    • La instrucción RETAIN se utiliza para especificar el orden de las variables en el conjunto de datos resultante. Las variables listadas aquí se mantendrán en el orden en que se enumeran. Esto no afecta la lógica del programa, sino la organización y presentación de los datos en el conjunto de datos RESULTADO.
  3. SET RESUMEN TOTALES;
    • La instrucción SET se utiliza para combinar los datos de dos o más conjuntos de datos. En este caso, combina RESUMEN y TOTALES en el nuevo conjunto de datos RESULTADO. La combinación se realiza apilando los registros de TOTALES debajo de los registros de RESUMEN.
  4. FORMAT PROPORCION_BASE 6.4;
    • Aplica un formato específico a la variable PROPORCION_BASE. El formato 6.4 significa que la variable se mostrará con un ancho total de 6 caracteres, incluyendo 4 decimales. Por ejemplo, un número como 0.1234 se mostrará en este formato.
  5. FORMAT PROPORCION_ACTUAL 6.4;
    • Se aplica el formato 6.4 a la variable PROPORCION_ACTUAL.
  6. RUN;
    • Ejecuta el bloque de código DATA.

El resultado final es el siguiente:

Tabla Resultado: Resultado del PSI para la variable «motor_de_decision»

Conclusión

El PSI de la variable «motor_de_decision» es:

\text{PSI} = 0,00014 + ... + 0,06992 = 0,77155

Tras analizar la variable categórica «motor_de_decision con las categorías proporcionadas y calcular el Índice de Estabilidad de la Población (PSI), hemos llegado a un valor de 0,77155. Este resultado se desglosa de la siguiente manera: una contribución mínima de la categoría «1.Resto», una significativa de «2.Empresa», la más elevada de «3.Joven», y aportaciones menores de «4.Empleado» y «5.Preconcedido».

Un PSI de 0,77 sugiere cambios sustanciales en la distribución de esta variable desde la creación del modelo. Generalmente, un PSI por debajo o igual a 0,1 indica estabilidad, entre 0,1 y 0,25 sugiere un cambio moderado, y un valor superior a 0,25 puede indicar una variación significativa que podría requerir una recalibración del modelo o incluso el desarrollo de uno nuevo. Dado que nuestro valor excede ampliamente el umbral de 0,25 se recomienda que la entidad financiera realice una revisión exhaustiva del modelo y considere actualizarlo para reflejar los patrones actuales de decisión de préstamo.

Variable continua: PD

«PD» representa la probabilidad de incumplimiento (Probability of Default) asignada por el modelo a cada cliente o contrato. Se utiliza para estimar la probabilidad de que un prestatario falle en cumplir con sus obligaciones de pago en un plazo determinado, generalmente 1 año. El valor de la «PD» varía entre 0 y 1, donde 0 indicaría que es imposible que un prestatario incumpla sus obligaciones y 1 señala que el incumplimiento es seguro.

El PSI cuantifica la variabilidad entre las distribuciones de distintas subpoblaciones o grupos; así que dividiremos la variable «PD» en 10 rangos iguales, creando así 10 categorías. Cada categoría tendrá aproximadamente la misma cantidad de observaciones. Analizaremos cómo se distribuyen los clientes de la base del modelo en estos deciles en comparación con los clientes actuales.

Si estás usando Altair Analytics Workbench el procedimiento para crear las categorías recibe el nombre de «PROC BIN» mientras que para SAS Studio el procedimiento es «PROC HPBIN». Solamente es una diferencia semántica puntual que probablemente se deba a diferencias en las filosofías del diseño del software, porque disponen de las mismas opciones dentro del procedimiento y proporcionan exactamente los mismos resultados.

Con Altair Analytics Workbench sería de la siguiente forma:

/*Creamos 10 categorías iguales para la variable PD*/
PROC BIN DATA = BBDD_MODELO OUTPUT=BASE_BUCKETIZADA NUMBIN=10 QUANTILE;
	INPUT PD;
	TITLE "Bucketización de la variable PD";
RUN;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. PROC BIN DATA = BBDD_MODELO OUTPUT=BASE_BUKETIZADA NUMBIN=10 QUANTILE;
    • PROC BIN: Inicia el procedimiento BIN, que es utilizado para el binning de datos.
    • DATA = BBDD_MODELO: Especifica el conjunto de datos de entrada, en este caso BBDD_MODELO.
    • OUTPUT=BASE_BUKETIZADA: Define el nombre del conjunto de datos de salida que contendrá los resultados del binning. En este caso, el conjunto de datos resultante se llamará BASE_BUKETIZADA.
    • NUMBIN=10: Indica que los datos se deben dividir en 10 categorías o buckets.
    • QUANTILE: Esta opción especifica que el método de binning debe basarse en cuantiles. Esto significa que cada categoría tendrá aproximadamente la misma cantidad de observaciones.
  2. INPUT PD;
    • INPUT PD;: Especifica la variable que se va a utilizar para el binning, en este caso, PD.
  3. TITLE «Bucketización de la variable PD»;
    • TITLE: Establece un título para los resultados o salidas del procedimiento. Aquí, el título es «Bucketización de la variable PD».
  4. RUN;
    • Ejecuta el procedimiento BIN.

Al ejecutar el procedimiento anterior se muestra el siguiente resultado:

Altair Analytics Workbench: The BIN Procedure

El reporte muestra la información general de la bucketización realizada (método utilizado, número de buckets y número de variables bucketizadas) y una tabla resumen con los límites, frecuencias y proporciones de cada bucket. También muestra el nombre de la nueva variable bucketizada que es «BIN_nombrevariable«.

Con SAS Studio sería de la siguiente forma:

/*Creamos 10 categorías iguales para la variable PD*/
PROC HPBIN DATA = BBDD_MODELO OUTPUT=BASE_BUCKETIZADA NUMBIN=10 QUANTILE;
	INPUT PD;
	TITLE "Bucketización de la variable PD";
RUN;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. PROC HPBIN DATA = BBDD_MODELO OUTPUT=BASE_BUKETIZADA NUMBIN=10 QUANTILE;
    • PROC HPBIN: Inicia el procedimiento HPBIN, que es utilizado para el binning de datos.
    • DATA = BBDD_MODELO: Especifica el conjunto de datos de entrada, en este caso BBDD_MODELO.
    • OUTPUT=BASE_BUKETIZADA: Define el nombre del conjunto de datos de salida que contendrá los resultados del binning. En este caso, el conjunto de datos resultante se llamará BASE_BUKETIZADA.
    • NUMBIN=10: Indica que los datos se deben dividir en 10 categorías o buckets.
    • QUANTILE: Esta opción especifica que el método de binning debe basarse en cuantiles. Esto significa que cada categoría tendrá aproximadamente la misma cantidad de observaciones.
  2. INPUT PD;
    • INPUT PD;: Especifica la variable que se va a utilizar para el binning, en este caso, PD.
  3. TITLE «Bucketización de la variable PD»;
    • TITLE: Establece un título para los resultados o salidas del procedimiento. Aquí, el título es «Bucketización de la variable PD».
  4. RUN;
    • Ejecuta el procedimiento HPBIN.

El reporte es idéntico al anterior:

SAS Studio: The HPBIN Procedure

Ya estés utilizando Altair Analytics Workbench o SAS Studio obtendrás exactamente el mismo resultado. La tabla «BASE_BUCKETIZADA» que resulta tras ejecutar el procedimiento queda de la siguiente manera:

Tabla: «BASE_BUCKETIZADA»

Recuentos y Proporciones

Una vez hemos creado la variable «BIN_PD», el proceso para la obtención de su PSI será igual que con la variable «motor_de_decision». Calculamos las frecuencias y los porcentajes de la variable «BIN_PD» en la base del modelo. También obtenemos el total de observaciones, almacenando el número en la macro variable «TOT_RECUENTO_BASE».

/*Recuentos y Proporciones de la tabla base buketizada (BASE_BUCKETIZADA)*/
/*Obtenemos las frecuencias de los distintos valores de la variable BIN_PD (categorías variable PD)*/
PROC SQL;
	CREATE TABLE BASE_AUX AS SELECT
		BIN_PD,
		COUNT(*) AS RECUENTO_BASE
	FROM BASE_BUCKETIZADA
	GROUP BY BIN_PD;
QUIT;

/*Sumamos todas las frecuencias de cada categoría para obtener el total de observaciones*/
PROC SQL NOPRINT;
	SELECT SUM(RECUENTO_BASE) INTO :TOT_RECUENTO_BASE
	FROM BASE_AUX;
QUIT;

/*Calculamos la proporción de cada categoría*/
DATA BASE;
	SET BASE_AUX;
	PROPORCION_BASE = (RECUENTO_BASE/&TOT_RECUENTO_BASE);
RUN;

/*Sumamos todas las proporciones de cada categoría. Esta suma tiene que ser igual a 1*/
PROC SQL NOPRINT;
	SELECT SUM(PROPORCION_BASE) INTO :TOT_PROPORCION_BASE
	FROM BASE;
QUIT;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. PROC SQL;
    • Inicia un procedimiento SQL en SAS para realizar consultas y manipulaciones de datos.
  2. CREATE TABLE BASE_AUX AS SELECT
    • CREATE TABLE BASE_AUX: Crea una nueva tabla llamada BASE_AUX.
    • AS SELECT: Indica que la estructura y contenido de BASE_AUX se basará en el resultado de la consulta SELECT que sigue.
  3. BIN_PD, COUNT(*) AS RECUENTO_BASE
    • BIN_PD: Columna seleccionada del conjunto de datos BASE_BUCKETIZADA.
    • COUNT(*): Función de agregación que cuenta todas las filas.
    • AS RECUENTO_BASE: Renombra el resultado de COUNT(*) a RECUENTO_BASE.
  4. FROM BASE_BUCKETIZADA
    • Especifica que los datos provienen del conjunto de datos BASE_BUCKETIZADA.
  5. GROUP BY BIN_PD;
    • Agrupa los datos por cada valor único en la columna BIN_PD.
  6. QUIT;
    • Finaliza el bloque PROC SQL.
  7. PROC SQL NOPRINT;
    • Inicia otro bloque PROC SQL sin mostrar los resultados (output).
  8. SELECT SUM(RECUENTO_BASE) INTO :TOT_RECUENTO_BASE FROM BASE_AUX;
    • SELECT SUM(RECUENTO_BASE): Calcula la suma total de RECUENTO_BASE.
    • INTO :TOT_RECUENTO_BASE: Almacena el resultado en una macro variable llamada TOT_RECUENTO_BASE.
    • FROM BASE_AUX: Especifica que la suma se realiza sobre los datos de BASE_AUX.
  9. DATA BASE;
    • Crea un conjunto de datos llamado BASE.
  10. SET BASE_AUX;
    • Lee y utiliza los datos del conjunto de datos BASE_AUX.
  11. PROPORCION_BASE = (RECUENTO_BASE / &TOT_RECUENTO_BASE);
    • Calcula la proporción de cada valor de RECUENTO_BASE con respecto al total en TOT_RECUENTO_BASE.
  12. RUN;
    • Ejecuta las instrucciones del bloque DATA.
  13. SELECT SUM(PROPORCION_BASE) INTO :TOT_PROPORCION_BASE FROM BASE;
    • Calcula la suma de PROPORCION_BASE en el conjunto de datos BASE y almacena el resultado en la macro variable TOT_PROPORCION_BASE.

Una vez hemos calculado los valores que nos interesan, la tabla Base queda con la siguiente estructura:

Tabla Base: Recuento y Proporciones de la variable «BIN_PD»

Ahora tenemos segmentar los datos de la tabla actual en categorías basadas en los valores de «PD», utilizando los límites del procedimiento de bucketización:

/*Creamos la variable BIN_PD en la base Oot asignando los límites de cada categoría*/
DATA ACTUAL_BUCKETIZADA;
	SET BBDD_OOT;
	IF PD < 0.0001297533 THEN BIN_PD = 1;
		ELSE IF 0.0001297533 <= PD < 0.0003390706 THEN BIN_PD = 2;
		ELSE IF 0.0003390706 <= PD < 0.0006651284 THEN BIN_PD = 3;
		ELSE IF 0.0006651284 <= PD < 0.0011938999 THEN BIN_PD = 4;
		ELSE IF 0.0011938999 <= PD < 0.002089652 THEN BIN_PD = 5;
		ELSE IF 0.002089652 <= PD < 0.0037419482 THEN BIN_PD = 6;
		ELSE IF 0.0037419482 <= PD < 0.0074608021 THEN BIN_PD = 7;
		ELSE IF 0.0074608021 <= PD < 0.0180660947 THEN BIN_PD = 8;
		ELSE IF 0.0180660947 <= PD < 0.0641020781 THEN BIN_PD = 9;
	ELSE BIN_PD = 10;
RUN;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. DATA ACTUAL_BUCKETIZADA;
    • Crea o reemplaza un conjunto de datos llamado ACTUAL_BUCKETIZADA.
  2. SET BBDD_OOT;
    • Lee y utiliza los datos del conjunto de datos BBDD_OOT. Este es el conjunto de datos de origen del que se tomará la variable PD para su clasificación en buckets.
  3. IF PD < 0.0001297533 THEN BIN_PD = 1; ELSE IF… ELSE BIN_PD = 10;
    • Esta serie de instrucciones IF...ELSE IF...ELSE clasifica cada observación en BBDD_OOT en una de las 10 categorías basadas en el valor de la variable PD.
    • Cada condición especifica un rango para el valor de PD. Por ejemplo, si PD es menor que 0.0001297533, BIN_PD se establece en 1; si PD está entre 0.0001297533 y 0.0003390706, BIN_PD se establece en 2, y así sucesivamente.
    • La última condición ELSE BIN_PD = 10; captura todos los valores de PD que no cumplen con ninguna de las condiciones anteriores, asignándoles el bucket 10.
  4. RUN;
    • Ejecuta el bloque de código DATA.

La tabla actual bucketizada nos queda así:

Tabla «Actual_Bucketizada»: Bucketización de la variable «PD»

Obtenemos los recuentos y proporciones de «BIN_PD» en la tabla «ACTUAL_BUCKETIZADA»:

/*Recuentos y Proporciones de la tabla actual buketizada (ACTUAL_BUCKETIZADA)*/
/*Obtenemos las frecuencias de los distintos valores de la variable BIN_PD (categorías variable PD)*/
PROC SQL;
	CREATE TABLE ACTUAL_AUX AS SELECT
		BIN_PD,
		COUNT(*) AS RECUENTO_ACTUAL
	FROM ACTUAL_BUCKETIZADA
	GROUP BY BIN_PD;
QUIT;

/*Sumamos todas las frecuencias de cada categoría para obtener el total de observaciones*/
PROC SQL NOPRINT;
	SELECT SUM(RECUENTO_ACTUAL) INTO :TOT_RECUENTO_ACTUAL
	FROM ACTUAL_AUX;
QUIT;

/*Calculamos la proporción de cada categoría*/
DATA ACTUAL;
	SET ACTUAL_AUX;
	PROPORCION_ACTUAL = (RECUENTO_ACTUAL/&TOT_RECUENTO_ACTUAL);
RUN;

/*Sumamos todas las proporciones de cada categoría. Esta suma tiene que ser igual a 1*/
PROC SQL NOPRINT;
	SELECT SUM(PROPORCION_ACTUAL) INTO :TOT_PROPORCION_ACTUAL
	FROM ACTUAL;
QUIT;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. PROC SQL;
    • Inicia un procedimiento SQL en SAS para realizar consultas y manipulaciones de datos.
  2. CREATE TABLE ACTUAL_AUX AS SELECT
    • CREATE TABLE ACTUAL_AUX: Crea una nueva tabla llamada ACTUAL_AUX.
    • AS SELECT: Indica que la estructura y contenido de ACTUAL_AUX se basará en el resultado de la consulta SELECT que sigue.
  3. BIN_PD, COUNT(*) AS RECUENTO_ACTUAL
    • BIN_PD: Columna seleccionada del conjunto de datos ACTUAL_BUCKETIZADA.
    • COUNT(*): Función de agregación que cuenta todas las filas.
    • AS RECUENTO_ACTUAL: Renombra el resultado de COUNT(*) a RECUENTO_ACTUAL.
  4. FROM ACTUAL_BUCKETIZADA
    • Especifica que los datos provienen del conjunto de datos BBDD_OOT.
  5. GROUP BY BIN_PD;
    • Agrupa los datos por cada valor único en la columna BIN_PD.
  6. QUIT;
    • Finaliza el bloque PROC SQL.
  7. PROC SQL NOPRINT;
    • Inicia otro bloque PROC SQL sin mostrar los resultados (output).
  8. SELECT SUM(RECUENTO_ACTUAL) INTO :TOT_RECUENTO_ACTUAL FROM ACTUAL_AUX;
    • SELECT SUM(RECUENTO_ACTUAL): Calcula la suma total de RECUENTO_ACTUAL.
    • INTO :TOT_RECUENTO_ACTUAL: Almacena el resultado en una macro variable llamada TOT_RECUENTO_ACTUAL.
    • FROM ACTUAL_AUX: Especifica que la suma se realiza sobre los datos de ACTUAL_AUX.
  9. DATA ACTUAL;
    • Crea un conjunto de datos llamado ACTUAL.
  10. SET ACTUAL_AUX;
    • Lee y utiliza los datos del conjunto de datos ACTUAL_AUX.
  11. PROPORCION_ACTUAL = (RECUENTO_ACTUAL / &TOT_RECUENTO_ACTUAL);
    • Calcula la proporción de cada valor de RECUENTO_ACTUAL con respecto al total en TOT_RECUENTO_ACTUAL.
  12. RUN;
    • Ejecuta las instrucciones del bloque DATA.
  13. SELECT SUM(PROPORCION_ACTUAL) INTO :TOT_PROPORCION_ACTUAL FROM ACTUAL;
    • Calcula la suma de PROPORCION_ACTUAL en el conjunto de datos ACTUAL y almacena el resultado en la macro variable TOT_PROPORCION_ACTUAL.

La tabla Actual queda de la siguiente manera:

Tabla Actual: Recuento y Proporciones de la variable «BIN_PD»

Cálculo del PSI

Realizamos el cálculo del PSI y creamos la variable «PD_BUCKET» que tomará los valores de la variable «BIN_PD» pero en formato de texto, porque queremos que el último registro sea un texto y tome el valor «TOTAL«.

/*Cálculo del PSI*/
DATA RESUMEN;
	MERGE BASE ACTUAL;
	BY BIN_PD;
	IF RECUENTO_BASE = . THEN RECUENTO_BASE = 0;
	IF RECUENTO_ACTUAL = . THEN RECUENTO_ACTUAL = 0;
	IF RECUENTO_BASE = 0 THEN PROPORCION_BASE = (1/&TOT_RECUENTO_BASE);
	IF RECUENTO_ACTUAL = 0 THEN PROPORCION_ACTUAL = (1/&TOT_RECUENTO_ACTUAL);
	PSI = (PROPORCION_ACTUAL-PROPORCION_BASE)*LOG(PROPORCION_ACTUAL/PROPORCION_BASE);
	PD_BUCKET=PUT(BIN_PD, 5.);
RUN;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. DATA RESUMEN;
    • Crea o reemplaza un conjunto de datos llamado RESUMEN.
  2. MERGE BASE ACTUAL;
    • Combina los conjuntos de datos BASE y ACTUAL. La fusión se realiza de forma que las filas de ambos conjuntos se alineen y se combinen en base a la variable especificada en la cláusula BY.
  3. BY BIN_PD;
    • La fusión de los datos se realiza en base a la variable BIN_PD. Esto significa que los datos en BASE y ACTUAL se compararán y combinarán según los valores de esta variable.
  4. IF RECUENTO_BASE = . THEN RECUENTO_BASE = 0;
    • Reemplaza los valores faltantes (.) en RECUENTO_BASE con 0. Esto asegura que no haya valores faltantes que puedan afectar los cálculos siguientes.
  5. IF RECUENTO_ACTUAL = . THEN RECUENTO_ACTUAL = 0;
    • Similar a la línea anterior, pero para RECUENTO_ACTUAL.
  6. IF RECUENTO_BASE = 0 THEN PROPORCION_BASE = (1/&TOT_RECUENTO_BASE);
    • Si RECUENTO_BASE es 0, asigna a PROPORCION_BASE un valor mínimo basado en el total de recuentos de la base. Esto evita divisiones por cero o valores indefinidos en cálculos posteriores.
  7. IF RECUENTO_ACTUAL = 0 THEN PROPORCION_ACTUAL = (1/&TOT_RECUENTO_ACTUAL);
    • Similar a la línea anterior, pero para PROPORCION_ACTUAL.
  8. PSI = (PROPORCION_ACTUAL – PROPORCION_BASE) * LOG(PROPORCION_ACTUAL / PROPORCION_BASE );
    • Calcula el PSI para cada bucket. La fórmula mide la divergencia en las proporciones entre la población base y la actual, indicando cambios en la distribución.
  9. PD_BUCKET=PUT(BIN_PD, 5.);
    • Convierte la variable BIN_PD a un formato de texto con un ancho de 5 caracteres. La función PUT() se utiliza en SAS para convertir variables numéricas a formato de cadena de texto.
  10. RUN;
    • Ejecuta el bloque de código DATA.

La tabla que resulta del código se muestra a continuación:

Tabla Resumen

Sumamos los PSIs de cada categoría y almacenamos el resultado en la macro variable PSI.

/*Guardamos el valor del PSI en la macro variable PSI*/
PROC SQL NOPRINT;
	SELECT SUM(PSI) INTO :PSI
	FROM RESUMEN;
QUIT;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. PROC SQL NOPRINT;
    • PROC SQL: Inicia un procedimiento SQL, que permite ejecutar consultas y comandos SQL dentro de SAS.
    • NOPRINT: Esta opción evita que los resultados de la consulta SQL se muestren en la salida. Se usa cuando solo se necesita realizar una acción (como crear o actualizar una macro variable) sin necesidad de visualizar los resultados.
  2. SELECT SUM(PSI) INTO :PSI FROM RESUMEN;
    • SELECT SUM(PSI): Calcula la suma total de la columna PSI en el conjunto de datos RESUMEN. El PSI, calculado previamente en cada fila, representa el índice de estabilidad para cada categoría definida por BIN_PD.
    • INTO :PSI: Almacena el resultado de la suma en una macro variable llamada PSI. Las macro variables en SAS son útiles para almacenar valores que pueden ser utilizados en otras partes del programa SAS. El prefijo : antes de PSI indica que se trata de una macro variable.
    • FROM RESUMEN: Especifica que la suma del PSI se realiza sobre los datos del conjunto RESUMEN.
  3. QUIT;
    • Finaliza el bloque PROC SQL.

Creamos la tabla de Totales.

/*Se crea la fila de totales*/
DATA TOTALES;
	PD_BUCKET = "TOTAL";
	PSI = &PSI;
	RECUENTO_BASE = &TOT_RECUENTO_BASE;
	RECUENTO_ACTUAL = &TOT_RECUENTO_ACTUAL;
	PROPORCION_BASE = &TOT_PROPORCION_BASE;
	PROPORCION_ACTUAL = &TOT_PROPORCION_ACTUAL;
	IF PSI <= 0.1 THEN RAG = "G";
		ELSE IF 0.1 < PSI <= 0.25 THEN RAG = "A";
		ELSE IF PSI > 0.25 THEN RAG = "R";
RUN;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. DATA TOTALES;
    • Crea o reemplaza un conjunto de datos llamado TOTALES.
  2. PD_BUCKET = «TOTAL»;
    • Asigna el valor «TOTAL» a la variable PD_BUCKET. Esto indica que la fila en TOTALES es un resumen o representación agregada de todos los datos.
  3. PSI = &PSI;
    • Asigna a la variable PSI el valor almacenado en la macro variable PSI. Esta macro variable contiene el valor total del PSI calculado previamente.
  4. RECUENTO_BASE = &TOT_RECUENTO_BASE;
    • Asigna a RECUENTO_BASE el valor almacenado en la macro variable TOT_RECUENTO_BASE. Esta variable representa el recuento total en la base de datos original.
  5. RECUENTO_ACTUAL = &TOT_RECUENTO_ACTUAL;
    • Asigna a RECUENTO_ACTUAL el valor almacenado en la macro variable TOT_RECUENTO_ACTUAL. Similar a RECUENTO_BASE, representa el recuento total en los datos actuales.
  6. PROPORCION_BASE = &TOT_PROPORCION_BASE;
    • Asigna a PROPORCION_BASE el valor de la macro variable TOT_PROPORCION_BASE, que es la proporción total en la base de datos original.
  7. PROPORCION_ACTUAL = &TOT_PROPORCION_ACTUAL;
    • Asigna a PROPORCION_ACTUAL el valor de la macro variable TOT_PROPORCION_ACTUAL, que es la proporción total en los datos actuales.
  8. IF PSI <= 0.1 THEN RAG = «G»; ELSE IF 0.1 < PSI <= 0.25 THEN RAG = «A»; ELSE IF PSI > 0.25 THEN RAG = «R»;
    • Esta serie de instrucciones condicionales clasifica el valor del PSI en categorías RAG (Rojo, Ámbar, Verde) según su valor. Si el PSI es menor o igual a 0.1, se clasifica como «G» (verde, indicando estabilidad); si está entre 0.1 y 0.25, se clasifica como «A» (ámbar, indicando una advertencia); si es mayor que 0.25, se clasifica como «R» (rojo, indicando inestabilidad).
  9. RUN;
    • Ejecuta el bloque de código DATA.

La tabla resultante es la siguiente:

Tabla Totales: Suma acumulada y RAG

Por último, unimos las tablas Resumen y Totales en una única tabla llamada Resultado. Ordenamos las columnas en el orden deseado con la palabra clave «RETAIN» y le ponemos 4 decimales a las proporciones.

/*Añadimos los totales a la tabla resumen*/
DATA RESULTADO (DROP= BIN_PD);
	RETAIN PD_BUCKET RECUENTO_BASE RECUENTO_ACTUAL PROPORCION_BASE PROPORCION_ACTUAL PSI RAG;
	SET RESUMEN TOTALES;
	FORMAT PROPORCION_BASE 6.4;
	FORMAT PROPORCION_ACTUAL 6.4;
RUN;
SAS
👇🏻¿Dudas con alguna parte del código?
  1. DATA RESULTADO (DROP= BIN_PD);
    • Crea o reemplaza un conjunto de datos llamado RESULTADO.
    • La opción DROP= BIN_PD excluye la variable BIN_PD del conjunto de datos resultante, RESULTADO. Esto significa que aunque BIN_PD pueda estar presente en los conjuntos de datos originales (RESUMEN o TOTALES), no se incluirá en RESULTADO.
  2. RETAIN PD_BUCKET RECUENTO_BASE RECUENTO_ACTUAL PROPORCION_BASE PROPORCION_ACTUAL PSI RAG;
    • La instrucción RETAIN especifica el orden en que las variables aparecerán en el conjunto de datos resultante. Además, RETAIN también asegura que los valores de estas variables se mantengan a través de las iteraciones del paso DATA.
  3. SET RESUMEN TOTALES;
    • La instrucción SET se utiliza para apilar o combinar los registros de los conjuntos de datos RESUMEN y TOTALES en el nuevo conjunto de datos RESULTADO. La combinación se realiza apilando los registros de TOTALES debajo de los registros de RESUMEN.
  4. FORMAT PROPORCION_BASE 6.4; FORMAT PROPORCION_ACTUAL 6.4;
    • Estas líneas aplican un formato específico a las variables PROPORCION_BASE y PROPORCION_ACTUAL. El formato 6.4 significa que estas variables se mostrarán con un total de 6 dígitos, incluyendo 4 dígitos después del punto decimal. Por ejemplo, un número como 0.1234 se mostrará en este formato.
  5. RUN;
    • Ejecuta el bloque de código DATA.

El resultado final es el siguiente:

Tabla Resultado: Resultado del PSI para la variable «PD»

Conclusión

El PSI de la variable «PD» es:

\text{PSI} = 0,03677 + ... + 0,00039 = 0,06738

Al evaluar la variable continua «PD» hemos obtenido un PSI de 0,06738. Este resultado se compone de pequeñas contribuciones en cada uno de los deciles, siendo la mayor en el primer rango.

Un PSI total de aproximadamente 0,067 indica que no ha habido cambios sustanciales en la distribución de la probabilidad de incumplimiento desde que se desarrolló el modelo. Un valor de PSI inferior a 0,1 generalmente se considera como indicativo de estabilidad, lo que sugiere que el modelo predictivo actual sigue siendo adecuado y no se necesitarían acciones inmediatas en términos de recalibración o desarrollo de un nuevo modelo basándonos exclusivamente en esta variable.

Por lo tanto, en base a la variable «PD», podemos concluir que el modelo predictivo mantiene su capacidad para estimar la probabilidad de incumplimiento de forma consistente con cómo fue diseñado originalmente. Esto implica que, al menos en lo que respecta a esta métrica específica, el modelo sigue siendo robusto y no muestra signos de degradación significativa que justifiquen una intervención urgente.

Conclusión

Tras evaluar las variables «Motor de decisión» y «PD» con el Índice de Estabilidad de la Población (PSI), hemos llegado a conclusiones distintas para cada una. Para «Motor de decisión», un PSI de 0,77 sugiere que ha habido cambios muy significativos en la distribución desde la creación del modelo, lo que podría señalar la necesidad de una actualización o revisión más detallada. Por otro lado, un PSI de 0,067 para «PD» indica una estabilidad en la distribución de la probabilidad de incumplimiento , lo que implica que esta variable no ha experimentado cambios que afecten la fiabilidad del modelo.

En términos generales, la combinación de estos resultados señala que, mientras la variable «PD» se mantiene estable y el modelo predictivo es todavía confiable en este aspecto, la variable «Motor de decisión» muestra un cambio considerable, especialmente destacado por la aparición de la categoría «3.Joven» en la base actual, la cual no existía en los datos de desarrollo. Este cambio sustancial, evidenciado por un PSI elevado para esta categoría, sugiere una dinámica de mercado emergente o un cambio en la demografía de los clientes que no se refleja en el modelo original.

Por lo tanto, se recomienda una revisión exhaustiva del modelo, considerando particularmente las implicaciones de la inclusión de la nueva categoría «3.Joven», para garantizar que el modelo sigue siendo relevante y refleja las condiciones actuales del mercado y comportamiento del cliente.

Bibliografía

Population Stability Index (PSI)

STATISTICAL PROPERTIES OF POPULATION STABILITY INDEX by Bilal Yurdakul

Tabla de contenidos
Compartir artículo

Un comentario

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Información básica sobre protección de datos Ver más

  • Responsable: Jorge Carballo Álvarez.
  • Finalidad:  Moderar los comentarios.
  • Legitimación:  Por consentimiento del interesado.
  • Destinatarios y encargados de tratamiento:  No se ceden o comunican datos a terceros para prestar este servicio. El Titular ha contratado los servicios de alojamiento web a Dreamhost que actúa como encargado de tratamiento.
  • Derechos: Acceder, rectificar y suprimir los datos.

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos. Contiene enlaces a sitios web de terceros con políticas de privacidad ajenas que podrás aceptar o no cuando accedas a ellos. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos.
Privacidad