Beispiel für eine Lern-API
Dieser Abschnitt enthält eine Beispielimplementierung von ILearningInterface. Beachten Sie, dass diese Implementierung nur ein Beispiel ist und nicht für die Verwendung in einer Produktionsumgebung geeignet ist.
Dieses Beispiel protokolliert Akzeptanz- und Kontaktzählungen und verwendet das Verhältnis von Akzeptanz zu Kontakten für ein bestimmtes Angebot als die Wahrscheinlichkeitsrate für das Angebot. Nicht präsentierte Angebote erhalten eine höhere Priorität für Empfehlungen. Angebote mit zumindest einem Kontakt werden basierend auf absteigender Akzeptanzwahrscheinlichkeitsrate sortiert.
In diesem Beispiel werden alle Zählungen im Speicher abgelegt. Das ist kein realistisches Szenario, weil der Speicherplatz des Laufzeitservers nicht ausreichen wird. In einem realen Produktionsszenario sollten die Zählungen persistent in einer Datenbank gespeichert werden.
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;

/**
* Dies ist eine Beispielimplementierung des Lernoptimierungsprogramms.
* Die Schnittstelle ILearning befindet sich in der Bibliothek interact.jar.
*
* Um diese Implementierung tatsächlich zu verwenden, wählen Sie ExternalLearning als optimizationType im Knoten offerServing
* der Interact-Anwendung innerhalb der Platform-Konfiguration aus. Innerhalb des Knotens offerServing gibt es auch eine
* Kategorie External Learning config - darin müssen Sie den Namen der Klasse folgendermaßen festlegen:
* com.unicacorp.interact.samples.learning.v2.SampleLearning. Beachten Sie allerdings, dass diese Implementierung nur ein Beispiel ist
* und nicht für die Verwendung in einer Produktionsumgebung gedacht ist.
*
*
* Dieses Beispiel protokolliert Akzeptanz- und Kontaktzählungen und verwendet das Verhältnis von Akzeptanz zu Kontakten
* für ein bestimmtes Angebot als die Wahrscheinlichkeitsrate für das Angebot.
*
*
* Nicht präsentierte Angebote werden eine höhere Priorität für Empfehlungen erhalten.
* Angebote mit zumindest einem Kontakt werden basierend auf absteigender Akzeptanzwahrscheinlichkeitsrate sortiert.
*
* Beachten Sie: Alle Zählungen werden im Speicher abgelegt. Das ist kein realistisches Szenario, weil der Speicherplatz des Laufzeitservers früher oder später erschöpft
* sein wird. In einem realen Produktionsszenario sollten die Zählungen persistent in einer Datenbank gespeichert werden.
*
*/

public class SampleLearning implements ILearning
{

// Eine Zuordnung von Angebots-IDs zur Kontaktzählung für das Angebots-ID
private Map<Long,Integer> _offerToContactCount = new HashMap<Long, Integer>();

// Eine Zuordnung von Angebots-IDs zur Kontaktzählung für das Angebots-ID
private Map<Long,Integer> _offerToAcceptCount = new HashMap<Long, Integer>();


/* (Nicht-Javadoc)
* @siehe 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
{
// Wenn Fernverbindungen erforderlich sind, ist dies eine gute Stelle, um diese Verbindungen zu initialisieren, weil diese
// Methode einmal beim Start der Interact-Laufzeit-Webanwendung aufgerufen wird.
// Dieses Beispiel hat keine Fernverbindungen und gibt aus Debugging-Gründen aus, dass diese Methode
// aufgerufen wird
System.out.println("Calling initialize for SampleLearning");
}

/* (Nicht-Javadoc)
* @siehe 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
{
// Wenn ein IC implementiert wird, wird diese Reinitialisierungsmethode aufgerufen, um es der Implementierung zu ermöglichen,
// aktualisierte Konfigurationseinstellungen neu anzuzeigen
System.out.println("Calling reinitialize for SampleLearning");
}


/* (Nicht-Javadoc)
* @siehe 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");

// Alle Kontakte im Speicher protokollieren
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");
// Alle Akzeptanzzählungen im Speicher durch Hinzufügen zur Zuordnung protokollieren
synchronized(_offerToAcceptCount)
{
Integer count = _offerToAcceptCount.get(offer.getOfferId());
if(count == null)
count = new Integer(1);
else
count++;
_offerToAcceptCount.put(offer.getOfferId(), ++count);
}
}

}

/* (Nicht-Javadoc)
* @siehe 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");

// Die möglichen Verfahren sortieren, indem die in dieser Klasse definierte Sortierkomponente aufgerufen wird, und die sortierte Liste zurückgeben
Collections.sort(recList,new MyOfferSorter());

// jetzt einfach zurückgeben, was über die Variable "numberRequested" angefordert wurde
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;
}

/* (Nicht-Javadoc)
* @siehe 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
{
// Wenn Fernverbindungen bestehen, ist dies eine gute Stelle, um
// sie zu trennen, weil diese Methode beim Herunterfahren der Interact-Laufzeit-Webanwendung
// aufgerufen wird.
Bei diesem Beispiel gibt es nichts wirklich zu tun,
// außer ein Debugging-Statement auszugeben.
System.out.println("Calling shutdown for SampleLearning");

}
// Sortieren nach:
// 1. Angebote mit null Kontakten - bei Gleichwertigkeit basiert die Reihenfolge auf der ursprünglichen Eingabe
// 2. Absteigende Akzeptanzwahrscheinlichkeitsrate - bei Gleichwertigkeit basiert die Reihenfolge auf der ursprünglichen Eingabe

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

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

// Kontaktzählung für beide Verfahren abrufen
Integer contactCount1 = _offerToContactCount.get(treatment1.getOffer().getOfferId());
Integer contactCount2 = _offerToContactCount.get(treatment2.getOffer().getOfferId());

// wenn ein Verfahren keinen Kontakt hatte, gewinnt sie
if(contactCount1 == null || contactCount1 == 0)
return -1;

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

// Akzeptanzzählung abrufen
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;

// absteigende Reihenfolge
return (int) (acceptProbability2 - acceptProbability1);

}
}

}