本文通过 DuckDB 结合 Python 统计工具,演示如何对出租车乘车数据集进行假设检验。重点探讨支付方式对小费行为的影响,以及行程时长与小费比例的相关性,提供完整的 SQL 数据处理与统计检验方法论。
环境准备
安装 DuckDB 并验证基础查询能力:
pip install duckdb
import duckdb
# 直接读取 CSV 文件并预览数据
duckdb.query("SELECT * FROM read_csv_auto('/content/cab_ride_data.csv') LIMIT 5").df()
测试数据可以从这里下载。
假设检验实例
假设1:支付方式影响给小费行为?
零假设 (H₀):不同支付方式的小费分布一致
备择假设 (H₁):支付方式与小费行为存在关联
实施步骤:
-
构建列联表
使用 SQL 聚合不同支付方式下的小费/非小费计数:SELECT payment_type, SUM(CASE WHEN tip > 0 THEN 1 ELSE 0 END) AS tipped, SUM(CASE WHEN tip = 0 THEN 1 ELSE 0 END) AS no_tip FROM read_csv('/content/cab_ride_data.csv') GROUP BY payment_type;
-
卡方检验
通过 SciPy 实现统计检验:# 导入卡方检验函数(用于分类变量的独立性检验) from scipy.stats import chi2_contingency # 从数据框中提取分类变量的列联表 # tipped列(是否给小费)和no_tip列(是否不给小费)构成2x2矩阵 contingency_table = df[['tipped', 'no_tip']].values # 执行卡方检验并解包结果: # chi2_stat: 卡方统计量(衡量观察值与期望值的偏离程度) # p_value: 显著性概率(原假设成立的可能性) # dof: 自由度((行数-1)*(列数-1)) # expected: 期望频数矩阵(基于原假设的预期分布) chi2_stat, p_value, dof, expected = chi2_contingency(contingency_table)
关键点解释:
- 卡方检验原理
通过比较实际观测频数与理论期望频数的差异,判断分类变量是否独立。公式:
χ² = Σ[(O-E)²/E],其中O=实际频数,E=期望频数 - 列联表要求
需要满足:- 所有单元格期望频数 ≥5;卡方检验基于大数定律,当期望频数过低时(如 <5),其分布可能偏离理论卡方分布
- 分类变量为二进制或有序类型
- 数据为频数形式(本文通过SUM(CASE WHEN)实现)
- 结果解读指南
- 若p<0.05:拒绝原假设(存在显著关联)
- 若p≥0.05:无法拒绝原假设(无足够证据证明关联)
- 卡方值越大,拒绝原假设的证据越强
典型应用场景:
- A/B测试结果分析(如不同支付方式的用户行为差异)
- 用户分群特征验证(如新老用户的产品使用模式对比)
结果解读:
- 卡方值
1.8509
,p值0.3964
(>0.05) - 结论:无充分证据表明支付方式影响小费行为。
假设2:行程时间与小费比例相关?
零假设 (H₀):行程时长与小费比例无关
备择假设 (H₁):二者存在显著相关性
实施步骤:
-
数据预处理
计算小费百分比并过滤无效数据:
SELECT corr(duration_min, tip_percentage) AS correlation FROM ( SELECT duration_min, (tip / fare) * 100 AS tip_percentage FROM read_csv('/content/cab_ride_data.csv') WHERE tip IS NOT NULL AND fare > 0 )
结果解读:
- 相关系数
-0.016
(接近0) - 结论:行程时长与小费比例无显著相关性。
最后总结
- 方法论整合
- 使用 DuckDB 高效处理大规模数据集
- 结合 Python 完成卡方检验(分类变量)与皮尔逊相关(连续变量)
- 核心洞见
- 支付方式未显著改变小费行为模式
- 行程时长对小费比例的影响缺乏统计支持
- 扩展建议
可进一步探索:- 不同时间段的费率差异
- 小费金额的分布特性
- 多变量联合分析(如支付方式+时段)
通过结构化假设检验流程,DuckDB 为数据驱动决策提供了轻量级解决方案。