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);
}
}
}
Copyright IBM Corporation 2013. All Rights Reserved.
|