top of page

COSAS VEREDES

  • fjroar
  • 4 jun 2023
  • 5 Min. de lectura

Dejando un poco de lado el ML publico ahora este post sobre la Luna y sobre una librería de funciones que estoy creando en R sobre un tema excitante como estudio de cuestiones relacionadas con nuestro satélite, muy fácil de observar y de fotografiar (y así aprovecho para mostraros una de mis fotos hechas desde la puerta de mi casa en una conjunción Luna - Marte):

A pesar, de la “cercanía”, nuestro satélite es a día de hoy uno de los objetos más difíciles de dominar bajo el conocimiento humano y la razón se haya en que es un satélite demasiado grande para el planeta alrededor del que gira. Así pues, un problema que debería ser sencillo por mera mecánica celeste como prever la posición de la Luna en un instante del futuro de modo exacto, obliga a realizar una programación fina que hace uso de 7 – 9 cifras decimales y donde cualquier imprecisión en cualquiera de los pasos intermedios provoca una rápida propagación de errores.

La librería RMoon que estoy completando, va a tratar de recoger una serie de algoritmos descritos que proceden del libro Astronomical Algorithms 2ª Ed publicado en 1.991, cuyo autor, el astrónomo belga Jean Meeus, compila una serie de interesantes algoritmos, no sólo enfocados a la Luna sino a todo el sistema solar, según cuenta él, por la frustraciones que encontraba en los cálculos de posiciones celestes en general, que aún por los 80 (y como veremos también ahora), no eran del todo precisos. Así pues, el autor pone a disposición del público algoritmos de un modo bastante simplificado (dentro de la complejidad que tienen), y con desviaciones de unos pocos segundos de arco con respecto a la realidad. De hecho, a día de hoy, se puede ver que para un día como es hoy, 4 de Junio de 2023, a las 23h (en España) una conocida aplicación de aficionado como Stellarium, ofrece un montón de datos sobre la luna, entre ellos se destaca la distancia entre los centros de la Tierra y la Luna que resulta ser de 367.252’49 Km tal y como se observa en esta salida:



Este dato contrasta con una aplicación, ya con algoritmos más precisos como es MoonCalc que para el mismo caso ofrece como distancia, el valor de 367.641Km tal y como se puede observar en:


Una diferencia de unos 400Km, que suele ser mayor conforme se considera momentos más alejados en el tiempo.

En este sentido he tomado MoonCalc como referencia y vamos a ver el valor que se obtendría siguiendo los pasos dados por las funciones que pongo a disposición del interesado justo para hoy día 4 de Junio a las 23h, según el Algoritmo del capítulo 46 del mencionado libro.

Antes de comenzar, para quien desee instalarse esta la librería RMoon, debe previamente de disponer de la librería devtools con una versión de R actual y posteriormente teclear:


library(devtools)

install_github("FJROAR/RMoon", force = T)


Para el/la interesado/a recomiendo que cada mes o 2 meses elimine la librería con remove.packages("RMoon") y vuelva a ejecutar las instrucciones anteriores donde iré incorporando nuevas funcionalidades y corrigiendo bugs que vaya observando.

Una vez hecho eso, vamos a estimar la posición de la luna para hoy 4 de Junio de 2023 a las 23h. En primer lugar, debe tenerse en cuenta que al estar en el sistema CET+2, la primera función requiere que se pase el dato descontando dos horas. Dicho lo cual se dan los siguientes pasos:


(1) Determinación del siglo juliano (considerando hasta el minuto) mediante la

ejecución de:


options(digits=11)

options(scipen=999)


Julday <- JulianDay(2023, 6, 4, 21, 0, 0)[[3]]


Esta función genera una lista de vectores (todas las funciones aquí comentadas

permiten la entrada de lista de vectores y generarán o vectores o listas de estos para el

análisis de datos tabulares) interesando el tercero de ellos que es el ciclo juliano igual a

0’232423340178


(2) A partir de este dato, se generan 9 argumentos básicos lunares que dependen

exclusivamente de dicho valor mediante ecuaciones de hasta grado 4, dichos

elementos serán utilizados para tener en cuenta las perturbaciones de otros elementos

del sistema solar como Venus y el propio Júpiter:


- La longitud media lunar referida al equinoccio medio del día considerado: L

- Su elongación media: D

- La anomalía media solar: M

- La anomalía media Lunar: M’

- Distancia media de la luna desde su nodo ascendente: F

- 3 argumentos adicionales que A1, A2, A3, que tienen que ver con las influencias

de los citados planetas y el hecho en sí de que la tierra está achatada

- Finalmente, un coeficiente E de excentricidad orbital (que decrece con el tiempo),

que va a permitir realizar un ajuste de la intensidad de las perturbaciones

anteriormente comentadas


Nota: Si la luna fuese un objeto mucho más pequeño, muchos de los coeficientes

citados y de lo que viene a continuación no serían necesarios


Todos estos elementos se invocarían en la siguiente lista (de vectores, para que se

pueda trabajar de modo vectorizado si se desea):


Moonbasics <- MoonBasicElements(Julday)


Generándose los siguientes valores en concreto:


L = 267’329400141 D = 310’877995896 M = 352’729499819

M’ = 194’28034595 F = 235’32422479 A1 = 2’1357098289

A2 = 149’70911125 A3 = 150’63343979 E = 0’99941026276


(3) Con los anteriores resultados, la función que permite derivar una lista de vectores

interesantes: como son el vector de longitud geocéntrica de la Luna en ese momento,

junto con el de distancia de los centros Luna – Tierra, esto se lograría del siguiente

modo:


MoonLongdist <- MoonGeoLongDist(Moonbasics[[1]], Moonbasics[[2]],

Moonbasics[[3]], Moonbasics[[4]], Moonbasics[[5]],

Moonbasics[[6]], Moonbasics[[7]], Moonbasics[[9]])

La función anterior ofrece 3 vectores interesantes de los cuáles se usan los 2 siguientes:

La longitud geocéntrica en grados = 263.64157018

La distancia Tierra - Luna = 367.643’22848 Km


(4) Finalmente cabe obtener el valor de la latitud geocéntrica (o vector

correspondiente según el dato sea único o múltiple), donde influyen prácticamente los

mismos elementos que para el caso de la longitud y la distancia anteriores. Esto se

obtiene del siguiente modo:


MoonLat <- MoonGeoLongDist(Moonbasics[[1]], Moonbasics[[2]],

Moonbasics[[3]], Moonbasics[[4]], Moonbasics[[5]],

Moonbasics[[6]], Moonbasics[[7]], Moonbasics[[9]])


Llegando a que: la latitud geocéntrica en grados = -3.961940254


Cabe destacar el gran parecido a nivel de distancia que existe entre el dato dado por MoonCalc igual a 367.641Km con una diferencia de apenas 2 Km.


Por último, cabe indicar que en el caso de Stellarium, se generan unas coordenadas de Ascensión Recta – Declinación que pueden compararse con los resultados de estas funciones:

Stellarium RMoon

AR (J2000) 17h 32m 56'96s 17h 31m 27s

Declinación -27º 59m 41'2s -27º 14m 24s


Para llegar con RMoon a los anteriores datos deben añadirse las líneas:


Ecliptica <- TrueObliqutiyEcliptic(Julday)

EcliptNut <- Ecliptica + NutationLong(Julday)

Coordenadas <- Ecliptic2Equatorial(MoonLongdist[[1]],

MoonLat,

EcliptNut)


Que permiten convertir las coordenadas eclípticas anteriores en ecuatoriales, teniendo en cuenta los movimientos del eje terrestre o nutación entre otros efectos.


Finalmente espero de aquí a las próximas Jornadas de Usuarios de R, poder disponer de un elenco importante de funciones que nos permita conocer un poco más de nuestro querido e interesantísimo satélite.

En numerosas empresas por las que he pasado como consultor o trabajando en ellas, me he encontrado en numerosas ocasiones stacking de modelos frente a simple mixturas de estos y cuando pregunto la razón, la verdad es que nadie me suele dar una respuesta clara.

Hoy me ha dado por usar Python, que en este blog lo uso poco la verdad (aunque lo mismo e incluso mejor cabe hacerlo con R):



Sucede fundamentalmente en banca y seguros que un proveedor ofrece un modelo externo (que lo denomina “variable” para que entre mejor en el cliente) para predecir mejor, por ejemplo, el Riesgo de Crédito y simultáneamente le ofrece adicionalmente el servicio de construir un modelo que integre dicha “variable” (que no olvidemos que es un modelo), con los datos propios de dicho cliente y por un precio adicional, el proveedor vende la consulta al dato, haciendo “su Agosto”.

Bueno, no soy yo quién va a opinar sobre lo bueno o lo malo de lo anterior, pero si me gustaría advertir a los clientes que compran ese tipo de desarrollos que tenga bien claro qué están comprando en base a lo que he visto a lo largo de mi vida laboral.

En general, lo que están comprando es un stacking de modelos y habitualmente se vende que dicho stacking va a ser mejor que usar cada uno de los modelos por separado pero … ¿Es esto cierto?

Antes de discutir sobre lo anterior, hay que tener en cuenta que hay otras opciones como la mixtura de modelos, que puede ofrecer en ocasiones mejores resultados que el stacking además de otras ventajas como:


  • En la mixtura no se estiman parámetros de las variables internas con la externa, por tanto, su puesta en producción es más sencilla


  • Siempre se mantiene el modelo de proveedor de forma separada al interno, por lo que si hay que cambiar de proveedor no hay que re-estimar todos los parámetros con el coste en tiempo y dinero que supone eso. Además, siempre se podrá optar o bien por el modelo interno o bien por el del proveedor de modo separado


  • Si hay errores operacionales, la reparación es más sencilla que si los 2 modelos están bajo una misma fórmula de stacking


  • La mixtura es fácil de optimizar y se puede dar fácilmente grados de credibilidad de un modelo frente a otro, además bajo la mixtura, no sólo se tiene que considerar un único modelo, sino que pueden entrar en juego más de uno

Pues bien, dicho lo anterior me he encontrado en no pocas ocasiones que algunos de los stacking de modelos que, en teoría por usar más variables deberían de ser al menos tan buenos como el modelo sin stacking, sin embargo resultan peores y claro, no puedo hacer uso de datos privados para mostrar mi aseveración pero sí puedo tomar algunos datos de kaggle y ver si esto es posible que pase o no y para mi sorpresa, puede que sí.

Lo anterior proviene de un notebook que podéis encontrar en: https://github.com/FJROAR/Ejemplo-Blog-Stacking


Aunque no son los mejores datos para esta prueba, la verdad es que resultan bastante sencillos de manejar y me sorprendió lo siguiente:

  • Si un cliente tiene un determinado modelo (pongámoslo sencillo con una regresión logística, a veces el cliente no tiene el modelo y es donde el proveedor le ofrece el hacerlo todo a la vez pero sin comprobar si el modelo con variables internas sólo era o no mejor que el otro con la variable externa que dicho proveedor vende):


  • Llega un proveedor y le ofrece un stacking basado en otra regresión logística (que idealmente use otras variables distintas):

  • Entonces realiza un stacking de los anteriores modelos (olvidándose por tanto del inicialmente construido por ellos, si es que lo tenían, que muchas veces ni tan siquiera se tiene) y se encuentra lo siguiente:


Como se observa, en este ejemplo, donde ambos modelos con una ROC del 52% directamente serían malos, se observa que, bajo un stacking, no se consigue una mejora, sino que empeora aún más si es que esto es posible... Es decir que, si un cliente le ha pagado al proveedor el servicio de consultoría, directamente ha tirado su dinero para tener algo más malo que lo que tenían inicialmente cuando lo esperable es al menos una mejora que compense el gasto además del coste de poner todo eso en producción, documentarlo, ... ¿Ocurre esto siempre? Obviamente no, pero conviene advertir que aunque he visto que esto pasa en ocasiones, lo que no suelo ver nunca es estudios serios de porqué se ha optado por el stacking frente a una simple mixtura, sabiendo además que aparte de los costes de consultoría o de desarrollo interno del modelo, están las dificultades de puesta y mantenimiento en producción del modelo anteriormente comentados.


Entonces ¿Qué ocurriría en este ejemplo bajo una mixtura simple? En este caso se observaría lo siguiente:


Tampoco la mixtura mejora, pero al menos no empeora (¡Ojo! Que a veces también puede empeorar si no se tiene cuidado).


Como se observa, la mixtura ha sido muy fácil a nivel de código (véase la reducción en líneas de código de una opción frente a otra), se observa que no ha hecho falta re-entrenar nada y los modelos están por fuera, al menos, si no mejora la mixtura, lo que si nos ahorra es una pasta en consultoría y nos da flexibilidad por si mañana viene un nuevo proveedor que nos promete increíbles mejoras, de cambiar o no.


Viendo este tipo de cosas que repito, me las he encontrado en más de un sitio, al menos en mi caso, mucha tiene que ser la mejora de un stacking frente a una mixtura para que yo recomiende lo primero frente a lo segundo y desde luego, todo justificado con datos y no con ideas no contrastadas y peregrinas.

  • fjroar
  • 20 jun 2022
  • 5 Min. de lectura

Figura 1: Código de implementación de la fórmula de cálculo de RWA para hipotecas


Lo que pretendo con esta entrada es hacer un poco de “calculo gordo y poco fino” sobre unos datos cualesquiera tomados de kaggle y comparar los algoritmos utilizados por los actuales Data Scientist bajo un entorno regulatorio a la clásica regresión logística (y por ende credit scoring). ¡Ojo! Que no voy a hablar de Machine Learning, sino que lo que voy a hacer es comparar un algoritmo clásico frente a uno de corte más actual y por tanto no me meteré en lo que significaría realmente un aprendizaje realmente automatizado, lo que quedaría para otra entrada.

En este sentido, voy a tratar de un modo muy simplista, un tema muy complejo y delicado como es el del riesgo de crédito en banca y lo que tiene que ver con la estimación del capital regulatorio, donde se habla constantemente que con pequeñas mejoras de estimación, se conseguiría liberar grandes cantidades de dinero, pero … ¿Es esto cierto? ¿Cómo hacer una cuantificación de lo que se dice basados en datos? Para hacer lo anterior, consideré los datos de https://www.kaggle.com/datasets/uciml/default-of-credit-card-clients-dataset Unos 30.000 registros con una tasa de impago del 20% que son datos que los asimilaré a una posible cartera hipotecaria y para lo que voy a hacer una aproximación sencilla de estimación de mejora de un algoritmo avanzado frente a uno clásico.

Para lo anterior conviene saber que el capital regulatorio viene a ser como ese dinero que el banco debe tener en la hucha por si se produce un impago masivo por parte de sus clientes, o una crisis, … y poder seguir funcionando dotando de liquidez los depósitos de sus clientes. Así pues, cada vez que un banco concede un crédito, asume el riesgo de que el cliente no se lo devuelva íntegramente y para ello debe hacer una reserva de dinero para que, en grandes números, los que paguen, cubran a los que no pagan. Estas reservas de capital son revisadas anualmente y hay como 2 esquemas principales, el primero es que un banco reserva un 35% del riesgo que asume (en una hipoteca) y lo manda a la “huchaca” y el segundo es que el regulador permite que el banco calcule un porcentaje de reserva en función del riesgo de impago, basado en sus propios datos, acorde a la siguiente fórmula para hipotecas (véase https://www.bde.es/f/webbde/SJU/normativa/circulares/c200803.pdf pg 94):


En esta fórmula hay 2 parámetros fundamentales que debe estimar la entidad bancaria y son el parámetro PD (probability of default o probabilidad de que un cliente pague o no pague) y LGD (loss given default o el dinero que finalmente, dado que ha impagado, no se va definitivamente a recuperar, a veces se llama también severidad), en este ejercicio se va a suponer que el LGD es constante siempre vale 0.45

Pues bien, la fórmula anterior que proviene del modelo de Vacisek (ver por ejemplo https://www.cemla.org/PDF/boletin/PUB_BOL_LXII-03-03.pdf ) para riesgo de crédito y cuya obtención no resulta sencilla, aunque por ley la tienes que utilizar, esta fórmula tiene en cuenta consideraciones como la correlación del impago que se suele suponer como R = 0.15 y que se consiga tener capital suficiente a un percentil del 99.9%, según se considera en dicha formulación.

Pues bien, en este trabajo lo que se hace es estimar 2 modelos de riesgo de crédito (que podrían ser por ejemplo de admisión) uno bajo un algoritmo tipo regresión logística y otro bajo otro de tipo random forest, dado que los datos estaban relativamente bien, se dejaron todas las variables explicativas (salvo la ID) y la explicada (que se denomina target) y construyo los modelos que muestro en el código de mi github https://github.com/FJROAR/Ejemplo-Blog-RWA obteniendo los siguientes resultados en cuanto a área bajo la curva:

Regresión Logística: 72.38% Random Forest: 76.33%

Figura 2: Curvas ROC realizadas con la librería ROCR


Una de las cosas que se observa en los datos es que la tasa de default era del 20% y no es realista (el banco estaría quebrado no, lo siguiente … si fuera así), en este caso se va a suponer un calibrado “grosero” a un tasa promedio más comedida. Este proceso de calibrado en la realidad suele ser bastante complejo y requiere de un ciclo completo de al menos unos 10 años, pero aquí sencillamente se va a suponer que la probabilidad media real (incondicionada o independiente a la muestra) estaría en torno al 1% y por tanto lo que se crea es un factor f que convertiría la tasa promedio del dataset original en unas medias en torno a dicho 1% con el factor:

f = 0.01 / tasa ~ 0.04

Pues bien, tras esto se aplica una política de riesgos “trivial” del tipo que sólo se acepta riesgo si la probabilidad predicha y calibrada por el modelo resulta ser menor al 1%, se trabaja con el conjunto test, que no se usó en la muestra. Cuando sucede eso y si se suponen que las hipotecas de media están en torno a los 150.000€ se obtienen las siguientes cifras para cada una de la modalidad estándard o avanzada en la estimación “grosera” del riesgo de crédito que en el citado conjunto test resultan ser de:

Regresión Logística Random Forest

Modelo Estándard: 317.625.000 Modelo Estándard: 306.547.500

Modelo Avanzado: 368.339.934 Modelo Avanzado: 300.048.403

En este caso y para las pocas exposiciones que se consideran (casi unas 10.000 exposiciones) se observan cosas interesantes como:

  • No por aplicar un modelo construido a partir de datos mejora las metodologías estándard de los reguladores, hay que ver cómo son las carteras y si realmente hay muchas exposiciones de bajo riesgo

  • Un modelo avanzado puede mejorar a uno clásico y suponer un importante ahorro de capital, en este caso, frente a la propia metodología estándard el ahorro sería de un 2.12%, pero es que si se compara frente a lo que supondría el Modelo Estándard de una regresión logística, dicho ahorro estaría en torno al 5.86

  • Por tanto ¿Merece la pena pagar el coste de regulación en hacer que un modelo de analítica avanzada sea más interpretable o mejor detallado? Claramente implica mucho más trabajo pero el dilema a considerar es si porque resulta complejo pero funciona, ¿Es admisible que se deje o no inmovilizado más o menos capital?

  • Es claro que la regulación debe exigir, si alguna vez acepta un algoritmo avanzado, una elevada batería de test y de pruebas, pero también parece claro que el incentivo para que las entidades bancaria atraigan talento y hagan cosas avanzadas y bien, está también ahí

  • Indicar que en estadística no existen “los siempres”, ni “los nuncas”, todo depende, y bajo mi experiencia también es cierto que una logística bien trabajada puede igualar y en ocasiones superar perfectamente a un random forest o algoritmo superior si se actúa, como he visto en más de una ocasión como no “autómatas preparadores de datos” sino como auténticos científicos a los que les gusta analizar datos y aplicar técnicas analíticas


Finalmente conviene recordar que los cálculos a realizar en casos reales y bajo entornos regulados resultan mucho más complejos que los aquí realizados. Con esta entrada sólo se desea demostrar de modo muy divulgativo y práctico como algoritmos avanzados podrían permitir una mejora de la predictividad de los modelos actuales formados por Credit Scoring y Regresiones Logísticas en su mayoría.

© 2021 by Francisco J. Rodríguez Aragón. Proudly created with Wix.com

bottom of page