<>2023 年第二届钉钉杯大学生大数据挑战赛 初赛 B:美国纽约公共自行车使用量预测分析 问题一
<>1 题目
Citi Bike是纽约市在2013年启动的一项自行车共享出行计划,由“花旗银行”(Citi Bank)赞助并取名为“花旗单车”(Citi
Bike)。在曼哈顿,布鲁克林,皇后区和泽西市有8,000辆自行车和500个车站。为纽约的居民和游客提供一种
方便快捷,并且省钱的自行车出行方式。人们随处都能借到Citi
Bank,并在他们的目的地归还。本案例的数据有两部分:第一部分是纽约市公共自行车的借还交易流水表。Citi
Bik自行车与共享单车不同,不能使用手机扫码在任意地点借还车,而需要使用固定的自行车桩借还车,数据集包含2013年7月1日至2016年8
月31日共38个月(1158天)的数据,每个月一个文件。其中2013年7月到2014年8
月的数据格式与其它年月的数据格式有所差别,具体体现在变量starttime和stoptime的存储格式不同。
第二部分是纽约市那段时间的天气数据,并存储在weather_data_NYC.csv文 件中,该文件包含2010年至2016年的小时级别的天气数据。
公共自行车数据字段表
变量编号变量名变量含义变量取值及说明
1trip duration旅行时长骑行时间,数值型,秒
2start time出发时间借车时间,字符串,m/d/YYY HH:MM:SS
3stop time结束时间还车时间,字符串,m/d/YYY HH:MM:SS
4start station id借车站点编号定性变量,站点唯一编号
5start station name借车站点名称字符串
6start station latitude借车站点维度数值型
7start station longtude借车站点经度数值型
8end station id还车站点编号定性变量,站点唯一编号
9end station name还车站点名称字符串
10end station latitude还车站点纬度数值型
11end station longitude还车站点经度数值型
12bile id自行车编号定性变量,自行车唯一编号
13Use type用户类型Subscriber:年度用户; Customer:24小时或者7天的临时用户
14birth year出生年份仅此列存在缺失值
15gender性别0:未知 1:男性 2:女性
天气数据字段简介表
变量编号变量名变量含义变量取值及说明
1date日期字符串
2time时间EDT(Eastern Daylight Timing)指美国东部夏令单位
3temperature气温单位:℃
4dew_poit露点单位:℃
5humidity湿度百分数
6pressure海平面气压单位:百帕
7visibility能见度单位:千米
8wind_direction风向离散型,类别包括west,calm等
9wind_speed风速单位:千米每小时
10moment_wind_speed瞬间风速单位:千米每小时
11precipitation降水量单位:毫米,存在缺失值
12activity活动离散型,类别包括snow等
13conditions状态离散型,类别包括overcast,light snow等
14WindDirDegrees风向角连续型,取值为0~359
15DateUTC格林尼治时间YYY/m/d HH:MM
二、解决问题
* 自行车借还情况功能实现:
实现各个站点在一天的自行车借还情况网络图,该网络图是有向图,箭头从借车站点指向还车站点(很多站点之间同时有借还记录,所以大部分站点两两之间是双向连接)。
(一)以2014年8月3日为例进行网络分析,实现自行车借还网络图,计算网络图的节点数,边数,网络密度(表示边的个数占所有可能的连接比例数),给出计算过程和画图结果。
(二)使用上述的网络分析图,对经度位于40.695~40.72,纬度位于-
74.023~-73.973之间的局域网区域进行分析,计算出平均最短路径长度(所有点 两两之间的最短路径长度进行算数平均)和网络直径(被定义网络中最短路径的
最大值)。
* 聚类分析
对于2013年7月1日至2015年8月31日数据集的自行车数据进行聚类分析,选 择合适的聚类数量K值,至少选择两种聚类算法进行聚类,并且比较不同的聚类
方法以及分析聚类结果。
* 站点借车量的预测分析:
对所有站点公共自行车的借车量预测,预测出未来的单日借车量。将2013年
7月-2015年7月数据作为训练集,2015年8月1-31日的数据作为测试集,预测2015
年8月1-31日每天的自行车单日借车量。给出每个站点预测结果的MAPE,并且给 出模型的参数数量,最后算出所有站点的MAPE的均值(注:测试集不能参与到训
练和验证中,否则作违规处理)。
M A P E = 1 n ∑ ∣ y i − y i ^ y i ∣ × 100 % MAPE = \frac{1}{n}
\sum{|\frac{y_i-\hat{y_i}}{y_i}|} \times 100\%MAPE=n1∑∣yiyi−yi^∣×100%
<>2 问题分析
<>2.1 问题一
* 绘制有向图
a. 读入数据并分别提取“起始站点编号”和“结束站点编号”两列数据,构建自行车借还网络图。
b. 对于第一步构建的网络图,我们需要计算网络图的节点数,边数,网络密度。节点数即为站点数,边数为借还次数。网络密度为边的数量占所有可能的连接比例。
c. 画出自行车借还网络图。
e. 计算平均最短路径长度和网络直径
首先选出符合条件(经度位于40.695~40.72,纬度位于-
74.023~-73.973之间)的借车站点和还车站点,并以它们为节点构建一个子图进行分析。然后可以直接使用networkx库中的函数来计算平均最短路径长度和网络直径。
<>2.2 问题二
*
数据预处理:对进行数据清洗和特征提取。可以使用PCA、LDA算法进行降维,减小计算复杂度。
*
聚类算法:
a. K-means:
进行数据聚类时,选择不同的K值进行多次试验,选取最优的聚类结果。可以使用轮廓系数、Calinski-Harabaz指数等评价指标进行比较和选择。
b. DBSCAN: 利用密度对数据点进行聚类,不需要预先指定聚类的数量。使用基于密度的聚类算法时,可以通过调整半径参数和密度参数来得到不同聚类效果。
c. 层次聚类:可分为自顶向下和自底向上两种方式。通过迭代计算每个数据点之间的相似度,将数据点逐渐合并,最后得到聚类结果。
d.改进的聚类算法
e. 深度聚类算法
*
聚类结果分析:选择最优的聚类结果后,对不同类别骑车的用户进行画像。分析每个类别的用户行为特征。
<>2.3 问题三
* 导入数据并进行数据预处理,整合以站点为单位的借车数据。
* 对数据进行时间序列分析,使用ARIMA模型进行单日借车量预测。
* 使用时间序列交叉验证方法进行模型评估,计算每个站点预测结果的MAPE。
* 计算所有站点的MAPE的均值,给出模型的参数数量。
<>3 Python代码实现
<>3.1 问题一
以1000条数据为例
import pandas as pd import networkx as nx import matplotlib.pyplot as plt #
导入数据 data = pd.read_csv('初赛数据集/2013-08 - Citi Bike trip data.csv') df = data[0:
1000] 。。。略 # 添加边 # 添加自行车借还关系作为网络图的边 for idx, row in df.iterrows(): G.add_edge(
row['start station id'], row['end station id']) # 获取节点数和边数 node_num = G.
number_of_nodes() edge_num = G.number_of_edges() # 计算网络密度 density = nx.density(G
) plt.figure(figsize=(15,10)) # 绘制网络图 pos = nx.spring_layout(G, k=0.1) #
用Spring算法布局网络图 nx.draw_networkx(G, pos=pos, node_size=20, edge_color='gray',
alpha=0.5) plt.savefig('img/有向图.png',dpi=300) plt.show() # 输出结果 print('节点数:',
node_num) print('边数:', edge_num) print('网络密度:', density)
import pandas as pd import networkx as nx # 导入数据 df = pd.read_csv(
'初赛数据集/2013-08 - Citi Bike trip data.csv') # 筛选符合条件的借还车站点 df_filtered = df[(df[
'start station longitude']>=-74.023) & (df['start station longitude']<=-73.973)
& (df['end station longitude']>=-74.023) & (df['end station longitude']<=-73.973
) & (df['start station latitude']>=40.695) & (df['start station latitude']<=
40.72) & (df['end station latitude']>=40.695) & (df['end station latitude']<=
40.72)] 。。。略 # 添加边 # 添加自行车借还关系作为网络图的边 for idx, row in df_filtered.iterrows(): G.
add_edge(row['start station id'], row['end station id']) # 计算平均最短路径长度和网络直径
average_shortest_path_length= nx.average_shortest_path_length(G) diameter = nx.
diameter(G) # 输出结果 print('平均最短路径长度:', average_shortest_path_length) print(
'网络直径:', diameter)
<>3.2 问题二
见另一篇博客,持续更新
<>3.3 问题三
见另一篇博客,持续更新
<>4 完整代码下载
见知乎文章底部链接,包括所有问题的全部代码
zhuanlan.zhihu.com/p/643865954