Worstel je met AI of full-stack ontwikkeling? Onze experts staan klaar om je te begeleiden: advies op maat, technische integratie en meer. Neem contact op met [email protected].

Contextuele targeting voor privacy-vriendelijke reclame dankzij tekstclassificatie Natural Language Processing API

Article by Rafał Rybnik, Hoofd Software Ontwikkeling bij Instytut Badań Pollster

Contextueel adverteren
Tenzij anders vermeld, zijn alle foto's in het artikel van de auteur.

Volg niet de gebruiker, volg interesses

In de huidige realiteit van onlinereclame berusten effectieve marketingtactieken op een verscheidenheid van technieken voor het volgen van gebruikers technieken, zoals cookies van derden (en alternatieve opslagplaatsen) en device fingerprinting. Maar in een wereld van datalekken, GDPR, CCPA en de toenemende wetgeving inzake gegevensbescherming die daarop is geïnspireerd, wordt deze aanpak achterhaald. Safari en Firefox hebben al oplossingen ingebouwd om cross-site tracking te beperken. Chrome werkt ook aan alternatieven. Het einde van third-party cookies is dus nabij. Apple's Identifier voor Advertisers (IDFA) zal binnenkort alleen nog toegankelijk zijn voor apps met expliciete toestemming van de gebruiker. De verdwijnen van de mogelijkheid tot cross-domain tracking doet adverteerders terugkeren naar contextual advertising.

In dit artikel laat ik zien hoe je context targeting kunt implementeren op basis van de Text Classification API geleverd door NLP Cloud. De aanpak die hier wordt beschreven kan gemakkelijk worden aangepast aan elke advertentie technologie (zoals ad servers, OpenRTB, enz.).

Contextgerichtheid

Omdat adverteerders niet in staat zullen zijn individuele gebruikers te targeten door gebruik te maken van cookies van derden, is een gemakkelijke voorspelling is dat contextuele reclamecampagnes weer in opkomst zijn. Dit zou de enige manier kunnen zijn om gebruikers interesses op een voldoende grote schaal. Contextuele advertenties zijn gebaseerd op inhoud waar de gebruiker naar kijkt op dit moment, in plaats van op zijn browsergeschiedenis of gedragsprofiel.

Contextueel adverteren
(foto van Wat is contextuele Reclame?)

Het is de bedoeling dat het interessanter wordt voor gebruikers, omdat ze advertenties te zien krijgen die aansluiten bij het onderwerp van de website pagina's die ze bezoeken.

Geef me een label.

De meeste ad serving technologieën en ad netwerken ondersteunen het doorgeven van keywords of tags tijdens de ad serveercodes. Tekst is de kern van het web en kan een uiterst rijke bron van informatie zijn. Echter, context, tags en trefwoorden eruit halen, bv. voor advertentie- of aanbevelingsdoeleinden, kan moeilijk en tijdrovend zijn. Maar als u de eigenaar bent van zelfs een middelgrote nieuwssite, zal het, buiten een paar tags toegewezen door de redactie, zal het moeilijk zijn om alle relevante onderwerpen te extraheren.

De eerste pogingen om dit proces te automatiseren hebben in het verleden tot min of meer hilarische mislukkingen geleid:

Onjuiste contextuele reclame
(foto van Slechte advertentieplaatsingen grappig, Als het niet van jou is)

Tekstindeling van artikelen

Gelukkig kunnen dankzij de vooruitgang op het gebied van natuurlijke taalverwerking veel nauwkeuriger matches worden gemaakt, in minder tijd. Tekstclassificatie is het toekennen van categorieën of labels die consistent zijn met de tekstinhoud.

Laten we eens kijken naar een voorbeeldpagina met artikelen over uiteenlopende onderwerpen:

Advertentie plaatsen

Ons doel is om advertentieplaatsingen banners te laten tonen die thematisch gerelateerd zijn aan de inhoud van het artikel.

Voorwaarden waaraan onze oplossing moet voldoen:

Merk op dat advertentiesystemen en webontwikkeling buiten het bestek van dit artikel vallen, maar de algemene concepten blijven dezelfde, ongeacht de gebruikte instrumenten en technologieën.

Tekstclassificatie API

Mijn voorkeursoplossing in dergelijke gevallen is om de logica die tekstclassificatie afhandelt te scheiden in een aparte API. We hebben twee opties: het zelf maken of een kant-en-klare oplossing gebruiken.

Het maken van een eenvoudige tekstclassificatie-engine met behulp van Python en Natural Language Processing bibliotheken is een taak voor een middag. Maar het probleem ontstaat in termen van nauwkeurigheid en het dienen van toegenomen verkeer. We moeten op een of andere manier omgaan met de groeiende gebruikersgroep en hun clickstream.

Als eigenaar van een website zult u waarschijnlijk niet willen spelen met het afstemmen en evalueren van de modellen voor machinaal leren. Dus zullen we zoveel mogelijk delegeren aan een externe oplossing. Merk op dat we niet van plan zijn hier gebruikersgegevens naartoe te sturen, alleen gegevens die bij de website horen. Dit maakt het gebruik van externe contextuele targeting tools veel eenvoudiger vanuit het oogpunt van gebruikersprivacy.

NLP Cloud is een aanbieder van meerdere API's voor tekstverwerking met behulp van modellen voor machinaal leren. Een van deze is de tekst classificator, die er veelbelovend uitziet in termen van eenvoudige implementatie (zie docs).

NLP Cloud modellen

Met de NLP Cloud API kunt u uitproberen welk algoritme nuttig zou kunnen zijn voor een bepaalde business case.

Tekstclassificatie integreren met de inhoud van de website

Aangezien de backend van de website op Python is gebaseerd (Flask), beginnen we met het schrijven van een eenvoudige client voor de Natural Language Processing API:

import pandas as pd
import requests
import json


class TextClassification:
    def __init__(self, key, base='https://api.nlpcloud.io/v1/bart-large-mnli',):
        self.base = base
        self.headers = {
            "accept": "application/json",
            "content-type": "application/json",
            "Authorization": f"Token {key}"
        }

    def get_keywords(self, text, labels):
        url = f"{self.base}/classification"
        payload = {
            "text":text,
            "labels":labels,
            "multi_class": True
        }

        response = requests.request("POST", url, json=payload, headers=self.headers)
        result = []
        try:
            result = dict(zip(response.json()['labels'], response.json()['scores']))
        except:
            pass
        return result
        
tc = TextClassification(key='APIKEY')

print(
    tc.get_keywords(
        "Football is a family of team sports that involve, to varying degrees, kicking a ball to score a goal. Unqualified, the word football normally means the form of football that is the most popular where the word is used. Sports commonly called football include association football (known as soccer in some countries); gridiron football (specifically American football or Canadian football); Australian rules football; rugby football (either rugby union or rugby league); and Gaelic football.[1][2] These various forms of football share to varying extent common origins and are known as football codes.",
        ["football", "sport", "cooking", "machine learning"]
    )
)

Results:

{
    'labels': [
        'sport', 
        'football', 
        'machine learning', 
        'cooking'
    ], 

    'scores': [
        0.9651273488998413, 
        0.938549280166626, 
        0.013061746023595333, 
        0.0016104158712550998
    ]
}

Vrij goed. Elk label krijgt zonder moeite zijn relevantie voor het onderwerp.

Het plan is dat de selectie van de te tonen banners zal worden gedaan door een ad serving systeem (beslissing zal worden gebaseerd op de scores van de individueel toegewezen labels). Daarom, om de API-sleutels niet bloot te API sleutels niet bloot te geven en om meer controle over de gegevens te hebben, zullen we een eenvoudige proxy schrijven:

@app.route('/get-labels',methods = ['POST'])
def get_labels():
    if request.method == 'POST':
        try:
            return tc.get_keywords(request.json['text'], request.json['labels'])
        except:
            return []

Campagnes

Laten we aannemen dat we 3 advertentiecampagnes hebben lopen:

Ad placement
Verzekeringsmaatschappij (trefwoord: insurance)

Ad placement
Onderneming voor hernieuwbare energie (trefwoord: renewables)

Ad placement
Kapper (trefwoord: good look)

Laten we een mechanisme schetsen op de front-end, dat de weergave van een passende creatieve zal beheren.

function displayAd(keyword, placement_id) {

    var conditions = {
        false: ' ',
        "insurance": ' ',
        "renewables": ' ',
        "good look": ' '
    }

    var banner = document.querySelector(placement_id);
    banner.innerHTML = conditions[keyword];

}

Dit is onze advertentieserver 🤪

Nu zullen we met fetch labels ophalen voor de tekst van een artikel, die we krijgen met de selector:

var text = document.querySelector("#article").textContent;
var labels = ["insurance", "renewables", "good look"];

var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");

var raw = JSON.stringify({"text":text,"labels":labels});

var requestOptions = {
    method: 'POST',
    headers: myHeaders,
    body: raw,
};

fetch("http://127.0.0.1:5000/get-labels", requestOptions)
    .then(response => 
    response.json()
    )
    .then(result => {
    if (result == []){
        console.log("self-promote");
        displayAd(false, "#banner");
    } else {
        var scores = result['scores'];
        var labels = result['labels'];

    if (Math.max(...scores) >= 0.8) {
        console.log("Ad success");
        var indexOfMaxScore = scores.reduce((iMax, x, i, arr) => x > arr[iMax] ? i : iMax, 0);
        displayAd(labels[indexOfMaxScore], "#banner");

    } else {
        displayAd(false, "#banner");
    }
    }
    })
    .catch(error => console.log('error', error));

Merk op dat we de client-advertentie alleen tonen als de score hoger is dan 0.8:

Math.max(…scores) >= 0.8

Anders tonen we zelfpromotie.

Dit is uiteraard een arbitraire waarde, die naar behoefte kan worden verscherpt of versoepeld.

Advertentie plaatsen
Nieuws over duurzame energiebron past PV-cel advertenties.

Advertentie plaatsen
Nieuws over de gevaren in huis kan de intentie om een verzekering te kopen.

Advertentie plaatsen
Hoewel een advertentie over verzekeringen geschikt zou zijn geweest voor het artikel, werd deze niet weergegeven omdat het juiste niveau van relevantie niet werd bereikt.

De aandachtige lezer zal opmerken dat het voorbeeld van het vaandel van de kapper niet voorkwam. Dit komt omdat het onderwerp van de artikelen gericht is op serieus wereldnieuws, waar modezaken niet aan de orde komen. Om de campagne te kunnen uitvoeren, moet u een andere site kiezen of uw zoekwoord strategie.

Prestaties

We kunnen de pagina snel laden dankzij deze asynchrone functie: fetch . Tegelijkertijd wordt de advertentie echter pas getoond nadat de etiketten zijn gedownload. Om deze reden en om de kosten te drukken, is het best om een of andere vorm van cache te implementeren in een productie omgeving.

Een extra wijziging zou kunnen zijn om de etiketten rechtstreeks in de databank op te slaan. Voor zelden bijgewerkte artikelen, is dit zeker zinvol.

Echter, een oplossing gebaseerd op een aparte API, die we kunnen voeden aan elke tekst en de labels krijgen, geeft ons de mogelijkheid om JS code virtueel te gebruiken op elke pagina in bijna real-time, zelfs zonder toegang tot de backend!

Takeaways

De grootste uitdaging bij het gebruik van contextuele targeting is het gebruik ervan op nieuwswebsites. Veel onderwerpen verschijnen in de artikelen die daar gepost worden, inclusief diegene die in lijn liggen met de industrie van de adverteerder. Maar tegelijkertijd dezelfde tijd, de sensationele, vaak trieste boventonen van de verhalen die ze bevatten zijn geen goede plaats om te adverteren.

De tekst classificatie-API van NLP Cloud, daarentegen, doet goed werk bij het taggen van teksten, dus kunnen we net zo goed het hele proces herhalen, deze keer met in gedachten dat we teksten met een bepaald onderwerp moeten uitsluiten om er banners op te plaatsen (zie de API-pagina voor tekstclassificatie)

Papieren vliegtuig

Dank u voor het lezen. Ik hoop dat u het net zo leuk vond om te lezen als ik het vond om dit voor u te schrijven.