• Non ci sono risultati.

4.4 Controlli e suggerimenti 1 Controll

4.4.3 Suggeritore di azion

Il suggeritore di azioni ha invece la funzione di mostrare all’utilizzatore una o più possibili azioni che possono essere compatibili con la sequenza di trigger presenti nell’area di lavoro. Si tratta quindi di un problema relativo ai sistemi di raccomandazione, ma diverso dal “caso tipo”.

Questo perché si tratta di “completare” una regola composta da due parti, di cui una conosciuta. E’ stata realizzata una pipeline “ad imbuto” che tramite selezioni successive evidenzi prima le migliori N regole dal punto di vista della compatibilità dei trigger, da queste le migliori per quanto riguarda la compatibilità tra utenti, da queste le azioni più popolari. Si tratta quindi di un sistema di raccomandazione di tipo misto, con una parte relativa al contenuto, una collaborativa e con un peso finale dato dalla popolarità.

Il primo passo consiste nell’estrazione delle regole che condividono almeno un trigger con quelli presenti nell’area di lavoro, per filtrare così quelle che non hanno possibilità di avere un buon punteggio, limitando le operazioni inutili. Il passo successivo consiste nell’effettuare un confronto tra la lista dei trigger nell’area di lavoro e quella di ogni altra regola estratta, per poter stabilire quale siano le regole presenti nel database più simili a quella in costruzione.

La similarità viene calcolate tramite l’indice (o coefficiente di similarità) di Jaccard , una 47 misura statistica di quanto siano simili tra loro due insiemi. Viene definita come la grandezza dell’intersezione tra i due insiemi divisa per la grandezza dell’unione tra essi: in altre parole,

47 "Jaccard index - Wikipedia." https://en.wikipedia.org/wiki/Jaccard_index. Ultimo accesso: 3

il numero di elementi in entrambi gli insiemi su il numero elementi nell’uno o nell’altro. Moltiplicato per 100 fornisce una misura in percentuale della similarità tra i due insiemi. E’ stata scelta questa misura perché ci da un modo di conoscere gli “argomenti” di una regola, senza che le ripetizioni di trigger vadano a pesare sulla similarità con altre regole.

L’indice di Jaccard è stato usato in [1] per migliorare le prestazioni di un recommender system di tipo collaborativo, utilizzandolo per calcolare la similarità tra utenti (invece di seguire un approccio tipico basato sull’andamento delle valutazioni). La misura da loro usata è al numeratore la sommatoria delle valutazione comune degli stessi oggetti, più uno alla sommatoria per l’eventuale similarità tra i valori medi di valutazione degli oggetti, e al denominatore il numero di valutazioni comuni tra i due utenti.

Immagine 12: indice di Jaccard

Nel nostro caso anche lo schema dei trigger ci può fornire delle informazioni riguardo la similitudine tra trigger, essendo codificato come una rappresentazione ad albero. Abbiamo quindi stabilito che due trigger che facciano parte della stessa categoria, ovvero che siano figli dello stesso nodo, siano più simili tra loro rispetto a due trigger che invece non condividano il nodo parente.

E’ stata pensata una misurazione alternativa, sempre basata sul concetto di intersezione su unione, che potesse però includere il concetto di vicinanza, ottenendo uno score più “morbido”. Invece di contare solo la presenza o meno di un trigger nell’intersezione, è stato anche dato un peso alla condivisione della stessa categoria, contato solo in caso i trigger non siano uguali. In questo modo essi ottengono un punteggio di similarità leggermente più elevato, a parità di trigger uguali, rispetto a quelli che non condividono nessuna categoria, permettendo di non perdere il valore di vicinanza implicito nella rappresentazione.

/**

* su unione), ma da un peso di 0.33 (invece che 0) agli elementi che * condividono la categoria di appartenenza, per non fare andare perduta * questa informazione.

* @param {*} setA * @param {*} setB */

function weightedJaccard(setA, setB) { let numerator = 0;

let denominator = 0; const weight = 0.33; // intersezione

for (let itemA of setA) { if (setB.has(itemA)) { numerator ++;

} else {

for (let itemB of setB) {

const categoryA = Main.getTriggerCategory(itemA); const categoryB = Main.getTriggerCategory(itemB);

if (categoryA && categoryB && categoryA === categoryB) { numerator += weight; } } } } // unione

const union = new Set(); setA.forEach(e => { union.add(e); }); setB.forEach(e => { union.add(e); }); denominator = union.size; return numerator / denominator; }

Code snippet 5: misura ispirata all’indice di Jaccard usata per calcolare la similarità tra due set di trigger.

Il passo successivo nella pipeline riguarda un filtro collaborativo. E’ stata utilizzato l’indice di correlazione di Pearson utilizzando come attributo su cui calcolare la correlazione il conteggio per ogni azione del numero di utilizzi in tutte le regole per quell’utente.

L’indice di correlazione di Pearson è una metrica che esprime la relazione di linearità tra 48 due variabili, ovvero se l’andamento della prima variabile sia proporzionale rispetto a quello della seconda, se non ci sia proporzionalità o se il rapporto di proporzionalità sia inverso. Questo rapporto viene espresso in un intervallo compreso tra -1 e 1. Nel nostro caso le variabili sono due array, che contengono il numero di volte che è stata usata nelle regole ogni azione dall’utente corrente e dall’altro utente con cui stiamo calcolando la similarità.

E’ stato scelto di calcolare la similarità sulle azioni per l’immediata disponibilità di questo valore, ma è possibile impostare questa similarità su diversi altri parametri, come il numero di attivazioni delle regole. Un’altra possibilità è quella di ottenere valori numerici dei pattern di comportamento dell’utente, come gli orari di attivazione dei sensori.

E’ stata usata la similarità tra le azioni utilizzate (quindi, in un parallelismo con i RS classici, con gli oggetti comprati) assegnando un punteggio minimo a quelle non usate. Non si è cercato di ricostruire le “valutazioni mancanti” partendo da quelle che abbiamo perché, dato il ristretto numero di azioni, è stato assunto che l’utente abbiamo avuto la possibilità di guardarle tutte prima di scegliere: quindi le “valutazioni” mancanti sono effettivamente espressioni di non utilizzo, non mancanza di dati.

L’ultimo passaggio nella pipeline è il filtro sulla popolarità delle azioni in questo contesto, contate cioè tra le regole coerenti con i trigger attuali. Da questo passaggio si consiglia infine la parte relativa alle azioni della regola che ha ottenuto il punteggio più alto sulla popolarità delle azioni, o in caso di parità una regola a caso tra quelle di punteggio più alto.

Schema di funzionamento del suggeritore per azioni:

● estrae i trigger nel workspace;

● trova le regole che includono almeno un trigger tra quelli presenti nel workspace;

48 "Pearson correlation coefficient - Wikipedia."

● calcola la similarità tra i trigger presenti nel workspace e quelli delle regole estratte, estrae le top N regole;

● da queste regole estrai le migliori dal punto di vista di similarità tra gli utenti;

● ordina le regole rimanenti secondo popolarità delle azioni, restituisci le azioni della regola con popolarità maggiore o una a caso tra quelle a pari punteggio massimo.

Documenti correlati