3 de agosto de 2014

Predecir Clientes con Bayes Ingenuo

NOTA: 
Para mismo ejemplo con R programming, ver nota publicada AQUI
El script considera variables discretas o categóricas. Para variables numericas, no. 

Una empresa quiere llamar a sus clientes para ofrecerles un nuevo producto, pero quiere contactar únicamente a los clientes con mayor probabilidad de compra, para ahorrar en el costo por llamada.

Si se tienen DATOS HISTÓRICOS (de campañas anteriores o pruebas pilotos) de clientes que SI aceptaron y clientes que NO aceptaron comprar un producto cuando fueron contactados, y también se tienen registros de NUEVOS CLIENTES a los que se le quiere calcular la probabilidad de compra, teniendo algo como:

















Puede utilizarse el método Bayes Ingenuo (o Naive Bayes) que calcula el Maximo a Posteriori (MAP) para clasificar a los clientes según su probabilidad de compra. Para esto se multiplica la probabilidad  de Compra=Si de cada atributo (EstadoCvivil,Profesion, etc.) y el resultado se multiplica por la probabilidad total de Compra=Si. Luego se hace lo mismo con la probabilidad para Compra=No de cada atributo y se multiplica por la totalidad de Compra=No. El resultado que tenga mayor valor (Compra=Si, ó Compra=No), será el elegido por tener mayor probabilidad de compra.

El cálculo de la probabilidad de cada atributo y para cada cliente nuevo seria esto:


















El resultado final seria la siguiente tabla con el nuevo campo Predic_Compra:







El siguiente Script clasifica los clientes usando metodo Bayes Ingenuo, con los pasos:

PASO 1:  Carga datos ejemplos en las tablas DATOS HISTORICOS (usados para construir probabilidad)
                y en la tabla NUEVOS CLIENTES (datos con clientes nuevos para predecir su Compra)
PASO 2: Usa la tabla DATOS HISTÓRICOS para crear tabla de Probabilidad de cada atributo. Para los
               atributos sin historia, asigna probabilidad=0
PASO 3: Usando la tabla de Probabilidad previamente creada, se asigna la probabilidad de Compra a los
               clientes nuevos.
PASO 4: Carga las tablas de Historia y Probabilidad, sólo para validar datos. Luego borra temporales.






// ==============================================================================
//                        PASO 1:   Cargar Datos Ejemplo
// ==============================================================================
Datos_Historicos:
LOAD * INLINE [
IdCliente,     EstadoCivil, Profesion,  Universitario,  TieneVehiculo,  Compra
    1,         Casado,      Empresario,     Si,             No,           No
    2,
         Casado,      Empresario,     Si,             Si,           No
    3,
         Soltero,     Empresario,     Si,             No,           Si
    4,
         Viudo,       Desempleado,    Si,             No,           Si
    5,
         Viudo,       Empleado,       No,             No,           Si
    6,
         Viudo,       Empleado,       No,             Si,           No
    7,
         Soltero,     Empleado,       No,             Si,           Si
    8,         Casado,      Desempleado,    Si,             No,           No
    9,         Casado,      Empleado,       No,             No,           Si
    10,        Viudo,       Desempleado,    No,             No,           Si
    11,        Casado,      Desempleado,    No,             Si,           Si
    12,        Soltero,     Desempleado,    Si,             Si,           No
    13,        Soltero,     Empresario,     No,             No,           Si
    14,        Viudo,       Desempleado,    Si,             Si,           No];

Nuevos_Clientes:
NoConcatenate LOAD * INLINE [
IdCliente,   EstadoCivil,    Profesion,   Universitario, TieneVehiculo, Compra
    111,
     Soltero,        Empresario,       No,            Si,         ?
    222,     Casado,         Desempleado,      Si,            No,         ?
    333,     Soltero,        Empleado,         No,            No,         ?];
   
// ==============================================================================
//                   PASO 2:   Crear tabla de Probabilidades
// ==============================================================================
Historia_CrossTable:
CrossTable(Variable,Valor,2)
LOAD  Compra, IdCliente, EstadoCivil, Profesion, Universitario, TieneVehiculo, Compra
Resident Datos_Historicos;

Probabilidad_tmp:
LOAD Compra, Variable,Valor,
     
Count(Valor) as CantidadAtributos
Resident Historia_CrossTable Group By Compra, Variable,Valor;

Left Join (Probabilidad_tmp)
LOAD  Variable, Compra,
      
if(Variable='Compra',NoOfRows('Datos_Historicos'),
         sum(CantidadAtributos))                        as CantidadTarget
Resident Probabilidad_tmp Group By Variable,Compra;

Probabilidad: 
NoConcatenate 
LOAD *, CantidadAtributos/CantidadTarget as Probabilidad
Compra&'-'&Variable&'-'&Valor            as key
Resident Probabilidad_tmp;

//-- Asigna probabilidad cero solo a los atributos sin Compra en DATOS HITORICOS
ProbCero: 
NoConcatenate 
LOAD Distinct Variable,Valor  
Resident Historia_CrossTable Where Variable<>'Compra';
Left Join(ProbCero)
LOAD Distinct Compra, 0 as Probabilidad
Resident Datos_Historicos; //<--crea prob=0 para todos

Concatenate(Probabilidad)
LOAD * Resident ProbCero
Where not  Exists(key, Compra&'-'&Variable&'-'&Valor); //<- Elije atributos sin probabilidad

// ==============================================================================
//                   PASO 3:   Asigna probabilidad a los Nuevos Clientes
// ==============================================================================
Nuevo_tmp:
LOAD Distinct IdCliente
Resident Nuevos_Clientes;

// Crea Compra={Si,No} a cada atributo de cada IdCliente
// para luego asignar probabilidad de Compra={Si,No} en cada atribututo
Left Join (Nuevo_tmp) 
LOAD 'Compra' as Variable, Compra as Valor
Resident Datos_Historicos;

// concatenacion natural con Nuevo_tmp
CrossTable(Variable,Valor)
LOAD  IdCliente, EstadoCivil, Profesion, Universitario, TieneVehiculo 
Resident Nuevos_Clientes;

Left Join (Nuevo_tmp)
LOAD Variable,Valor, Compra, Probabilidad
Resident Probabilidad;

// Calcula probabilidad final y Elige Compra={Si,No} con mayor probabilidad
Nuevo:
LOAD  Compra, IdCliente,
      
if(Compra=Previous(Compra) and IdCliente=Previous(IdCliente), Peek(ProbCompra)*Probabilidad,Probabilidad) as ProbCompra
Resident Nuevo_tmp  Order by  Compra,IdCliente;
ProbFinal:
LOAD IdCliente, Compra,
     
min(ProbCompra) as ProbAtributos
Resident Nuevo Group By IdCliente, Compra;

Left Join (ProbFinal)
LOAD IdCliente,
    
max(ProbAtributos) as ProbAtributos,
     1
as _FLAG
Resident ProbFinal Group By IdCliente;   

// Asigna probabilidad final a cada cliente nuevo
Left join (Nuevos_Clientes)
LOAD IdCliente, ProbAtributos,
     
Compra as Predic_Compra
Resident ProbFinal Where _FLAG=1;

// ==============================================================================
// PASO 4: Crea tablas de Datos Historicos y Probabilidad. Luego borra temporales
// ==============================================================================
QUALIFY*;
Historia:     
LOAD * Resident Datos_Historicos;
Probabilidades:
LOAD * Resident Probabilidad;

DROP Table Nuevo, Datos_Historicos, ProbFinal, Probabilidad, Historia_CrossTable, Probabilidad_tmp, Nuevo_tmp,ProbCero;
EXIT Script;

2 comentarios:

Giomar Giraldo dijo...

Gracias por compartirlo !!

Luis Mariano Antezana dijo...

Gracias por compartir, buenisimo todos los ejemplos y gracias por poner los archivos para cargar in line en qlikview, se hace mucho mas facil seguir los ejemplos. Gracias Genio.