完整内容看文章最后的推广群
2025五一杯数学建模竞赛(五一赛)A题保姆级分析完整思路+代码+数据教学
DS数模-五一数学建模竞赛 A题保姆级教程思路分析
下面我将以背景介绍、数据集分析、问题分析的步骤来给大家讲解A题的具体思路。
1 背景介绍
该题目属于交通流量推测与建模问题,核心目标是通过主路监测数据反推未安装监测设备的支路车流量。主路车流量是各支路流量的总和,结合历史规律(如线性增长、周期性变化等),建立数学模型描述支路流量随时间的变化规律。其应用价值在于优化交通信号灯配时、缓解拥堵和道路资源规划。
共包含5个子问题,涉及不同道路拓扑(Y型、多支路交汇、信号灯控制等)和复杂条件(时间延迟、信号灯周期、数据误差)。各问题的核心差异如下:
- 问题1:简单Y型道路,两支路流量分别呈单一段线性增长和分段线性变化。
- 问题2:多支路交汇,需考虑支路到达监测点的行驶时间差异及周期性流量。
- 问题3-4:引入交通信号灯控制,支路流量受红灯/绿灯周期性影响,且需处理数据误差。
- 问题5:确定监测设备的最少记录时刻,以推断支路流量函数。
这道题目的核心难点是: - 多变量解耦:主路数据为各支路流量叠加,需通过约束条件和历史规律分离变量。
- 时间延迟建模:车辆行驶到监测点的时间差需在模型中体现(如问题2支路1、2的2分钟延迟)。
- 周期性函数拟合:问题2支路4的周期性流量需选择合适的周期函数(如三角函数)。
- 信号灯同步性:确定绿灯开始时刻(如问题3中首个绿灯为7:06)并分段建模。
给大家提示一下几个方法:1 分段建模:对具有不同趋势的时间段分别定义函数,确保分段点连续。2 约束优化:利用主路流量=支路流量之和的约束,构建方程组求解参数。3 参数拟合方法:最小二乘法、非线性回归或傅里叶变换(周期性支路)。4 误差分析:通过残差计算或交叉验证评估模型可靠性。
2 数据集分析
以下为各附件核心字段说明及数据特性:
所有表格包含以下字段:
- 时刻 (Moment): 时间戳(格式 HH:MM)
- 时间 t (Time t): 以分钟为单位的连续时间索引(0~59)
- 车流量: 不同主路的车流量数值(单位未明确,假设为辆/分钟)
数据特征分析
- 表1-主路3:车流量随时间线性增长,08:00后出现下降。
- 表2-主路5:数值精度不一致(如35.700000000000003),存在突变点(如07:36的71.3)。
- 表3-主路4:数值波动剧烈(如07:08的34.6到07:10的37.3)。
- 表4-主路4:数据分布与表3不同,可能为不同传感器数据。
数据预处理过程:
1 缺失值检查:验证时间连续性2 数值精度统一:保留2位小数3 异常值检测:基于标准差或分位数 4 时间格式转换:将时刻转为datetime对象
import pandas as pd
import numpy as np
def preprocess_table(sheet_name):
# 读取数据
df = pd.read_excel("Attachment.xlsx", sheet_name=sheet_name)
# 1. 数据清洗
df = df.round(2) # 统一精度
df = df.drop_duplicates(subset=["时间 t (Time t)"]) # 去重
# 2. 缺失值处理
expected_t = range(60)
missing_t = list(set(expected_t) - set(df["时间 t (Time t)"]))
if missing_t:
print(f"缺失时间点:{missing_t}")
# 线性插值填充(可选)
df = df.set_index("时间 t (Time t)").reindex(expected_t).interpolate().reset_index()
# 3. 异常值检测
flow_col = df.columns[-1]
mean = df[flow_col].mean()
std = df[flow_col].std()
outliers = df[np.abs(df[flow_col] - mean) > 3*std]
if not outliers.empty:
print(f"异常值:\n{outliers}")
# 4. 时间格式转换
df["时刻 (Moment)"] = pd.to_datetime(df["时刻 (Moment)"], format="%H:%M")
return df
# 处理所有表格
tables = {
"Table1": "主路3的车流量",
"Table2": "主路5的车流量",
"Table3": "主路4的车流量",
"Table4": "主路4的车流量"
}
processed_data = {}
for sheet, col in tables.items():
df = preprocess_table(sheet)
processed_data[sheet] = df
print(f"\n{sheet}预处理完成,示例如下:")
print(df.head(3))
输出验证:
# 检查数据分布
for name, df in processed_data.items():
print(f"\n{name}统计描述:")
print(df.describe())
# 保存预处理结果
with pd.ExcelWriter("Processed_Data.xlsx") as writer:
for name, df in processed_data.items():
df.to_excel(writer, sheet_name=name, index=False)
以下是针对交通流量数据集的可视化方法及Python代码实现,涵盖趋势分析、异常检测和多路对比:
时间序列折线图来观察流量变化趋势
import matplotlib.pyplot as plt
def plot_timeseries(df, road_name):
plt.figure(figsize=(15, 5))
plt.plot(df["时间 t (Time t)"], df.iloc[:, -1],
marker='o', linestyle='--', linewidth=1)
plt.title(f"{road_name} Traffic Flow")
plt.xlabel("Time t (minutes)")
plt.ylabel("Vehicles/min")
plt.grid(alpha=0.4)
plt.xticks(range(0, 60, 5))
plt.show()
# 示例使用
plot_timeseries(processed_data["Table1"], "Main Road 3")
箱线图来检测异常值分布)
import seaborn as sns
def plot_boxplot(df_list, road_names):
flows = [df.iloc[:, -1] for df in df_list]
plt.figure(figsize=(10, 5))
sns.boxplot(data=flows, palette="Set2")
plt.xticks(range(len(road_names)), road_names)
plt.title("Traffic Flow Distribution Comparison")
plt.ylabel("Vehicles/min")
plt.show()
# 示例使用
plot_boxplot([processed_data["Table1"],
processed_data["Table2"]],
["Road3", "Road5"])
3 问题分析
问题一分析与求解:
时间特性:
时间相关性:流量数据具有强时间依赖性(前序时刻影响后续时刻)
多路耦合:不同主路流量可能存在相互影响(如相邻道路拥堵导致分流)
突变特征:部分时段出现流量骤变(如交通事故、信号灯变化)
模型:
代码:
# 环境准备
import pandas as pd
import numpy as np
from sklearn.model_selection import TimeSeriesSplit
from statsmodels.tsa.arima.model import ARIMA
from xgboost import XGBRegressor
import tensorflow as tf
# 数据加载
def load_data(path):
df = pd.read_excel(path, parse_dates=['时刻 (Moment)'])
df.set_index('时刻 (Moment)', inplace=True)
return df['主路3的车流量 (Traffic flow on the Main road 3)']
# 特征工程
def create_features(series, lags=6):
df = pd.DataFrame(series)
for i in range(1, lags+1):
df[f'lag_{i}'] = series.shift(i)
df['hour'] = df.index.hour
df['day_part'] = np.where(df['hour'] < 12, 0, 1)
return df.dropna()
# 模型训练
def train_models(X_train, y_train):
# ARIMA
arima = ARIMA(y_train, order=(2,1,1))
arima_model = arima.fit()
# XGBoost
xgb = XGBRegressor(objective='reg:squarederror')
xgb.fit(X_train[['lag_1', 'hour']], y_train)
# LSTM
lstm = tf.keras.Sequential([
tf.keras.layers.LSTM(50, input_shape=(X_train.shape[1], 1)),
tf.keras.layers.Dense(1)
])
lstm.compile(loss='mae', optimizer='adam')
X_3d = X_train.values.reshape((X_train.shape[0], X_train.shape[1], 1))
lstm.fit(X_3d, y_train, epochs=30, verbose=0)
return arima_model, xgb, lstm
# 主流程
if __name__ == "__main__":
# 数据准备
data = load_data("Processed_Data.xlsx")
processed_df = create_features(data)
# 划分训练测试集
split = int(len(processed_df)*0.8)
train, test = processed_df.iloc[:split], processed_df.iloc[split:]
# 模型训练
arima, xgb, lstm = train_models(train.drop(columns=['value']), train['value'])
# 模型保存
arima.save('arima_model.pkl')
xgb.save_model('xgb_model.json')
lstm.save('lstm_model.h5')
其中更详细的思路、各题目思路、代码、讲解视频、成品论文及其他相关内容,可以点击下方名片获取: