Archivos de la categoría Modelos

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 Sigue leyendo Machine learnig. Análisis gráfico del funcionamiento de algunos algoritmos de clasificacion

Ajuste de splines con R

spline_R1

El ajuste por polinomios, el ajuste por spline, es una técnica imprescindible dentro de análisis actuarial. Como siempre la parte matemática y la parte debida al puro azar pueden arrojar discrepancias. ¿Dónde son mayores estas discrepancias cuando usamos métodos estadísticos clásicos? Donde siempre, donde tenemos pocos datos, el comportamiento errático que tiene una tendencia y que habitualmente achacamos a la falta de información los actuarios gustan de corregirlo con ajuste por cúbicas, aunque es mejor emplear ajuste por polinomios ya que no tienen que ser necesariamente polinomios de grado 3. En mi caso particular tengo un Excel que no puedo poner a vuestra disposición porque no lo hice yo, creo que lo hizo alguna divinidad egipcia y desde entonces circula por el mundo la función cubic_spline. Hoy quiero aprovechar el blog no solo para sugeriros como realizar splines con R, además quería pedir ayuda para crear una herramienta en shiny que permita realizar este ajuste que voy a mostraros a continuación.

Disponemos de una serie de datos, probablemente una serie de parámetros de un modelo, que tiene tendencia. Deseamos ajustar un polinomio que recoja esa tendencia y que evite por interpolación los comportamientos erráticos que tienen algunos puntos de la serie. El código de R es Sigue leyendo Ajuste de splines con R

El parámetro gamma, el coste, la complejidad de un SVM

letra_o_svm_r

Cuando clasificamos datos con SVM es necesario fijar un margen de separación entre observaciones, si no fijamos este margen nuestro modelo sería tan bueno tan bueno que sólo serviría para esos datos, estaría sobrestimando y eso es malo. El coste C y el gamma son los dos parámetros con los que contamos en los SVM. El parámetro C es el peso que le

damos a cada observación a la hora de clasificar un mayor coste implicaría un mayor peso de una observación y el SVM sería más estricto (este link aclara mejor las cosas). Si tuvieramos un modelo que clasificara observaciones en el plano como una letra O podemos ver como se modifica la estimación en esta secuencia en la que se ha modificado el parámetro C:

r_svm_2

Sigue leyendo El parámetro gamma, el coste, la complejidad de un SVM

Como salva la linealidad una red neuronal

En los últimos tiempos estoy empeñado en usar redes neuronales para la tarificación en seguros. Históricamente la tarificación de seguros, el pricing, se ha basado en modelos lineales generalizados GLM (sus siglas en inglés) porque su estructura es sencilla, se interpreta bien y no olvidemos que el sector asegurador está regulado y es necesario elaborar una nota detallada de cómo se articula una tarifa y el GLM nos ofrece una estructura multiplicativa que se comprende y con la que los reguladores se sienten muy cómodos. Sin embargo, una red neuronal es el paradigma de "caja negra", ¿cómo podemos saber que hace esa caja negra? Estoy trabajando en ello, la descripción del funcionamiento de las ponderaciones de una red está muy arriba en la lista de mis tareas pendientes.

Pero esta entrada del blog va encaminada a describir de forma como las neuronas de una red neuronal salvan la linealidad y como un mayor número de neuronas son capaces de ajustar mejor a una estructura compleja y si llegamos a describir como funciona esa estructura compleja podremos usar estas técnicas para realizar tarifas de riesgo. 
Como siempre, para ilustrar el funcionamiento se emplea un ejemplo muy sencillo:

#Variable independiente
indep = runif(500,100,3000)
#Función para crear la variable dependiente
foo = function(x){ mean(x)*(1-sin(-0.006042*x)+sqrt(x/100))
}
dep = sapply(indep,foo)

dep=dep+(runif(length(dep),-500,500))

dep = as.matrix(dep)
indep = as.matrix(indep)
plot(indep,dep)

redes_neuronales_tarificacion_seguros1

Creamos unos datos aleatorios que serán en una matriz nuestros datos inependientes y como variable dependiente una variable que dibuja una nube de puntos que simula una curva de observaciones. Si realizamos un modelo lineal se ajustará una recta sobre los datos, una red neuronal mejorará los resultados. Y para demostrarlo vamos a emplear el paquete de R monmlp que realiza un perceptrón multicapa Sigue leyendo Como salva la linealidad una red neuronal

Qué pasa si uso una regresión de poisson en vez de una regresión logística

Para un tema de mi trabajo voy a utilizar una regresión de poisson en vez de una regresión logística, el evento es si o no y no tiene nada que ver el tiempo, ni se puede contabilizar como un número, pero a efectos prácticos es mejor para mi usar una regresión de poisson. Entonces, ¿qué pasa si hago una poisson en vez de binomial? Como siempre si mi n es muy grande hay relación entre ambas distribuciones. Pero yo quiero saber si me puede clasificar mis registros igual una regresión de poisson y una binomial y se me ha ocurrido hacer un ejercicio teórico muy simple.

Construyo con SAS 10.000 datos aleatorios con las variables independientes x e y normalmente distribuidas y la variable dependiente z que es una función logística "perfecta" de x e y:

data logistica;
do i=1 to 10000;
x=rannor(8);
y=rannor(2);
prob=1/(1+exp(-(-10+5*x-5*y)));
z=ranbin(8,1,prob);
output;
end;
drop i;
run;

data entrenamiento test;
set logistica;
if ranuni(6)>0.8 then output test;
else output entrenamiento;
run;

proc freq data=entrenamiento;
tables z;
quit;

Separo los datos en entrenamiento y test y vemos que un 8% aproximadamente de mis registros tienen valor 1. Sobre estos datos hago una logística y una poisson y veo los parámetros Sigue leyendo Qué pasa si uso una regresión de poisson en vez de una regresión logística

Resolución del juego de modelos con R

Hace mucho planteé un juego de identificación de modelos con R y ya se me había olvidado daros la solución. Pensando en el Grupo de Usuarios de R y en hacer algo parecido en una presentación recordé que había que solucionar el ejercicio. Lo primero es la creación de los datos, se me ocurrió una función sencilla y una nube de puntos alrededor de ella:

#Variable independiente
indep = runif(500,100,500)
#Función para crear la variable dependiente
foo = function(x){ mean(x)*(1-sin(-0.006042*x))
}
dep = sapply(indep,foo)

dep=dep+(runif(length(dep),-100,100))
datos = data.frame(cbind(indep,dep))
plot(datos)

juego_modelos1

Seleccionamos los datos de entrenamiento y test:

#Datos de entrenamiento y test
indices = sample(1:length(dep),length(dep)/2) 
entrenamiento = datos[indices,]
test = datos[-indices,]

El más sencillo de todos era el caso de la regresión lineal y fue el que puse de ejemplo:

#REgresión lineal
modelo.1=lm(dep ~ indep,entrenamiento)
plot(test)
points(test$indep,predict(modelo.1,test),col="red")

juego_modelos2

Una línea que pasa por la media de la nube de puntos. Otro de los casos menos complicados es el árbol de regresión Sigue leyendo Resolución del juego de modelos con R

KNN con SAS. Mejorando K-Means

Imagen de previsualización de YouTube

La clasificación por k vecinos más cercanos es EL MÉTODO supervisado no paramétrico. El KNN, si empleamos las siglas en inglés, clasifica las observaciones en función de su probabilidad de pertenecer a uno u otro grupo, en el video que encabeza la entrada queda muy bien explicado. El caso es que tenemos la posibilidad de realizar esta clasificación con SAS STAT y el PROC DISCRIM y me parece interesante dedicarle unas líneas. Hace años ya hablamos de segmentación con SAS  y vamos a emplear los mismos datos para ilustrar esta entrada. Primero generamos un conjunto de datos con datos simulados de 3 esferas que clasificamos en 3 grupos:

data pelota;
do i = 1 to 1000;
a=0; b=5; x = a+(b-a)*ranuni(34);
a=0; b=5; y = a+(b-a)*ranuni(14);
grupo=1;
distancia = sqrt(((x-2.5)**2)+((y-2.5)**2));
if distancia < 2.5 then output;
end;
run;

data pelota1;
set pelota;
grupo=1;
run;

data pelota2;
set pelota;
x = x+4.5;
grupo=2;
run;

data pelota3;
set pelota;
x = x+2.5;
y = y+3.5;
grupo=3;
run;

data datos;
set pelota1 pelota2 pelota3;
run;

proc gplot data=datos;
	plot y * x = grupo; 
run;quit;

KNN_SAS1

Si realizamos un análisis mediante k-means sin asignar centroides obtenemos esta clasificación Sigue leyendo KNN con SAS. Mejorando K-Means

Valor atípico o pocos registros. Animación con R

outlier¿Cómo influye un solo punto en una recta de regresión? Evidentemente cuanto menos observaciones tengo más puede "descolocar" la recta de regresión. Sin embargo, cuantos más puntos tengo más complicado es encontrar ese punto con una recta de regresión, sin analizar los residuos podríamos hasta pasarlo por alto, aunque puede ser que nos interese ese punto. El código de R que genera la animación es:

library(animation)
saveGIF(
  for (i in c(100,50,25,10,5,1)){
    x <- seq(-500,500, by = i )
    y=sin(x)+x/100
    y[10]=y[10]+10
    plot (y,x,main=paste("Regresión lineal con ",1000/i," observaciones"))
    reg <- lm(y~x)
    points( fitted.values(reg),x, type="l", col="red", lwd=2)},
  interval = .85, ,movie.name="/Users/raulvaquerizo/Desktop/R/animaciones/outlier.gif")

Interpretación de los parámetros de un modelo GLM

Muchos estudiantes  terminarán trabajando con GLM que siguen buscando relaciones lineales en multitud de organizaciones a lo largo del planeta. Y hoy quería ayudar a esos estudiantes  a interpretar los parámetros resultantes de un GLM, más concretamente los resultados de un PROC GENMOD de SAS aunque lo que vaya a contar ahora se puede extrapolar a otras salidas de SAS o R. En la línea de siempre no entro en aspectos teóricos y os remito a los apuntes del profesor Juan Miguel Marín. Con un GLM al final lo que buscamos (como siempre) es distinguir lo que es aleatorio de lo que es debido al azar a través de relaciones lineales de un modo similar a como lo hace una regresión lineal, sin embargo los GLM nos permiten que nuestra variable dependiente no sólo siga una distribución normal, puede seguir otras distribuciones como Gamma, Poisson o Binomial. Además un GLM puede trabajar indistintamente con variables categóricas y numéricas pero yo recomiendo trabajar siempre con variables categóricas y en la práctica cuando realizamos un modelo de esta tipo siempre realizaremos agrupaciones de variables numéricas. Si disponemos de variables agrupadas, de factores, los parámetros de los modelos nos servirán para saber como se comporta nuestra variable dependiente a lo largo de cada nivel del factor.

El modelo siempre fija un nivel base del factor, un nivel que promedia nuestros datos y el resto de niveles corrigen el promedio en base al coeficiente estimado. Imaginemos que modelizamos el número de abandonos en 3 carreras de coches, cuando la carrera se disputa en un circuito A el número de abandonos es 5, sin embargo en el circuito B son 10 y en el circuito C son 15. Si fijamos como nivel base de nuestro factor circuito el B tendríamos un modelo de este modo abandonos = 10 + 0.5*es circuito A + 1*es circuito B + 1.5*es circuito C + Error. El nivel base promedia nuestro modelo por lo que va multiplicado por 1 y el resto de niveles se corrigen por su multiplicador. Esta es la base de la modelización multivariante en el sector asegurador. Veamos en un ejemplo como se articulan los parámetros de estos modelos. Simulamos unos datos con la probabilidad de tener un siniestro por edad, zona y edad:

data datos_aleatorios;
do idcliente = 1 to 2000;
if ranuni(1) >= 0.75 then sexo = "F";
else sexo="M";
edad = ranpoi(45,40);
if ranuni(8)>=0.9 then zona=1;
else if ranuni(8)>0.7 then zona=2;
else if ranuni(8)>0.4 then zona=3;
else zona=4;
output;end;
run;

data datos_aleatorios;
set datos_aleatorios;
if zona=1 then incremento_zona = 0.1+(0.5-0.1)*ranuni(8);
if zona=2 then incremento_zona = 0.1+(0.7-0.1)*ranuni(8);
if zona=3 then incremento_zona = 0.1+(0.2-0.1)*ranuni(8);
if zona=4 then incremento_zona = 0.1+(0.9-0.1)*ranuni(8);

incremento_edad=exp(1/edad*10)-1;

sini = (ranuni(9) - sum(incremento_zona, -incremento_edad))>0.8 ;
run;

Se da una probabilidad aleatoria de tener un siniestro que se ve incrementada o decrementada por la zona y la edad, el sexo, aunque aparece, no influye. El número de siniestros suponemos que sigue una distribución de poisson. Para entender mejor como funciona un GLM vamos a agregar los datos por los factores en estudio y contamos el número de clientes sumando el número de siniestros:

proc sql;
create table datos_agregados as select
sexo,
case
when edad<= 30 then "1 menos 30"
when edad<= 40 then "2 31-40"
when edad<= 50 then "3 41-50"
else "4 mas 50" end as edad,
zona,
log(count(idcliente)) as exposicion,
sum(sini) as sini
from datos_aleatorios
group by 1,2,3;
quit;

Nuestros datos tienen que ir ponderados por el logaritmo del número de clientes, será nuestro offset, ya que no es lo mismo tener un siniestro en un grupo de 2 clientes que un siniestro en un grupo de 20 clientes. Ponderados por el logaritmo porque siempre cuesta menos trabajar con números pequeños y además tienen unos superpoderes de los que no somos conscientes hasta que trabajamos con ellos. Ahora estos datos son los que emplearemos para el modelo:

proc genmod data=datos_agregados;
class sexo edad zona;
model sini = sexo edad zona / dist = poisson
link = log
offset = exposicion;
run;

GENMOD como todos los procedimientos de SAS necesita que le indiquemos las variables categóricas, en model especificamos el modelo y las opciones son los aspectos más interesantes. En dist especificamos la distribución de nuestra variable dependiente en link la función de enlace que vamos a emplear y como offset para ponderar la variable exposición que hemos creado a la hora de agregar los datos. Y los parámetros que estima este modelo son:

parametros_modelo_GENMOD1

El intervalo de confianza de algunos estimadores contiene el valor 0, esos factores no son significativos como es el caso del sexo o bien puede haber agrupación de niveles de factores como es el caso de la edad entre 31 y 50 años o la zona 2 que puede unirse con otra zona. Vemos que el estimador del nivel base siempre es el último nivel del factor (esto puede cambiarse) y toma valores 0 y no 1 como habíamos usado en el ejemplo, para transformarlo en 1 sólo hemos de realizar el exponencial:

Parameter   Estimate
Intercept 0.062
sexo F 0.932
sexo M 1.000
edad 1 menos 30 2.951
edad 2 31-40 2.062
edad 3 41-50 1.494
edad 4 mas 50 1.000
zona 1 1.854
zona 2 1.218
zona 3 3.091
zona 4 1.000
Scale 1.000

Vemos que la zona 3 tiene casi el triple de siniestralidad que la zona 4 y lo mismo sucede con las edades jóvenes frente a las mayores edades, en cuanto al sexo que no fue significativo tenemos que las mujeres tienen un 7% menos de siniestralidad. Algunos resultados, aunque no salgan estadísticamente significativos, es evidente que pueden interesarnos comercialmente ya que mi producto puede dar un descuento a las mujeres y aunque sea pequeño se puede mantener, igual razonamiento para algunas zonas o grupos de edad susceptibles de unirse entre ellos. Este ejemplo es muy burdo pero aquellos que empiecen a trabajar con GLM se van a encontrar situaciones de este tipo, es necesario interpretar los parámetros estimados para describir como funciona el modelo pero igual de  importante es la agrupación de factores y el posterior suavizado de los parámetros.

Truco para EMB Emblem. Cambiar el nivel base de un factor

Un buen truco que me han descubierto hoy para los usuarios de EMB Emblem, como cambiar el nivel base de un factor de datos sin necesidad de pasar por los datos (habitualmente SAS) o sin hacerlo a posteriori (habitualmente Excel y lo que hacía el ahora escribiente). Cuando se generan los datos se genera el fichero binario *.BID y el fichero que se emplea para leer ese fichero *.FAC; para alterar el nivel base debemos abrir este archivo *.FAC con un block de notas o cualquier editor de texto plano. Al abrirlo tendremos lo siguiente:

XXXXXXXXXX        --> ES EL NOMBRE DEL ARCHIVO
99                                 -->ES EL NÚMERO DE FACTORES
XXXXXXXXXX.Bid --> ES EL NOMBRE DEL ARCHIVO BINARIO CON LOS DATOS
0
99999999                   --> ES EL NÚMERO DE REGISTROS
No. Levels Base         --> ES LA DESCRIPCION DE LO QUE VIENE A CONTINUACIÓN
XXXXXXXXXXXX  --> NOMBRE DE UN FACTOR
999                 99         --> EL PRIMERO ES EL NÚMERO DE NIVELES Y EL SEGUNDO ES EL NIVEL BASE

ASÍ PARA TODOS LOS FACTORES. Si deseamos cambiar el nivel base de un factor sólo tenemos que cambiar ese segundo número que hay tras cada definición de los factores. Un truco muy sencillo y que será de utilidad para aquellos que usáis EMB Emblem. Saludos.