资讯动态

泰迪杯车辆驾驶行为分析:Python特征工程与聚类实战

发布时间:2026/10/13 17:20:18 来源:尧图企业网站定制
简介本资源为第七届泰迪杯数据挖掘比赛「车辆驾驶行为分析」赛题的完整项目源码与配套文档面向计算机、人工智能、自动化等专业学生及数据挖掘初学者可用于课程设计、毕业设计或竞赛复盘。项目围绕车辆驾驶行为评测展开结合省、市、县级地区温度、天气、湿度等环境特征建立环境评测模型探究环境因素对行驶节能的影响并将环境因素融入驾驶行为评测模型涵盖数据预处理、异常值剔除、经纬度与路程速度分析、KMeans聚类及汽车评价体系得分等环节。压缩包共10个文件包含5个ipynb实验笔记、2个py脚本、2个md说明及1份docx比赛总结整体约1.82MB结构清晰便于按模块学习。目前已有167人学习下载读者可获取完整赛题方案、可运行代码、比赛总结与排错思路适合在此基础上修改扩展实现更多功能。1. 泰迪杯车辆驾驶行为分析从一份比赛数据到可复现的 Python 方案第一次拿到泰迪杯车辆驾驶行为分析这道题的人八成会先愣一下数据里没有标签只有一堆带时间戳的车速、转速、经纬度却要判断急加速、急减速、急转弯、超速这些行为。这其实是典型的数据挖掘赛题——给原始信号让你自己定义行为、自己构造特征、自己选模型。它解决的是「从连续车况数据里自动识别驾驶风格」的问题适合想练完整数据挖掘链路的人数据清洗、特征工程、无监督聚类、可视化、报告撰写一条龙走完。Python 在这里是主力工具pandas 处理时序、scipy 做信号平滑、sklearn 做聚类和分类、matplotlib 出图基本够用。下面我按自己复现这类赛题的顺序把能抄作业的部分拆开讲。2. 车辆驾驶行为分析的数据底座字段、采样与预处理2.1 先搞清楚数据长什么样再动手泰迪杯这类赛题常见的数据形态是「一车一文件」或「一段行程一文件」字段大致包括时间戳、车速km/h、发动机转速、经纬度、方向角有的还会给档位或刹车信号。采样频率不固定常见 1Hz 到 10Hz 不等。动手前先做三件事统计每辆车的记录条数、看时间戳是否连续、检查缺失和异常值分布。这一步不做后面特征全是歪的。import pandas as pd import numpy as np # 读取单个行程文件假设是 csv列名按实际调整 df pd.read_csv(trip_001.csv, parse_dates[timestamp]) df df.sort_values(timestamp).reset_index(dropTrue) # 基础体检条数、时间跨度、缺失率 print(记录数:, len(df)) print(时间跨度:, df[timestamp].max() - df[timestamp].min()) print(缺失率:\n, df.isnull().mean()) # 采样间隔分布判断是否等间隔 dt df[timestamp].diff().dt.total_seconds().dropna() print(采样间隔描述:\n, dt.describe())逻辑说明先排序保证时序正确再算采样间隔。如果间隔忽大忽小说明数据不是严格等间隔后面算加速度不能直接用diff()除以固定值得除以真实时间差。参数上parse_dates把时间列转成 datetimediff()得到相邻时间差total_seconds()统一成秒。2.2 缺失值与异常值的处理边界车速突然从 60 跳到 0 再跳回 60这种多半是信号丢失或 GPS 漂移不是真实急刹。常见做法是对车速做物理范围过滤0 到 200 km/h对超出范围的值置为 NaN再用线性插值补短缺口比如连续缺失少于 5 个点长缺口直接截断该段。经纬度异常可以用相邻点距离判断超过合理速度对应的距离就标记。# 车速物理范围过滤 df.loc[(df[speed] 0) | (df[speed] 200), speed] np.nan # 短缺口线性插值limit 控制最多补几个点 df[speed] df[speed].interpolate(methodlinear, limit5) # 经纬度跳变检测相邻点距离过大则标记 def haversine(lat1, lon1, lat2, lon2): R 6371.0 phi1, phi2 np.radians(lat1), np.radians(lat2) dphi np.radians(lat2 - lat1) dlambda np.radians(lon2 - lon1) a np.sin(dphi/2)**2 np.cos(phi1)*np.cos(phi2)*np.sin(dlambda/2)**2 return 2 * R * np.arcsin(np.sqrt(a)) df[dist_km] haversine(df[lat].shift(), df[lon].shift(), df[lat], df[lon]) df[jump] df[dist_km] 0.5 # 相邻点超过 500 米视为跳变逻辑说明interpolate的limit5是关键参数补太多会把真实停车抹平。haversine 算的是球面距离比欧氏距离准。jump阈值 0.5 公里是经验值1Hz 采样下正常车速 180 km/h 也就 0.05 公里超过 0.5 基本是漂移。2.3 平滑处理别把真实急刹也磨平了原始车速有噪声直接求导算加速度会得到一堆毛刺。常用 Savitzky-Golay 滤波或滑动平均。Savitzky-Golay 的好处是保留峰值形状适合识别急加速急减速。窗口长度取奇数多项式阶数一般 2 或 3。窗口太大急刹的尖峰会被削掉窗口太小噪声还在。from scipy.signal import savgol_filter # window_length 必须为奇数polyorder 小于 window_length df[speed_smooth] savgol_filter(df[speed].interpolate(), window_length7, polyorder2) # 用平滑后车速算加速度单位 m/s^2 df[dt] df[timestamp].diff().dt.total_seconds() df[acc] df[speed_smooth].diff() / 3.6 / df[dt]逻辑说明window_length7对应 1Hz 下 7 秒窗口能压住噪声又保留急刹。polyorder2拟合抛物线对加速度变化友好。除以 3.6 是把 km/h 转 m/s。dt用真实时间差避免非等间隔带来的误差。3. 驾驶行为特征工程从车速曲线到可聚类样本3.1 行为定义先于特征计算急加速、急减速、急转弯、超速这四个行为得先有量化定义。行业里常见的阈值加速度大于 2.5 m/s² 算急加速小于 -2.5 m/s² 算急减速横向加速度大于 2.0 m/s² 算急转弯车速超过道路限速或 80 km/h 算超速。这些阈值不是死的泰迪杯评分往往看你能不能自圆其说。我一般会先按这些阈值打标签再统计每段行程的行为频次作为特征。# 按阈值打行为标签 df[hard_accel] df[acc] 2.5 df[hard_brake] df[acc] -2.5 df[speeding] df[speed_smooth] 80 # 横向加速度需要方向角变化率这里用方向角 diff 近似 df[yaw_rate] df[heading].diff() / df[dt] df[hard_turn] df[yaw_rate].abs() 30 # 度每秒逻辑说明hard_accel和hard_brake直接看纵向加速度。yaw_rate用方向角变化率近似横向加速度阈值 30 度每秒是经验值实际要看数据里方向角的单位和噪声。如果方向角噪声大先平滑再求导。3.2 滑窗统计把连续信号变成表格模型吃的是表格不是时间序列。常见做法是切滑动窗口比如 10 秒一个窗步长 5 秒每个窗内统计平均车速、最大加速度、最小加速度、急加速次数、急减速次数、超速时长占比、方向角变化方差。这样每个窗变成一个样本后续可以聚类或分类。window_sec 10 step_sec 5 records [] for start in np.arange(0, len(df) - window_sec, step_sec): seg df.iloc[start:start window_sec] records.append({ mean_speed: seg[speed_smooth].mean(), max_acc: seg[acc].max(), min_acc: seg[acc].min(), hard_accel_cnt: seg[hard_accel].sum(), hard_brake_cnt: seg[hard_brake].sum(), speeding_ratio: seg[speeding].mean(), yaw_var: seg[yaw_rate].var(), }) feat pd.DataFrame(records)逻辑说明窗口长度和步长是超参数10 秒窗能覆盖一次完整急刹过程步长 5 秒保证样本量。speeding_ratio是占比不是次数避免窗口长度影响。yaw_var用方差而不是均值因为转弯是波动。3.3 特征标准化与降维聚类前必须标准化否则车速的数值范围会压过加速度。用 StandardScaler 或 MinMaxScaler。如果特征多可以 PCA 降到 2 到 3 维方便可视化也去掉共线性。from sklearn.preprocessing import StandardScaler from sklearn.decomposition import PCA scaler StandardScaler() X scaler.fit_transform(feat) pca PCA(n_components2) X_pca pca.fit_transform(X) print(解释方差比:, pca.explained_variance_ratio_)逻辑说明fit_transform在训练集上做如果后面有测试集要用同一个 scaler 的transform。PCA 的explained_variance_ratio_告诉你前两个主成分保留了多少信息一般要看到 70% 以上才适合二维可视化。4. 聚类与分类把行程分成激进、平稳、疲劳几类4.1 KMeans 聚类的参数怎么定无监督场景下KMeans 是最常用的。K 值用肘部法或轮廓系数选。我一般先跑 K 从 2 到 8看轮廓系数最高点。特征用上一章的滑窗统计。聚类完每类看质心解释成「激进」「平稳」「一般」。from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score scores [] for k in range(2, 9): km KMeans(n_clustersk, random_state42, n_init10) labels km.fit_predict(X) scores.append((k, silhouette_score(X, labels))) print(scores)逻辑说明n_init10表示跑 10 次不同初始化取最好避免局部最优。random_state固定保证可复现。轮廓系数越接近 1 越好但也要结合业务解释有时候 K3 比 K4 更好讲。4.2 有标签时用随机森林做行为识别如果赛题给了部分标签或者你自己按阈值打了标签可以用随机森林做分类。随机森林对特征尺度不敏感能输出特征重要性适合写报告。from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split # y 是行为标签比如 0 平稳 1 激进 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42, stratifyy) rf RandomForestClassifier(n_estimators200, max_depth8, random_state42) rf.fit(X_train, y_train) print(准确率:, rf.score(X_test, y_test)) print(特征重要性:, dict(zip(feat.columns, rf.feature_importances_)))逻辑说明stratifyy保证训练测试集类别比例一致。n_estimators200是常用起点max_depth8防止过拟合。特征重要性可以帮你回头删掉没用的特征。4.3 结果可视化让评委一眼看懂聚类结果用散点图PCA 二维上色。行为频次用柱状图。车速曲线叠加急加速急减速标记用折线图。图要标轴、标单位、标阈值线。import matplotlib.pyplot as plt plt.figure(figsize(10, 6)) plt.scatter(X_pca[:, 0], X_pca[:, 1], clabels, cmapviridis, s10) plt.xlabel(PC1) plt.ylabel(PC2) plt.title(Driving Behavior Clusters) plt.colorbar(labelCluster) plt.savefig(clusters.png, dpi150)逻辑说明clabels按聚类上色cmap选对比明显的色带。dpi150保证报告里清晰。保存而不是show()方便批量出图。5. 避坑与排查车辆驾驶行为分析里最容易翻车的 5 个点5.1 现象加速度算出来全是尖刺急加速次数虚高原因原始车速噪声大直接diff()求导放大了噪声。解决先 Savitzky-Golay 平滑再求导窗口长度至少 5且用真实时间差而不是固定间隔。5.2 现象聚类结果每类都差不多轮廓系数很低原因特征没标准化车速数值范围压过其他特征或者窗口太长把不同行为混在一起。解决StandardScaler 标准化窗口缩短到 5 到 10 秒检查特征方差。5.3 现象经纬度跳变导致距离特征完全失真原因GPS 漂移或信号丢失相邻点距离几百米。解决haversine 算距离设阈值标记跳变点跳变点不参与距离统计或整段剔除。5.4 现象超速判定和实际不符明明没超速却标红原因限速信息缺失用固定 80 km/h 一刀切但城市道路和高速限速不同。解决如果没有道路限速数据就在报告里说明用固定阈值或者按车速分布分位数动态定阈值。5.5 现象随机森林准确率很高但特征重要性全是车速原因标签是用车速阈值打的模型只是学会了阈值。解决标签要综合多个特征定义或者用无监督聚类代替有监督避免循环论证。6. 从比赛到落地把驾驶行为分析做成可复用的评分卡比赛交完不是终点。这套东西稍微改改就能用在车队管理、保险 UBI、试驾评估上。我的习惯是最后把滑窗特征和聚类标签固化成一个评分卡每个窗口输出一个 0 到 100 的驾驶风险分分数越低越激进。具体做法是取聚类质心算每个样本到「平稳类」质心的距离归一化后取反。这样新数据进来跑同样的预处理和特征工程直接出分。# 假设 cluster 0 是平稳类 calm_center km.cluster_centers_[0] dist np.linalg.norm(X - calm_center, axis1) score 100 * (1 - (dist - dist.min()) / (dist.max() - dist.min())) feat[risk_score] score逻辑说明cluster_centers_是标准化空间里的质心np.linalg.norm算欧氏距离。归一化用 min-max保证分数在 0 到 100。这个分数可以直接给业务方看比聚类标签直观。验证方法上我会留一段没参与训练的行程人工看车速曲线标出真实急刹点再对比评分卡低分区间是否重合。重合度高说明方案可用不重合回头查特征窗口和阈值。参数上窗口长度、平滑窗口、聚类 K 值这三个最敏感建议各做一组对比实验把轮廓系数和业务解释一起看。血泪经验是别一上来就上深度学习。车辆行为分析的数据量通常不大LSTM 容易过拟合调参成本高报告里也不好解释。传统特征工程加树模型或聚类性价比最高评委也认。我一般会先把基线跑通再考虑要不要加复杂模型。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑