当我提到啤酒与尿布,亲爱的读者可能要嗤之以鼻了,这么俗套的故事还要说啊!的确,如果你在google或百度搜索引擎上搜索啤酒与尿布的关键词(你键入啤酒,后边会有尿布的提示),搜索结果成千上万,小伙伴们早就对啤酒与尿布的那些事了然于心了。如果读者你还对这件事的来龙去脉不太了解,你可以阅读一下这篇文档,其实用一句话概括这件事,就是“年轻的父亲们在周末常常会从超市购买尿布和啤酒”。
前两天,我在搜资料时,一个偶然的机会,竟然找到了啤酒与尿布的数据集。当时我特别高兴,这事你懂得,没有什么比能让一个学统计的获得原始数据更激动人心的事了!这两天我就琢磨着用数据分析一下,是不是真的能获得“神奇”的结论—啤酒与尿布有很大的关联。众所周知,啤酒与尿布那点事是使用所谓的“关联规则”(Association Rules)搞出来的,但是一番折腾后,我发现自己的分析结果不尽如人意,“关联规则”这种算法应用之后分析不出啥来。但是应用分类树模型,却能得到激动人心的结论,真可谓是东方不亮西方亮。不过所谓“激动人心的结论”也是打了折扣了的,因为一些结果解释起来也是让人匪夷所思。
我先来说一下这个数据,所谓“向之所欣,俯仰之间,已为陈迹”,得到数据时我很开心,经过分析之后,发现这些数据有问题,自己就“郁郁寡欢”了。同样的心情变化也可以用下图说明:
“数据虐我千万遍,我待数据如初恋”一直是我做统计时的座右铭(是不是有点恶心),我仍然满清热情地和这批啤酒与尿布数据玩了一把。这批数据的每一行是一位顾客的购买记录,包括他(或她)买了哪些商品、星期几买的、他(她)有没有孩子等等,以下是我提取的字段名称。
> names(data)
[1] "product.A.1" "product.A.2"
[3] "product.A.3" "product.A.4"
[5] "product.A.5" "product.A.6"
[7] "product.A.7" "product.A.8"
[9] "product.A.9" "product.A.10"
[11] "product.A.11" "product.A.12"
[13] "product.A.13" "product.A.14"
[15] "product.A.15" "car"
[17] "street" "street.number"
[19] "town" "ZIP"
[21] "area" "country"
[23] "gender" "age.of.buyer"
[25] "time.of.day" "weekday"
[27] "month" "year"
[29] "quarter" "product.B.1"
[31] "product.B.2" "product.B.3"
[33] "product.B.4" "product.B.5"
[35] "product.B.6" "product.C.1"
[37] "product.C.2" "product.C.3"
[39] "product.C.4" "product.C.5"
[41] "product.C.6" "product.C.7"
[43] "product.C.8" "typical.beer.drinking.events"
[45] "product.D.1" "product.D.2"
[47] "product.D.3" "product.D.4"
[49] "car.type" "product.E.1"
[51] "product.E.2" "product.E.3"
[53] "product.E.4" "product.E.5"
[55] "product.E.6" "product.E.7"
[57] "product.E.8" "product.E.9"
[59] "product.E.10" "product.E.11"
[61] "product.E.12" "children.yes.no."
[63] "product.category.A" "product.category.B"
[65] "mostly.bought.product.category" "least.bought.product"
[67] "product.category.C" "product.category.D"
[69] "product.category.E" "product.category.F"
[71] "product.category.G" "product.category.H"
[73] "product.category.I" "product.category.J"
[75] "product.category.K" "nappies"
[77] "product.F.1" "product.F.2"
[79] "has.studied.yes.no." "product.G.1"
[81] "product.G.2" "product.G.3"
[83] "product.G.4" "product.G.5"
[85] "product.G.6" "product.G.7"
[87] "average.temperature" "product.H.1"
[89] "product.H.2" "product.I.1"
[91] "product.J.1" "product.J.2"
[93] "education" "sales.of.crisps"
[95] "product.K.1" "beer"
最后一个字段beer是该顾客购买的啤酒量的多少,有三个等级:“low”,”medium”,”high”;第76个字段nappies是购买尿布数量的多少,也有三个等级:“low”, “medium”, “high”。我们采用”beer~.”建立模型,即我们从除了beer以外的所有变量中寻找那些影响啤酒的购买量的变量。学习方法为分类树。
R包rpart中的函数rpart()可以执行分类树的功能,下图是运行后得到的一棵没有修剪过的分类树。
没有修剪过的树显得臃肿不堪,且树大招风,为了方便,我们修剪这棵树得到如下一棵利索的树:
树是由节点构成的,自上而下,每一个节点可以分割成两个子节点,那些处于树的末端不再分割的节点称为叶子节点。处于最上一层的是根节点(root),从上图我们发现,根节点的标识是“media”,然后有一组数(550, 577, 1373),这告诉我们,在这一节点上,共有2500条交易记录,其中550条记录啤酒购买量属于“high”,577条记录啤酒购买量属于“low”,1373条记录啤酒购买量属于“medium”,比例结果是(high,low,medium)~(22%,23.1%,54.92%),这样算来,“medium”所占比例最大,所以该节点标识为“medium”。就停在这里,随便给出一条交易记录(不包含最后的啤酒购买量字段),问:预测该条记录的啤酒购买量是?没错,应该是“medium”。
树的第一次分割,用的是nappies这个字段,这就意味着,啤酒购买量的高低与尿布的销量有着紧密的关系。先看左分割,其条件是nappies=high,结果是(high, low, medium)=(376, 233, 401)~(37.2%,23.1%,39.7%) ,仍然是“medium”的比例最大,但注意到的是“high”的比例从未分割之前的22%增加到37.2,总体来说,啤酒购买量偏大。再看又分割,其条件是nappies %in% c(low, medium),分割结果是(high, low, medium)=(174, 344, 972)~(11.7%, 23.1%, 65.2%),仍然是medium比例最大,值得注意的是“medium”的比例从未分割之前的54.9%增加到65.2%,“high”比例从22%减少至11.7%, 总体来说,啤酒购买量偏少了。也就是说,左右节点对比可以得出的结论是,那些购买了尿布的消费者往往啤酒的购买量也比较多。
按照这样的分析思路,继续分析上边的tree,还可以得出的结论是:周末(Friday,Saturday,Thursday)时消费者购买啤酒量较多,有小孩的消费者购买啤酒量较多,男性消费者购买啤酒量较多。综合以上的结果,我们得到的结论是:
原来的妇女通常在家照顾孩子,所以她们经常会嘱咐丈夫在周末下班回家的路上为孩子买尿布,而丈夫在买尿布的同时又会顺手购买自己爱喝的啤酒。