数据背景
Instacart最近新鲜开源了它2017年网上销售食品杂货的数据。这个数据包括了超过200,000 Instacart用户的三百万订单。如果你不了解Instacart是干嘛的,我来简单的拆分一下 insta--及时的,cart--购物车,其实就是一个可以在网上下单超市食品日杂然后选一个固定的两小时时间给你送到家里的送货服务。很鸡冻~~, 因为美国人购物一般是去超市里,不想我们大天朝网购跑腿送货这么发达,所以关于类似的开源dataset我还是第一次见(Walmart,Target这种超市有很多的data但是一般不会开源)官方开源数据的主要目的是想办kaggle竞赛,让大家预测一下根据用户之前的购买记录应该给他在app里面推荐什么。估计目前为止应该有很多大牛在建NLP和ML模型,我也就不凑这个热闹了。这篇笔记主要是带大家用这个新鲜出炉的数据做做可视化看看美国人平时都在买什么吃什么!
在正式开始看数据之前,放上两个link。
这一个是官方的宣布,里面也有一些有趣的例子
官方post
这一个是数据的下载地址
数据下载地址
废话不多说,进入正题
第一步:导入数据
数据分析的第一步,当然是要了解data,首先从官方介绍上看一看数据的大小,每个file对应的是什么数据,每一行和每一数列都代表着什么。这些信息基本在官方给出的data dictionary都有提到。关于代码, 这里用的是R, 主要用到的package有dplyr,ggplot2,gganimate和treemap。
library(reshape2)
library(ggplot2)
library(ggthemes)
library(dplyr)
library(tidyr)
library(stringr)
library(gridExtra)
library(gganimate)
library(treemap)
orders <- read.csv("~/Documents/Rstudio/Instacart/instacart_2017_05_01/orders.csv")
products <- read.csv("~/Documents/Rstudio/Instacart/instacart_2017_05_01/products.csv")
order_products__prior <- read.csv("~/Documents/Rstudio/Instacart/instacart_2017_05_01/order_products__prior.csv")
order_products__train <- read.csv("~/Documents/Rstudio/Instacart/instacart_2017_05_01/order_products__train.csv")
departments <- read.csv("~/Documents/Rstudio/Instacart/instacart_2017_05_01/departments.csv")
aisles <- read.csv("~/Documents/Rstudio/Instacart/instacart_2017_05_01/aisles.csv")
官方一共给出6个datasets。除了参考官方的dictionary之外,我们读入数据之后可以用head(orders)
来看一下每行每列都代表什么。在这里我们可以看到关于order_product_set,官方给出了两个datasets, 一个是order_products__prior和order_products__train,其中train是指用户们最近的购买记录,大概有131K行,prior是指对于这些用户,他们所有之前的购买记录大概有3.2 million行,因为我们接下来的分析并不涉及到对用户购买的预测,所以我们选用order_products__train这个dataset来节省R的运行时间。
第二步:对数据进行整理,分类。
我们想看一下美国人的订单的里都买了什么,最直白的就是看order中的products。但是问题是products的种类太多,我们不可能全都画出来看一遍,所以第一个问题就是如果对products进行分类,根据我们有的data,有两种可以选择的分类方法,一种是根据department分类,一种是根据aisle分类。具体的关系是department里包括很多aisle,aisle里面包括很多具体的product。我们知道aisle指的是超市中一排一排的货架,那么我们能不能根据这些信息还原出一个虚拟的Instacart超市呢?想到这种矩阵式结构图,就想到了treemap。具体操作如下
##先将product和department,aisle数据join起来
tmp <- products %>% group_by(department_id, aisle_id) %>% summarize(n=n())
tmp <- tmp %>% left_join(departments,by="department_id")
tmp <- tmp %>% left_join(aisles,by="aisle_id")
## 将order_product和department,aisle数据join起来
tmp2<-order_products__train %>%
group_by(product_id) %>%
summarize(count=n()) %>%
left_join(products,by="product_id") %>%
ungroup() %>%
group_by(department_id,aisle_id) %>%
summarize(sumcount = sum(count)) %>%
left_join(tmp, by = c("department_id", "aisle_id"))
treemap(tmp2,index=c("department","aisle"),vSize="n",vColor="department",palette="Set3",title="", border.col="#FFFFFF",type="categorical", fontsize.legend = 0,bg.labels = "#FFFFFF")
图1. Instacart虚拟超市!
在这张图中,我们把aisle根据他们所属的department放在一起,长方形的尺寸代表着这个aisle product的种类。对应的code是在treemap中指定vSize = "n",当然我们也可以用实际所有order中product的数量来表示长方形的尺寸,对应的将vSize设为"sumcount"就可以了。从这张图大概看出来人们用instacart购买的产品还是多种多样的,但是这个图中department的位置其实是没有意义的,并不是说超市中也是这么排列的。另外从这张图中我觉得department作为product的分类过于广泛,所以之后的分析我都会用aisle作为product的分类。这个treemap的idea和code来源于这个post,有兴趣的同学可以去看看,里面也有很多有趣的分析!
第三步:分类柱状图📊
准备工作做的差不多,我们就可以来看看到底哪些product最受美国人欢迎。
full_orders<-left_join(order_products__train,products,by='product_id')%>%
left_join(.,aisles,by='aisle_id')%>%
left_join(.,departments,by='department_id')
full_orders%>%group_by(aisle)%>%dplyr::summarise(count=n())%>%
mutate(percentage = count*100/sum(count))%>%arrange(desc(count))%>%top_n(20)%>%
ggplot(.,aes(x=reorder(.$aisle,-.$count),y=.$percentage))+xlab('categories')+
ylab("Percentage of Purchase")+geom_bar(stat="identity",show.legend = FALSE,color = 'steelblue',fill='steelblue')+
theme_minimal()+theme(axis.text.x = element_text(angle = 90, hjust = 1))
图2. 销量最高的产品类别
在这个图中我们只显示了前20购买最多的产品类别。排在前五的是新鲜蔬菜,新鲜水果,包装的蔬菜水果,酸奶,奶酪🧀和水/气泡水,就这个图来看美国人还是吃的挺健康的哈。但是其实Instacart的用户并不能代表美国大众,因为instacart的定位人群主要是工作繁忙没有时间或者不方便去超市的人群,比如纽约白领,这些中上层阶级吃的比较健康也是预料之中的,另外前20中的frozen meals和energy bars也都间接验证了这些用户都是比较繁忙需要在用餐上节省时间的。如果有一天walmart或者costco也能开源数据那我们就可以做一个有趣的对比了!
上面的图是对整个数据的总结,从这个图我们可以衍生出很多细分的图,比如说,如果按天数分,周一,周二和周六,周日人们下单的东西有什么区别吗?
图3. 每天前5销量最高的产品类别
图中的0代表周日,1-6代表周一到周六,可以看出每天买的东西类别上没有什么区别,但是明显周日和周一是购买数量最多的两天,感觉大家是在为即将到来的一周做准备,哈哈。
除此之外,我也很好奇,每天不同时刻人们购买的东西有什么区别吗,美国人是不是也有深夜放毒的习惯呢?但是由于一天有24个小时,不能像星期几一样在一张图中一次性显示出来,这时候我们有要放出另一个神奇的包了,我们可以用gganimate让柱状图随着时间的变化而变化。具体操作如下:
tmp_date<-order_time%>%group_by(order_hour_of_day,aisle)%>%dplyr::summarise(count=n())%>%arrange(desc(count))%>%top_n(20)
plot<-ggplot(tmp_date,aes(x=aisle,y=count,fill=aisle))+geom_bar(stat = 'identity',show.legend = FALSE)+theme_minimal()+theme(axis.text.x = element_text(angle = 90, hjust = 1))+
labs(
title = 'Hour of day: {frame_time}',
y = 'Count',
x = 'category'
)+ transition_time(order_hour_of_day)+ease_aes('linear')
animate(plot, width = 800, height= 1000)
图4. 每小时前20销量最高产品类别
从动图中可以看出大部分下单时间在早上9点到下午4点,说实话,动图看起来很直观,但是总结起来信息真的很难。而且这个数据中只有人们下单的时间并没有实际送达的时间,所以并不能看出来早中晚大家吃的有什么不一样。所以这个图就放在这看看大家自己能看出什么有趣的发现吧。
最后,作为bonus,看一下最受欢迎的前五种商品是什么。
图5. 销量前五的商品
排名第一第二的居然是香蕉和袋装的有机香蕉,哈哈,看来美国人真的是很爱香蕉,看到这张图的小伙伴有没有冲动也想买香蕉吃了呢。
总结
关于Instacart的数据可视化就写到这里啦,其实关于这个dataset还有很多有趣的分析可以做,尤其是人们的购买习惯,上面我提到的那篇post最后发现有一个用户特别喜欢买牛奶,一直定期买牛奶。有兴趣的小伙伴们可以自己看。美中不足的是,这个数据里没有关于地理位置和价钱的信息,不然又可以分地区看看人们的购买习惯和人们的消费水平。当然,所有的数据分析最后都应该以支持商业决策为目的,非让我说写了这么多最后总结出什么呢,大概就是每一个用户我可能都会推荐他买香蕉吧!
看到最后如果你觉得还算有趣,就给个赞把!之后还会不定期的更新各种和数据分析有关的案例和教程,包括R,Python和Sql。欢迎关注!一起学习!💖
网友评论