邬书豪,车联网数据挖掘工程师 ,R语言中文社区专栏作者。微信ID:tsaiedu
知乎专栏:https://www.zhihu.com/people/wu-shu-hao-67/activities
往期回顾
2016年底以来,国内共享单车突然就火爆了起来。在街头,仿佛一夜之间,共享单车已经到了“泛滥”的地步,各大城市路边排满各种颜色的共享单车(忽如一夜春风来,千街万道单车来)。除了较早入局的摩拜单车、ofo外,整个2016年至少有25个新的共享单车品牌汹涌入局,其中甚至还包括电动自行车共享品牌。在Kaggle里面有一个关于共享单车的数据集,今天我们就探索一下美国华盛顿共享单车的租赁量......
一、导入+简单探索数据
## 导入分析所需的程序包
library(Rmisc) # multiplot()
library(ggplot2) # ggplot()
library(lubridate) # ymd_hms()
library(dplyr) # group_by() / %>% / summarise()
library(corrplot) # corrplot.mixed()
options(scipen = 20) # 避免绘图时使用科学计数法表示某一个数值
# 导入数据
bike <- read.csv("E:\\NEW_R\\shuhaoge\\共享单车\\train.csv")
str(bike) # 查看数据集的基本结构
summary(bike) # 计算各个变量的主要描述性统计量
首先,根据str()对数据集结构的简单探索,我们发现我们的数据有10886行,12列,除了租用时间点是因子型数据,其他都是数值型。对于我们以后的探索分析,我们需要对datetime变量进行拆分重塑,weather/season两个变量进行数据的重编码。其次,从summary()中我们发现最少的租赁次数(count)是1个。其他详细探索就看下文吧......
二、数据重塑
## 重编码变量,从而在描述性分析是看起来直观
table(bike$season) # 查看season的取值
table(bike$weather) # 查看weather的取值
# 修正这两个变量的取值
bike$season <- factor(bike$season, labels = c("Spring", "Summer", "Fall", "Winter"))
bike$weather <- factor(bike$weather, labels = c("Good", "Normal", "Bad", "Very Bad"))
table(bike$season)
table(bike$weather)
# ymd_hms将因子型变量(datetime)转换为POSIXct对象,并且提取其中的小时转化为因子型
bike$hour <- factor(hour(ymd_hms(bike$datetime)))
bike <- bike[-c(10, 11)] # 剔除casual和registered两列
head(bike)
从展示出来的数据重塑后的前六行,大家肯定也就了解上面重塑的作用了,对我们后续的可视化提供了不少直观性。
三、描述性分析
在描述性分析这一部分呢,我会给大家探索出hour、season、holiday、working和weather这几个变量与其对应的平均租车频数的关系。另外针对几个连续性变量,我绘制了一张相关系数图来展示相关性。
## 探索不同时间段的平均租车频次
p1 <-
bike %>%
group_by(hour) %>%
summarise(mcount = mean(count)) %>%
ggplot(aes(x = hour, y = mcount, fill = hour)) +
geom_bar(stat = 'identity') +
guides(fill = 'none') +
theme_minimal()
p1
根据上面的条形图,我们可以清晰地看出一天内存在两个租车高峰期,分别是早上8-9点和下午5-7点,很明显是我们上班族的上下班高峰期。从中可以得知上班族为共享单车行业贡献了多少力量!!!
## 探索不同季节的平均租车频次
p2 <-
bike %>%
group_by(season) %>%
summarise(mcount = mean(count)) %>%
ggplot(aes(x = reorder(season, mcount), y = mcount, fill = season)) +
geom_bar(stat = 'identity') +
labs(x = 'senson', y = 'mcount') +
guides(fill = 'none') +
theme_minimal()p2
p3 <-
bike %>%
group_by(season) %>%
summarise(mcount = mean(count)) %>%
ggplot(aes(x = reorder(season, mcount), y = mcount, fill = season)) +
geom_bar(stat = 'identity', width = 1) +
coord_polar(theta = "y") +
labs(x = 'senson', y = 'mcount') +
guides(fill = 'none') +
theme_minimal()p3
multiplot(p2, p3, cols = 2)
这两个图传达的意义是一样的,我使用两种绘图方式,只是为了方便大家去对比这两种图,并且学会这两种图的绘制方式。根据这两个图得知,春天每小时平均租车次数最少,大概115次;秋天每小时平均租车次数最多,几乎是春天的一倍,达到了230次左右。
## 探索不同季节不同时间段平均租车频次
p4 <-
bike %>%
group_by(season, hour) %>%
summarise(mcount = mean(count)) %>%
ggplot(aes(x = hour, y = mcount, colour = season)) +
geom_line(aes(group = season)) +
theme_bw() +
geom_point()
p4
这个折线图可以完美地展示出不同季节内不同时间段的平均租车频次,生动形象,简单粗暴!!!以后大家遇到类似的探索分析,也可以尝试使用这种绘图方式去生动形象地传达信息。
## 探索不同天气平均租车频次
p5 <-
bike %>%
group_by(weather) %>%
summarise(mcount = mean(count)) %>%
ggplot(aes(x = reorder(weather, mcount), y = mcount, fill = weather)) +
geom_bar(stat = 'identity') +
labs(x = 'weather') +
guides(fill = 'none') +
theme_minimal()p5
p6 <-
bike %>%
group_by(weather) %>%
summarise(mcount = mean(count)) %>%
ggplot(aes(x = reorder(weather, mcount), y = mcount, fill = weather)) +
geom_bar(stat = 'identity', width = 1) +
coord_polar(theta = "y") +
labs(x = 'senson', y = 'mcount') +
guides(fill = 'none') +
theme_minimal()p6
multiplot(p5, p6, cols = 2)
根据条形图和极坐标图可以看出,好天气的每小时平均租车频次最多,超过了200次;最低的就是Bad天气时,大概平均租车频次是120次。细心的读者肯定会发现,Very Bad天气居然高于Bad天气的平均租车频次,会感到出乎意料。那么我告诉大家,这个是由于数据量导致的,因为只有一个Very Bad天气的个样本。下面我给大家绘制一副折线图去验证这个原因。
## 探索不同天气不同时间段平均租车频次
p7 <-
bike %>%
group_by(weather, hour) %>%
summarise(mcount = mean(count)) %>%
ggplot(aes(x = hour, y = mcount, colour = weather)) +
geom_line(aes(group = weather)) +
theme_bw() +
geom_point()
p7
首先先看那个Very Bad天气的那个样本点,发现只有一个点。也就是说两年的记录内一共发生了一次在特别恶劣的天气中租车的事件,通过对样本的查看,发现其发生在2012年1月9号的下午6-7点之间。也就是说在这个非常恶劣的天气下的下班时间,有一个上班族“被逼无奈”骑着共享单车回的家。啥也不说了,为他默哀三秒钟......默哀结束后继续分析我们的折线图,这幅图同样是简单粗暴的展示了不同天气下不同时间段的平均租车频次。总之就是:天气好的时候大家才可能骑共享单车去想自己要去的地方。
## 探索是否假期和是否工作日时的平均租车频次
# 探索是否假期的平均租车频次
p8 <-
bike %>%
group_by(holiday) %>%
summarise(mcount = mean(count)) %>%
ggplot(aes(x = factor(holiday), y = mcount, fill = factor(holiday))) +
geom_bar(stat = 'identity') +
guides(fill = 'none') +
labs(x = 'holiday') +
theme_minimal()p8
# 探索是否工作日的平均租车频次
p9 <-
bike %>%
group_by(workingday) %>%
summarise(mcount = mean(count)) %>%
ggplot(aes(x = factor(workingday), y = mcount, fill = factor(workingday))) +
geom_bar(stat = 'identity') +
guides(fill = 'none') +
labs(x = 'workingday') +
theme_minimal()
p9
multiplot(p8, p9, cols = 2)
上面两幅图中分别是是否假期和是否工作日与平均租车频次的对比,发现差距并不大。也就是说虽然假期和其他非工作日的样本相对少一些,但是无论是哪种情况,平均的租车频次几乎是稳定不变的。
# 探索是否假期时不同时间段平均租车频次
p10 <-
bike %>%
group_by(holiday, hour) %>%
summarise(mcount = mean(count)) %>%
ggplot(aes(x = hour, y = mcount, colour = factor(holiday))) +
geom_line(aes(group = factor(holiday))) +
geom_point() +
theme_bw()
p10
从折线图中可以发现,假期(1)时的租车高峰时下午一点左右和六点左右,早上的8点左右的租车频次降低了不少。非假期(0)时的租车高峰期就是早上8点左右和下午的6点左右,即上班族的上下班高峰期。
## 探索是否工作日不同时间段平均租车频次
p11 <-
bike %>%
group_by(workingday, hour) %>%
summarise(mcount = mean(count)) %>%
ggplot(aes(x = hour, y = mcount, colour = factor(workingday))) +
geom_line(aes(group = factor(workingday))) +
theme_bw() +
geom_point()
p11
可知,是否工作日对租车频次的影响远比是否假期的影响大。在非工作日时,人们的租车频次只有一个高峰期(中午到下午的四点左右),但是这个高峰期相对平缓。
## 探索几个连续性变量与租车频次的相关系数
cor(bike[c(6:9, 10)]) %>%
corrplot.mixed()
这个相关系数图中,我们发现temp和atemp的相关系数达到了惊人的0.98,大概猜测temp是由atemp经过某种变换得到了。其次就是看图的最后一行,count与temp和atemp程较弱的正相关,与humidity呈现较弱的负相关,与windspeed几乎不相关。这也不难解释,这些连续性自变量就是有关温度、湿度和风速的数值,相对来说不会对租车频次产生较大的影响,除非是极端的温度、湿度和风速。
总结:这篇文章主要内容就是描述性分析,绘制一些图去生动形象的描述各个变量的关系。相对而言,图比数值对于视觉的冲击较大,大家可以多尝试用图去传达数据。
相关课程推荐
Kaggle十大案例精讲课程(连载中)
☟☟☟ 猛戳阅读原文,即刻加入课程。