共享单车数据集_共享单车数据可视化报告

这篇博客探讨了共享单车数据集,分析了季节、天气、时间等因素如何影响骑行需求。通过数据可视化,揭示了骑行需求在不同时间段、工作日与非工作日、不同天气条件下的变化。研究发现,骑行需求在夏季和工作日通勤时间较高,恶劣天气下需求下降,而注册用户的需求明显高于非注册用户,并且有明显的使用规律。
摘要由CSDN通过智能技术生成

1.1 项目说明

自行车共享系统是一种租赁自行车的方法,注册会员、租车、还车都将通过城市中的站点网络自动完成,通过这个系统人们可以根据需要从一个地方租赁一辆自行车然后骑到自己的目的地归还。为了更好地服务和维护共享单车平台,开发和运营人员会通过系统记录的数据来研究和优化共享单车平台,挖掘数据有用信息,最后落地优化系统。这些系统生成的数据很有吸引力,骑行时间、出发地点、到达地点和经过的时间都被显式地记录下来。

在这次比赛中,参与者需要结合历史天气数据下的使用模式,来预测D.C.华盛顿首都自行车共享项目的自行车租赁需求。

1.2 变量说明

datetime(日期) - hourly date + timestamp

season(季节) - 1 = spring, 2 = summer, 3 = fall, 4 = winter

holiday(是否假日) - whether the day is considered a holiday

workingday(是否工作日) - whether the day is neither a weekend nor holiday

weather(天气等级) -

1. 清澈,少云,多云。

2. 雾+阴天,雾+碎云、雾+少云、雾

3. 小雪、小雨+雷暴+散云,小雨+云

4. 暴雨+冰雹+雷暴+雾,雪+雾

temp(温度) - temperature in Celsius

atemp(体感温度) - "feels like" temperature in Celsius

humidity(相对湿度) - relative humidity

windspeed(风速) - wind speed

casual(临时租赁数量) - number of non-registered user rentals initiated

registered(会员租赁数量) - number of registered user rentals initiated

count(总租赁数量) - number of total rentals

2.准备数据:

2.1检查缺失值

%matplotlib inline

import numpy as np
import pandas as pd 
from datetime import datetime
import matplotlib.pyplot as plt
import seaborn as sns


train=pd.read_csv('train.csv')

#查看训练集数据是否有缺失值
train.info()

输出

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10886 entries, 0 to 10885
Data columns (total 12 columns):
datetime      10886 non-null object
season        10886 non-null int64
holiday       10886 non-null int64
workingday    10886 non-null int64
weather       10886 non-null int64
temp          10886 non-null float64
atemp         10886 non-null float64
humidity      10886 non-null int64
windspeed     10886 non-null float64
casual        10886 non-null int64
registered    10886 non-null int64
count         10886 non-null int64
dtypes: float64(3), int64(8), object(1)
memory usage: 1020.6+ KB
#查看测试集数据是否有缺失值
test=pd.read_csv('test.csv')
test.info()

输出

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6493 entries, 0 to 6492
Data columns (total 9 columns):
datetime      6493 non-null object
season        6493 non-null int64
holiday       6493 non-null int64
workingday    6493 non-null int64
weather       6493 non-null int64
temp          6493 non-null float64
atemp         6493 non-null float64
humidity      6493 non-null int64
windspeed     6493 non-null float64
dtypes: float64(3), int64(5), object(1)
memory usage: 456.6+ KB

本数据集没有缺失数据,但没有缺失不代表没有异常

2.2将训练数据集与测试数据集合并(方便对数据进行统一预处理)

#进行中文转换
import matplotlib as mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['font.serif'] = ['SimHei']
import seaborn as sns
sns.set_style("darkgrid",{"font.sans-serif":['simhei', 'Arial']})
dataset=pd.concat([train,test],axis=0)
dataset.isnull().sum()

输出

atemp            0
casual        6493
count         6493
datetime         0
holiday          0
humidity         0
registered    6493
season           0
temp             0
weather          0
windspeed        0
workingday       0
dtype: int64

三个目标变量存在缺失值,且数量与测试数据集一致,因此能判断数据较完整无缺失情况,缺失的只是需要预测的那一部分目标变量。将超过样本均值3个标注差以外的数据看作异常值,本文对异常情况暂不处理。

将量化的特征转换为方便识别和可视化的字段

# season特征 & weather特征
dataset['season']=dataset['season'].map({1:'spring',2:'summer',3:'fall',4:'winter'})
dataset['weather']=dataset['weather'].map({1:'Good',2:'Normal',3:'Bad',4:'Ver Bad'})

将被量化的季节特征和天气特征转化为用字符串描述的数据。

3 特征衍生

为了更好地理解数据,分析前我们需要判断能否从数据已有的特征中提取、构建出某些有价值的特征,这就是衍生特征

在本篇分析的数据中,我们能对时间数据datetime做特征衍生,datetime包含了日期和时间信息,从中我们能提取出年、月、日、小时等信息。

# 特征衍生
dataset['datetime']=pd.to_datetime(dataset['datetime']) # 将datetime字段转换为datetime

dataset['year']=dataset.datetime.apply(lambda d:d.year) # 对datetime调用year提取年
dataset['month']=dataset.datetime.apply(lambda d:d.month) # 对datetime调用month提取月
dataset['day']=dataset.datetime.apply(lambda d:d.day) # 对datetime调用day提取日
dataset['hour']=dataset.datetime.apply(lambda d:d.hour) # 对datetime调用hour提取小时

# 删除无用字段
dataset.drop('datetime',axis=1,inplace=True)

3ca2957b70241672a7517620396649d5.png

4 可视化分析

通过Matplotlib、Seaborn等工具可视化理解数据,分析特征与标签之间的相关性。

4.1 标签特征的整体分布

count(数量)为本次分析的标签特征,我们需要围绕此特征做可视化分析。下图是count的核密度图:可见count分布呈右偏状,主要集中在0~400这个区间。

b04e6e3921e66462a37bafd4fe5caf5b.png

4.2 时间维度看需求趋势

月份维度

数据涵括了两年的跨度,因此按年分开绘制每个月的骑行需求趋势图

# 筛选提取出2011年和2012年的骑行好数据
Month_tendency_2011=dataset[dataset.year==2011].groupby('month')[['casual','registered','count']].sum()
Month_tendency_2012=dataset[dataset.year==2012].groupby('month')[['casual','registered','count']].sum()
# 绘制图像
plt.style.use('ggplot')
fig,[ax1,ax2]=plt.subplots(2,1,figsize=(12,15)) 
plt.subplots_adjust(hspace=0.3)
Month_tendency_2011.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',ax=ax1)
ax1.set_title('2011年需求趋势',fontsize=15)
ax1.grid(linestyle='--',alpha=0.8)
ax1.set_ylim(0,150000)
ax1.set_xlabel('月份',fontsize=13)
ax1.set_ylabel('数量',fontsize=13)
Month_tendency_2012.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',ax=ax2)
ax2.set_title('2012年需求趋势',fontsize=15)
ax2.grid(linestyle='--',alpha=0.8)
ax2.set_ylim(0,150000)
ax2.set_xlabel('月份',fontsize=13)
ax2.set_ylabel('数量',fontsize=13)
sns.despine(left=True)

1ac38f3af8b8cc5aaa988f5552dc0919.png

上图为可视化结果,整体上可见2012年相较于2011年,骑行的需求有了大幅的增长。总需求和注册用户需求的变化最为明显,而非注册用户提升效果一般,这说明:经过一年的运营,越来越多的使用者在平台上注册了,注册用户提升显著。从月份角度,我们能看到的是:6月~9月是骑行旺季,12月~2月是骑行淡季。

小时维度

按照一天24小时可视化骑行需求,我们能发现一些有趣的结论:

# 提取出每小时的骑行需求均值
Hour_tendency=dataset.groupby('hour')[['casual','registered','count']].mean()
# 绘制图像
Hour_tendency.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',figsize=(12,6))
plt.title('小时需求趋势',fontsize=15)
plt.grid(linestyle='--',alpha=0.8)
plt.ylim(0,550)
plt.xlabel('小时',fontsize=13)
plt.ylabel('数量',fontsize=13)
sns.despine(left=True)

7323d4dc11af932885961ed3053dfbcc.png

从24小时观察骑行需求:存在6~7AM以及5~6PM两个峰值,中午12AM有一个小峰值,符合通勤规律,注册用户特征更为明显,而非注册用户则变化平缓。

工作日和非工作日的小时维度

plt.style.use('ggplot')
plt.figure(figsize=(12,6))
sns.pointplot(x='hour',y='count',hue='workingday',data=dataset,ci=None,palette='Spectral')
sns.despine(left=True)
plt.xlabel('小时',fontsize=13)
plt.ylabel('数量',fontsize=13)
plt.grid(linestyle='--',alpha=0.5)
plt.title('工作日/假期 需求趋势',fontsize=15) # 标题设置

e40096674b10a2c350425863d7bded0f.png

可见工作日与非工作日的骑行需求规律反差巨大,非工作日的共享单车苏醒慢,骑行需求高峰出现在12AM~3PM的这段时间内,另外凌晨0AM~4AM的骑行需求大于工作日。

不同季节的小时维度

plt.figure(figsize=(12,6))
sns.pointplot(x='hour',y='count',hue='season',data=dataset,ci=None,palette='Spectral')
sns.despine(left=True)
plt.xlabel('小时',fontsize=13)
plt.ylabel('数量',fontsize=13)
plt.grid(linestyle='--',alpha=0.5)
plt.title('季节需求趋势',fontsize=15)

e12385199212b24574b6c4f5d6c611c9.png

春夏秋冬四季24小时需求趋势一致,值得关注的是春季的整体小于夏秋冬三个季节,体感舒适度最高的秋天整体骑行需求最高。为何春季需求会低于其他季节?这是个值得思考的问题,单限于数据信息有限,未找出合理的解释。这也说明了结合业务的重要性,只有深入了解了业务规律才能做出准确判断。

4.3 天气维度

不同天气、气温等外在环境会影响骑行需求。

不同天气状况的骑行需求

# 将数据按天聚合
Weather_Demand=dataset.groupby(['weather','day'])[['count']].sum()
Weather_Demand.reset_index(inplace=True)
# 不同天气的骑行需求散点图 
plt.figure(figsize=(12,6))
sns.stripplot(x='weather',y='count',data=Weather_Demand,palette='Set1',jitter=True,alpha=0.6)
sns.despine(left=True)
plt.xlabel('季节',fontsize=13)
plt.ylabel('数量',fontsize=13)
plt.title('天气的分布趋势',fontsize=15)

00a05e1661e54292bb22d94019e9d19c.png

可见,天气情况越糟,骑行需求越小。

# 不同天气的骑行需求趋势
plt.figure(figsize=(12,6))
sns.pointplot(x='hour',y='count',hue='weather',data=dataset,ci=None,palette='Spectral')
sns.despine(left=True)
plt.xlabel('小时',fontsize=13)
plt.ylabel('数量',fontsize=13)
plt.grid(linestyle='--',alpha=0.5)
plt.title('天气的需求趋势',fontsize=15)

ab49141217e143cdce93f8c0e1d29b55.png

整体需求趋势也印证了,天气越差骑行需求越少,极端天气未形成趋势线,极端情况还是占少数的。

气温与体表温度

气温与体表温度应该是正相关的,先来看看两者的分布图:

# 温度与体表温度的关系度量
plt.figure(figsize=(10,8))
sns.kdeplot(dataset['temp'],dataset['atemp'],shade=True,shade_lowest=False,cut=10,cmap='YlGnBu',cbar=True)
sns.despine(left=True)
plt.grid(linestyle='--',alpha=0.4)
plt.xlim(0,50)
plt.ylim(0,50)
plt.xlabel('温度',fontsize=13)
plt.ylabel('体表温度',fontsize=13)
plt.title('温度和体表温度的相关性',fontsize=15)

7b2de32b7750a61ced72ab3f845de6b9.png

从两者的关系度量图中我们能看出呈现正相关分布,另外能获取到的信息是:颜色最深的分布最为集中,最适宜的气温27℃~28℃、体表温度31℃左右的骑行需求是最密集的。

# 温度与风速的关系度量
plt.figure(figsize=(10,8))
sns.kdeplot(dataset['temp'],dataset['windspeed'],shade=True,shade_lowest=False,cut=10,cmap='YlGnBu',cbar=True)
sns.despine(left=True)
plt.grid(linestyle='--',alpha=0.4)
plt.xlim(0,50)
plt.ylim(-10,40)
plt.xlabel('温度',fontsize=13)
plt.ylabel('风速',fontsize=13)
plt.title('温度和风速的相关性',fontsize=15)

06ab6c58427e223e137589a7d847f699.png

风速的分布存在断层,初步推断可能是异常数据,这里先不做处理;可见气温27℃~28℃,风速8~9骑行需求是最密集的。

气温与湿度

# 温度与湿度的关系度量
plt.figure(figsize=(10,8))
sns.kdeplot(dataset['temp'],dataset['humidity'],shade=True,shade_lowest=False,cut=10,cmap='YlGnBu',cbar=True)
sns.despine(left=True)
plt.grid(linestyle='--',alpha=0.4)
plt.xlim(0,40)
plt.ylim(0,110)
plt.xlabel('温度',fontsize=13)
plt.ylabel('湿度',fontsize=13)
plt.title('温度和湿度的相关性',fontsize=15)

f3032ffa3de464cc281d97b97275add8.png

气温27℃~28℃,湿度80~90骑行需求是最密集的。

天气因素与骑行需求

将气温和风速作为天气因素分析骑行需求(忽略体表温度,气温即代表了体表温度),使用散点图绘制,散点的大小和颜色代表了骑行量,每个散点代表一天。

plt.figure(figsize=(12,6))
plt.scatter(x='temp',y='windspeed',
            s=dataset['count']/2,
            c='count',cmap='RdBu_r',
            edgecolors='black',linestyle='--',linewidth=0.2,alpha=0.6,
            data=dataset)
plt.title('天气因素与骑行需求',fontsize=15)
plt.xlabel('温度',fontsize=13)
plt.ylabel('风速',fontsize=13)
sns.despine(left=True)

4c9fdca48f53dbc24e80cadb19dde2c1.png

可见骑行需求较多的分布范围:气温20℃~35℃,风速40以下;人们更热衷于温暖天气骑行,炎热天气需求也大的原因可能是因为相对于公共交通,骑行更加灵活方便吧。

将气温和湿度作为天气因素分析骑行需求:

plt.figure(figsize=(12,6))
plt.scatter(x='temp',y='humidity',
            s=dataset['count']/2,
            c='count',cmap='RdBu_r',
            edgecolors='black',linestyle='--',linewidth=0.2,alpha=0.6,
            data=dataset)
plt.title('天气因素与骑行需求',fontsize=15)
plt.xlabel('温度',fontsize=13)
plt.ylabel('湿度',fontsize=13)
sns.despine(left=True)

8bea48d38ac4682ec7bebd2aaccc5f4f.png

可见骑行需求较多的分布范围:气温20℃~35℃,湿度20~80。

4.5 注册用户与未注册用户

如何能提升平台用户数量?当然是拉新促活促转化,接下来,让我们来观察下注册用户与非注册用户的差异吧。

# 衍生特征
dataset['dif']=dataset['registered']-dataset['casual'] # 衍生特征注册用户与非注册用户的骑行需求差值
fig,axes=plt.subplots(2,2,figsize=(20,8))
plt.subplots_adjust(hspace=0.3,wspace=0.1)
# 绘制子图1:月度差异
Month_Dif = dataset.groupby('month')[['casual','registered']].mean()
Month_Dif.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',ax=axes[0,0])
axes[0,0].set_title('月份趋势需求差异',fontsize=15)
axes[0,0].grid(linestyle='--',alpha=0.8)
axes[0,0].set_xlabel('月份',fontsize=13)
axes[0,0].set_ylabel('数量',fontsize=13)
# 绘制子图2:小时差异
H1=dataset.groupby('hour')[['casual','registered']].mean()
H1.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',ax=axes[0,1])
axes[0,1].set_title('小时趋势需求差异',fontsize=15)
axes[0,1].grid(linestyle='--',alpha=0.8)
axes[0,1].set_xlabel('小时',fontsize=13)
axes[0,1].set_ylabel('数量',fontsize=13)
# 绘制子图3:工作日差异
H2_1=dataset[dataset.workingday==1].groupby('hour')[['casual','registered']].mean() # 工作日
H2_0=dataset[dataset.workingday==0].groupby('hour')[['casual','registered']].mean() # 非工作日
H2_1.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',ax=axes[1,0])
axes[1,0].set_title('工作日时间趋势需求差异',fontsize=15)
axes[1,0].grid(linestyle='--',alpha=0.8)
axes[1,0].set_xlabel('小时',fontsize=13)
axes[1,0].set_ylabel('数量',fontsize=13)
# 绘制子图4:非工作日差异
H2_0.plot(kind='line',linestyle='--',linewidth=2,colormap='Set1',ax=axes[1,1])
axes[1,1].set_title('假期时间趋势需求差异',fontsize=15)
axes[1,1].grid(linestyle='--',alpha=0.8)
axes[1,1].set_xlabel('小时',fontsize=13)
axes[1,1].set_ylabel('数量',fontsize=13)
sns.despine(left=True)

0ae82a079ba6ef51f74cd63d08d4780b.png

上图为注册用户与非注册用户在各因素下的差异组合图:

第一幅为两者的月度差异图,可见整体趋势相同,注册用户远高于非注册用户;

第二幅为两者的小时差异图,可见注册用户的小时规律明显,非注册用户则只在12AM~5PM存在峰值,整体差异较大;

第三幅为两者的工作日差异图,可见注册用户工作日小时规律明显,二非注册用户趋势平缓;

第四幅为两者的非工作日差异图,可见非工作日两者差异相较于其他因素差异较小,且趋势相同,值得注意的是注册用户在凌晨更加活跃。

总的来说,注册用户需求远高于非注册用户,注册用户的使用规律明显,而非注册用户受其他因素的影响相对较弱。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值