Bayes Ingenuo en Qlikview

    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:

    Clientes.jpg

     

     

    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 algo como:

    Bayes_3.jpg



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

    Bayes_4.jpg

     

     

    El siguiente Script clasifica los clientes usando método 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, ValorCompra, 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(ProbAtributosas 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 y 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;

     

     

     

    Esta nota esta publicada en Qlikview en Español: Predecir Clientes con Bayes Ingenuo

     

    NOTA: en el software libre estadistico R se obtiene mismo resultado con el siguiente codigo:

    datosT <- read.csv("C:/datos/Datos_Historicos.csv")

    datosV <- read.csv("C:/datos/Nuevos_Clientes.csv")

    library(e1071);library (class)

    modelo <- naiveBayes(Compra ~., data=datosT[-1])

    prediccion <- predict (modelo, datosT[,1:5]);