Costruzione di un motore di raccomandazione di prodotti con Apache Cassandra e Apache Pulsar

Building a product recommendation engine with Apache Cassandra and Apache Pulsar

Il percorso per implementare soluzioni di intelligenza artificiale e apprendimento automatico richiede di risolvere molte sfide comuni che si presentano regolarmente nei sistemi digitali: l’aggiornamento dei sistemi legacy, l’eliminazione dei processi batch e l’uso di tecnologie innovative basate su IA/ML per migliorare l’esperienza del cliente in modi che sembravano fantascienza solo pochi anni fa.

Per illustrare questa evoluzione, seguiamo un ipotetico appaltatore che è stato assunto per aiutare a implementare soluzioni di IA/ML presso un grande rivenditore. Questo è il primo di una serie di articoli che dettaglieranno gli aspetti importanti del percorso verso IA/ML.

Il Problema

È il primo giorno presso BigBoxCo nel team “Infrastruttura”. Dopo aver svolto le obbligatorie attività di risorse umane, ho ricevuto il mio badge di appaltatore e mi sono diretto al mio nuovo spazio di lavoro. Dopo aver incontrato il team, mi è stato detto che abbiamo una riunione con il team “Raccomandazioni” questa mattina. Il mio accesso al sistema non funziona ancora, quindi spero che l’IT risolva il problema mentre siamo in riunione.

In sala riunioni siamo solo in pochi: il mio responsabile e altri due ingegneri del mio nuovo team, e un ingegnere del team Raccomandazioni. Iniziamo con delle presentazioni e poi passiamo a discutere un problema della settimana precedente. A quanto pare, c’è stata una sorta di fallimento del processo batch durante la notte della scorsa settimana e ne stanno ancora risentendo.

Sembra che le attuali raccomandazioni di prodotti siano basate sui dati raccolti dagli ordini dei clienti. Con ogni ordine, viene registrata una nuova associazione tra i prodotti ordinati. Quando i clienti visualizzano le pagine dei prodotti, possono ottenere raccomandazioni in base a quanti altri clienti hanno acquistato il prodotto corrente insieme a prodotti diversi.

Le raccomandazioni di prodotti vengono fornite agli utenti su bigboxco.com tramite uno strato di microservizi nel cloud. Lo strato di microservizi utilizza un’implementazione locale (cloud) del data center di Apache Cassandra per fornire i risultati.

Tuttavia, come vengono raccolti e forniti i risultati è un’altra storia. Fondamentalmente, i risultati delle associazioni tra i prodotti (acquistati insieme) vengono compilati durante un processo MapReduce. Questo è il processo batch che è fallito la scorsa settimana. Sebbene questo processo batch non sia mai stato veloce, è diventato sempre più lento e fragile nel tempo. Infatti, a volte il processo impiega due o addirittura tre giorni per essere eseguito.

Migliorare l’Esperienza

Dopo la riunione, ho controllato il mio computer e sembrava che potessi finalmente accedere. Mentre guardo in giro, il nostro ingegnere principale (PE) passa di lì e si presenta. Gli ho parlato della riunione con il team Raccomandazioni e mi ha raccontato un po’ di più sulla storia del servizio Raccomandazioni.

Sembra che quel processo batch sia stato in uso per circa dieci anni. L’ingegnere che l’ha progettato se n’è andato; non molte persone nell’organizzazione lo capiscono davvero e nessuno vuole toccarlo.

Il problema, inizio a spiegare, è che l’insieme di dati che guida ogni raccomandazione è quasi sempre vecchio di un paio di giorni. Anche se potrebbe non sembrare un grosso problema nell’insieme delle cose, se i dati delle raccomandazioni potessero essere resi più aggiornati, sarebbe vantaggioso per le promozioni a breve termine gestite dal marketing.

Lui annuisce e dice di essere sicuramente aperto a suggerimenti per migliorare il sistema.

Forse un Problema di Grafo?

All’inizio, mi sembra che questo sia un problema di grafo. Abbiamo clienti che accedono al sito e acquistano prodotti. Prima di ciò, quando guardano un prodotto o lo aggiungono al carrello, possiamo mostrare raccomandazioni sotto forma di “I clienti che hanno acquistato X hanno acquistato anche Y”. Il sito ha già questa funzionalità, in quanto il servizio di raccomandazioni fa esattamente questo: restituisce i primi quattro prodotti aggiuntivi che vengono spesso acquistati insieme.

Tuttavia, dovremmo avere un modo per “classificare” i prodotti perché l’associazione di un prodotto con tutti gli altri acquistati contemporaneamente da uno qualsiasi dei nostri 200 milioni di clienti diventerà grande, rapidamente. Quindi, possiamo classificarli in base al numero di volte in cui compaiono in un ordine.

Un grafo di raccomandazioni di prodotti che mostra la relazione tra i clienti e i prodotti acquistati da loro.

Dopo aver modellato tutto ciò e averlo eseguito sul nostro database di grafi con volumi reali di dati, mi sono reso rapidamente conto che non avrebbe funzionato. La ricerca da un prodotto ai clienti vicini, ai loro prodotti e al calcolo dei prodotti che compaiono più spesso richiede circa 10 secondi. Fondamentalmente, abbiamo “rimandato” il problema del processo batch di due giorni ad ogni ricerca, posizionando la latenza della ricerca proprio dove non la vogliamo: di fronte al cliente.

Ma forse quel modello grafico non è troppo lontano da ciò che dobbiamo fare qui. In effetti, l’approccio descritto sopra è una tecnica di apprendimento automatico (ML) nota come “filtraggio collaborativo”. Fondamentalmente, il filtraggio collaborativo è un approccio che esamina la similarità di determinati oggetti di dati in base all’attività con altri utenti, e ci consente di fare previsioni basate su tali dati. Nel nostro caso, raccoglieremo implicitamente dati sui carrelli/ordini dalla nostra base clienti e li useremo per fare migliori raccomandazioni di prodotto al fine di aumentare le vendite online.

Implementazione

Prima di tutto, analizziamo la raccolta dati. Aggiungere una chiamata di servizio extra alla funzione di “effettua ordine” non è un grosso problema. Infatti, esiste già; è solo che i dati vengono archiviati in un database e elaborati successivamente. Non fraintendetemi: vogliamo comunque includere l’elaborazione batch. Ma vogliamo anche elaborare quei dati del carrello in tempo reale in modo da poterli reinserire immediatamente nell’insieme di dati online e usarli subito dopo.

Inizieremo inserendo una soluzione di event streaming come Apache Pulsar. In questo modo, tutte le nuove attività dei carrelli vengono inserite in un topic Pulsar, dove vengono consumate e inviate sia al database batch sottostante che per aiutare ad addestrare il nostro modello di ML in tempo reale.

Per quanto riguarda quest’ultimo, il nostro consumatore Pulsar scriverà su una tabella Cassandra (mostrata in Figura 2) progettata semplicemente per contenere le voci per ogni prodotto nell’ordine. Il prodotto avrà quindi una riga per tutti gli altri prodotti di quell’ordine e di altri ordini:

Migliorare un sistema di raccomandazione già esistente basato su batch con Apache Pulsar e Apache Cassandra.

Potremo quindi interrogare questa tabella per un determinato prodotto (“DSH915” in questo esempio), in questo modo:

Potremo poi prendere i primi quattro risultati e inserirli nella tabella delle raccomandazioni di prodotti, pronti per essere interrogati dal servizio tramite `product_id`:

In questo modo, i nuovi dati di raccomandazione vengono costantemente aggiornati. Inoltre, tutti gli asset di infrastruttura descritti sopra si trovano nel data center locale. Pertanto, il processo di estrarre le relazioni tra i prodotti da un ordine, inviarle attraverso un topic Pulsar e elaborarle in raccomandazioni memorizzate in Cassandra avviene in meno di un secondo. Con questo semplice modello di dati, Cassandra è in grado di fornire le raccomandazioni richieste in millisecondi a cifra singola.

Conclusioni e Prossimi Passi

Dovremo assicurarci di esaminare come i nostri dati vengono scritti nelle tabelle di Cassandra a lungo termine. In questo modo possiamo anticipare eventuali problemi legati a cose come la crescita illimitata delle righe e gli aggiornamenti in-place.

Potrebbe essere necessario aggiungere anche alcuni filtri euristiche aggiuntivi, come una lista “non raccomandare”. Questo perché ci sono alcuni prodotti che i nostri clienti compreranno una sola volta o raramente, e raccomandarli toglierà spazio ad altri prodotti che sono molto più propensi a comprare per impulso. Ad esempio, raccomandare l’acquisto di qualcosa dalla nostra divisione elettrodomestici come una lavatrice non porterà probabilmente a un “acquisto per impulso”.

Un’altra miglioramento futuro sarebbe implementare una piattaforma AI/ML in tempo reale come Kaskada per gestire sia lo streaming delle relazioni tra i prodotti che per fornire direttamente i dati di raccomandazione al servizio.

Fortunatamente, abbiamo trovato un modo per potenziare il processo batch esistente, lento, utilizzando Pulsar per inviare gli eventi di aggiunta al carrello da elaborare in tempo reale. Una volta che avremo familiarità con le prestazioni di questo sistema nel lungo periodo, dovremmo considerare di spegnere il vecchio processo batch. Il PE ha riconosciuto che abbiamo fatto buoni progressi con la nuova soluzione e, ancora meglio, che abbiamo anche iniziato a gettare le basi per eliminare alcuni debiti tecnici. Alla fine, tutti si sentono bene a riguardo.

In un prossimo articolo, daremo un’occhiata al miglioramento delle promozioni di prodotti con la ricerca vettoriale.