首先关联规则很简单,但是数据的转化具有一定的复杂。
先说关联规则,举个通俗的例子,也就是看很多东西之间的关联度,而这个关联度和数值层面的相关性类似,但是通常处理的是因子型或文本型数据。比如购物车的关联购买。
比如很多人买了啤酒,然后又买了烟,从业务层面,我们希望卖酒的旁边就是卖烟的,这样能刺激相同用户购买。说到这,可以看到,关联规则是一个特殊的聚类,也就是探究人群购物的本质;但是这种聚类是纯粹的从商品层面聚类,比如烟和酒是一类,烟酒茶是一类,口香糖和大蒜是一类等等等等,通过关联规则,可以判定这部分商品是最多用户买的,放在一起就会有更高的价值。
那么说道这,R中有很多的包都是用来计算关联规则的,一般用Aprior算法,这个算法关注三个指标,support,confidence,lift;
通俗点说,support就是购买单一商品的概率,这个指标有什么用呢?比如整个超市的搓澡巾就卖出去10个,即使所有的商品都和肥皂有关联,可能我们也会舍弃他,因为本身的概率很小,这个指标理解为卡掉那些不被经常购买的商品。
confidence,就是置信区间,可以通俗理解为,我购买几个商品组合,和我购买单一商品相比有多大,举个例子,如果我买了10个搓澡巾,8个都是和肥皂一起买的,这个{搓澡巾、肥皂}对于{搓澡巾}的置信区间就是0.8
lift,可以理解为提升度;比如商店一共卖10个搓澡巾,20块肥皂;其中搓澡巾和肥皂在一起的有8次,也就是{搓澡巾,肥皂}=8;也就是说同时发现两种产品的概率为0.8,而单独卖搓澡巾就是0.2,单独卖肥皂就是1.2,搓澡巾的提升度为0.8/0.2=4,而肥皂的提升度为0.8/1.2=0.67;也就是说,有肥皂的时候比没有肥皂的时候搓澡巾卖的更好;而反之不成立
说完这些,我们看下稀疏矩阵的处理,因为从SQL推出的数据是这样的:
test<-data.frame(a=c('A','A','A','B','B','C'),b=c('P1','P2','P3','P1','P2','P1')) a b 1 A P1 2 A P2 3 A P3 4 B P1 5 B P2 6 C P1也就是我们说的长格式,但是如果我们应用Apriori函数进行关联规则探索的话,Apriori应用的格式是一行里面,有很多sep,然后把数据分割成点,类似这样:
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 whole milk,butter,yogurt,rice,abrasive cleaner以上是6行的示例;
这个格式和普通的csv有很大的差距,下面首先需要把SQL的CSV转化为这种格式的csv:
先看一个示例:
test<-data.frame(Pin=c('A','A','A','B','B','C'), Products=c('P1','P2','P3','P1','P2','P1'))这个数据集作为测试集,第一列是用户ID,也就是pin,第二列是商品名称,也就是Products:
Pin Products 1 A P1 2 A P2 3 A P3 4 B P1 5 B P2 6 C P1然而,我们需要转化为,A用户,买了一行,三个商品的情景;也就是一个函数,通过逗号把各个列组合到一起:
library(plyr) test_name<-ddply(test,'Pin',function(x)c(Products=paste(x$Products,collapse=',')))ddply是一个优秀的数据整形包,前面的’PIN’ 是按照PIN的列进行整形,后面的函数,就是PIN里面每一行对应的函数,结果为:
Pin Products 1 A P1,P2,P3 2 B P1,P2 3 C P1出来这个形式的数据集还不够,这个也不是最终的形式,最后需要转存成csv,然后用一个特殊的稀疏矩阵工具打开:
write.csv(test_name,'D:\\R study\\test_name.csv',row.names = F) test_sparsematrix<-read.transactions('D:\\R study\\test_name.csv',sep=',', + encoding='UTF-8')结果为:
test_sparsematrix transactions in sparse format with 4 transactions (rows) and 8 items (columns)看下summary:
summary(test_sparsematrix) transactions as itemMatrix in sparse format with 4 rows (elements/itemsets/transactions) and 8 columns (items) and a density of 0.25 most frequent items: A B C P1 P1,P2 (Other) 1 1 1 1 1 3 element (itemset/transaction) length distribution: sizes 2 4 Min. 1st Qu. Median Mean 3rd Qu. Max. 2 2 2 2 2 2 includes extended item information - examples: labels 1 A 2 B 3 C这个结果就可以后续处理了。
这里借用一个数据集,参考Rblogger上的方式进行处理:
https://github.com/nupur1492/RProjects/blob/master/MarketBasketAnalysis/groceries.csv
把这个文件储存在本地文件夹中,然后这个是个csv,用最简单的方式打开:
groceries_raw<-read.csv("D:\\R study\\groceries.csv",stringsAsFactors = F) head(groceries_raw) head(groceries_raw) Member_number Date itemDescription 1 1.619053e+12 10/22/2012 citrus fruit 2 1.679032e+12 10/03/2010 tropical fruit 3 1.634043e+12 07/07/2011 whole milk 4 1.656022e+12 03/13/2010 pip fruit 5 1.612011e+12 09/07/2013 other vegetables 6 1.660042e+12 06/06/2010 whole milk这和我们上面的test是一样的,但是需要转化为arules看得懂的格式,具体的方法就参考之前的test,先转存csv,然后再读取之:
write.csv(ddply(groceries_raw, 'Member_number', function(x)c(Products=paste(x$itemDescription, collapse=',')))[,2], 'D:\\R study\\groceries.csv', row.names = F) groceries<-read.transactions("D:\\R study\\groceries.csv", sep = ",",encoding='UTF-8')需要说明的一点是,这个关联规则的变量不存在其他干扰项,所以会有
ddply(groceries_raw, 'Member_number', function(x)c(Products=paste(x$itemDescription, collapse=',')))[,2]也就是取真正的product一列,忽略掉ID列;
看下真正的groceries:
transactions as itemMatrix in sparse format with 197 rows (elements/itemsets/transactions) and 83 columns (items) and a density of 0.01204819 most frequent items: whole milk rolls/buns sausage 15 11 11 frankfurter other vegetables (Other) 9 7 144 element (itemset/transaction) length distribution: sizes 1 197 Min. 1st Qu. Median Mean 3rd Qu. Max. 1 1 1 1 1 1 includes extended item information - examples: labels 1 abrasive cleaner 2 baking powder 3 beef先看看整体的分布,也就是相对销售较好的产品:
itemFrequencyPlot(groceries,support=0.05)看到蛋卷、香肠和全脂牛奶是support>0.5的三个SKU。也是出现概率最高的SKU。
rules1<-apriori(groceries,parameter = list(support=0.05, confidence=0.1, minlen=1)) summary(rules1) inspect(rules1[1:3])然而数据量太小,minlen是组合的个数,一旦设置为2,就看不到相关性,如果换一个数据集效果会好很多。