Ga naar hoofdinhoud

Market Basket Analysis met R

Leer over Market Basket Analysis en het APRIORI‑algoritme erachter. Zie hoe het retailers helpt de business te boosten door te voorspellen welke items klanten samen kopen.
· 15 min lezen

Verken met AI

Je bent data scientist (of je wordt het!), en je krijgt een klant die een retailwinkel runt. Je klant geeft je transactiegegevens met items die klanten in de winkel hebben gekocht over een bepaalde periode en vraagt je die data te gebruiken om de business een boost te geven. Je klant zal jouw bevindingen gebruiken om niet alleen items in de voorraad te wijzigen/bij te werken/toe te voegen, maar ook om de indeling van de fysieke winkel of de online shop aan te passen. Om inzichten te vinden die je klant helpen, gebruik je Market Basket Analysis (MBA), dat Association Rule Mining toepast op de gegeven transactiegegevens.

In deze tutorial leer je:

  • Wat Association Rule Mining is en de toepassingen ervan
  • Wat het APRIORI-algoritme is
  • Hoe je MBA/Association Rule Mining implementeert in R met visualisaties

Association Rule Mining

Association Rule Mining gebruik je wanneer je een verband wilt vinden tussen verschillende objecten in een verzameling, of veelvoorkomende patronen wilt vinden in een transactiedatabase, relationele databases of een andere informatiebron. Toepassingen van Association Rule Mining vind je in marketing, basket data-analyse (of Market Basket Analysis) in retail, clusteren en classificeren. Het kan je vertellen welke items klanten vaak samen kopen door een set regels te genereren, zogenaamde Association Rules. Simpel gezegd: het geeft regels in de vorm als dit, dan dat. Klanten kunnen die regels gebruiken voor tal van marketingstrategieën:

  • De winkelindeling aanpassen op basis van trends
  • Analyse van klantgedrag
  • Catalogusontwerp
  • Cross-marketing in online winkels
  • Welke items trending zijn onder klanten
  • Gepersonaliseerde e-mails met extra verkoopkansen

Bekijk het volgende voorbeeld:

example

Hier zie je een set transactiegegevens. Je ziet transacties genummerd 1 tot en met 5. Elke transactie toont de items die in die transactie zijn gekocht. Je ziet dat luiers samen met bier worden gekocht in drie transacties. Op dezelfde manier worden brood met melk in drie transacties gekocht, waardoor het frequente itemsets zijn. Association rules worden gegeven in de volgende vorm:

$A=>B[Support,Confidence]$

Het deel vóór $=>$ noem je als (Antecedent) en het deel na $=>$ noem je dan (Consequent).

Waar A en B verzamelingen van items zijn in de transactiegegevens. A en B zijn disjuncte verzamelingen.

$Computer=>Anti-virus Software[Support=20\%,confidence=60\%]$

Bovenstaande regel zegt:

  1. In 20% van de transacties wordt antivirussoftware gekocht bij de aanschaf van een computer
  2. 60% van de klanten die antivirussoftware kopen, doet dat bij de aanschaf van een computer

In de volgende sectie leer je de basisconcepten van Association Rule Mining:

Basisconcepten van Association Rule Mining

Basic Concepts of Association Rule Mining
  1. Itemset: Verzameling van één of meer items. K-itemset betekent een set van k items.

  2. Support Count: Hoe vaak een itemset voorkomt

  3. Support (s): Het deel van de transacties dat itemset 'X' bevat

    $Support(X)=\frac{frequency(X)}{N}$

Voor een regel A=>B is de support:

$Support(A=>B)=\frac{frequency(A,B)}{N}$

Let op: P(AUB) is de kans dat A en B samen voorkomen. P staat voor kans (probability).

Ga aan de slag en probeer als oefening de support voor Milk=>Diaper te vinden.

  1. Confidence (c): Voor een regel A=>B laat confidence zien in hoeveel procent van de gevallen B samen met A wordt gekocht.

$Confidence(A=>B)=\frac{P(A\cap B)}{P(A)}=\frac{frequency(A,B)}{frequency(A)}$

Het aantal transacties met zowel A als B, gedeeld door het totale aantal transacties met A.

$Confidence(Bread=>Milk)=\frac{3}{4}=0.75=75\%$

Vind nu de confidence voor Milk=>Diaper.

Let op: Support en confidence meten hoe interessant de regel is. Ze worden bepaald door de drempels voor minimum support en minimum confidence. Deze door de klant ingestelde drempels helpen om de sterkte van regels te vergelijken. Hoe dichter bij of boven de drempel, hoe nuttiger de regel voor de klant.

  1. Frequent Itemsets: Itemsets waarvan de support groter is dan of gelijk aan de minimum support-drempel (min_sup). In bovenstaand voorbeeld is min_sup=3. Dit stel je zelf in.

  2. Sterke regels: Als een regel A=>B[Support, Confidence] voldoet aan min_sup en min_confidence, dan is het een sterke regel.

  3. Lift: Lift geeft de correlatie tussen A en B in de regel A=>B. Correlatie toont hoe itemset A itemset B beïnvloedt.

$Lift(A=>B)=\frac{Support}{Supp(A)Supp(B)}$

Voor de regel {Bread}=>{Milk} wordt de lift als volgt berekend:

$support(Bread)=\frac{4}{5}=0.8$

$support(Milk)=\frac{4}{5}=0.8$

$Lift(Bread=>Milk)=\frac{0.6}{0.8*0.8}=0.9$

  • Als de regel een lift van 1 heeft, dan zijn A en B onafhankelijk en kan er geen regel uit worden afgeleid.

  • Als de lift > 1 is, dan zijn A en B afhankelijk van elkaar, waarbij de mate wordt aangegeven door de liftwaarde.

  • Als de lift < 1 is, dan heeft de aanwezigheid van A een negatief effect op B.

Doel van Association Rule Mining

Wanneer je Association Rule Mining toepast op een verzameling transacties T, is je doel om alle regels te vinden met:

  1. Support groter dan of gelijk aan min_support
  2. Confidence groter dan of gelijk aan min_confidence

APRIORI-algoritme

In dit deel van de tutorial leer je over het algoritme dat onder de R-libraries voor Market Basket Analysis draait. Dit helpt je je klanten beter te begrijpen en nauwkeuriger te analyseren. Als je het APRIORI-algoritme en de werking al kent, ga dan door naar het code-gedeelte.

Association Rule Mining bestaat uit twee stappen:

  1. Genereren van frequente itemsets: Vind alle frequente itemsets met support >= vooraf bepaalde min_support

  2. Regels genereren: Maak alle Association Rules uit frequente itemsets. Bereken support en confidence voor alle regels. Snoei regels die niet voldoen aan de min_support- en min_confidence-drempels.

Genereren van frequente itemsets is de meest rekenintensieve stap, omdat hiervoor een volledige database-scan nodig is.

Van bovenstaande stappen is het genereren van frequente itemsets het duurst qua rekenwerk.

Boven zag je een voorbeeld met slechts 5 transacties, maar in de echte wereld kunnen retailtransacties oplopen tot GB’s en TB’s aan data, waarvoor een geoptimaliseerd algoritme nodig is om itemsets weg te snoeien die later niet helpen. Hiervoor wordt het APRIORI-algoritme gebruikt. Dat stelt:

Elke deelverzameling van een frequente itemset moet ook frequent zijn. Met andere woorden: er mag geen superset van een infrequente itemset worden gegenereerd of getest

Dit wordt weergegeven in een Itemset Lattice, een grafische representatie van het APRIORI-principe. Het bestaat uit knooppunten voor k-itemsets en de relatie van deelverzamelingen van die k-itemset.

itemset lattice

Je ziet in de bovenstaande figuur dat onderaan alle items staan in de transactiegegevens en dat je vervolgens naar boven subsets blijft maken tot aan de lege set. Voor d items wordt de grootte van het rooster $2^d$. Dit laat zien hoe lastig het is om frequente itemsets te genereren door voor elke combinatie de support te vinden. De volgende figuur laat zien hoeveel APRIORI helpt om het aantal te genereren sets te verminderen:

itemset lattice 2

Als itemset {a,b} infrequent is, hoeven we al zijn supersets niet mee te nemen.

Laten we dit begrijpen met een voorbeeld. In het volgende voorbeeld zie je waarom APRIORI een effectief algoritme is en genereer je stap voor stap sterke associatieregels. Volg mee met je notitieboek en pen!

example

Zoals je ziet begin je met het maken van een kandidatenlijst voor de 1-itemset die alle items bevat die individueel in de transactiegegevens voorkomen. Bedenk bij retaildata uit de praktijk hoe duur deze kandidaatgeneratie is. Hier speelt APRIORI zijn rol en helpt het het aantal kandidaten te verkleinen, zodat er uiteindelijk nuttige regels ontstaan. In de volgende stappen zie je hoe we het einde van de frequent itemset-generatie bereiken, de eerste stap van association rule mining.

example

Je volgende stap is alle frequente itemsets opsommen. Je neemt de laatste niet-lege frequente itemset, die in dit voorbeeld L2={I1, I2},{I2, I3} is. Maak dan alle niet-lege deelverzamelingen van de itemsets in die lijst met frequente itemsets. Volg zoals hieronder geïllustreerd:

example

Je ziet hierboven vier sterke regels. Neem bijvoorbeeld ${I2}=>I3$ met een confidence van 75%: dat vertelt dat 75% van de mensen die I2 kochten ook I3 kochten.

Je hebt nu het volledige APRIORI-algoritme geleerd, een van de meest gebruikte algoritmen in data mining. Door naar de code, pfoe!

MBA/Association Rule Mining implementeren in R

In deze tutorial gebruik je een dataset uit de UCI Machine Learning Repository. De dataset heet Online-Retail en je kunt hem hier downloaden. De dataset bevat transactiegegevens van 01/12/2010 tot 09/12/2011 voor een in het VK geregistreerde non-store online retailer. We gebruiken deze en niet een R-dataset omdat je retaildata vaker in deze vorm zult ontvangen, waarop je datapreprocessing moet toepassen.

Beschrijving van de dataset

  • Aantal rijen:541909
  • Aantal attributen:08
Attribuutinformatie
  • InvoiceNo: Factuurnummer. Nominaal, een 6-cijferig geheel getal dat uniek is voor elke transactie. Als deze code met de letter 'c' begint, duidt dit op een annulering. +StockCode: Product(code). Nominaal, een 5-cijferig geheel getal dat uniek is voor elk product.
  • Description: Productnaam. Nominaal.
  • Quantity: Het aantal van elk product per transactie. Numeriek.
  • InvoiceDate: Factuurdatum en -tijd. Numeriek, de dag en tijd waarop elke transactie is gegenereerd. Voorbeeld uit de dataset: 12/1/2010 8:26
  • UnitPrice: Stukprijs. Numeriek, productprijs per eenheid in pond sterling.
  • CustomerID: Klantnummer. Nominaal, een 5-cijferig geheel getal dat uniek is voor elke klant.
  • Country: Land. Nominaal, de naam van het land waar de klant woont.

Libraries laden

Eerst laad je de benodigde libraries. Een korte beschrijving van de libraries (overgenomen van Hier) staat in de volgende tabel, zodat je weet wat elke library doet:

PackageBeschrijving
arulesBiedt infrastructuur voor het representeren, manipuleren en analyseren van transactiegegevens en patronen (frequente itemsets en associatieregels).
arulesVizBreidt het pakket 'arules' uit met diverse visualisatietechnieken voor associatieregels en itemsets. Het pakket bevat ook meerdere interactieve visualisaties voor het verkennen van regels.
tidyverseDe tidyverse is een samenhangende collectie van R‑packages ontworpen voor data science
readxlLees Excel-bestanden in R
plyrTools om data te splitsen, functies toe te passen en weer te combineren
ggplot2Maak grafieken en charts
knitrDynamische rapportgeneratie in R
lubridateLubridate is een R‑package dat werken met datums en tijden makkelijker maakt.
#install and load package arules
#install.packages("arules")
library(arules)
#install and load arulesViz
#install.packages("arulesViz")
library(arulesViz)
#install and load tidyverse
#install.packages("tidyverse")
library(tidyverse)
#install and load readxml
#install.packages("readxml")
library(readxl)
#install and load knitr
#install.packages("knitr")
library(knitr)
#load ggplot2 as it comes in tidyverse
library(ggplot2)
#install and load lubridate
#install.packages("lubridate")
library(lubridate)
#install and load plyr
#install.packages("plyr")
library(plyr)
library(dplyr)

Data preprocessing

Gebruik read_excel(path to file) om de dataset uit het gedownloade bestand in R te lezen. Geef je volledige bestandspad inclusief bestandsnaam op in read_excel(path-to-file-with-filename)

#read excel into R dataframe
retail <- read_excel('D:/Documents/Online_Retail.xlsx')
#complete.cases(data) will return a logical vector indicating which rows have no missing values. Then use the vector to get only rows that are complete using retail[,].
retail <- retail[complete.cases(retail), ]
#mutate function is from dplyr package. It is used to edit or add new columns to dataframe. Here Description column is being converted to factor column. as.factor converts column to factor column. %>% is an operator with which you may pipe values to another function or expression
retail %>% mutate(Description = as.factor(Description))
retail %>% mutate(Country = as.factor(Country))
#Converts character data to date. Store InvoiceDate as date in new variable
retail$Date <- as.Date(retail$InvoiceDate)
#Extract time from InvoiceDate and store in another variable
TransTime<- format(retail$InvoiceDate,"%H:%M:%S")
#Convert and edit InvoiceNo into numeric
InvoiceNo <- as.numeric(as.character(retail$InvoiceNo))
NAs introduced by coercion
#Bind new columns TransTime and InvoiceNo into dataframe retail
cbind(retail,TransTime)
cbind(retail,InvoiceNo)
#get a glimpse of your data
glimpse(retail)

Opmerking: Pagina 1 van 100.
Observations: 406,829
Variables: 9
$ InvoiceNo   <chr> "536365", "536365", "536365", "536365", "536365", "536365", "53...
$ StockCode   <chr> "85123A", "71053", "84406B", "84029G", "84029E", "22752", "2173...
$ Description <chr> "WHITE HANGING HEART T-LIGHT HOLDER", "WHITE METAL LANTERN", "C...
$ Quantity    <dbl> 6, 6, 8, 6, 6, 2, 6, 6, 6, 32, 6, 6, 8, 6, 6, 3, 2, 3, 3, 4, 4,...
$ InvoiceDate <dttm> 2010-12-01 08:26:00, 2010-12-01 08:26:00, 2010-12-01 08:26:00,...
$ UnitPrice   <dbl> 2.55, 3.39, 2.75, 3.39, 3.39, 7.65, 4.25, 1.85, 1.85, 1.69, 2.1...
$ CustomerID  <dbl> 17850, 17850, 17850, 17850, 17850, 17850, 17850, 17850, 17850, ...
$ Country     <chr> "United Kingdom", "United Kingdom", "United Kingdom", "United K...
$ Date        <date> 2010-12-01, 2010-12-01, 2010-12-01, 2010-12-01, 2010-12-01, 20...

Nu zal de dataframe retail 10 attributen bevatten, met twee extra attributen Date en Time.

Voordat we MBA/Association Rule Mining toepassen, moeten we de dataframe omzetten naar transactiegegevens zodat alle items die samen in één factuur zijn gekocht in één rij staan. Je ziet in de uitvoer van glimpse dat elke transactie atomair is, dus alle producten die bij één factuur horen zijn atomaire rijen zoals in relationele databases. Dit formaat heet ook wel het singles-formaat.

Wat je moet doen is de data in de retail-dataframe groeperen op CustomerID, CustomerID en Date of je kunt ook groeperen met InvoiceNo en Date. We hebben deze groepering nodig om er een functie op toe te passen en de output in een andere dataframe op te slaan. Dit kan met ddply.

De volgende code combineert alle producten uit één InvoiceNo en date en zet alle producten uit die InvoiceNo en date in één rij, met elk item gescheiden door ,

library(plyr)
#ddply(dataframe, variables_to_be_used_to_split_data_frame, function_to_be_applied)
transactionData <- ddply(retail,c("InvoiceNo","Date"),
                       function(df1)paste(df1$Description,
                       collapse = ","))
#The R function paste() concatenates vectors to character and separated results using collapse=[any optional charcater string ]. Here ',' is used
transactionData

Opmerking: Pagina 1 van 100.

Vervolgens kun je, omdat InvoiceNo en Date niet nodig zijn bij het minen van regels, deze op NULL zetten.

#set column InvoiceNo of dataframe transactionData  
transactionData$InvoiceNo <- NULL
#set column Date of dataframe transactionData
transactionData$Date <- NULL
#Rename column to items
colnames(transactionData) <- c("items")
#Show Dataframe transactionData
transactionData

Opmerking: Pagina 1 van 100.

Dit formaat voor transactiegegevens heet het basket-formaat. Vervolgens moet je deze transactiegegevens opslaan in een .csv-bestand (Comma Separated Values). Gebruik hiervoor write.csv()

write.csv(transactionData,"D:/Documents/market_basket_transactions.csv", quote = FALSE, row.names = FALSE)
#transactionData: Data to be written
#"D:/Documents/market_basket.csv": location of file with file name to be written to
#quote: If TRUE it will surround character or factor column with double quotes. If FALSE nothing will be quoted
#row.names: either a logical value indicating whether the row names of x are to be written along with x, or a character vector of row names to be written.

Kijk of je transactiegegevens de juiste vorm hebben:

transaction data

Vervolgens moet je deze transactiegegevens laden in een object van de transactieklasse. Dit doe je met de R-functie read.transactions uit het arules-pakket.

De volgende regel code neemt het transactiegegevensbestand D:/Documents/market_basket_transactions.csv in basket-formaat en zet het om in een object van de transactieklasse.

tr <- read.transactions('D:/Documents/market_basket_transactions.csv', format = 'basket', sep=',')
#sep tell how items are separated. In this case you have separated using ','

Als je bovenstaande code uitvoert, kun je veel EOF within quoted string in je output krijgen, maak je geen zorgen.

Als je al transactiegegevens in een dataframe hebt, gebruik dan de volgende regel code om die om te zetten naar een transactieobject:

          `trObj<-as(dataframe.dat,"transactions")`

Bekijk het tr-transactieobject:

tr
transactions in sparse format with
 22191 transactions (rows) and
 30066 items (columns)
 summary(tr)
 
transactions in sparse format with
 22191 transactions (rows) and
 7876 items (columns)
transactions as itemMatrix in sparse format with
 22191 rows (elements/itemsets/transactions) and
 7876 columns (items) and a density of 0.001930725

most frequent items:
WHITE HANGING HEART T-LIGHT HOLDER           REGENCY CAKESTAND 3 TIER
                              1803                               1709
           JUMBO BAG RED RETROSPOT                      PARTY BUNTING
                              1460                               1285
     ASSORTED COLOUR BIRD ORNAMENT                            (Other)
                              1250                             329938

element (itemset/transaction) length distribution:
sizes
   1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17
3598 1594 1141  908  861  758  696  676  663  593  624  537  516  531  551  522  464
  18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   33   34
 441  483  419  395  315  306  272  238  253  229  213  222  215  170  159  138  142
  35   36   37   38   39   40   41   42   43   44   45   46   47   48   49   50   51
 134  109  111   90  113   94   93   87   88   65   63   67   63   60   59   49   64
  52   53   54   55   56   57   58   59   60   61   62   63   64   65   66   67   68
  40   41   49   43   36   29   39   30   27   28   17   25   25   20   27   24   22
  69   70   71   72   73   74   75   76   77   78   79   80   81   82   83   84   85
  15   20   19   13   16   16   11   15   12    7    9   14   15   12    8    9   11
  86   87   88   89   90   91   92   93   94   95   96   97   98   99  100  101  102
  11   14    8    6    5    6   11    6    4    4    3    6    5    2    4    2    4
 103  104  105  106  107  108  109  110  111  112  113  114  116  117  118  120  121
   4    3    2    2    6    3    4    3    2    1    3    1    3    3    3    1    2
 122  123  125  126  127  131  132  133  134  140  141  142  143  145  146  147  150
   2    1    3    2    2    1    1    2    1    1    2    2    1    1    2    1    1
 154  157  168  171  177  178  180  202  204  228  236  249  250  285  320  400  419
   3    2    2    2    1    1    1    1    1    1    1    1    1    1    1    1    1

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
   1.00    3.00   10.00   15.21   21.00  419.00

includes extended item information - examples:
                      labels
1                   1 HANGER
2     10 COLOUR SPACEBOY PEN
3 12 COLOURED PARTY BALLOONS

summary(tr) is een erg handige opdracht die informatie geeft over ons transactieobject. Laten we bekijken wat de bovenstaande output zegt:

  • Er zijn 22191 transacties (rijen) en 7876 items (kolommen). Let op: 7876 zijn de productbeschrijvingen in de dataset en 22191 transacties zijn combinaties van deze items.

  • Dichtheid (density) geeft het percentage niet-nulcellen in een sparse matrix. Je kunt het zien als het totaal aantal gekochte items gedeeld door het mogelijke aantal items in die matrix. Je kunt berekenen hoeveel items zijn gekocht met de dichtheid: 22191x7876x0.001930725=337445

Informatie! Sparse matrix: een sparse matrix of sparse array is een matrix waarin de meeste elementen nul zijn. Als de meeste elementen niet nul zijn, noem je de matrix dense. Het aantal nulwaarden gedeeld door het totale aantal elementen heet de sparsity van de matrix (gelijk aan 1 min de density).

  • Summary kan ook de meest frequente items tonen.

  • Distributie van de lengte van elementen (itemset/transactie): Dit toont hoeveel transacties er zijn voor 1-itemsets, 2-itemsets, enzovoort. De eerste rij toont het aantal items en de tweede rij het aantal transacties.

Bijvoorbeeld, er zijn slechts 3598 transacties met één item, 1594 transacties met twee items, en er zijn 419 items in één transactie, wat de langste is.

Je kunt een itemFrequencyPlot genereren om een frequentiebalkdiagram van items te maken op basis van een itemMatrix (bijv. >transactions of items in >itemsets en >rules), wat in ons geval zo is.

# Create an item frequency plot for the top 20 items
if (!require("RColorBrewer")) {
  # install color package of R
install.packages("RColorBrewer")
#include library RColorBrewer
library(RColorBrewer)
}
itemFrequencyPlot(tr,topN=20,type="absolute",col=brewer.pal(8,'Pastel2'), main="Absolute Item Frequency Plot")
absolute item frequency plot

In 

itemFrequencyPlot(tr,topN=20,type="absolute")

is het eerste argument het te plotten transactieobject, tr. Met topN plot je de N items met de hoogste frequentie. type kan type="absolute" of type="relative" zijn. Bij absolute worden de numerieke frequenties van elk item afzonderlijk geplot. Bij relative wordt geplot hoe vaak items voorkomen ten opzichte van andere.

relative item frequency plot
itemFrequencyPlot(tr,topN=20,type="relative",col=brewer.pal(8,'Pastel2'),main="Relative Item Frequency Plot")

Deze plot laat zien dat 'WHITE HANGING HEART T-LIGHT HOLDER' en 'REGENCY CAKESTAND 3 TIER' de meeste verkopen hebben. Dus om de verkoop van 'SET OF 3 CAKE TINS PANTRY DESIGN' te verhogen, kan de retailer deze bij 'REGENCY CAKESTAND 3 TIER' in de buurt plaatsen.

Andere opties voor itemFrequencyPlot vind je hier.

Regels genereren!

De volgende stap is het minen van regels met het APRIORI-algoritme. De functie apriori() komt uit het pakket arules.

# Min Support as 0.001, confidence as 0.8.
association.rules <- apriori(tr, parameter = list(supp=0.001, conf=0.8,maxlen=10))
 Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen maxlen target
        0.8    0.1    1 none FALSE            TRUE       5   0.001      1     10  rules
   ext
 FALSE

Algorithmic control:
 filter tree heap memopt load sort verbose
    0.1 TRUE TRUE  FALSE TRUE    2    TRUE

Absolute minimum support count: 22

set item appearances ...[0 item(s)] done [0.00s].
set transactions ...[30066 item(s), 22191 transaction(s)] done [0.11s].
sorting and recoding items ... [2324 item(s)] done [0.02s].
creating transaction tree ... done [0.02s].
checking subsets of size 1 2 3 4 5 6 7 8 9 10
Mining stopped (maxlen reached). Only patterns up to a length of 10 returned!
 done [0.70s].
writing ... [49122 rule(s)] done [0.06s].
creating S4 object  ... done [0.06s]. 
set of 49122 rules

rule length distribution (lhs + rhs):sizes
    2     3     4     5     6     7     8     9    10
  105  2111  6854 16424 14855  6102  1937   613   121

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
  2.000   5.000   5.000   5.499   6.000  10.000

summary of quality measures:
    support           confidence          lift             count       
 Min.   :0.001036   Min.   :0.8000   Min.   :  9.846   Min.   : 23.00  
 1st Qu.:0.001082   1st Qu.:0.8333   1st Qu.: 22.237   1st Qu.: 24.00  
 Median :0.001262   Median :0.8788   Median : 28.760   Median : 28.00  
 Mean   :0.001417   Mean   :0.8849   Mean   : 64.589   Mean   : 31.45  
 3rd Qu.:0.001532   3rd Qu.:0.9259   3rd Qu.: 69.200   3rd Qu.: 34.00  
 Max.   :0.015997   Max.   :1.0000   Max.   :715.839   Max.   :355.00  

mining info:
 data ntransactions support confidence
   tr         22191   0.001        0.8

apriori gebruikt tr als het transactieobject waarop gemined moet worden. Met parameter stel je min_sup en min_confidence in. De standaardwaarden voor parameter zijn minimum support 0,1, minimum confidence 0,8 en maximaal 10 items (maxlen).

summary(association.rules) toont het volgende:

  • Parameterspecificatie: min_sup=0,001 en min_confidence=0,8 met maximaal 10 items per regel.

  • Totaal aantal regels: De set van 49122 regels

  • Verdeling van regellengte: Lengte 5 items heeft de meeste regels: 16424 en lengte 2 items het laagst: 105

  • Samenvatting van kwaliteitsmaten: Min- en maxwaarden voor support, confidence en lift.

  • Informatie gebruikt voor het maken van regels: De data, support en confidence die we aan het algoritme gaven.

Omdat er 49122 regels zijn, printen we alleen de top 10:

inspect(association.rules[1:10])
     lhs                         rhs             support     confidence lift      count
[1]  {WOBBLY CHICKEN}         => {METAL}         0.001261773 1          443.82000 28   
[2]  {WOBBLY CHICKEN}         => {DECORATION}    0.001261773 1          443.82000 28   
[3]  {DECOUPAGE}              => {GREETING CARD} 0.001036456 1          389.31579 23   
[4]  {BILLBOARD FONTS DESIGN} => {WRAP}          0.001306836 1          715.83871 29   
[5]  {WOBBLY RABBIT}          => {METAL}         0.001532153 1          443.82000 34   
[6]  {WOBBLY RABBIT}          => {DECORATION}    0.001532153 1          443.82000 34   
[7]  {FUNK MONKEY}            => {ART LIGHTS}    0.001712406 1          583.97368 38   
[8]  {ART LIGHTS}             => {FUNK MONKEY}   0.001712406 1          583.97368 38   
[9]  {BLACK TEA}              => {SUGAR JARS}    0.002072912 1          238.61290 46   
[10] {BLACK TEA}              => {COFFEE}        0.002072912 1           69.34687 46 

Met bovenstaande output kun je analyses maken zoals:

  • 100% van de klanten die 'WOBBLY CHICKEN' kochten, kochten ook 'METAL'.

  • 100% van de klanten die 'BLACK TEA' kochten, kochten ook 'SUGAR JARS'.

Het aantal en de grootte van regels beperken

Hoe kun je de grootte en het aantal gegenereerde regels beperken? Dat kan door parameters in apriori in te stellen. Je past deze parameters aan om het aantal regels te sturen. Wil je sterkere regels, verhoog dan conf; voor langere regels geef je een hogere waarde aan maxlen.

shorter.association.rules <- apriori(tr, parameter = list(supp=0.001, conf=0.8,maxlen=3))

Redundante regels verwijderen

Je kunt regels verwijderen die deelverzamelingen zijn van grotere regels. Gebruik onderstaande code om zulke regels te verwijderen:

subset.rules <- which(colSums(is.subset(association.rules, association.rules)) > 1) # get subset rules in vector
length(subset.rules)  #> 3913
[1] 44014
subset.association.rules. <- association.rules[-subset.rules] # remove subset rules.
  • which() geeft de posities terug van elementen in de vector waarvoor de waarde TRUE is.

  • colSums() vormt rij- en kolomsommen voor dataframes en numerieke arrays.

  • is.subset() Bepaalt of elementen van de ene vector alle elementen van de andere bevatten

Soms wil je met een specifiek product werken. Als je wilt achterhalen wat invloed heeft op de aankoop van item X, kun je de optie appearance in het apriori-commando gebruiken. appearance geeft opties om LHS (ALS-gedeelte) en RHS (DAN-gedeelte) van de regel in te stellen.

Bijvoorbeeld, om te vinden wat klanten kopen vóórdat ze 'METAL' kopen, voer je de volgende regel uit:

metal.association.rules <- apriori(tr, parameter = list(supp=0.001, conf=0.8),appearance = list(default="lhs",rhs="METAL"))
Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen maxlen target
        0.8    0.1    1 none FALSE            TRUE       5   0.001      1     10  rules
   ext
 FALSE

Algorithmic control:
 filter tree heap memopt load sort verbose
    0.1 TRUE TRUE  FALSE TRUE    2    TRUE

Absolute minimum support count: 22

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[30066 item(s), 22191 transaction(s)] done [0.21s].
sorting and recoding items ... [2324 item(s)] done [0.02s].
creating transaction tree ... done [0.02s].
checking subsets of size 1 2 3 4 5 6 7 8 9 10
Mining stopped (maxlen reached). Only patterns up to a length of 10 returned!
 done [0.63s].
writing ... [5 rule(s)] done [0.07s].
creating S4 object  ... done [0.02s]. 
# Here lhs=METAL because you want to find out the probability of that in how many customers buy METAL along with other items
inspect(head(metal.association.rules))
    lhs                            rhs     support     confidence lift   count
[1] {WOBBLY CHICKEN}            => {METAL} 0.001261773 1          443.82 28   
[2] {WOBBLY RABBIT}             => {METAL} 0.001532153 1          443.82 34   
[3] {DECORATION}                => {METAL} 0.002253166 1          443.82 50   
[4] {DECORATION,WOBBLY CHICKEN} => {METAL} 0.001261773 1          443.82 28   
[5] {DECORATION,WOBBLY RABBIT}  => {METAL} 0.001532153 1          443.82 34 

Op dezelfde manier houd je, om de vraag te beantwoorden Klanten die METAL kochten, kochten ook...., METAL op de lhs:

metal.association.rules <- apriori(tr, parameter = list(supp=0.001, conf=0.8),appearance = list(lhs="METAL",default="rhs"))
Apriori

Parameter specification:
 confidence minval smax arem  aval originalSupport maxtime support minlen maxlen target
        0.8    0.1    1 none FALSE            TRUE       5   0.001      1     10  rules
   ext
 FALSE

Algorithmic control:
 filter tree heap memopt load sort verbose
    0.1 TRUE TRUE  FALSE TRUE    2    TRUE

Absolute minimum support count: 22

set item appearances ...[1 item(s)] done [0.00s].
set transactions ...[30066 item(s), 22191 transaction(s)] done [0.10s].
sorting and recoding items ... [2324 item(s)] done [0.02s].
creating transaction tree ... done [0.02s].
checking subsets of size 1 2 done [0.01s].
writing ... [1 rule(s)] done [0.00s].
creating S4 object  ... done [0.01s].
# Here lhs=METAL because you want to find out the probability of that in how many customers buy METAL along with other items
inspect(head(metal.association.rules))
    lhs        rhs          support     confidence lift   count
[1] {METAL} => {DECORATION} 0.002253166 1          443.82 50 

Associatieregels visualiseren

Aangezien er op basis van data honderden of duizenden regels worden gegenereerd, heb je een paar manieren nodig om je bevindingen te presenteren. ItemFrequencyPlot hebben we al besproken; dat is ook een geweldige manier om de best verkopende items te zien.

Hier bespreken we de volgende visualisaties:

  • Scatterplot
  • Interactieve scatterplot
  • Individuele regelweergave

Scatterplot

Een rechttoe rechtaan visualisatie van associatieregels is een scatterplot met plot() uit het arulesViz-pakket. Het gebruikt support en confidence op de assen. Daarnaast wordt standaard een derde maat, lift, gebruikt om de punten te kleuren (grijswaarden).

# Filter rules with confidence greater than 0.4 or 40%
subRules<-association.rules[quality(association.rules)$confidence>0.4]
#Plot SubRules
plot(subRules)
scatter plot

Bovenstaande plot laat zien dat regels met hoge lift een lage support hebben. Je kunt de volgende opties gebruiken voor de plot:

plot(rulesObject, measure, shading, method)
  • rulesObject: het rules-object dat je wilt plotten

  • measure: Maten voor regelinteressantheid. Kan support, confidence, lift of een combinatie zijn, afhankelijk van de method-waarde.

  • shading: Maat gebruikt om punten te kleuren (support, confidence, lift). Standaard is lift.

  • method: Te gebruiken visualisatiemethode (scatterplot, two-key plot, matrix3D).

plot(subRules,method="two-key plot")
two key plot

De two-key plot gebruikt support en confidence respectievelijk op de x- en y-as. Voor kleuren wordt order gebruikt. Order is het aantal items in de regel.

Interactieve scatterplot

Een geweldige interactieve plot om je regels te presenteren gebruikt arulesViz en plotly. Je kunt over elke regel hoveren en alle kwaliteitsmaten (support, confidence en lift) bekijken.

plotly_arules(subRules)
'plotly_arules' is deprecated.
Use 'plot' instead.
See help("Deprecated")plot: Too many rules supplied. Only plotting the best 1000 rules using measure lift (change parameter max if needed)To reduce overplotting, jitter is added! Use jitter = 0 to prevent jitter.

Grafiekgebaseerde visualisaties

Grafiekgebaseerde technieken visualiseren associatieregels met knooppunten en randen, waarbij knooppunten zijn gelabeld met itemnamen en itemsets of regels worden weergegeven als een tweede set knooppunten. Items worden met itemsets/regellijsten verbonden met gerichte pijlen. Pijlen van items naar regelknooppunten geven LHS-items aan en een pijl van een regel naar een item geeft de RHS aan. De grootte en kleur van knooppunten vertegenwoordigen vaak interessematen.

Grafiekplots zijn een geweldige manier om regels te visualiseren, maar raken snel vol bij veel regels. Visualiseer daarom beter een kleiner aantal regels met grafiekgebaseerde visualisaties.

Laten we 10 regels selecteren uit subRules met de hoogste confidence.

top10subRules <- head(subRules, n = 10, by = "confidence")

Plot nu een interactieve grafiek:

Opmerking: Je kunt al je plots interactief maken met de parameter engine=htmlwidget in plot

plot(top10subRules, method = "graph",  engine = "htmlwidget")
graph

Met arulesViz kunnen grafieken voor sets associatieregels worden geëxporteerd in het GraphML-formaat of als een Graphviz dot-bestand om te verkennen in tools zoals Gephi. Bijvoorbeeld, de 1000 regels met de hoogste lift exporteer je met:

saveAsGraph(head(subRules, n = 1000, by = "lift"), file = "rules.graphml")

Individuele regelweergave

Deze weergave heet ook wel de Parallel Coordinates Plot. Het is handig om te visualiseren welke producten samen met welke items welke verkoop veroorzaken.

Zoals hierboven vermeld, is de RHS de consequent of het item waarvan we voorspellen dat de klant het zal kopen; de posities staan in de LHS waarbij 2 de meest recente toevoeging aan het mandje is en 1 het item dat we eerder hadden.

# Filter top 20 rules with highest lift
subRules2<-head(subRules, n=20, by="lift")
plot(subRules2, method="paracoord")
parallel coordinates plot

Kijk naar de bovenste pijl. Die laat zien dat wanneer ik 'CHILDS GARDEN SPADE PINK' en 'CHILDS GARDEN RAKE PINK' in mijn winkelmandje heb, ik waarschijnlijk ook 'CHILDS GARDEN RAKE BLUE' erbij koop.

Conclusie

Gefeliciteerd! Je hebt APRIORI geleerd, een van de meest gebruikte algoritmen in data mining. Je hebt alles geleerd over Association Rule Mining, de toepassingen ervan en de toepassing in retail, bekend als Market Basket Analysis. Je kunt nu ook Market Basket Analysis implementeren in R en je associatieregels presenteren met mooie plots! Veel leerplezier!

Referenties:

  1. https://datascienceplus.com/a-gentle-introduction-on-market-basket-analysis%E2%80%8A-%E2%80%8Aassociation-rules/

  2. https://en.wikipedia.org/wiki/Sparse_matrix

  3. https://cran.r-project.org/web/packages/arulesViz/vignettes/arulesViz.pdf

Wil je meer leren over R? Volg dan DataCamp’s cursus Importing and Managing Financial Data in R.

Onderwerpen

Gerelateerd