l’algoritmo Apriori è un classico algoritmo di ricerca delle associazioni. È utilizzato per la generazione degli itemset frequenti, per approssimazioni successive, a partire dagli itemset con un solo elemento.
Il presupposto teorico su cui si basa l’algoritmo parte dalla considerazione che se un insieme di oggetti (itemset) è frequente, allora anche tutti i suoi sottoinsiemi sono frequenti, ma se un itemset non è frequente, allora neanche gli insiemi che lo contengono sono frequenti ( fonte: Wikipedia).
In questo breve draft utilizzeremo l’algoritmo Apriori per individuare gli oggetti che sono spesso comprati insieme, ovvero cercheremo di trovare le regole di associazione degli elementi all’interno di un insieme di dati.
i dati che utilizzeremo sono scaricabili qui. In questo caso i dati sono in formato csv, ma la stessa procedura è applicabile a dati che provendono da un database aziendale o un data lake
groceries <- read.csv("groceries.csv") %>%
tibble::as_tibble() %>%
mutate(Date = lubridate::dmy(as.character(Date))) %>%
arrange(Member_number)
DT::datatable(groceries, rownames = FALSE, style = "bootstrap",
options = list(pageLength = 7, dom = 't'),
filter = list(position = "top"))
Qui potete vedere un’anteprima dei dati. Nel dataset sono presenti il codice identificativo del cliente, la data e gli oggetti inseriti nel carrello, per un totale di 38765 ordini.
Per poter utilizzare l’algoritmo è necessario che ogni riga del dataset comprenda tutti gli oggetti comprati in ogni singolo ordine. Nella libreria
plyr
esiste una funzione che fa al caso nostro.
Il dataset trasformato appare nella seguente forma
library(plyr)
itemList_df <- ddply(groceries, c("Member_number","Date"),
function(df1) paste(df1$itemDescription,collapse = ",")) %>%
rename(itemList = V1) %>%
select(itemList)
DT::datatable(itemList_df, style = "bootstrap",
options = list(pageLength = 7, dom = 't'),
filter = list(position = "top"))
Per l’implementazione dell’algoritmo utilizzeremo la libreria
arules
che fornisce un ambiente di calcolo per le regole associative e gli itemset. Per una review approfondita rimando all’articolo di Hahsler e colleghi
library(arules)
write.csv(itemList_df, "ItemList.csv", quote = FALSE, row.names = TRUE)
transactions <- read.transactions(file= "ItemList.csv", rm.duplicates= FALSE, format="basket",sep=",",cols=1)
transactions@itemInfo$labels <- gsub("\"","",transactions@itemInfo$labels)
basket_rules <- apriori(transactions, parameter = list(minlen=2,sup = 0.001, conf = 0.01, target="rules"))
Apriori
Parameter specification:
confidence minval smax arem aval originalSupport maxtime support minlen
0.01 0.1 1 none FALSE TRUE 5 0.001 2
maxlen target ext
10 rules FALSE
Algorithmic control:
filter tree heap memopt load sort verbose
0.1 TRUE TRUE FALSE TRUE 2 TRUE
Absolute minimum support count: 14
set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[168 item(s), 14964 transaction(s)] done [0.00s].
sorting and recoding items ... [149 item(s)] done [0.00s].
creating transaction tree ... done [0.00s].
checking subsets of size 1 2 3 4 done [0.00s].
writing ... [1186 rule(s)] done [0.00s].
creating S4 object ... done [0.00s].
A questo punto è possibile visualizzare le associazioni più frequenti
df_basket <- as(basket_rules,"data.frame") %>%
arrange(desc(lift))
DT::datatable(head(df_basket, 20))
L’indicatore Lift è il fattore che ci indica la probabilità di co-occorrenza di A e B in rapporto alla probabilità dell’occorrenza dei due item nel caso in cui fossero indipendenti. Quindi più è alto il Lift più è alta la probabilità che i due item siano acquistati insieme
Se siamo interessati ad un prodotto in particolare, è possibile utilizzare la stessa funzione utilizzata in precedenza. Facciamo finta di essere interessati ai prodotti che si associano maggiormente al burro.
Apriori
Parameter specification:
confidence minval smax arem aval originalSupport maxtime support minlen
0.01 0.1 1 none FALSE TRUE 5 1e-05 2
maxlen target ext
10 rules FALSE
Algorithmic control:
filter tree heap memopt load sort verbose
0.1 TRUE TRUE FALSE TRUE 2 TRUE
Absolute minimum support count: 0
set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[168 item(s), 14964 transaction(s)] done [0.00s].
sorting and recoding items ... [168 item(s)] done [0.00s].
creating transaction tree ... done [0.00s].
checking subsets of size 1 2 done [0.00s].
writing ... [55 rule(s)] done [0.00s].
creating S4 object ... done [0.00s].
A work by Fabio Paderi
Â