En este blog se exploran las posibilidades de analizar datos y crear modelos basados en la Teoría de la Información usando Powerhouse

lunes, 22 de octubre de 2007

El problema XOR

A principios de los 60 Frank Rosenblatt propuso una técnica llamada Perceptron Convergence Procedure para entrenar una red neuronal capaz de resolver simples problemas de reconocimiento de patrones.

El Perceptron era una red neuronal sin unidades ocultas, lo que no le permitía resolver ciertos problemas. Esta dificultad fue el tema principal del libro Perceptrones de Seymour Papert y Marvin Minsky.

Uno de los problemas más conocidos que no podía resolver el Perceptron era una función lógica llamada OR Exclusiva o simplemente XOR. Las funciones lógicas tienen normalmente dos entradas y una salida que depende de los valores de las entradas. Las entradas y las salidas pueden tomar dos valores: Verdadero y Falso, ó 0 y 1. Así para cada función lógica existe una tabla que indica cuál será la salida dada la combinación de los valores de la entrada. Para la función XOR la tabla es la siguiente:

El resultado de XOR será Verdadero (1) sólo si las dos entradas son distintas, sino será Falso (0).

Una manera de ver por qué este aparentemente simple problema ponía en dificultades al Perceptron, es representar cada entrada en un espacio de dos dimensiones, una para X y la otra para Y.

El Perceptron puede resolver problemas que son linealmente separables, o sea, que exista una línea (o hiperplano) que separe grupos de entradas que tengan la misma salida. En el caso del XOR es imposible encontrar tal solución, como puede verse en el siguiente gráfico


La entradas que tienen el mismo resultado en la función XOR son 0,1 y 1,0 por un lado, y 0,0 y 1,1 por el otro. En el gráfico se puede notar que no es posible encontrar una línea que separe estas entradas en dos grupos.

Luego de la publicación del libro de Minsky y Papert, el campo de la investigación de las redes neuronales comenzó a debilitarse y la mayoría de sus investigadores se pasaron al área del la Inteligencia Artificial simbólica.

A fines de los 70 y principios de los 80 se descubre cómo entrenar redes neuronales multicapas capaces de resolver cualquier tipo de problemas, incluyendo el XOR.

Resumiendo, una red neuronal con una capa oculta (hidden layer) resuelve sin inconvenientes el problema del XOR.

¿Qué pasa con Powerhouse? ¿Es capaz de resolver el XOR?

coinciden con las reglas del El modelo OPFIT no puede lograrlo, pero sí el MAXIT. Abajo se ve el modelo que se obtiene. Tiene 4 reglas y logra un 100% de aciertos. Las reglas que encuentra el modelo MAXIT son las reglas que definen las función XOR.


Para encontrar el modelo se usaron datos de entrenamiento que contenían alrededor de 1000 ejemplos del XOR

Datos de prueba contaminados

Una de las claves para asegurarnos que un modelo tendrá el rendimiento esperado cuando lo pongamos a trabajar con datos nuevos es haberlo probado con datos históricos que no se hayan usado absolutamente para nada.

Esto parece una obviedad pero muchas veces se toman ciertas decisiones que terminan contaminando los datos de prueba.

Hay dos maneras de contaminar los datos de prueba, en el armado de los mismos y en las pruebas del modelo.

Armado de los datos de prueba

Los datos de prueba (test set) deben ser armados de la misma manera en que se armaron los datos de entrenamiento (training set). Quiero decir, si a una variable se la transformó de una determinada manera, por ejemplo, se la transformó de continua a discreta utilizando determinados rangos, a la misma variable de los datos de prueba se la debe tranformar usando los mismos rangos. Esto está claro y rara vez trae inconvenientes. El problema está en la manera en que se obtuvo la transformación. En nuestro ejemplo, cómo se obtuvieron los rangos.

Los datos de prueba no deben ser usados para obtener una transformación.

Es imprescindible separar los datos de prueba antes de obtener cualquier transformación que se desee aplicar tanto a los datos de entrenamiento como a los de prueba.

El primer paso de cualquier proyecto de Data Mining debe ser separar los datos de entrenamiento y de prueba. Esta separación debe ser al azar y sin reemplazo.

Luego, si se desea trabajar los datos para encontrar las mejores transformaciones, se deben usar sólo los datos de entrenamiento. Una vez que se encuentran todos los parámetros necesarios para transformar las variables, se usarán estos mismos parámetros para transformar las variables de los datos de prueba.

Uso de los datos de prueba

Una vez que se cuenta con los datos de entrenamiento y de prueba se deben usar los datos de entrenamiento para crear el modelo y solamente cuando uno está convencido de tener el modelo final, recién ahora será el momento de usar los datos de prueba para estimar rendimiento que el modelo tendrá cuando trabaje con datos nuevos.

Si la herramienta que se usa para encontrar el modelo necesita de un conjunto de datos de prueba, entonces es necesario que haya dos tablas de datos de prueba: una para que use la herramienta de modelado y otra que nos reservamos para la prueba final.

Por ejemplo, las redes neuronales necesitan un conjunto de datos de prueba, normalmente llamado test set, para evitar que la red copie el ruido (Para una discusión detallada de lo que significa el ruido en los datos se puede consultar ¿Qué es el ruido?). A medida que la red va modificando sus ponderadores (weights) probando una y otra vez los datos de entrenamiento, se corre el riesgo que la red aprenda detalles que sólo aparecen en estos datos. Para evitar este comportamiento no deseable, una vez cada n ciclos de entrenamiento, a la red se la prueba con otros datos, los datos de prueba, para confirmar que su rendimiento sigue mejorando no solo en los datos de entrenamiento sino con otros independientes. Cuando, el rendimiento sobre los datos de prueba deja de mejorar, se detiene el entrenamiento y la red queda entrenada.

El problema es que los datos usados durante el entrenamiento, de alguna manera formaron parte de este entrenamiento y de esta manera quedaron contaminados. Así, que en el caso de las redes neuronales es necesario un tercer conjunto de prueba. El rendimiento de la red será estimado usando este tercer conjunto de datos.

Powerhouse no necesita de datos de prueba para crear los modelos. Los algoritmos basados en la Teoría de la Información son tan simples y directos que no requieren que los datos de entrenamiento sean evaluados una y otra vez.

De todas maneras, si usando Powerhouse o alguna otra herramienta que no necesita datos de prueba (como una regresión lineal por ejemplo) se usan los datos de prueba para elegir el mejor modelo, entonces estos datos también se contaminan y se debería contar con un tercer conjunto de datos para la prueba final.

En resumen, los datos de prueba final (a veces llamados datos de evaluación) deben usarse sólo una vez, ya que al ser usados quedarán automáticamente contaminados.

Una manera de obtener nuevos datos de prueba es volver a empezar todo desde el principio.

jueves, 18 de octubre de 2007

Pasos para construir un score

En este artículo explicaré lo simple que es armar un score en Powerhouse. Como ejemplo utilizaré datos de una compañia de seguros publicados para una competencia de Data Mining y que actualmente sirven como benchmark.

El problema a resolver es muy simple:

¿Podría decirme quién está interesado en comprar una póliza de seguros para una casa rodante (caravan) y explicarme por qué?

Para resolver el problema se publicaron dos tablas de datos, una con 85 variables explicatorias acerca de quién compró o no una póliza en el pasado. O sea, cada fila consiste de 85 variables independientes más otra variable dependiente que indica con 1 ó 0 si la persona compró o no. La otra tabla es similar a la anterior excepto porque no contiene la variable que indica si la persona compró la póliza o no.

Si estuviéramos trabajando en un proyecto real con una compañía de seguros, la primera tabla de datos podría venir de una campaña de marketing realizada con una muestra de los clientes y la segunda tabla estaría formada por los clientes que no participaron en la campaña anterior.

Con el propósito de minimizar los costos de la segunda campaña (la que se hará con la segunda lista de clientes), la oferta no será enviada a toda la lista de clientes, sino a aquellos 800 clientes con mayor probabilidad de que compren el seguro.

Así que los pasos a realizar en el proyecto serán:
  1. Construir un modelo usando los datos de la primera tabla
  2. Aplicar el modelo a la segunda tabla para obtener una probabilidad de que el cliente compre el seguro
  3. Seleccionar los 800 clientes con mayor probablidad
En un proyecto real se enviarían los folletos a estos 800 clientes con la esperanza que compraran la póliza un porcentaje similar al obtenido en las pruebas con la primera tabla. Pero en nuestro caso usaremos un dato que fue publicado luego que la competencia finalizó. Este dato fue la lista de los clientes pertenecientes a la segunda tabla y que compraron la póliza. Dicho de otro modo, nuestra segunda tabla contiene la variable a predecir. De este modo podremos probar el modelo y compararlo con los resultados obtenidos por los participantes de la competencia.

En la página web The Insurance Company (TIC) Benchmark hay más detalles del problema con los datos y los resultados.

Un score es un número que tiene asociada una probabilidad. Un score de riesgo de crédito indicará la probabilidad de falta de pago.

En este caso, el score tendrá asociada la probabilidad de que el cliente compre la póliza de seguros.

Bueno, luego de esta larga introducción podemos comenzar con el proyecto.

Powerhouse tiene tres modelos que generan un score, el OPFIT, el MAXIT y el Scorecard. Para esta tarea podemos usar el modelo OPFIT o el Socrecard.

Comenzamos cargando los datos y definiendo CARAVAN como la variable a predecir (es la variable 86). Hay que tener en cuenta que no hace falta hacer ninguna preparación previa de los datos. Cuando los mismos son cargados en Powerhouse, quedan automáticamente preparados para que cada variable exponga al máximo la información que pueda contener acerca de la variable a predecir.

Al terminar la carga y la preparación de los datos (esta preparación en realidad forma parte de algo más complejo que es un mapeo de información, pero para este ejercicio no hace falta considerar este tema), aparece una ventana de estadísticas que sirve para realizar un análisis exploratorio

La pantalla muestra una lista de todas las variables con varias columnas con información acerca de la misma. La parte inferior de la ventana muestra más detalles acerca de la variable que está seleccionada en ese momento.

En un proyecto real esta información es muy útil para verificar si las variables contienen la información que se espera que tengan.

El siguiente paso es seleccionar las variables más importantes. El modelo que vayamos a construir debe estar basado en una pocas variables por varias razones:
  1. Es más simple de entender
  2. Existe mayor probabilidad de que funcione correctamente con datos nuevos
  3. Se facilita la preparación de variables para el área de sistemas
En un siguiente artículo discutiré este tema con mayor profundidad.

Tenemos a disposición 85 variables. ¿Cómo seleccionar un grupo óptimo de variables? La tarea no es simple debido a la explosión combinatoria que aparece si se desean probar todos los grupos posibles. Afortunadamente Powerhouse usa un método basado en la Teoría de la Información que le permite encontrar un grupo óptimo de variables en muy poco tiempo (para este caso Powerhouse tardó 30 segundos para encontrar las variables con mayor información acerca de la variable a predecir). La siguiente tabla muestra las variables seleccionadas

Las variables aparecen en orden. O sea, PPERSAUT es la variable que mayor información aporta acerca de si el cliente comprará o no la póliza. La siguiente variable es la que mayor información adicional aporta., y así sucesivamente. Las 5 variables juntas aportan un 58% de la información necesaria para predecir sin errores si el cliente comprará o no la póliza.

Powerhouse no continuó seleccionando más variables porque la siguiente variable no aportaría la suficiente información adicional para justificar la pérdida de representatividad de la muestra con la que se construirá el modelo. Dicho de otro modo, Powerhouse nos dice: "Para obtener un buen modelo que funcione tanto con datos del training set como con datos nuevos, éstas son las 5 variables recomendadas"

Si bien no es necesario para este artículo profundizar más en el análisis de las variables seleccionadas, vale la pena notar que las últimas dos variables parecen aportar más información que cada una del resto, tomadas por separado. O sea, la última variable aporta 58.11% - 36.90% = 21.21% de información adicional. De la misma manera, la variable anterior aporta 17.26%. Esto parece contradecir lo que dije anteriormente, que la primer variable es la que lleva la mayor cantidad de información posible. Pero esta contradicción es sólo aparente. Lo que está sucediendo es que las variables que van siendo agregadas están interactuando con las ya seleccionadas previamente, entonces la información que aportan es mayor que si las tomáramos aisladamente.

Continuando con la creación del score, lo que falta ahora es realizar un modelo con estas 5 variables. Con un clic sobre esta selección elegimos construir un OPFIT. El modelo se construye en unos pocos segundos y se muestra una ventana con el modelo, pero no analizaremos esta ventana, solo nos concetraremos en el rendimiento, especificamente en la curva de Lift sobre el Test set.

El problema original nos pide elegir los 800 clientes entre 4.000 con mayor probabilidad de comprar una póliza, o sea, el 20%. Del gráfico de Lift podemos notar que 20% de los clientes (escala horizontal) seleccionados con el modelo contiene aproximadamente un 50% de compradores de póliza. Los datos de la primera tabla muestran que un 5.72% de los clientes compraron la póliza (este dato sale de la distribución de la variable a predecir). Por lo tanto podemos estimar la cantidad de clientes que comprarán la póliza en la segunda tabla. Debe ser 5.72% de 4.000 ó lo que es lo mismo, 229 clientes. Así que en base a estos cálculos deberíamos esperar que el modelo seleccione aproximadamente un 50% de 229, o sea unos 114 clientes.

Veamos si esto es cierto. Recordemos que nosotros ya conocemos cuáles clientes de la segunda tabla realmente compraron la póliza, así que simplemente aplicaremos el modelo a la segunda tabla de clientes, los ordenamos en base al score de mayor a menor, seleccionamos los primeros 800 y contamos cuántos clientes compraron la póliza.

Para aplicar el modelo a la segunda tabla, primero debemos agrega esta nueva tabla al proyecto haciendo clic derecho sobre el proyecto y elegiendo "Agregar Fuente de Datos".

Luego hacemos clic sobre el signo + de la tabla agregada y buscamos la variable CARAVAN que es la que nos dice si el cliente compró o no la póliza. La arrastramos hasta el área de trabajo para crear una vista con esta variable. Luego arrastramos el modelo OPFIT hasta esta vista y obtendremos el score para cada cliente.

Ahora podemos exportar esta Vista para cargarla en Excel y seleccionar los clientes con mayor probabilidad. ¿El resultado? 118 clientes, aproximadamente lo que esperábamos (114).

El ganador de este concurso obtuvo 121 clientes y el segundo 115, así que Powerhouse no lo hizo tan mal. Es más, si consideramos que el tiempo total del proyecto fue inferior a 5 minutos, podemos asumir que los resultados han sido más que satisfactorios.

Ya está listo y probado el modelo de score, pero todavía falta algo para terminar con el proyecto, falta explicar por qué. Para esto usaremos el modelo Scorecard. Este modelo podríamos haberlo usado en un principio en vez del OPFIT, pero se supone que OPFIT es levemente más preciso que el Scorecard. De hecho, una prueba rápida revela que el Scorecard encuentra 117 clientes en los 800 (OPFIT encontró 118), así que la diferencia es realmente muy pequeña.

Pero el Scorecard que construiremos será más simple y menos preciso, ya que solo lo quereos para explicar las relaciones encontradas en los datos. Así que en vez de usar los parámetros default en las opciones del modelo, cambiaremos uno de ellos. En vez de usar 5 rangos (o 5 bins) para las variables, usaremos solo dos, así el modelo será más simple de entender

El modelo es el siguiente:

El modelo de score se interpreta de la siguiente manera. El score será un número entre 0 y 100. A mayor score, mayor probabilidad de que el cliente compre una póliza. Cada variable aporta parte del score. Así por ejemplo, para la variable PPERSAUT tenemos dos valores de score, si la variable toma un valor menor que 5.5, entonces para esta variable, el score es 0. En cambio, si el valor de PPERSAUT es mayor o igual a 5.5, entonces el score será 40. El resto de las variables se interpretan de la misma manera.

La tercera columna "Si es nulo" es para el caso de que el valor de esa variable no se conozca. En ese caso el score asociado a esa variable será el indicado en esta columna. Por ejemplo, para la primera variable es 17.

El score total de un cliente es la suma de los scores individuales de cada variable.

La variable PPERSAUT se refiere a "Contribution car policies", y según el modelo a mayores valores que tome, mayor será la probabilidad de que el cliente compre la póliza.

Con el resto de las variables se puede hacer una análisis similar. En particular se puede ver que la variable MOSHOOFD tiene una relación inversa con la probabilidad: a mayores valores, menor es la probabilidad.

Este modelo puede exportarse a Excel y se obtendrá, entre otras cosas, una tabla con las probabilidades asociadas a cada score.

Conclusión, realizar un score con Powerhouse es una tarea muy simple que lleva pocos minutos una vez que se cuenta con la tabla de datos correspondiente.

Powerhouse no sólo obtiene modelos precisos y robustos (trabajan muy bien con datos nuevos), sino que a su vez estos modelos son muy simples de entender.

Un ejemplo del uso de variables mixtas

Hoy encontré un data set en Internet acerca de créditos. Se llama Home Equity Loan Data Set y lo usan en varios documentos con ejemplos del uso de SAS Enterprise Miner.

Quise comparar los resultados publicados con los que podría obtener con Powerhouse. Para obtener un resultado rápido, usé el AutoWizard, que una vez seleccionados los datos e identificada la variable a predecir, generó un modelo de segmentación y el de predicción en 10 segundos.

Luego generé el reporte de rendimiento del modelo de predicción OPFIT. Sobre el Training set el modelo acertó un 82.9% de la veces y sobre el Test set un 82.4%. El KS (Kolmogorov-Smirn Statistic) fue de 56.3% en el Trainig set y 45.4 en el Test set. La siguiente gráfica muestra el Lift

La tabla muestra el Lift por decil

No es un mal modelo y tiene un rendimiento similar al Modelo de Regresión costruído en SAS y publicado en el documento Data Mining using SAS Enterprise Miner. A case study approach.

Luego hice algo de análisis exploratorio usando el reporte de Estadísticas de Powerhouse (debería haberlo analizado antes) y me di cuenta que una variable que podría ser muy importante, había sido ignorada por tener un porcentaje de Nulos demasiado elevado.

La variable ignorada es DEBTINC que representa la relación entre la deuda y los ingresos (Debt to Income). Esta variable normalmente lleva mucha información acerca de la capacidad de pago de una persona. Cuanto mayor es esta relación, mayor probabilidad de mora existe.

Tenía varias opciones para incluir esta variable, aumentar el porcentaje permitido de Nulls en las variables (el valor prefijado era de 20%), hacer que Powehouse reemplace los Nulos o tratar esta variable como Mixta, asignando un valor no numérico a cada valor faltante.

Lo primero que hice fue reemplazar los Nulos, pero DEBTINC no apareció en la selección de variables y el modelo que obtuve no fue mejor que el anterior. Esto concuerda con la idea principal dada en ¿Qué hacer con los Nulls?, no reemplazar los Nulos salvo en casos absolutamente necesarios.

Luego pensé que quizás tratar a DEBTINC como Mixta podría funcionar. Probablemente el hecho de que este valor no esté completado lleve información acerca de la variable a predecir (para más detalles de este enfoque llamado Missing Value Pattern, se puede consultar el capítulo 8 de Data Preparation for Data Mining de Dorian Pyle), así que simplemente hice un nuevo proyecto en el que en la variable DEBTINC reemplacé los Nulos por "N/C" y declaré esta variable como Mixta. Luego procedí como lo hice anteriormente y estos fueron los resultados:

La variable DEBTINC fue seleccionada en primer lugar. El porcentaje de aciertos subió a un 88.66% y 88.77% para el TR y el TS respectivamente. El KS también mejoró mucho, 68.2 y 67.8 para el TR y TS. La curva Lift sobre el Test set mejoró notablemente

De la tabla de Lift se puede ver por ejemplo que el Lift para el decil 1 y 2 es 4.43 y 3.61 respectivamente, lo cual comparado con 2.90 y 2.34 del modelo anterior, es una mejora de alrededor de un 50%!


Conclusión, las variables Mixtas no sólo sirven para reemplazar valores vacíos, también pueden hacer un buen trabajo con valores faltantes.

martes, 16 de octubre de 2007

¿Es necesario balancear los datos?

Supongamos un proyecto de Data Mining del área de marketing de una empresa en donde el objetivo es construir un modelo para predecir quién responderá a la oferta de un producto.

Existen distintas maneras de llevar adelante un proyecto de este tipo, una de ellas es realizar una campaña ofertando el producto a una muestra al azar de clientes con el objeto de recabar información que será usada en el proyecto. La idea es usar una muestra que sea lo más pequeña posible pero que contenga la suficiente información para hacer el modelo. Por ejemplo, si la empresa tuviera 100.000 clientes, se podría tomar una muestra al azar de 10.000 para enviarles el folleto. Una vez que pase un tiempo prudencial, se puede armar la tabla con todas las variables disponibles de los clientes de la muestra más una variable que indique si el cliente compró o no el producto. O sea, la variable a predecir será "Compra" cuyos dos únicos valores serán "SI" o "NO".

Depende el tipo de producto, podría ser que el porcentaje de gente que compre el producto sea muy bajo, por ejemplo, sólo el 1%.

Así que la variable "Compra" tendrá la distribución de valores:

Muchas herramientas para construir modelos tienen problemas con este tipo de distribución de la variable a predecir. Por ejemplo, si se entrena una red neuronal con un nodo como Salida (Output) se obtendrá un modelo cuya respuesta será la misma para todos los clientes: "NO". ¿Por qué? Porque los algoritmos de entrenamiento están diseñados para reducir el error. Si la respuesta es para todos los casos "NO", el error que se comete es del 1%, o dicho de otro modo, el modelo acertará el 99% de las veces!

A este tipo de modelo, el que siempre contesta lo mismo para cometer el mínimo error, se lo conoce como modelo naïve.

Lo que se necesita es un modelo que supere el modelo naïve.

Una vía para lograr que la herramienta de modelado no produzca un modelo naïve es balancear los datos, o lo que es lo mismo, modificar la distribución de la variable a predecir para que sea 50%/50%. Una manera de lograr esto es la siguiente:

Seleccionar todas las filas en donde la variable a predecir toma el valor "SI". En nuestro caso hipotético de la campaña de marketing nos quedaríamos con unas 100 filas (el 1% de 10.000). Luego se deben incluir otros 100 casos en los que el cliente no compró el producto ("NO"). Ahora tendremos una tabla de datos en los que la distribución de la variable a predecir es 50%/50%.

Pero estos datos tienen dos problemas: la distribución de la variable a predecir no es real (¡ya lo sabíamos!) y son insuficientes para realizar un buen modelo, al menos en nuestro caso en que sólo conseguimos 200 filas.

¿Cómo solucionamos la falta de datos? Existen dos maneras. Hay herramientas que generan nuevas filas artificiales en las que la variable de salida toma el valor menos representado (en nuestro caso "SI"). No tengo claro la validez de este método y si realmente ayuda. En mi caso particular, hace unos años utilicé esta práctica con redes neuronales y no obtuve ningún beneficio.

La otra solución es aumentar el tamaño de la muestra, pero esto incrementa los costos del proyecto (para tener una muestra representativa de la población, el costo podría aumentar hasta¡ 10 veces!)

¿Qué hacer si la herramienta de Data Mining es Powerhouse? Nada

Una de las grandes ventajas que tiene Powerhouse es que no es necesario (ni aconsejable) balancear los datos. Todas las pruebas realizadas por nosotros y por muchos usuarios de Powerhouse, indicaron que es mejor no balancear que hacerlo.

viernes, 12 de octubre de 2007

¿Qué hacer con los NULLS?

Llamaré NULL a una posición de una variable que debería tener un valor pero está vacía. Por ejemplo, la siguiente variable tiene un NULL en la fila 4

Los NULLS pueden ser de dos tipos: valores faltantes y valores vacíos. Es muy importante tener en claro la diferencia entre los dos.

Un valor faltante es un valor que tiene sentido que exista. El ejemplo de arriba muestra una variable llamada Hpwr (potencia) y que pertenece a una tabla de datos acerca de vehículos. Otras variables de la misma tabla son MiGal (millas por galón), Cyl (cantidad de cilindros), WtLbs (peso en libras), Acc0-60 (aceleración de 0 a 60 mph), etc. En esta tabla, al vehículo representado en la fila 4 le falta el valor de la potencia. Debería existir un valor, pero no está. Este es un NULL del tipo valor faltante.

En cambio, un valor vacío es un valor que no tiene sentido que exista. Por ejemplo, consideremos una variable que indique el saldo en la cuenta corriente de un cliente. Si el cliente no posee cuenta corriente, ¿qué valor debería tener esa variable para ese cliente? Cero no puede ser, porque esto significaría que el cliente decidió tener cuenta corriente y en su saldo tiene 0$, y esto no es cierto. Veremos un poco más adelante cómo tratar con este caso.

Ahora que tenemos claro los dos tipos de NULLS veremos qué hacer en cada caso.

El caso más simple es el de valores faltantes. Por alguna razón el valor no está presente, aunque debería estarlo. ¿Qué hacer? La respuesta más simple es ignorar toda la fila. Hay veces en que los valores faltantes aparecen desparramados al azar en toda la tabla de datos, pero con suerte no hay demasiados. O sea, si tomáramos la decisión de ignorar las filas que tienen al menos un valor faltante, todavía nos quedaríamos con un porcentaje importante de total de filas (por ejemplo, sólo el 10% de las filas serían ignoradas así que nos quedaría el 90% para trabajar). Esta es la mejor solución, pero no siempre es posible.

Hay ocasiones en que si bien ninguna variable tiene individualmente más que un pequeño porcentaje de valores faltantes, el hecho de considerar todas las variables en conjunto hace que la cantidad de filas ignoradas sea lo suficientemente grande como para quedarnos sin datos para analizar. En este caso la única respuesta es completar los valores vacíos. El problema es con qué valor. Con cualquier valor que pongamos estaremos introduciendo un sesgo. En el artículo sobre la preparación de datos hablé sobre la estructura que conserva una fila. Si reemplazamos el valor faltante por un valor que no es apropiado, estaremos modificando esta estructura. Completar con el valor promedio de la variable no es una buena idea, por la razón expuesta anteriormente.

Dorian Pyle en su libro Data Preparation for Data Mining hace un tratamiento exhaustivo sobre el reemplazo de NULLS. Powerhouse se basa en uno de estos métodos para realizar el reemplazo automático de valores faltantes que tiene que ver con interferir lo mínimo posible con la estructura entre variables.

Antes de pasar al tratamiento de valores vacíos vale la pena tener en cuenta un caso que aparece muy a menudo. Muchas veces las variables que tienen sólo dos valores, por ejemplo SI y NO, vienen con un solo valor completado (por ejemplo SI) y el otro valor está vacío (significando en realidad que debería ser un NO). O sea, si nos guiamos por la cantidad de NULL reportados podríamos descartar esta variable por contener demasidos NULLS, pero un análisis más detallado indicará que sólo hay que cambiar los valores faltantes por NO. Powerhouse puede hacer esto en forma automática por medio de la opción VRN (o NRV en Inglés) durante la carga de datos.

Veamos ahora cómo tratar los NULLS cuando son del tipo valor vacío, o sea, que están sin completar porque no tiene sentido poner un valor.

En Powerhouse existe un tipo de variable llamada Mixta. La misma puede contener valores numéricos y categóricos a la vez. En el ejemplo del saldo de la cuenta corriente, si el cliente tiene cuenta corriente, el valor será el saldo, caso contrario, el valor será alguna indicación tal como "SIN CUENTA".


Powerhouse tratará esta variable como si fuera numérica para clientes con cuenta corriente y como si fuera categórica para el resto de los clientes.

Resumiendo, si la cantidad de valores faltantes no es demasiado grande, lo ideal es ignorar las filas que contienen valores faltantes, caso contrario reemplazarlos de manera que se interfiera lo mínimo posible con la estructura interna de los datos.

Si los NULLS representan valores vacíos, usar un string cualquiera para reemplazar los vacíos para que Powerhouse automáticamente trate esta variable como Mixta.

jueves, 11 de octubre de 2007

¿Qué es el ruido?

La Teoría de la Información tiene una definición precisa del ruido, pero en este artículo trataré este tema de una manera más informal. Aquel que quiera conocer más acerca de la Teoría de la Información y cómo es posible usarla para medir el ruido y la señal que contienen los datos puede leer Data Mining y Teoría de la Información.

En cualquier tipo de comunicación, el ruido es algo que hay que evitar, ya que ensucia el mensaje que se está transmitiendo.

Cuando nos referimos a un modelo de predicción, podemos asumir que las variables independientes transmiten información sobre la variable dependiente. Dicho de otro modo, existen variables que comunican información que nos será útil para predecir la variable de interés.

Ahora bien, no siempre los modelos alcanzan un alto grado de precisión en sus predicciones debido a distintas razones. Por ejemplo, podría ser que las relaciones entre las variables independientes y la dependiente no sean lineales y la herramienta usada para construir el modelo sólo tenga en cuenta relaciones lineales.

Otra razón que muchas veces escuchamos tiene que ver con el ruido en los datos. Se suele decir que los datos contienen ruido y esto interfiere con la creación de un buen modelo. Pero ¿qué es el ruido?

Podemos definir el ruido como una señal aleatoria que se suporpone a la señal original y confunde al destinatario. Veamos un ejemplo viendo primero una señal sin ruido y luego con rudio superpuesto.

Supongamos que tenemos la siguiente relación entre dos variables

y = x2 – x + 2

Una tabla de datos que contenga esta relación tendrá dos variables X e Y. La variable X será la variable independiente e Y la dependiente. Podemos asumir que X transmite información acerca de Y y un buen modelo será capaz de usar la información de X para estimar Y.

Si graficamos esta relación veremos que para cada valor de X existe solamente un valor de Y posible

Los datos podrán contener varios valores de X iguales, por ejemplo, varias filas en donde X es 5, pero en cada una de estas filas, la variable Y tendrá el mismo valor: 22 (que es el resultado de la ecuación dada más arriba).

Supongamos ahora que los datos tienen la siguiente particularidad: para un mismo valor de X pueden existir varios valores de Y. O sea, ahora si existen varias filas en donde X es 5, no necesariamente el valor de Y será en todas ellas 22. Podría ser que en algunas sea 20, en otras 22 y en otras 30.

El gráfico de estos nuevos datos se verá así:

Estos nuevos datos contienen ruido porque para una misma señal (en nuestro ejemplo la señal es el valor de X) existen distintos valores que puede tomar la variable a predecir.

El ruido, así como la información, se mide en bits. Powerhouse mide el ruido que contienen los datos y la información que queda luego de suprimir el ruido. Por ejemplo, si los datos contaminados con ruido son analizados con Powerhouse, resulta que el 58% de la información es ruido, con lo que sólo el 42% servirá para estimar exactamente Y. Dicho de otro modo, un modelo construido con estos datos nunca será lo suficientemente preciso debido a que parte de la información contiene ruido. Es importante notar que no importa el tipo de herramienta usada para construir el modelo. Si los datos contienen ruido, el modelo no será perfecto, y el grado de precisión dependerá justamente del nivel de rudio.

La información en los datos

Hace unas semanas encontré una tesis de grado en la que se mostraba cómo una red neuronal (NN) resolvía un problema de clasificación. El dataset usado tiene 41 variables independientes mas la variable dependiente. Se trata de clasificar el tipo de onda (hay tres clases) en base a los atributos dados por las variables. Si bien todas las variables contienen ruido, las últimas 20 no contienen información acerca del tipo de onda (son solo ruido).

La tesis muestra cómo con una NN se logra un modelo con aproximadamente un 83% de aciertos en la clasificación.

Quise ver si Powerhouse era capaz de lograr resultados similares, y en este artículo contaré paso por paso lo que fui logrando y las sorpresas que tuve.

Comencé como siempre lo hago, realizando un modelo default. Para ser más preciso, usé solamente las variables seleccionadas y luego el modelo OPFIT (una especie de regresión logística aplicada a los datos preparados por Powerhouse).

La siguiente pantalla de Powerhouse muestra la información que había disponible para resolver el problema


Para mantener las cosas simples, solo usaré 2 columnas de esta pantalla en todos los análisis de este artículo, la que muestra las variables seleccionadas y la que muestra la ganancia de información.

Powerhouse seleccionó solamente 3 variables x7, x11 y x15. Estas tres variables llevan más del 60% de la información necesaria para clasificar correctamente la forma de onda.

Esto significa que el modelo construído con estas tres variables sería bastante bueno, pero seguramente no tan bueno como el de las redes neuronales.

El modelo OPFIT basado en estas tres variables confirmó mi sospecha de que no lograría demasiado. Sólo se logra un 59% de aciertos en el Training Set (datos usados para construir el modelo) y un 56% en el Test Set (datos nunca vistos. Hay que considerar que en Powerhouse, a diferencia de una NN, el Test Set realmente no se usa para nada).

La matriz de confusión da un poco más de detalles sobre los resultados


Ya que el modelo OPFIT no lograba discriminar la clase "0", probé con otro modelo de Powerhouse llamado MAXIT.

Este modelo, al igual que el OPFIT, se basa en el mapa de información creado por Powerhouse. La diferencia es que mientras que OPFIT mapea la información usando una simple función de transferencia lineal, MAXIT lo hace mediante un conjunto de reglas. En general, OPFIT funciona bien con la mayoría de los problemas que aparecen en áreas de negocios, ya que las no linealidades encontradas en los datos son resueltas en la transformación de datos que se realiza cuando se construye el mapa de información, pero hay veces en que, si bien existe información, OPFIT no puede acceder a ella mientras que MAXIT si lo hace.

Los resultados del modelo MAXIT con estas mismas tres variables mejoraron respecto del OPFIT

Ahora el porcentaje de aciertos subió al 66% en el Training Set y 64% en el Test Set, y además los aciertos de la clase "0" mejoraron bastante. De todas maneras, todavía estaba lejos del 83% logrado por una NN. Pero claro, la NN usó todas las variables disponibles y estos modelos sólo usaron 3 variables.

Así que el siguiente paso fue construir los modelos con todas las variables disponibles. Pero en Powerhouse no es posible construir un modelo sin antes haber seleccionado las variables, así que primero se debe hacer una selección aclarando que se desean todas las variales disponibles. O sea, se espera lograr una lista de variables ordenadas según la información que aportan. Y acá fue donde apareció la sorpresa, no hacen falta todas las variables ya que ¡11 de ellas contienen el 100% de la información necesaria para predecir la clase!


En la columna de la ganancia de información se puede ver que las últimas 3 variables aportan menos que el 1% de información. Es más, también se puede comprobar que el algoritmo de selección de variables es muy robusto respecto del ruido, ya que variables que sólo aportan ruido (x21 hasta x41, según se aclara en el sitio donde se obtuvieron los datos) aparecen al final de una selección forzada a elegir todas las variables. Powerhouse no continúa seleccionando variables porque ya no es necesario. Estas 11 variables contienen toda la información necesaria.

El modelo MAXIT sobre estas 11 variables no mejoró demasiado, 72% para el TR y 67% para el TS. Así que me pregunté por qué MAXIT no estaba capturando toda la información disponible si una red neuronal lo hacía. Entonces recordé que la red (al menos la que yo construí usando un producto comercial llamado NeuralWare) contiene 3 nodos de salida, uno para cada clase. Así que intenté un método que muchas veces mejoró mis resultados: construir tres modelos distintos, uno para cada clase, en vez de pretender que un solo modelo prediga las tres clases.

Lo único que tuve que hacer es agregar tres variables a la tabla de datos. La primera contenía un 1 cada vez que la clase a predecir era "0" y un 0 cada vez que la clase era "1" ó "2". La segunda contenía un 1 cada vez que la clase era "1" y un 0 si era "0" ó "2". La tercera, un 1 si la clase era "2" y un 0 si era "0" ó "1". Así que primero construí un modelo (ahora usé el OPFIT) para predecir la primera variable agregada, o sea para predecir si la clase es "0". Luego hice los otros dos modelos (también OPFIT) , uno para predecir si la clase es "1" y otro para "2".

Luego los apliqué a los datos y consideré que la clase sería aquella en que el modelo OPFIT diera el score más alto (el modelo OPFIT no solo predice categorías y valores continuos, sino que en cada predicción muestra un score). Por ejemplo, si los scores eran 0.89, 0.95 y 0.32 para las clases "0", "1" y "2" respectivamente, la predicción sería la clase "1" por tener el score más alto.

¿El resultado? ¡Un 86% de aciertos en el Training set y un 83% en el Test set!

En este ejercicio podemos ver dos cosas importantes:

  1. Muchas veces unas pocas variables contienen toda la información necesaria para resolver el modelo. Agregar más variables complejiza el modelo innecesariamente.
  2. Una manera de mejorar los resultados es construir varios modelos y luego unirlos para obtener el resultado buscado.

miércoles, 10 de octubre de 2007

La importancia de preparar los datos

Preparar los datos antes de construir un modelo con cualquier herramienta es esencial para obtener los mejores resultados. Veamos por qué.

Variables numéricas

Supongamos que estamos trabajando con una variable cuya distribución tiene una larga cola. Un ejemplo podría ser el sueldo de una persona, tal como se puede ver en el siguiente gráfico



Esta variable tiene una mediana de 1.200$ y una media de aproximadamente 1.700$, pero contiene sueldos mucho mayores, llegando a un máximo de 130.000$.

Cuando se usa esta variable sin ningún tratamiento previo, salvo expresarla en una nueva escala, como ser 0 a 1 ó –1 a +1, como lo requeriría una red neuronal, se estaría desaprovechando gran parte de la información que pudiera contener. ¿Por qué? La razón es simple, los algoritmos que trabajan con los diferentes valores de la variable tratarán de encontrar intervalos en que la variable puede discriminar valores de la variable dependiente. Pero estos intervalos siempre son relativos al rango total de la variable.

Por ejemplo, supongamos que estamos modelando un score para predecir la probabilidad de que un cliente acepte un determinado producto y creemos que el sueldo podría ser una buena variable predictora. Intuitivamente podríamos asumir que una persona con un sueldo de 1.000$ se debería comportar de manera diferente que otra cuyo sueldo sea 5.000$. Después de todo hay una diferencia de 4.000$ en los sueldos. Pero la herramienta que usemos para modelar, por ejemplo una red neuronal, verá una diferencia muy pequeña porque ambos valores solo difieren apenas en un 2%, ya que 1.000$ representa el 0.77% respecto del rango total de la variable (0 a 130.000$) y 4.000$ representa el 3.08%.

¿Cómo solucionamos esto? Existen varios métodos. Uno de ellos es aplicar la función matemática logaritmo a esta variable. El logaritmo tiene la propiedad de comprimir los valores altos y expandir los bajos. Por ejemplo, si aplicamos el logaritmo en base 10 a nuestro ejemplo y luego calculamos los valores relativos, nos queda:

Valor Original

Log

Log Relativo

1,000 $

3.00

59%

4,000 $

3.60

70%

Ahora la diferencia entre los dos sueldos es de un 11%, cinco veces más que en el caso anterior. De todas maneras hay que tener en cuenta que los logaritmos no son ni la solución ideal ni una solución universal. Por ejemplo, no es posible aplicar el logaritmo si existen valores menores o iguales a cero. Afortunadamente existen métodos numéricos capaces de modificar la forma de la distribución para que la variable incremente su poder discriminatorio, pero la explicación de los mismos quedará para un siguiente artículo.

Variables categóricas

Otro problema comúnmente encontrado en proyectos de Data Mining es la asignación de valores numéricos a variables categóricas. La práctica normal es asignar los valores numéricos al azar, sin seguir ningún método particular.

El problema con este método es que asignar valores numéricos arbitrarios a cada categoría podría destruir la estructura interna de los datos. Para aclarar esto supongamos que tomamos una fila de una tabla de datos. En general, los valores que toman las variables mantienen una cierta relación, por ejemplo, la altura y el peso de una persona. Esta relación entre variables es la que debemos mantener cuando le asignamos valores numéricos a las categorías. Si no lo hacemos, podríamos estar modificando las relaciones internas de modo que la herramienta de modelado tenga que lidiar con relaciones más complejas.

Como ejemplo práctico de preparar los datos antes de modelarlos veremos un caso real obtenido de Internet. En el sitio web de UCI Machine Learning Repository existe una tabla de datos llamada Adult. Con Powerhouse se seleccionaron 5 variables para predecir si la persona tiene ingresos mayores a 50 mil dólares anuales o no. Luego se prepararon dos modelos de regresión lineal, uno con los datos sin preparar (en donde las variables categóricas fueron numeradas en forma arbitraria) y otro con los datos preparados con Powerhouse.

Los resultados se resumen en la siguiente tabla


Datos sin Preparar

Datos Preparados

KS

44

60

R2

0.19

0.32


Con datos preparados el estadístico KS (Kolmogorov-Smirnoff) mejora casi un 50% y el coeficiente de determinación mejora más de un 50%.

Un libro que desarrolla de manera excelente el tema de preparación de datos es Data Preparation for Data Mining de Dorian Pyle.


Powerhouse, una manera diferente de hacer Data Mining

Powerhouse es una herramienta de Data Mining basada en un enfoque completamente distinto que el usado normalmente para analizar datos.

Cuando se intenta realizar un modelo de predicción, generalmente se asume que los datos contienen la información suficiente para lograr un buen modelo.

Powerhouse no supone que existe información, la mide.

Claude Shannon detalló en su Teoría de la Información cómo es posible medir la información en bits usando un concepto llamado entropía.

Powerhouse sienta sus bases en la Teoría de la Información y logra mejorar la práctica de hacer Data Mining mediante las siguientes ventajas que le otorga este enfoque:
  • Los datos son preparados automáticamente a fin de exponer al máximo la información que puedan contener
  • La selección de variables es un proceso directo, rápido y que garantiza un grupo óptimo de variables con información libre de ruido
  • Crea modelos de predicción simples de entender y con rendimientos similares a las redes neuronales
  • Descubre modelos de segmentación que exponen clusters naturales en los datos
El sitio web de Powerhouse contiene información más detallada sobre sus características y ventajas.