В нашем распоряжении есть информация о 9’835 покупках 169 продуктов в виде csv файла:
head -n5 groceries.csv
## citrus fruit,semi-finished bread,margarine,ready soups
## tropical fruit,yogurt,coffee
## whole milk
## pip fruit,yogurt,cream cheese ,meat spreads
## other vegetables,whole milk,condensed milk,long life bakery product
где строки представляют список покупок одним потребителем.
Загрузим данные из пакета arules, где они находятся в специальном формате transactions и вкратце проанализируем их:
library(arules)
## Loading required package: Matrix
##
## Attaching package: 'arules'
## The following objects are masked from 'package:base':
##
## abbreviate, write
data(Groceries)
dim(Groceries)
## [1] 9835 169
Для доступа к транзакциям в пакете arules существует функция inspect:
inspect(Groceries[1:5])
## items
## 1 {citrus fruit,
## semi-finished bread,
## margarine,
## ready soups}
## 2 {tropical fruit,
## yogurt,
## coffee}
## 3 {whole milk}
## 4 {pip fruit,
## yogurt,
## cream cheese ,
## meat spreads}
## 5 {other vegetables,
## whole milk,
## condensed milk,
## long life bakery product}
Краткое резюме всех транзакций
summary(Groceries)
## transactions as itemMatrix in sparse format with
## 9835 rows (elements/itemsets/transactions) and
## 169 columns (items) and a density of 0.02609146
##
## most frequent items:
## whole milk other vegetables rolls/buns soda yogurt
## 2513 1903 1809 1715 1372
## (Other)
## 34055
##
## element (itemset/transaction) length distribution:
## sizes
## 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
## 2159 1643 1299 1005 855 645 545 438 350 246 182 117 78 77 55 46 29 14 14 9
## 21 22 23 24 26 27 28 29 32
## 11 4 6 1 1 1 1 3 1
##
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.000 2.000 3.000 4.409 6.000 32.000
##
## includes extended item information - examples:
## labels level2 level1
## 1 frankfurter sausage meat and sausage
## 2 sausage sausage meat and sausage
## 3 liver loaf sausage meat and sausage
Мы можем визуализировать распределение количества покупок:
library(ggplot2)
lst <- LIST(Groceries)
num <- sapply(lst, 'length')
ggplot(data=NULL, aes(x=num)) +
geom_histogram(binwidth=.5, fill='grey60', color='white') +
scale_x_continuous(breaks = 0:20, limits=c(-1,20))
## Warning: Removed 29 rows containing non-finite values (stat_bin).
Мы можем также визуализировать наиболее часто покупаемый единичный продукт:
x <- sort(table(do.call('c',lst[num==1])),decreasing = T)[1:10]
ggplot(data=NULL) +
geom_bar(aes(x=reorder(names(x),-x), y=x),stat='identity', fill='grey50',width=.4) +
theme(axis.text.x=element_text(angle=90))+
coord_flip()+
xlab('')
Или наиболее часто покупаемые пары продуктов:
x <- sort(table(unlist(lapply(lst[num==2],function(x) (paste0(x,collapse = ','))))),decreasing=T)[1:10]
ggplot(data=NULL) +
geom_bar(aes(x=reorder(names(x),-x), y=x),stat='identity', fill='grey50',width=.4) +
theme(axis.text.x=element_text(angle=90))+
coord_flip() +
xlab('')
Или наиболее часто покупаемые продукты вообще:
x <- sort(table(do.call('c',lst)),decreasing = T)[1:10]
ggplot(data=NULL) +
geom_bar(aes(x=reorder(names(x),-x), y=x),stat='identity',fill='grey50', width=.4) +
theme(axis.text.x=element_text(angle=90))+
xlab('')+
coord_flip()
Анализ потребительской корзины позволяет ответить на вопросы:
Анализ потребительской корзины происходит при помощи алгоритма apriori, предложенного Rakesh Agrawal и Ramakrishnan Srikant в 1994. Данный алгоритм реализован в пакете R под названием arules (“association rules”). Логика действия алгоритма такова:
1.алгоритм “отсекает” редкие комбинации покупок, которые “априори” не могут сформировать повторяемый паттерн покупок “IF” –> “THEN” (если бы этого не было, общее количество различных комбинаций покупок из 100 продуктов было бы \(2^{100}\))
для комбинаций, прошедших фильтр, вычисляется “support”, или частота покупки такой комбинации
lhs – “левая часть корзины” (“IF”, если мы купили “ЭТО”)rhs – “правая часть корзины” (“THEN”, то мы купим “ТО”)rhs вычисляются:
confidence - условная вероятность P(rhs|lhs)lift - увеличение вероятности покупки rhs (при условии покупки lhs) по сравнению с отсутствием корреляции между двумя покупками (lift=1 говорит об отсутствии корреляции между rhs и lhs).Если мы считаем, что любые транзакции с частотой менее 3 покупок в день – это шум, то мы можем составить правила покупок таким образом:
rules <- apriori(Groceries,
parameter=list(support=0.01,
confidence=.1,
minlen=2))
## Apriori
##
## Parameter specification:
## confidence minval smax arem aval originalSupport support minlen maxlen target ext
## 0.1 0.1 1 none FALSE TRUE 0.01 2 10 rules FALSE
##
## Algorithmic control:
## filter tree heap memopt load sort verbose
## 0.1 TRUE TRUE FALSE TRUE 2 TRUE
##
## Absolute minimum support count: 98
##
## set item appearances ...[0 item(s)] done [0.00s].
## set transactions ...[169 item(s), 9835 transaction(s)] done [0.01s].
## sorting and recoding items ... [88 item(s)] done [0.00s].
## creating transaction tree ... done [0.01s].
## checking subsets of size 1 2 3 4 done [0.01s].
## writing ... [427 rule(s)] done [0.00s].
## creating S4 object ... done [0.00s].
inspect(sort(rules, by='confidence')[1:10])
## lhs rhs support confidence lift
## 362 {citrus fruit,root vegetables} => {other vegetables} 0.01037112 0.5862069 3.029608
## 377 {tropical fruit,root vegetables} => {other vegetables} 0.01230300 0.5845411 3.020999
## 332 {curd,yogurt} => {whole milk} 0.01006609 0.5823529 2.279125
## 338 {other vegetables,butter} => {whole milk} 0.01148958 0.5736041 2.244885
## 380 {tropical fruit,root vegetables} => {whole milk} 0.01199797 0.5700483 2.230969
## 398 {root vegetables,yogurt} => {whole milk} 0.01453991 0.5629921 2.203354
## 341 {other vegetables,domestic eggs} => {whole milk} 0.01230300 0.5525114 2.162336
## 350 {yogurt,whipped/sour cream} => {whole milk} 0.01087951 0.5245098 2.052747
## 404 {root vegetables,rolls/buns} => {whole milk} 0.01270971 0.5230126 2.046888
## 356 {pip fruit,other vegetables} => {whole milk} 0.01352313 0.5175097 2.025351
Информация в данной таблице для транзакции №362 может быть прочитана следующим образом:
Пакет arules позволяет фильтровать как по rhs (т.е. найдет триггеры, которые приведут к покупке пива):
beer_rhs <- subset(rules, rhs %pin% 'beer')
inspect(beer_rhs)
## lhs rhs support confidence lift
## 26 {shopping bags} => {canned beer} 0.01138790 0.1155831 1.487905
## 91 {bottled water} => {bottled beer} 0.01576004 0.1425943 1.770726
так и по lhs (т.е. определить, к чему приведет покупка пива)
beer_lhs <- subset(rules, lhs %pin% 'beer')
inspect(sort(beer_lhs, by="lift"))
## lhs rhs support confidence lift
## 90 {bottled beer} => {bottled water} 0.01576004 0.1957071 1.7707259
## 25 {canned beer} => {shopping bags} 0.01138790 0.1465969 1.4879052
## 92 {bottled beer} => {soda} 0.01698017 0.2108586 1.2092094
## 94 {bottled beer} => {other vegetables} 0.01616675 0.2007576 1.0375464
## 27 {canned beer} => {soda} 0.01382816 0.1780105 1.0208356
## 95 {bottled beer} => {whole milk} 0.02043721 0.2537879 0.9932367
## 93 {bottled beer} => {rolls/buns} 0.01362481 0.1691919 0.9198466
## 28 {canned beer} => {rolls/buns} 0.01128622 0.1452880 0.7898878
Анализ покупательской корзины позволяет на основе исторических данных делать прогнозы какие покупки, как правило, делаются вместе. Данные, полученные на основе анализа покупательской корзины, могут использоваться: