Ejemplo de API de aprendizaje
Esta sección contiene una implementación de muestra de ILearningInterface. Tenga en cuenta que esta implementación es sólo una muestra y no está diseñada para utilizarse en un entorno de producción.
Este ejemplo realiza un seguimiento de los recuentos de aceptaciones y contactos, y utiliza la proporción de aceptaciones y contactos para una determinada oferta como la tasa de probabilidad de aceptación de la oferta. Las ofertas que no se presentan reciben una mayor prioridad de recomendación. Las ofertas con al menos un contacto se ordenan según la tasa de probabilidad de aceptación descendente.
En este ejemplo, todos los recuentos se mantienen en memoria. No es un escenario realista, ya que el servidor de ejecución se quedará sin memoria. En un escenario de producción real, los recuentos deben ser persistentes en una base de datos.
package com.unicacorp.interact.samples.learning.v2;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.unicacorp.interact.samples.learning.SampleOptimizer.MyOfferSorter;
import com.unicacorp.interact.treatment.optimization.IClientArgs;
import com.unicacorp.interact.treatment.optimization.IInteractSession;
import com.unicacorp.interact.treatment.optimization.ILearningConfig;
import com.unicacorp.interact.treatment.optimization.ILearningContext;
import com.unicacorp.interact.treatment.optimization.IOffer;
import com.unicacorp.interact.treatment.optimization.LearningException;
import com.unicacorp.interact.treatment.optimization.v2.ILearning;
import com.unicacorp.interact.treatment.optimization.v2.ITreatment;

/**
* Es una implementación de muestra del optimizador de aprendizaje.
* La interfaz ILearning puede encontrarse en la biblioteca interact.jar.
*
* Para utilizar realmente esta implementación, seleccione ExternalLearning como optimizationType en el nodo offerServing
* de la aplicación de Interact en la configuración de plataforma. En el nodo offerserving también hay
* una categoría External Learning Config, donde debe establecer el nombre de la clase en:
* com.unicacorp.interact.samples.learning.v2.SampleLearning. Tenga en cuenta que esta implementación es sólo una muestra
* y no está diseñada para utilizarse en un entorno de producción.
*
*
* Este ejemplo realiza un seguimiento de los recuentos de aceptaciones y contactos, y utiliza la proporción de aceptaciones y contactos
* para una determinada oferta como la tasa de probabilidad de aceptación de la oferta.
*
*
* Las ofertas que no se presenten recibirán una mayor prioridad de recomendación.
* Las ofertas con al menos un contacto se ordenarán según la tasa de probabilidad de aceptación descendente.
*
* Nota: todos los recuentos se mantienen en memoria. No es un escenario realista, ya que se quedará sin memoria antes o
* después. En un escenario de producción real, los recuentos deben ser persistentes en una base de datos.
*
*/

public class SampleLearning implements ILearning
{

// Una correlación de ID de oferta con recuentos de contactos para el ID de oferta
private Map<Long,Integer> _offerToContactCount = new HashMap<Long, Integer>();

// Una correlación de ID de oferta con recuentos de contactos para el ID de oferta
private Map<Long,Integer> _offerToAcceptCount = new HashMap<Long, Integer>();


/* (non-Javadoc)
* @see com.unicacorp.interact.treatment.optimization.v2.ILearning#initialize
* (com.unicacorp.interact.treatment.optimization.v2.ILearningConfig, boolean)
*/
public void initialize(ILearningConfig config, boolean debug) throws LearningException
{
// Si se necesitan conexiones remotas, es un buen lugar para inicializarlas ya que este
// método se invoca una vez al inicio de la aplicación web de tiempo de ejecución de Interact.
// Este ejemplo no tiene conexiones remotas e imprime a efectos de depuración que este método
// se invocará
System.out.println("Calling initialize for SampleLearning");
}

/* (non-Javadoc)
* @see com.unicacorp.interact.treatment.optimization.v2.ILearning#reinitialize
* (com.unicacorp.interact.treatment.optimization.v2.ILearningConfig, boolean)
*/
public void reinitialize(ILearningConfig config, boolean debug) throws LearningException
{
// Si se despliega un IC, se invoca este método de reinicialización para que la implementación
// renueve los valores de configuración actualizados
System.out.println("Calling reinitialize for SampleLearning");
}


/* (non-Javadoc)
* @see com.unicacorp.interact.treatment.optimization.v2.ILearning#logEvent
* (com.unicacorp.interact.treatment.optimization.v2.ILearningContext,
* com.unicacorp.interact.treatment.optimization.v2.IOffer,
* com.unicacorp.interact.treatment.optimization.v2.IClientArgs,
* com.unicacorp.interact.treatment.optimization.IInteractSession, boolean)
*/
public void logEvent(ILearningContext context, IOffer offer, IClientArgs clientArgs,
IInteractSession session, boolean debug) throws LearningException
{
System.out.println("Calling logEvent for SampleLearning");


if(context.getLearningContext()==ILearningContext.LOG_AS_CONTACT)
{
System.out.println("adding contact");

// Realizar un seguimiento de todos los contactos en la memoria
synchronized(_offerToAcceptCount)
{
Integer count = _offerToAcceptCount.get(offer.getOfferId());
if(count == null)
count = new Integer(1);
else
count++;
_offerToAcceptCount.put(offer.getOfferId(), ++count);
}

}
else if(context.getLearningContext()==ILearningContext.LOG_AS_ACCEPT)
{
System.out.println("adding accept");
// Realizar un seguimiento de todos los recuentos de aceptación en la memoria mediante la adición
a la correlación
synchronized(_offerToAcceptCount)
{
Integer count = _offerToAcceptCount.get(offer.getOfferId());
if(count == null)
count = new Integer(1);
else
count++;
_offerToAcceptCount.put(offer.getOfferId(), ++count);
}
}

}

/* (non-Javadoc)
* @see com.unicacorp.interact.treatment.optimization.v2.ILearning#optimizeRecommendList
* (java.util.List, com.unicacorp.interact.treatment.optimization.v2.IClientArgs,
* com.unicacorp.interact.treatment.optimization.IInteractSession, boolean)
*/
public List<ITreatment> optimizeRecommendList(List<ITreatment> recList,
IClientArgs clientArgs, IInteractSession session, boolean debug)
throws LearningException
{
System.out.println("Calling optimizeRecommendList for SampleLearning");

// Ordenar los tratamientos candidatos invocando el clasificador definido en esta clase y devolver la lista ordenada
Collections.sort(recList,new MyOfferSorter());

// ahora devolver sólo lo que se ha solicitado mediante la variable "numberRequested"
List<ITreatment> result = new ArrayList<ITreatment>();

for(int x=0;x<(Integer)clientArgs.getValue(IClientArgs.NUMBER_OF_OFFERS_REQUESTED) && x<recList.size();x++)
{
result.add(recList.get(x));
}
return result;
}

/* (non-Javadoc)
* @see com.unicacorp.interact.treatment.optimization.v2.ILearning#shutdown
* (com.unicacorp.interact.treatment.optimization.v2.ILearningConfig, boolean)
*/
public void shutdown(ILearningConfig config, boolean debug) throws LearningException
{
// Si existen conexiones remotas, es un buen lugar para desconectarse ordenadamente
// de ellas ya que este método se invoca en la conclusión de la aplicación web de tiempo de ejecución de
// Interact. Para este ejemplo, no hay nada que hacer
// excepto imprimir una sentencia de depuración.
System.out.println("Calling shutdown for SampleLearning");

}
// Ordenar por:
// 1. ofertas con cero contactos - para los vínculos, el orden se basa en la entrada original
// 2. tasa de probabilidad de aceptación descendente - para los vínculos, el orden se basa en la entrada original

public class MyOfferSorter implements Comparator<ITreatment>
{
private static final long serialVersionUID = 1L;

/* (non-Javadoc)
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
public int compare(ITreatment treatment1, ITreatment treatment2)
{

// obtener el recuento de contactos para ambos tratamientos
Integer contactCount1 = _offerToContactCount.get(treatment1.getOffer().getOfferId());
Integer contactCount2 = _offerToContactCount.get(treatment2.getOffer().getOfferId());

// si no se ha puesto en contacto con el tratamiento, será el ganador
if(contactCount1 == null || contactCount1 == 0)
return -1;

if(contactCount2 == null || contactCount2 == 0)
return 1;

// obtener los recuentos de aceptación
Integer acceptCount1 = _offerToAcceptCount.get(treatment1.getOffer().getOfferId());
Integer acceptCount2 = _offerToAcceptCount.get(treatment2.getOffer().getOfferId());

float acceptProbability1 = (float) acceptCount1 / (float) contactCount1;
float acceptProbability2 = (float) acceptCount2 / (float) contactCount2;

// orden descendente
return (int) (acceptProbability2 - acceptProbability1);

}
}

}