【竞赛系列】机器学习实操项目08——全球城市计算AI挑战赛(数据可视化分析)

上一章: 【竞赛系列】机器学习实操项目07------全球城市计算AI挑战赛(baseline、时间序列分析、地铁流量预测)
下一章:
机器学习核心知识点目录: 机器学习核心知识点目录
机器学习实战项目目录: 【从 0 到 1 落地】机器学习实操项目目录:覆盖入门到进阶,大学生就业 / 竞赛必备

文章目录

    • 一、工具库导入与数据加载
      • [1.1 导入数据分析与可视化工具库](#1.1 导入数据分析与可视化工具库)
      • [1.2 读取地铁流量训练数据与测试提交模板](#1.2 读取地铁流量训练数据与测试提交模板)
    • 二、时间特征工程(提取精细化时间维度)
      • [2.1 从时间戳提取多维度时间特征](#2.1 从时间戳提取多维度时间特征)
    • 三、多站点流量可视化分析(按日期对比)
      • [3.1 1月1日0-9号站点进站人数对比](#3.1 1月1日0-9号站点进站人数对比)
      • [3.2 1月1日0-9号站点出站人数对比](#3.2 1月1日0-9号站点出站人数对比)
      • [3.3 1月3日0-9号站点出站人数对比](#3.3 1月3日0-9号站点出站人数对比)
      • [3.4 1月1日及以后0-9号站点进站人数对比](#3.4 1月1日及以后0-9号站点进站人数对比)
    • 四、单站点多日期流量对比(按小时聚合)
      • [4.1 4号站点1月4日vs1月5日进站人数小时级对比](#4.1 4号站点1月4日vs1月5日进站人数小时级对比)
      • [4.2 4号站点1月3日vs1月4日进站人数小时级对比](#4.2 4号站点1月3日vs1月4日进站人数小时级对比)
      • [4.3 4号站点1月1-4日进站人数小时级对比](#4.3 4号站点1月1-4日进站人数小时级对比)
      • [4.4 4号站点每日出站人数总量统计](#4.4 4号站点每日出站人数总量统计)
      • [4.5 查看处理后的数据全貌](#4.5 查看处理后的数据全貌)

本文基于已有的地铁流量训练数据,进一步聚焦多站点、多日期的流量对比分析,通过时间特征提取与可视化,验证不同站点、不同日期的流量分布规律,为后续预测模型优化提供更细致的数据支撑。

通过网盘分享的文件:天池地铁流量预测
链接: https://pan.baidu.com/s/1k-sI1sDGufBSLJveNTm6nA?pwd=pgkk 提取码: pgkk

一、工具库导入与数据加载

1.1 导入数据分析与可视化工具库

该步骤加载数据处理(numpy/pandas)、特征工程(TF-IDF/SVD)、模型训练(XGBoost/LightGBM)及可视化(matplotlib/seaborn)所需库,部分库(如文本处理、机器学习模型)为备用,核心用于后续数据EDA的工具已标注,同时屏蔽警告确保输出简洁。

python 复制代码
## 数据工具包(核心用于数值计算与表格数据处理)
import numpy as np
np.random.seed(42)  # 设置numpy随机种子,确保随机操作可复现
import pandas as pd  # 核心库,用于DataFrame构建、数据读写与清洗
from tqdm import tqdm  # 显示循环进度条,便于追踪数据处理进度

## 字符串处理工具包(本EDA案例暂未使用,备用)
import string  # 字符串操作(如标点处理)
import re  # 正则表达式,用于文本匹配与提取
import gensim  # 文本语义建模(如Word2Vec)
from collections import Counter  # 计数工具,用于统计元素频次
import pickle  # 数据序列化存储,便于保存中间结果
from nltk.corpus import stopwords  # NLTK停用词库,用于文本去噪

# 特征工程与模型评估工具(本EDA案例暂未使用机器学习模型,备用)
from sklearn.feature_extraction.text import TfidfVectorizer  # 文本TF-IDF特征提取
from sklearn.decomposition import TruncatedSVD  # 截断SVD,用于高维特征降维
from sklearn.preprocessing import StandardScaler  # 数据标准化,消除量纲影响
from sklearn.model_selection import train_test_split  # 划分训练集与测试集
from sklearn.metrics import roc_auc_score  # 计算AUC指标,评估分类模型
from sklearn.model_selection import KFold  # K折交叉验证,避免模型过拟合

import warnings
warnings.filterwarnings('ignore')  # 屏蔽运行过程中的警告信息,避免干扰输出

# 梯度提升树模型(本EDA案例暂未使用,备用)
import xgboost as xgb  # XGBoost模型,适用于结构化数据预测
import lightgbm as lgb  # LightGBM模型,高效处理大规模数据
from functools import partial  # 函数偏应用,用于固定部分函数参数

# 系统操作与时间处理工具(核心用于文件路径、内存管理与时间特征)
import os  # 系统文件操作,用于路径拼接、文件夹创建
import gc  # 垃圾回收,释放未使用的内存,避免内存溢出
from scipy.sparse import vstack  # 垂直堆叠稀疏矩阵(本案例暂未使用)
import time  # 时间管理,用于记录代码运行耗时
import datetime  # 日期时间处理,核心用于后续提取时间特征

import joblib  # 模型与特征保存工具(本案例暂未使用,备用)

# 多进程与可视化工具(核心用于并行处理与图表绘制)
import multiprocessing as mp  # 多进程处理,提升数据处理效率(本案例暂未使用)
import pandas as pd  # 重复导入,确保代码独立运行时无依赖问题
import numpy as np  # 重复导入,确保代码独立运行时无依赖问题
import matplotlib.pyplot as plt  # 核心可视化库,用于绘制折线图、柱状图等
import re  # 重复导入,确保代码独立运行时无依赖问题
%matplotlib inline  # 设置Jupyter Notebook中图像内嵌显示,无需额外调用plt.show()
import seaborn as sns  # 基于matplotlib的高级可视化库,美化图表样式
%matplotlib inline  # 重复设置,确保图像内嵌生效

1.2 读取地铁流量训练数据与测试提交模板

该步骤读取核心训练数据(df_data.csv)与测试提交模板(testA_submit_2019-01-29.csv),训练数据包含"站点ID、时间段、进站人数、出站人数"等关键信息,后续EDA将基于训练数据展开,测试模板用于后续预测结果填充(本部分暂未涉及)。

python 复制代码
from tqdm import tqdm  # 重复导入,确保代码块独立运行
from tqdm import tqdm_notebook  # 显示Notebook环境下的进度条(本案例暂未使用)

# 读取地铁流量训练数据:包含314928条10分钟级记录,涵盖多个站点的进出站人数
df_data = pd.read_csv('./input/df_data.csv')
# 读取测试提交模板:需预测2019-01-29日各站点的10分钟级进出站人数,本部分暂用其结构
test_A_submit = pd.read_csv('./input/testA_submit_2019-01-29.csv') 

二、时间特征工程(提取精细化时间维度)

2.1 从时间戳提取多维度时间特征

该步骤将原始startTime(字符串格式)解析为datetime格式,进一步提取"日(day)、小时(hours_in_day)、星期几(day_of_week)、日内10分钟段(ten_minutes_in_day)"4个核心时间特征,为后续"按日期/小时/时段"的流量对比分析提供维度支持。

python 复制代码
# 时间相关特征:将startTime(字符串)解析为datetime格式,便于提取细分时间特征
df_data['time'] = pd.to_datetime(df_data['startTime'])
# 提取"日"特征:1-31,对应月份中的具体日期(如1月1日为1,1月2日为2)
df_data['day'] = df_data['time'].dt.day  
# 提取"小时"特征:0-23,对应一天中的24个小时(如凌晨0点为0,中午12点为12)
df_data['hours_in_day'] = df_data['time'].dt.hour 
# 提取"星期几"特征:0-6,0代表星期一,6代表星期日(用于区分工作日/周末)
df_data['day_of_week'] = df_data['time'].dt.dayofweek 
# 提取"日内10分钟段"特征:0-143,一天24小时×6个10分钟段=144个段(如00:00-00:10为0,23:50-24:00为143)
df_data['ten_minutes_in_day'] = df_data['hours_in_day'] * 6 + df_data['time'].dt.minute // 10 
# 删除临时的time列(已提取所有所需时间特征,避免数据冗余)
del df_data['time']

三、多站点流量可视化分析(按日期对比)

3.1 1月1日0-9号站点进站人数对比

该步骤筛选1月1日(day==1)的数据,以"日内10分钟段"为x轴、"进站人数(inNums)"为y轴,绘制0-9号共10个站点的流量趋势图,核心目的是对比不同站点在同一日期的流量分布差异(如高峰时段、流量峰值大小)。

python 复制代码
# 筛选1月1日(day==1)的所有站点数据
tmp = df_data[df_data.day==1]
# 生成x轴数据:日内10分钟段的索引(0-143),基于0号站点的时段数量构建,确保所有站点x轴一致
dt = [r for r in range(tmp.loc[tmp.stationID==0, 'ten_minutes_in_day'].shape[0])]

# 创建图像:设置画布大小为20×10(宽×高),便于清晰展示10条曲线
fig = plt.figure(1,figsize=[20,10])
# 设置y轴标签:进站人数(inNums)
plt.ylabel('inNums')
# 设置x轴标签:日期(此处特指1月1日,x轴实际为日内10分钟段)
plt.xlabel('date')
# 设置图表标题:1月1日0-9号站点进站人数对比
plt.title('inNums of stationID ')

# 循环绘制0-9号站点的进站人数趋势
for i in range(0,10):
    # 筛选当前站点(i)的1月1日数据,按10分钟段排序后取inNums,绘制折线
    plt.plot(dt, tmp.loc[tmp.stationID==i, 'inNums'], label = str(i)+' stationID' )

# 添加图例:区分不同站点的曲线,默认显示在右上角
plt.legend()
# 显示图像(因设置了%matplotlib inline,可省略,但保留确保兼容性)
plt.show()

3.2 1月1日0-9号站点出站人数对比

该步骤与3.1逻辑一致,仅将指标从"进站人数(inNums)"改为"出站人数(outNums)",目的是对比同一日期(1月1日)不同站点的出站流量分布差异,观察进站与出站高峰是否错位(如早高峰进站集中,晚高峰出站集中)。

python 复制代码
# 筛选1月1日(day==1)的所有站点数据
tmp = df_data[df_data.day==1]
# 生成x轴数据:日内10分钟段索引(0-143),与3.1保持一致
dt = [r for r in range(tmp.loc[tmp.stationID==0, 'ten_minutes_in_day'].shape[0])]

# 创建图像:画布大小20×10
fig = plt.figure(1,figsize=[20,10])
# 设置y轴标签:出站人数(outNums)
plt.ylabel('outNums')
# 设置x轴标签:日期(1月1日)
plt.xlabel('date')
# 设置图表标题:1月1日0-9号站点出站人数对比
plt.title('outNums of stationID ')

# 循环绘制0-9号站点的出站人数趋势
for i in range(0,10):
    plt.plot(dt, tmp.loc[tmp.stationID==i, 'outNums'], label = str(i)+' stationID' )

# 添加图例
plt.legend()
# 显示图像
plt.show()

3.3 1月3日0-9号站点出站人数对比

该步骤将日期改为1月3日(day==3),重复3.2的出站人数对比逻辑,目的是观察"同一批站点(0-9号)在不同日期的流量模式是否一致"------若曲线趋势相似(如高峰时段相同),则验证流量分布的稳定性,为后续预测提供规律支撑。

python 复制代码
# 筛选1月3日(day==3)的所有站点数据
tmp = df_data[df_data.day==3]
# 生成x轴数据:日内10分钟段索引(0-143)
dt = [r for r in range(tmp.loc[tmp.stationID==0, 'ten_minutes_in_day'].shape[0])]

# 创建图像:画布大小20×10
fig = plt.figure(1,figsize=[20,10])
# 设置y轴标签:出站人数(outNums)
plt.ylabel('outNums')
# 设置x轴标签:日期(1月3日)
plt.xlabel('date')
# 设置图表标题:1月3日0-9号站点出站人数对比
plt.title('outNums of stationID ')

# 循环绘制0-9号站点的出站人数趋势
for i in range(0,10):
    plt.plot(dt, tmp.loc[tmp.stationID==i, 'outNums'], label = str(i)+' stationID' )

# 添加图例
plt.legend()
# 显示图像
plt.show()

3.4 1月1日及以后0-9号站点进站人数对比

该步骤筛选1月1日及以后(day>=1)的所有数据,绘制0-9号站点的进站人数趋势,目的是观察"多日期叠加下的流量整体规律"------若同一站点在不同日期的曲线高度重合,说明该站点流量模式稳定;若存在明显差异(如某日期流量骤降),则需排查是否为节假日或特殊事件。

python 复制代码
# 筛选1月1日及以后(day>=1)的所有站点数据
tmp = df_data[df_data.day>=1]
# 生成x轴数据:日内10分钟段索引(0-143)
dt = [r for r in range(tmp.loc[tmp.stationID==0, 'ten_minutes_in_day'].shape[0])]

# 创建图像:画布大小20×10
fig = plt.figure(1,figsize=[20,10])
# 设置y轴标签:进站人数(inNums)
plt.ylabel('inNums')
# 设置x轴标签:日期(1月1日及以后)
plt.xlabel('date')
# 设置图表标题:1月1日及以后0-9号站点进站人数对比
plt.title('inNums of stationID ')

# 循环绘制0-9号站点的进站人数趋势
for i in range(0,10):
    plt.plot(dt, tmp.loc[tmp.stationID==i, 'inNums'], label = str(i)+' stationID' )

# 添加图例
plt.legend()
# 显示图像
plt.show()

四、单站点多日期流量对比(按小时聚合)

4.1 4号站点1月4日vs1月5日进站人数小时级对比

该步骤聚焦4号站点(高流量站点,前期分析中已关注),筛选1月4日和5日的数据,按"小时(hours_in_day)"聚合计算每小时平均进站人数,用带圆点的折线图(style='o-')对比两天的小时级流量差异,核心观察"相邻日期的小时级流量模式是否一致"(如早高峰是否都在7-9点)。

python 复制代码
# 筛选4号站点1月4日和5日(day.isin([4,5]))的数据
tmp = df_data.loc[(df_data.day.isin([4,5]))]
# 按"小时(hours_in_day)"和"日期(day)"聚合,计算每小时进站人数均值
# 绘制对比图:x轴为小时(0-23),y轴为平均进站人数,不同日期用不同颜色曲线
tmp.loc[tmp.stationID == 4].pivot_table(index='hours_in_day',\
                                        columns='day',values='inNums').plot(style='o-')

4.2 4号站点1月3日vs1月4日进站人数小时级对比

该步骤将日期改为1月3日和4日,重复4.1的逻辑,进一步验证4号站点"非连续相邻日期"的小时级流量稳定性------若3日和4日的高峰时段、流量峰值相近,说明该站点流量受日期连续性影响小,模式更稳定,预测时可参考更多历史日期。

python 复制代码
# 筛选4号站点1月3日和4日(day.isin([3,4]))的数据
tmp = df_data.loc[(df_data.day.isin([3,4]))]
# 按"小时"和"日期"聚合,计算每小时进站人数均值并绘制对比图
tmp.loc[tmp.stationID == 4].pivot_table(index='hours_in_day',\
                                        columns='day',values='inNums').plot(style='o-')

4.3 4号站点1月1-4日进站人数小时级对比

该步骤扩展日期范围至1月1-4日,按小时聚合4号站点的进站人数,绘制4条日期曲线,目的是观察"多日期叠加下的小时级流量规律"------若4条曲线趋势一致(如早高峰7-9点、晚高峰17-19点),则可确定该站点的核心流量模式,为预测时的"小时级比例映射"提供直接依据。

python 复制代码
# 筛选4号站点1月1-4日(day.isin([1,2,3,4]))的数据
tmp = df_data.loc[(df_data.day.isin([1,2,3,4]))]
# 按"小时"和"日期"聚合,计算每小时进站人数均值并绘制对比图
tmp.loc[tmp.stationID == 4].pivot_table(index='hours_in_day',\
                                        columns='day',values='inNums').plot(style='o-')

4.4 4号站点每日出站人数总量统计

该步骤按"日(day)"聚合4号站点的出站人数总量,输出1月1-29日(29日为预测日,数据为0)的统计结果,核心用于观察"每日流量总量的变化趋势"------如1月1日(元旦)流量较低,1月2-4日(工作日)流量回升且稳定,为预测时的"日期类型调整系数"(如节假日系数、工作日系数)提供数据支撑。

python 复制代码
# 按"日(day)"聚合4号站点的出站人数总量,输出各日期的累计出站人数
df_data[df_data.stationID==4].groupby(['day'])['outNums'].sum()

输出结果:

复制代码
day
1     24016.0
2     38615.0
3     38065.0
4     38791.0
5     25276.0
6     21186.0
7     37678.0
8     37507.0
9     36826.0
10    37480.0
11    38778.0
12    25621.0
13    22081.0
14    38860.0
15    37295.0
16    38719.0
17    39327.0
18    41707.0
19    27112.0
20    23881.0
21    40142.0
22    39285.0
23    39348.0
24    39737.0
25    39597.0
28    36844.0
29        0.0
Name: outNums, dtype: float64

4.5 查看处理后的数据全貌

该步骤展示经过时间特征工程处理后的完整数据集df_data,包含原始字段(站点ID、时间段、进出站人数)和新增时间特征(日、小时、星期几、日内10分钟段),便于直观了解数据结构与字段含义,确认特征提取结果是否符合预期,为后续更复杂的分析或建模提供数据基础。

python 复制代码
df_data

输出结果:

| | stationID | startTime | endTime | inNums | outNums | day | hours_in_day | day_of_week | ten_minutes_in_day |
| 0 | 0 | 2019-01-01 00:00:00 | 2019-01-01 00:10:00 | 0.0 | 0.0 | 1 | 0 | 1 | 0 |
| 1 | 0 | 2019-01-01 00:10:00 | 2019-01-01 00:20:00 | 0.0 | 0.0 | 1 | 0 | 1 | 1 |
| 2 | 0 | 2019-01-01 00:20:00 | 2019-01-01 00:30:00 | 0.0 | 0.0 | 1 | 0 | 1 | 2 |
| 3 | 0 | 2019-01-01 00:30:00 | 2019-01-01 00:40:00 | 0.0 | 0.0 | 1 | 0 | 1 | 3 |
| 4 | 0 | 2019-01-01 00:40:00 | 2019-01-01 00:50:00 | 0.0 | 0.0 | 1 | 0 | 1 | 4 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 314923 | 9 | 2019-01-29 23:10:00 | 2019-01-29 23:20:00 | 0.0 | 0.0 | 29 | 23 | 1 | 139 |
| 314924 | 9 | 2019-01-29 23:20:00 | 2019-01-29 23:30:00 | 0.0 | 0.0 | 29 | 23 | 1 | 140 |
| 314925 | 9 | 2019-01-29 23:30:00 | 2019-01-29 23:40:00 | 0.0 | 0.0 | 29 | 23 | 1 | 141 |
| 314926 | 9 | 2019-01-29 23:40:00 | 2019-01-29 23:50:00 | 0.0 | 0.0 | 29 | 23 | 1 | 142 |

314927 9 2019-01-29 23:50:00 2019-01-30 00:00:00 0.0 0.0 29 23 1 143

314928 rows × 9 columns

通过上述步骤,我们完成了从数据加载、时间特征提取到多维度可视化分析的全流程。核心发现包括:

  1. 不同站点在同一日期的流量分布存在显著差异(如峰值大小和时段);
  2. 同一站点在不同日期的流量模式具有稳定性(如高峰时段固定);
  3. 部分日期(如节假日)的流量总量与工作日存在明显差异。

这些规律为后续构建基于"时间序列相似性"的预测模型提供了关键依据。

上一章: 【竞赛系列】机器学习实操项目07------全球城市计算AI挑战赛(baseline、时间序列分析、地铁流量预测)
下一章:
机器学习核心知识点目录: 机器学习核心知识点目录
机器学习实战项目目录: 【从 0 到 1 落地】机器学习实操项目目录:覆盖入门到进阶,大学生就业 / 竞赛必备

相关推荐
算家计算2 小时前
一张图+一段音频=电影级视频!阿里Wan2.2-S2V-14B本地部署教程:实现丝滑口型同步
人工智能·开源·aigc
XINVRY-FPGA2 小时前
XCVP1902-2MSEVSVA6865 AMD 赛灵思 XilinxVersal Premium FPGA
人工智能·嵌入式硬件·神经网络·fpga开发·云计算·腾讯云·fpga
算家计算2 小时前
多年AI顽疾被攻克!OpenAI前CTO团队破解AI随机性难题,大模型可靠性迎来飞跃
人工智能·llm·资讯
非优秀程序员2 小时前
免费宝藏书《MCP 从入门到实践(图文指南版)》速览
人工智能·开源·产品
F_D_Z2 小时前
【PyTorch】单对象分割
人工智能·pytorch·python·深度学习·机器学习
浊酒南街2 小时前
Pytorch基础入门4
人工智能·pytorch·python
阿杜杜不是阿木木3 小时前
开始 ComfyUI 的 AI 绘图之旅-Flux.1文生图(全网首发,官网都没有更新)(七)
人工智能·ai·ai作画·aigc·图生图
艾醒3 小时前
探索大语言模型(LLM):Ollama快速安装部署及使用(含Linux环境下离线安装)
人工智能·深度学习·算法
nju_spy3 小时前
南京大学 LLM开发基础(一)前向反向传播搭建
人工智能·pytorch·深度学习·大语言模型·梯度·梯度下降·反向传播