🚖 Kaggle 项目经验分享:Uber 出行数据分析实战
最近我在 Kaggle 上做了一个 Uber 出行数据分析 的小项目。本来数据是公开的,但后来数据分享者把数据集设置成了私有,现在已经无法直接复现 😢。不过没关系,这次我还是想把我的分析思路、方法以及一些业务洞察整理出来,分享给大家。
1. 项目背景
网约车平台的运营,离不开对 用户出行行为、司机接单习惯、支付方式、取消原因 等数据的理解。通过数据分析,我们能回答很多有价值的问题:
- 哪些区域和路线最受欢迎?
- 哪些车型贡献了最多营收?
- 为什么订单会被取消?是司机问题还是用户问题?
- 在什么时间段,出行需求最高?
在这个项目里,我主要目标是:
- 熟悉 Uber 出行业务的数据结构。
- 从订单分布、营收、完成率等角度探索出行业务模式。
- 通过可视化把业务问题更直观地呈现出来。
2. 数据处理与探索
✅ 缺失值处理
数据并不完美,缺失和异常很常见。比如:
- 评分字段:缺失时按车型均值填补。
- 订单金额:缺失时用行程距离近似替代。
- 支付方式 :缺失时统一标记为
Unknown
。
python
# 填补评分缺失
num_cols_to_fill = ['Avg VTAT', 'Avg CTAT', 'Driver Ratings', 'Customer Rating']
for col in num_cols_to_fill:
df[col] = df.groupby('Vehicle Type')[col].transform(lambda x: x.fillna(x.mean()))
# 金额缺失处理
df['Booking Value'] = np.where(df['Booking Value'].isnull(), df['Ride Distance'], df['Booking Value'])
# 支付方式缺失处理
df['Payment Method'] = df['Payment Method'].fillna('Unknown')
✅ 一致性检查
- 如果订单状态是
Completed
,金额必须存在。 - 如果订单是
Cancelled
,金额应该为空。
这类规则校验在真实业务中非常重要。
3. 数据分析与可视化
我分为两个部分来做:
- 描述性分析(主要回答"现状是什么")。
- 解释性分析(进一步回答"为什么会这样")。
3.1 热门地点与路线
- Top 20 上车点/下车点:需求高度集中在交通枢纽和商圈。
- Top 10 路线:多是住宅区 ↔ 商业区,符合通勤逻辑。
python
top_routes = (
df.groupby(['Pickup Location', 'Drop Location'])
.size()
.reset_index(name='count')
.sort_values(by='count', ascending=False)
.head(10)
)
plt.figure(figsize=(10, 6))
plt.barh(
[f"{row['Pickup Location']} → {row['Drop Location']}" for _, row in top_routes.iterrows()],
top_routes['count'],
color='coral'
)
plt.title("Top 10 Routes by Order Count")
plt.gca().invert_yaxis()
plt.show()
👉 派单调度和区域补贴策略,可以基于这些信息优化。
3.2 车型分析
- 订单占比:经济型车型占大多数。
- 平均金额:高端车型单均值明显更高。
- 营收贡献:虽然经济型量大,但中高端车型在总营收中也很有分量。
python
vehicle_revenue = (
df.groupby('Vehicle Type')['Booking Value']
.sum()
.reset_index()
.sort_values(by='Booking Value', ascending=False)
)
sns.barplot(x='Vehicle Type', y='Booking Value', data=vehicle_revenue, palette='Greens_d')
plt.title('Total Revenue Contribution by Vehicle Type')
plt.show()
👉 平台要在"量"和"利"之间找到平衡点。
3.3 支付方式分析
- 大部分用户选择电子支付。
- 现金支付比例低,但有时与取消率相关。
python
payment_completion = (
df.groupby('Payment Method')['Booking Status']
.apply(lambda x: (x == 'Completed').mean())
.reset_index(name='Completion Rate')
)
sns.barplot(x='Payment Method', y='Completion Rate', data=payment_completion, palette='Set3')
plt.title("Completion Rate by Payment Method")
plt.show()
👉 在一些数据中,现金支付订单的完成率会显著低于电子支付。
3.4 订单完成率分析
距离区间 vs 完成率
python
bins = [0, 5, 15, 50]
labels = ['Short (0-5km)', 'Medium (5-15km)', 'Long (15km+)']
df['Distance Category'] = pd.cut(df['Ride Distance'], bins=bins, labels=labels, right=False)
completion_rate = (
df.groupby('Distance Category')['Booking Status']
.apply(lambda x: (x == 'Completed').mean())
.reset_index(name='Completion Rate')
)
👉 越长途,越容易被取消。
车型 vs 完成率
python
vehicle_completion = (
df.groupby('Vehicle Type')['Booking Status']
.apply(lambda x: (x == 'Completed').mean())
.reset_index(name='Completion Rate')
.sort_values('Completion Rate', ascending=False)
)
👉 高端车型因为等待时间长,完成率往往低于经济型车型。
3.5 用户 vs 司机 取消对比
python
cancel_summary = {
"Customer Cancelled": (df['Booking Status'] == 'Cancelled by Customer').mean(),
"Driver Cancelled": (df['Booking Status'] == 'Cancelled by Driver').mean()
}
sns.barplot(x=list(cancel_summary.keys()), y=list(cancel_summary.values()), palette='pastel')
plt.title("Cancellation Rate: Customer vs Driver")
plt.show()
👉 如果用户取消率高,说明体验不好(比如等待太久);如果司机取消率高,说明供给侧不稳定。
3.6 时间维度分析
python
df['Booking Time'] = pd.to_datetime(df['Booking Time'])
df['Hour'] = df['Booking Time'].dt.hour
hourly_orders = df.groupby('Hour').size()
hourly_orders.plot(kind='bar', color='steelblue')
plt.title("Order Count by Hour of Day")
plt.show()
👉 可以看到明显的 早晚高峰。
4. 收获与总结
这次项目虽然没能用到完整数据,但依然让我收获了很多:
-
思路比数据更重要
- 数据可能消失,但分析逻辑和方法是通用的。
-
业务视角是关键
- 不只是画图,而是要能解释为什么,找到优化的切入点。
-
分析的"两个层次"
- 描述性:告诉大家"现状是什么"。
- 解释性:进一步回答"为什么是这样"。
-
未来可以扩展
- 结合用户分群、供需预测做更复杂的建模。
- 加入时间序列预测,模拟未来出行需求。