Archivo de la categoría: Modelos

Modelos tweedie con H2O. Mutualizar siniestralidad en base a factores de riesgo

Ya he escrito sobre la distribución tweedie en otra ocasión y hoy vuelvo a traeros un ejemplo de uso que además servirá para introducir un método, una forma de trabajar con modelos en H2O y R además de emplear gradient boosting machine (gbm) para la obtención de primas de riesgo. Ya hay buenos profesionales repartidos en el mercado laboral a los que les he mostrado como hacer modelos de riesgo para el sector asegurador con R y H2O dentro del Máster en Big Data de la UNED donde imparto el módulo de seguros. Pero hoy quiero traer al blog un resumen de otro tipo de modelos que nos pueden servir para segmentar una cartera de seguros en base a la siniestralidad esperada de un riesgo. Recordad que un seguro trata de mutualizar el gasto entre una cartera, no sé a priori quien va a tener un siniestro (¡si lo supiera!) pero si dispongo de información histórica de mi cartera y esa información me puede dar unas pistas sobre lo que ocurrirá a futuro (habitualmente un año), quiero ver que parte de esa información histórica es reproducible asumiendo siempre un error.

Para entender mejor como se mutualiza, como se reparte el riesgo, como se reparte la siniestralidad en nuestra cartera, vamos a emplear modelos tweedie, además los vamos a realizar con H2O y de paso os comento como trabajo en un entorno R + H2O. El ejemplo lo ilustramos con un conjunto de datos de la librería CASdatasets:

library(CASdatasets)
library(tidyverse)
data("norauto")

Para instalar la librería CASdatasets seguid las instrucciones, no hagáis el español como hice yo. El conjunto de datos de trabajo será norauto que contiene los datos de una cartera de seguros de automóviles. Como he comentado, si simplificamos, lo que buscamos es reproducir esa parte del pasado en el año siguiente. En nuestro caso tenemos un importe siniestral y si asumimos que no hay IPC (si, el IPC afecta a los seguros por eso os suben aunque no hayáis tenido siniestros Seguir leyendo Modelos tweedie con H2O. Mutualizar siniestralidad en base a factores de riesgo

La importancia del valor predictivo positivo en las pruebas diagnósticas

El valor predictivo positivo es un dato olvidado cuando realizamos una prueba diagnóstica o (mejor dicho) cuando empleamos este método de medir la potencia de mi modelo. En ocasiones un modelo parece excepcional, pero, cabe preguntarse si un buen modelo puede hacernos perder dinero. Además incidir en la necesidad de calibrar los modelos y medir su comportamiento predictivo y su “comportamiento económico”.

Imagen de previsualización de YouTube

Este video es continuación del que tenemos en la anterior entrada del blog. Espero despertar alguna conciencia e incidir sobre la importancia de medir económicamente el comportamiento de un modelo. La historia que se cuenta es real y supuso un buen proyecto para la compañía en la que trabajaba, no haciendo modelos, pero si instalando un nuevo entorno de detección de fraude. Saludos.

Principales elementos en las pruebas diagnósticas

Primer video que subo. Ilustro de modo sencillo algunos elementos de las pruebas diagnósticas con un ejemplo sencillo que podéis reproducir en cualquier hoja de cálculo. No soy precisamente un experto en este tipo de análisis pero me han sido útiles en algunos momentos de mi vida profesional, además, esa visión “simplista” de las cosas puede ayudar a muchos a comprender conceptos más complejos.

Imagen de previsualización de YouTube

Si tiene éxito continuaré hablando sobre razones de probabilidad. Gracias.

Identificar los municipios costeros y limítrofes de España con R.

Otro ejercicio con spatial data R Rstats y data sciense para el trabajo con objetos espaciales en el ecosistema big data. Empiezo con frase ilógica y ridícula para mejorar las búsquedas de Google pero el tema que traigo hoy creo que puede ser útil para aquellos que, dado un spatial data, tienen que identificar los polígonos que bordean ese objeto, en este caso vamos a identificar los municipios que bordean España, pueden ser limítrofes con Francia y Portugal o bien municipios costeros. No se plantean algoritmos complicados, como en entradas anteriores nos centramos en la extracción de mapas de GADM:

Obtención de los mapas necesarios

library(maptools)
library(raster)
library(maps)
library(tidyverse)
library(sqldf)

Espania <- getData('GADM', country='Spain', level=0)
Espania$name = Espania$NAME_1
Espania2 <- getData('GADM', country='Spain', level=4)
Espania2$name = Espania$NAME_1

Por un lado obtenemos el mapa de España sin división territorial que en GADM es el nivel 0 y por otro lado el municipal que es nivel 4. Un tipo brillante sería capaz de encontrar un algoritmo que identificara que polígonos no tienen adyacencia, pero un tipo mediocre pensaría "si cruzo el borde con los municipios, los objetos que crucen son el exterior"

Municipios del contorno

contorno <- map_data(Espania) %>% mutate(lat2=round(lat,1), long2=round(long,1)) %>% select(long2,lat2) 

municipios <- map_data(Espania2) %>% mutate(lat2=round(lat,1), long2=round(long,1))  %>% select(long2,lat2,region) 

contorno <- inner_join(municipios, contorno) 

En este punto hay aspectos claramente mejorables, el cruce se realiza por latitud y longitud, Seguir leyendo Identificar los municipios costeros y limítrofes de España con R.

El análisis de supervivencia en R para segmentar el churn

El análisis de supervivencia es uno de los olvidados por el Machine Learning y la nueva forma de ver el oficio. A la regresión logística si la damos algo de recorrido porque aparece en scikit-learn (con sus cositas), sin embargo, el análisis de supervivencia no tiene ese cartel porque en el momento que trabajas con un gran número de variables estos modelos “empiezan a echar chispas”.  Sin embargo ofrecen una serie de gráficos y resultados que más allá de la estimación nos describen problemas y pueden servirnos para segmentar poblaciones en base a la duración hasta la ocurrencia de un evento.

El modelo de supervivencia tiene como variable fundamental el tiempo hasta que ocurre un evento y como este tiempo se modifica en base a unas variables explicativas, mas allá de una tasa nos puede permitir identificar segmentos y poblaciones con comportamientos distintos. El ejemplo que quiero mostraros es el paradigma de todo lo que estoy contando, identificar segmentos de clientes que abandonan mi compañía de telecomunicaciones, mas allá de priorizar clientes en base a su probabilidad de anulación tratamos de identificar características que hacen que mi cliente dure más o menos en la compañía.

El ejemplo que vamos a usar está sacado de este:

https://github.com/zangell44/survival-analysis-lifeline-basics/blob/master/customer_churn.ipynb

Tenéis la descripción de las variables, la más importante es tenure, tiempo en meses hasta que se produce el evento y churn que es el evento, la cancelación de la línea, el resto de variables son propias de la línea. En nuestro caso vamos a trabajar con R porque me parecen interesantes los objetos que generan algunas funciones. Leemos los datos y realizamos una pequeña transformación sobre la variable respuesta:

datos <- read.csv('https://raw.githubusercontent.com/treselle-systems/customer_churn_analysis/master/WA_Fn-UseC_-Telco-Customer-Churn.csv')

datos$Churn <- as.integer(ifelse(datos$Churn=="Yes",1,0))

Las librerías de R que vamos a usar son survival y survminer Seguir leyendo El análisis de supervivencia en R para segmentar el churn

Modelos GAM con R. Dejando satisfechos a los equipos de negocio

Los modelos GAM (Generalized Additive Model) son el conjuntos de modelos que tenemos los estadísticos, actuarios, data scientist o como nos denominen en el momento que leas esto para dejar a nuestros equipos de negocio contentos con los resultados de nuestro modelo GLM. No voy a entrar en los aspectos teóricos de este tipo de modelos, hay documentación como esta que os puede ayudar. Por qué se quedan contentos los equipos de negocio, porque nos ayudan a dar sentido a los modelos. Retomemos un ejemplo que vimos en otra entrada del blog: https://analisisydecision.es/los-parametros-del-modelo-glm-como-relatividades-como-recargos-o-descuentos/ en esta entrada presentamos como el resultado de un modelo GLM se transforma en una relatividad, en un mecanismo para ofrecer recargos y descuentos.

Si desarrollamos un modelo GLM en último término podríamos enseñar este gráfico al responsable comercial:

Parece evidente que a mayor edad mayor proporción de siniestros, además, a partir de los 40 – 45 puede considerarse que las relatividades no varían. Se aprecian tendencias, pero no tiene sentido de negocio aplicar directamente los resultados de las estimaciones, no podemos aplicar esas relatividades obtenidas, es necesario realizar un suavizado y seguramente nos veríamos tentados, una vez hecho el modelo, de aplicar unos suavizados posteriores a la obtención de los parámetros. Podríamos hacer:

#g2 es el gráfico anterior obtenido en https://analisisydecision.es/los-parametros-del-modelo-glm-como-relatividades-como-recargos-o-descuentos/

spline_edad_factor <- smooth.spline(relatividades$rela,w=relatividades$exp,spar=0.65)
g2 + geom_line(aes(y=spline_edad_factor$y *5000), group=1, color="green",size=1.5)

Con smoot.spline hacemos una función de suavizado para nuestras relatividades, el nivel del suavizado lo controlamos con el parámetro spar que va desde 0 (sin suavizado) a 1 (función lineal). El caso es que el resultado de ese suavizado ya podría tener un mayor sentido de negocio y tendríamos más contentos a nuestro equipo comercial, pero... lo estamos haciendo a posteriori, eso no es una estimación, es echar balones fuera. Bien, qué os parece si tenemos un mecanismo para hacer una función previa a la estimación, pues este mecanismo se denomina modelo GAM y la librería de R que vamos a emplear para aproximarnos a ellos es mgcv. Vamos a replicar el modelo más básico con la edad del conductor. Seguir leyendo Modelos GAM con R. Dejando satisfechos a los equipos de negocio

Inteligencia Arficial frente a un juego de niños. La partícula tonta de Nicolás

Pablo Picasso decía que en aprender a pintar como los pintores del renacimiento tardó unos años pero pintar como los niños le llevó toda la vida y en ocasiones creo que hacemos las cosas difíciles porque nos creemos que hacemos cosas difíciles y entonces llega un niño de nueve años y dice “Papá un punto que primero vaya a la izquierda y luego a la derecha no es tan difícil”.
Os pongo en antecedentes, el pasado 7 de mayo fui al AWS Summit de Madrid porque Sergio Caballero iba a contar uno de los casos de uso. Los de AWS no se deben ni imaginar de las maravillas que ha hecho Sergio en el Ayuntamiento de Alcobendas porque sólo dejaron que hablara 10 minutos, muy torpes ellos, su trabajo es mejor escaparate que el planteado por Mai-Lan Tomsen, un error en el planteamiento de la jornada. El caso es que había una “competición” de vehículos que circulaban por un circuito guiados por complicados algoritmos de inteligencia artificial. Vimos algún “bucanero serio” de alguno de los participantes, ya sabemos reinforcement learning, pero reinforcement reinforcement. Otros participantes más o menos honrosos, en fin, distraído. Viendo la competición me entraron ganas de participar y al llegar a casa me siento a preparar un algoritmo que recorriera el circuito del Jarama de Madrid, no un circuito cualquiera un circuito donde yo he visto ganar carreras a Jorge Martínez Aspar.

Portátil y R, empiezo mi trabajo con imager, busco en la Wikipedia el circuito, lo cargo, genero un data frame, selecciono puntos y comienzo a diseñar mi propia estrategia de reinforcement learning combinadas con técnicas de machine learning, algo como “SVM direccionables” se acerca por detrás mi hijo y me suelta “Papá un punto que primero vaya a la izquierda y luego a la derecha no es tan difícil”. Bueno, pues en 20 minutos sale esto:

De momento no funciona pero no me digáis que no es genial la idea, lo que hace con pocas líneas de código y una consulta en sql. En el repositorio de analisisydecision tenéis el código en R que realiza esta maravilla, he llamado al código partícula tonta y tiene aspectos interesantes en cuanto al uso de la librería imager de R para el tratamiento de imágenes y como transformo una imagen en un data frame de coordenadas y por supuesto la genial idea de Nicolás.

Por cierto, al ver el resultado Nicolás dijo que no sólo derecha e izquierda, también era necesario un arriba y abajo. Tengo abandonado el proyecto, como muchos, pero la anécdota me ayudó en mi trabajo.

Gráfico de correlaciones entre factores. Gráfico de la V de Cramer

Un gráfico muy habitual a la hora de construir modelos de riesgo para el cálculo de tarifas es el gráfico de correlaciones de la V de Cramer que nos sirve para medir la correlación entre factores, entre variables cuantitativas hace muchos años ya escribí sobre el tema. Hoy os traigo la creación de un corrplot con R aplicado a la V de Cramer y además os descubro una función muy elegante para realizar este análisis de correlaciones entre factores, esta función está sacada de stackoverflow (como no) y añado un análisis gráfico que nos permite conocer algunas opciones de corrplot.

 library(vcd)
library(corrplot)
library(tidyverse)

data(mtcars)

#Partimos de una matriz vacía con las dimensiones apropiadas
empty_m <- matrix(ncol = length(correlaciones),
                  nrow = length(correlaciones),
                  dimnames = list(names(correlaciones),
                                  names(correlaciones)))

#Calculamos el estadístico y vamos rellenando la matriz
calculate_cramer <- function(m, df) {
  for (r in seq(nrow(m))){
    for (c in seq(ncol(m))){
      m[[r, c]] <- assocstats(table(df[[r]], df[[c]]))$cramer
    }
  }
  return(m)
}

Lo que hace la brillante función es, partiendo de una matriz cuadrada con los factores, ir rellenando con el correspondiente cálculo de la V de Cramer. El resultado final será igual que una matriz de correlaciones por lo que podremos realizar el gráfico.

predictoras <- c("cyl","vs","am","gear","carb")
correlaciones <- select(mtcars,predictoras)

cor_matrix <- calculate_cramer(empty_m ,correlaciones)
#Ya podemos graficarlo
corrplot(cor_matrix, method="number", is.corr=F,type="upper", diag=F, cl.lim=c(0,1))

remove(correlaciones)

El resultado:

Aspectos interesantes con la función corrplot, con method = "number" sale el valor, no me gustan las bolas, aunque podéis probar con pie, mejor poned is.corr = F con type="upper" sale la parte superior de la matriz, quitamos la diagonal que es 1 con diag=F y la V de Cramer es un valor que va entre 0 y 1 con cl.lim establecemos los límites de la leyenda en el gráfico de correlaciones. A partir de aquí cada uno que establezca un umbral para determinar que dos factores están correlados, yo por ejemplo lo establezco en 0.33, saludos.

Preparar nuestros datos para sklearn. Pasar de string a número

Cuando trabajamos con python y sklearn necesitamos que todos los datos que vamos a modelizar sean númericos, si tenemos variables carácter necesitamos previamente transformarlas a números. La forma más rápida para realizar esta tarea es emplear preprocesing de sklearn:

import pandas as pd
dias = {'dia': ['lunes','martes','viernes','miercoles','jueves','martes','miercoles','jueves','lunes']}
dias = pd.DataFrame(dias)
dias

Creamos un data frame a partir de una diccionario que se compone de los días de la semana ahora vamos a codificar las etiquetas con el LabelEncoder de sklearn:

from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(dias['dia'])

Podemos listar las clases:

list(le.classes_)

Me gustaría destacar que hay que tener especial cuidado con el orden de las codificaciones porque es un orden léxico-gráfico, no va por orden de aparición:

dias = le.transform(dias['dia'])
dias

Ahora ya estamos en disposición de poder emplear sklearn para entrenar nuestro modelo.

Machine learnig. Análisis gráfico del funcionamiento de algunos algoritmos de clasificacion

Letra_O

De forma gráfica os voy a presentar algunas técnicas de clasificación supervisada de las más empleadas en Machine Learning y podremos ver cómo se comportan de forma gráfica en el plano. Como siempre prefiero ilustrarlo a entrar en temas teóricos y para esta tarea se me ha ocurrido pintar una letra O y comenzar a trabajar con Python, así de simple. Lo primero es tener los datos, evidentemente serán puntos aleatorios en el plano donde pintamos una variable dependiente con forma de O:

import numpy as np
import pandas as pd
from pylab import *

largo = 10000

df = pd.DataFrame(np.random.uniform(0,100,size=(largo, 2)), columns=list('XY'))

dependiente1 = np.where(((df.X-50)**2/20**2 + (df.Y-50)**2/40**2>1) ,1,0)
dependiente2 = np.where(((df.X-50)**2/30**2 + (df.Y-50)**2/50**2>1) ,1,0)
dependiente = dependiente1 - dependiente2

plt.scatter(df.X, df.Y,c=dependiente,marker=".")
show()

Se crea un data frame con 10.000 registros y dos variables aleatorias con valores entre 0 y 100 X e Y. Soy consciente de la forma en la que se obtiene la variable dependiente, no entiendo como funciona np.where con condiciones múltiples y por ello toman valor 1 aquellas observaciones del plano que están entre las dos eclipses que pinto dentro del plano. Con todo esto tenemos unos datos como ilustran el scatter plot con el que se inicia esta entrada. El siguiente paso será dividir los datos en validación y test mediante train_test_split:

#Dividimos en validacion y test
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(df,dependiente,stratify=dependiente,
test_size = 0.5, random_state=123)

Ahora vamos a estudiar gráficamente como se comportan algunos algoritmos de machine learning para clasificar la letra O en el espacio. Empezamos por los árboles de decisión Seguir leyendo Machine learnig. Análisis gráfico del funcionamiento de algunos algoritmos de clasificacion