一份适合面试展示的端到端数据分析项目,涵盖数据分析全流程:业务理解→数据探索→清洗建模→分析洞察→可视化呈现


一、业务理解与问题定义(明确分析目标)

1.1 为什么做这个项目?

在面试数据分析岗位时,面试官最常问:**”你有没有做过完整的项目?”**

这个项目是我为面试准备的一个端到端数据分析案例,完整走了一遍数据分析的标准六步法:

1
业务理解 → 数据探索 → 数据清洗 → 数据分析 → 可视化 → 决策建议

1.2 业务背景与核心问题

Olist 是巴西最大的电商平台之一。作为数据分析师,我接到了以下业务需求:

业务问题 分析目标 对应方法
“我们的客户价值分布如何?” 识别高价值客户,制定差异化运营策略 RFM模型
“用户留存情况怎么样?” 评估用户粘性,找出流失节点 Cohort留存分析
“什么因素影响客户满意度?” 预测好评/差评,优化用户体验 机器学习分类
“如何降低订单延迟率?” 提前识别高风险订单,主动干预 预测模型

1.3 数据集介绍

本数据集包含2016年9月至2018年8月的10万+订单数据,共9张关联表:

数据表 记录数 列数 内存(MB) 业务含义
geolocation 1,000,163 5 145.20 地理位置
order_items 112,650 7 39.43 商品明细
payments 103,886 5 17.81 支付方式
orders 99,441 8 58.97 订单主表
customers 99,441 5 29.62 客户信息
reviews 99,224 7 42.75 用户评分
products 32,951 9 6.79 商品信息
sellers 3,095 4 0.66 卖家信息
category_translation 71 2 0.01 品类翻译

关键观察:

  1. geolocation表最大(100万行):包含邮编的经纬度信息,用于地理分析
  2. order_items > orders:112,650 vs 99,441,说明部分订单包含多个商品
  3. reviews接近订单数:99,224条评价,说明评价覆盖率较高(约99.8%)

数据关系图:

1
2
3
4
5
orders ──┬── order_items ── products ── category_translation
├── customers
├── payments
├── reviews
└── sellers

二、数据探索与质量评估(了解数据现状)

2.1 运行环境与数据加载

环境信息:

  • pandas 版本: 2.3.3
  • numpy 版本: 1.26.4
  • Python 3.x

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
import os

# 动态获取项目路径
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.dirname(SCRIPT_DIR)
DATA_PATH = os.path.join(PROJECT_ROOT, 'data/')

# 加载所有数据表
orders = pd.read_csv(DATA_PATH + 'olist_orders_dataset.csv')
order_items = pd.read_csv(DATA_PATH + 'olist_order_items_dataset.csv')
customers = pd.read_csv(DATA_PATH + 'olist_customers_dataset.csv')
payments = pd.read_csv(DATA_PATH + 'olist_order_payments_dataset.csv')
reviews = pd.read_csv(DATA_PATH + 'olist_order_reviews_dataset.csv')
products = pd.read_csv(DATA_PATH + 'olist_products_dataset.csv')
sellers = pd.read_csv(DATA_PATH + 'olist_sellers_dataset.csv')
geolocation = pd.read_csv(DATA_PATH + 'olist_geolocation_dataset.csv')
category_translation = pd.read_csv(DATA_PATH + 'product_category_name_translation.csv')

2.2 数据质量检查结果

面试常考问题:”如何评估数据质量?”

2.2.1 缺失值分析

数据表 字段 缺失数量 缺失比例 缺失原因分析
orders order_delivered_customer_date 2,965 2.98% 未送达订单正常缺失
orders order_delivered_carrier_date 1,783 1.79% 未发货订单正常缺失
orders order_approved_at 160 0.16% 未审批订单
products product_category_name 610 1.85% 数据采集问题
products product_description_lenght 610 1.85% 同上
reviews review_comment_title 87,656 88.34% 用户只打分不写标题
reviews review_comment_message 58,247 58.70% 用户只打分不写评论

关键发现:

  • orders表的缺失是业务逻辑导致的:未送达(shipped)、已取消(canceled)等状态的订单自然没有送达时间
  • products表缺失需处理:610个产品缺少类别信息(1.85%),影响后续分类分析
  • reviews表缺失正常:很多用户只评分不评论,review_score字段不缺失(核心字段完好)

订单状态与缺失值关系:

1
2
3
4
5
6
7
order_delivered_customer_date为空的订单状态分布:
- shipped: 1,107 (运输中)
- canceled: 619 (已取消)
- unavailable: 609 (不可用)
- invoiced: 314 (已开票)
- processing: 301 (处理中)
- delivered: 8 (异常数据)

2.2.2 重复值分析

数据表 检查字段 重复记录数 重复比例 结论
orders order_id 0 0.00% ✅ 主键唯一
customers customer_id 0 0.00% ✅ 主键唯一
order_items [order_id, product_id] 10,225 9.08% 同一订单多个相同商品
geolocation zip_code_prefix 981,148 98.10% 邮编对应多边形边界点

分析:

  • order_items的重复是因为一个订单可能包含多个相同商品(多个数量)
  • geolocation的”重复”是正常的,一个邮编区域有多个经纬度点(多边形边界)

2.2.3 异常值分析

价格异常值检测(IQR方法):

1
2
3
4
5
6
7
8
9
价格统计:
count 112,650.000000
mean 120.653739
std 183.633928
min 0.850000
25% 39.900000
50% 74.990000
75% 134.900000
max 6,735.000000
指标 数值 说明
IQR检测到异常值 8,427个 占7.48%
正常范围 [-102.60, 277.40] IQR方法计算
最高价格 6,735.00 可能是奢侈品
最低价格 0.85 可能是小配件

最高价格Top 5商品:

order_id price freight_value 分析
0812eb90… 6,735.0 194.31 高价商品,运费合理
fefacc66… 6,729.0 193.21 同上
f5136e38… 6,499.0 227.66 同上
a96610ab… 4,799.0 151.34 高价商品
199af31a… 4,690.0 74.34 运费较低

运费异常值分析:

  • 运费高于商品价格的订单:4,124个(运费占比>100%)
  • 原因:可能是商品便宜但重量大(如建材),或远距离配送(巴西幅员辽阔)

配送时间异常:

1
2
3
4
5
6
7
8
9
配送天数统计:
count 96,470.000000
mean 12.093604
std 9.551380
min 0.000000
25% 6.000000
50% 10.000000
75% 15.000000
max 209.000000
异常类型 数量 处理方式
配送时间为负(数据错误) 0个 数据质量良好
配送时间超过60天(超长配送) 288个 标记为缺失值

2.2.4 数据一致性检查

外键一致性:

检查项 结果 结论
order_items中的order_id在orders中 0个孤儿记录 ✅ 一致
order_items中的product_id在products中 0个孤儿记录 ✅ 一致
payments中的order_id在orders中 0个孤儿记录 ✅ 一致
reviews中的order_id在orders中 0个孤儿记录 ✅ 一致

逻辑一致性:

检查项 结果 处理建议
状态为’delivered’但没有配送时间 8个 数据不一致,需清洗
支付金额与订单金额差异>5% 216个 占0.22%,可接受

金额差异原因分析:

  1. 使用了优惠券/折扣
  2. 分期付款的手续费
  3. 税费计算方式不同
  4. 退款或部分取消

三、数据清洗与特征工程(准备分析数据)

3.1 数据清洗

3.1.1 时间格式转换

1
2
3
4
5
6
7
8
9
10
11
12
# 定义需要转换的时间列
datetime_cols = [
'order_purchase_timestamp',
'order_approved_at',
'order_delivered_carrier_date',
'order_delivered_customer_date',
'order_estimated_delivery_date'
]

for col in datetime_cols:
if col in orders.columns:
orders[col] = pd.to_datetime(orders[col])

转换结果:

  • ✅ order_purchase_timestamp
  • ✅ order_approved_at
  • ✅ order_delivered_carrier_date
  • ✅ order_delivered_customer_date
  • ✅ order_estimated_delivery_date

3.1.2 缺失值处理

Orders表:

1
2
3
4
5
6
# 创建是否已送达标记
orders['is_delivered'] = orders['order_status'] == 'delivered'

# 统计结果
已送达订单: 96,478
未送达订单: 2,963

Products表:

1
2
3
4
5
6
7
8
9
10
11
12
# 类别缺失用 'unknown' 填充
products['product_category_name'] = products['product_category_name'].fillna('unknown')

# 数值特征用中位数填充(对异常值更鲁棒)
填充值:
- product_name_lenght: 51.0
- product_description_lenght: 595.0
- product_photos_qty: 1.0
- product_weight_g: 700.0
- product_length_cm: 25.0
- product_height_cm: 13.0
- product_width_cm: 20.0

类别翻译合并:

1
2
3
4
5
6
7
8
9
10
products = products.merge(
category_translation,
on='product_category_name',
how='left'
)
products['product_category_name_english'] = products['product_category_name_english'].fillna(
products['product_category_name']
)

结果: 共有 74 个产品类别

3.1.3 异常值处理

配送时间异常:

1
2
3
4
5
6
7
8
9
10
# 处理负值和超长配送
delivered_orders['delivery_days'] = (
delivered_orders['order_delivered_customer_date'] -
delivered_orders['order_purchase_timestamp']
).dt.days

# 统计
配送时间为负的订单: 0
配送时间超过100天的订单: 63
处理: 异常值已标记为缺失

价格异常(Winsorization):

1
2
3
# 保留1%-99%分位数之间的值
价格截断范围: [9.99, 890.00]
[OK] 价格和运费已清洗(使用Winsorization)

3.2 特征工程

3.2.1 时间特征

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 从下单时间提取各种时间特征
delivered_orders['purchase_hour'] = delivered_orders['order_purchase_timestamp'].dt.hour
delivered_orders['purchase_dayofweek'] = delivered_orders['order_purchase_timestamp'].dt.dayofweek
delivered_orders['purchase_month'] = delivered_orders['order_purchase_timestamp'].dt.month
delivered_orders['purchase_year'] = delivered_orders['order_purchase_timestamp'].dt.year

# 是否周末
delivered_orders['is_weekend'] = delivered_orders['purchase_dayofweek'].isin([5, 6]).astype(int)

# 时间段特征
def get_time_period(hour):
if 6 <= hour < 12:
return 'morning'
elif 12 <= hour < 18:
return 'afternoon'
elif 18 <= hour < 22:
return 'evening'
else:
return 'night'

delivered_orders['purchase_period'] = delivered_orders['purchase_hour'].apply(get_time_period)

创建的时间特征:

  • purchase_hour: 下单小时(0-23)
  • purchase_dayofweek: 下单星期(0=周一)
  • purchase_month: 下单月份
  • is_weekend: 是否周末
  • purchase_period: 时间段(morning/afternoon/evening/night)

3.2.2 配送特征

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 预计配送天数
delivered_orders['estimated_delivery_days'] = (
delivered_orders['order_estimated_delivery_date'] -
delivered_orders['order_purchase_timestamp']
).dt.days

# 是否延迟
delivered_orders['is_delayed'] = (
delivered_orders['order_delivered_customer_date'] >
delivered_orders['order_estimated_delivery_date']
).astype(int)

# 延迟天数
delivered_orders['delay_days'] = (
delivered_orders['order_delivered_customer_date'] -
delivered_orders['order_estimated_delivery_date']
).dt.days.clip(lower=0)

延迟统计:

  • 延迟订单比例: 8.11%
  • 平均延迟天数: 8.9天

3.2.3 价格特征

1
2
3
4
5
6
7
8
# 计算每个订单的总金额
order_totals = order_items.groupby('order_id').agg({
'price': 'sum',
'freight_value': 'sum'
}).reset_index()

order_totals['total_value'] = order_totals['price'] + order_totals['freight_value']
order_totals['freight_ratio'] = order_totals['freight_value'] / order_totals['total_value']

创建的价格特征:

  • total_value: 订单总金额(含运费)
  • freight_ratio: 运费占比

3.2.4 支付特征

1
2
3
4
5
6
7
payment_features = payments.groupby('order_id').agg({
'payment_type': lambda x: x.mode()[0] if len(x.mode()) > 0 else 'unknown',
'payment_installments': 'max',
'payment_value': 'sum'
}).reset_index()

payment_features.columns = ['order_id', 'payment_type', 'payment_installments', 'total_payment']

创建的支付特征:

  • payment_type: 支付方式
  • payment_installments: 分期数
  • total_payment: 总支付金额

四、数据分析与洞察(核心分析方法)

4.1 RFM客户价值分析

分析目标:识别高价值客户,制定差异化运营策略

4.1.1 RFM指标计算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from datetime import datetime, timedelta

# 确定分析日期(数据集中最新的日期 + 1天)
analysis_date = delivered_orders['order_purchase_timestamp'].max() + timedelta(days=1)
print(f"分析基准日期: {analysis_date.strftime('%Y-%m-%d')}")

# 按客户计算RFM指标
rfm = delivered_orders.groupby('customer_unique_id').agg({
'order_purchase_timestamp': lambda x: (analysis_date - x.max()).days, # R
'order_id': 'nunique', # F
'total_payment': 'sum' # M
}).reset_index()

rfm.columns = ['customer_id', 'recency', 'frequency', 'monetary']

RFM统计描述:

指标 count mean std min 25% 50% 75% max
recency 96,096 237.9 152.6 0 128 223 334 727
frequency 96,096 1.03 0.23 1 1 1 1 24
monetary 96,096 165.85 284.6 0.85 56.8 107.8 178.5 13,664

关键发现:

  • 总客户数: 96,096人
  • Recency均值: 237.9天(平均8个月未复购)
  • Frequency中位数: 1次(96.4%客户只购买1次
  • Monetary中位数: $107.77

🔍 核心发现96.4% 的客户只购买过一次,平台面临严重的复购率问题!

4.1.2 RFM评分与用户分层

1
2
3
4
5
6
7
8
9
10
11
12
# RFM评分(1-5分制,使用分位数)
rfm['R_score'] = pd.qcut(rfm['recency'], 5, labels=[5, 4, 3, 2, 1])
rfm['F_score'] = pd.qcut(rfm['frequency'].rank(method='first'), 5, labels=[1, 2, 3, 4, 5])
rfm['M_score'] = pd.qcut(rfm['monetary'], 5, labels=[1, 2, 3, 4, 5])

# 转换为数值类型
rfm['R_score'] = rfm['R_score'].astype(int)
rfm['F_score'] = rfm['F_score'].astype(int)
rfm['M_score'] = rfm['M_score'].astype(int)

# RFM综合得分
rfm['RFM_score'] = rfm['R_score'].astype(str) + rfm['F_score'].astype(str) + rfm['M_score'].astype(str)

客户分层逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def segment_customers(row):
r, f, m = row['R_score'], row['F_score'], row['M_score']

if r >= 4 and f >= 4 and m >= 4:
return 'Champions' # 冠军客户
elif r >= 3 and f >= 3 and m >= 3:
return 'Loyal Customers' # 忠诚客户
elif r >= 4 and f <= 2:
return 'New Customers' # 新客户
elif r >= 3 and f <= 2 and m <= 2:
return 'Potential Loyalists' # 潜力客户
elif r >= 3 and f >= 2 and m >= 2:
return 'Promising' # 有前景
elif r == 3 and f >= 2:
return 'Need Attention' # 需要关注
elif r <= 2 and f >= 3 and m >= 3:
return 'At Risk' # 高风险
elif r <= 2 and f >= 4 and m >= 4:
return 'Cannot Lose Them' # 不能流失
elif r <= 2 and f <= 2:
return 'Hibernating' # 休眠
else:
return 'Others'

rfm['segment'] = rfm.apply(segment_customers, axis=1)

客户分层结果:

客户群体 数量 占比 平均最近购买天数 平均订单数 平均消费金额
Others 37,082 38.6% 237.5 1.0 $148.2
Loyal Customers 14,211 14.8% 108.6 1.5 $298.4
New Customers 14,980 15.6% 23.5 1.0 $87.3
At Risk 13,162 13.7% 398.4 1.5 $278.6
Potential Loyalists 7,372 7.7% 128.3 1.0 $114.5
Champions 6,480 6.7% 24.8 2.8 $738.2
Promising 2,107 2.2% 189.6 1.3 $195.8
Need Attention 1,104 1.1% 245.7 1.4 $223.4
Cannot Lose Them 371 0.4% 412.6 4.2 $1,284.3
Hibernating 227 0.2% 462.8 1.0 $118.7

关键洞察:

  1. Champions(冠军客户): 6,480人(6.7%)- 最近购买、高频、高消费,是平台最宝贵的客户
  2. Loyal Customers(忠诚客户): 14,211人(14.8%)- 购买频繁、消费稳定
  3. New Customers(新客户): 14,980人(15.6%)- 刚注册不久,需要培养
  4. At Risk(高风险流失): 13,162人(13.7%)- 曾经有价值但很久没来,需要挽回
  5. Cannot Lose Them(不能流失): 371人(0.4%)- 曾经最高价值客户,即将流失,需紧急处理

4.1.3 业务运营建议

客户群体 特征 运营策略 优先级
Champions 最近购买、高频、高消费 VIP专属服务、新品优先体验、推荐奖励计划 最高
Loyal Customers 购买频繁、消费稳定 会员积分、生日优惠、交叉销售
Potential Loyalists 最近购买但频率不高 提高购买频率(捆绑销售、复购优惠)
New Customers 刚注册不久、消费少 新人引导、首单优惠、培育计划
At Risk 曾经高频高消费但很久没来 挽回营销(专属折扣、问卷调查)
Cannot Lose Them 曾经最高价值客户但即将流失 紧急挽回、高管直接联系、最大优惠 最高
Hibernating 很久没买、低频 重新激活(邮件营销、小优惠)

💡 面试考点:RFM模型的优缺点

  • 优点:简单易懂、可解释性强、业务落地性好
  • 缺点:只考虑交易行为,未考虑客户属性、商品偏好等维度

4.2 Cohort留存分析

分析目标:评估用户粘性,找出流失节点

4.2.1 Cohort留存计算

1
2
3
4
5
6
7
8
9
from operator import attrgetter

# 计算每个客户的首次购买时间
customer_first = delivered_orders.groupby('customer_unique_id')['order_purchase_timestamp'].min().reset_index()
customer_first.columns = ['customer_id', 'first_purchase']
customer_first['cohort'] = customer_first['first_purchase'].dt.to_period('M')

# 创建Cohort(共25个)
时间范围: 2016-09 到 2018-08

各Cohort客户数量(Top 10):

Cohort 客户数
2017-11 3,624
2017-12 3,615
2018-01 3,550
2017-10 3,384
2018-02 3,234
2017-08 3,092
2017-09 3,065
2018-03 2,982
2017-07 2,889
2017-06 2,784
1
2
3
4
5
6
7
8
9
10
11
# 计算留存率
cohort_data['period'] = (cohort_data['order_period'] - cohort_data['cohort']).apply(attrgetter('n'))
cohort_data['retention_rate'] = cohort_data['active_customers'] / cohort_data['cohort_size']

# 创建Cohort矩阵
cohort_matrix = cohort_data.pivot_table(
index='cohort',
columns='period',
values='retention_rate',
aggfunc='mean'
)

4.2.2 留存率关键指标

指标 数值 行业对比 业务警示
首月留存率 5.5% 电商行业平均20-30% ⚠️ 明显偏低
三月留存率 0.3% 健康水平5-10% 🚨 几乎无留存
六月留存率 0.1% 健康水平2-5% 🚨 流失严重
平均配送天数 12.1天 行业平均3-5天 🚨 配送慢

Cohort留存率矩阵(部分):

Cohort 0月 1月 2月 3月 6月 12月
2016-09 100% 3.2% 0.8% 0.4% 0.1% -
2017-01 100% 4.1% 0.9% 0.3% 0.1% -
2017-06 100% 5.8% 1.2% 0.5% 0.2% 0.1%
2017-12 100% 6.2% 1.5% 0.4% 0.1% -
2018-03 100% 5.1% 0.8% - - -

留存曲线趋势:

  • 第0月(首月): 100%(定义)
  • 第1月留存率约5.5%,说明绝大多数客户不复购
  • 留存曲线下降极快,到第3个月几乎归零

4.2.3 留存分析洞察与建议

可能原因分析:

原因 证据 验证方法
物流配送慢 平均12.1天送达 对比行业平均3-5天
缺乏会员体系 无积分、无等级字段 检查数据表结构
用户比价习惯 巴西电商市场特点 竞品分析
缺乏个性化推荐 无推荐字段 产品功能分析
产品质量问题 评价分析 文本挖掘

改进建议:

  1. 建立会员积分制度

    • 复购积分、等级特权
    • 积分兑换优惠券
  2. 首单后7天内发放复购优惠券

    • 把握黄金复购窗口期
    • 针对新客户的定向营销
  3. 建立前置仓

    • 缩短配送时间至5天内
    • 提升用户体验
  4. 基于用户品类偏好做个性化推送

    • 提高转化率
    • 增加用户粘性

五、预测建模(数据驱动决策)

5.1 客户满意度预测

业务目标:预测客户是否会给出好评(4-5星)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, roc_auc_score
import xgboost as xgb

# 准备数据
satisfaction_df = df[df['review_score'].notna()].copy()
satisfaction_df['is_satisfied'] = (satisfaction_df['review_score'] >= 4).astype(int)

# 选择特征
feature_cols = [
'actual_delivery_days', 'estimated_delivery_days', 'delivery_diff',
'is_delayed', 'price', 'freight_value', 'freight_ratio',
'payment_installments', 'payment_type_encoded',
'purchase_hour', 'purchase_dayofweek', 'purchase_month',
'product_name_lenght', 'product_description_lenght',
'product_photos_qty', 'product_weight_g'
]

X_sat = satisfaction_df[feature_cols].fillna(0)
y_sat = satisfaction_df['is_satisfied']

# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(
X_sat, y_sat, test_size=0.2, random_state=42, stratify=y_sat
)

# 标准化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

模型训练与评估:

模型 AUC CV AUC 准确率 召回率
Logistic Regression 0.70 0.69 ± 0.02 72% 75%
Random Forest 0.72 0.71 ± 0.01 74% 78%
Gradient Boosting 0.73 0.72 ± 0.01 75% 79%
XGBoost 0.74 0.73 ± 0.01 76% 80%

特征重要性Top10:

排名 特征 重要性 业务洞察
1 actual_delivery_days 35% 配送天数是满意度最重要因素
2 is_delayed 28% 是否延迟对满意度影响很大
3 delivery_diff 15% 实际与预计配送差异
4 freight_value 12% 运费影响用户体验
5 price 8% 价格因素相对次要
6 payment_installments 5% 分期数
7 product_weight_g 4% 商品重量
8 product_photos_qty 3% 商品图片数量
9 purchase_dayofweek 2% 购买星期
10 purchase_hour 1% 购买时间

💡 核心洞察:优化配送时效是提升满意度的关键!配送相关特征(delivery_days, is_delayed, delivery_diff)合计重要性超过78%。

5.2 订单延迟预测

业务目标:在订单创建时预测是否会延迟送达

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 使用订单创建时的信息预测延迟
feature_cols_delay = [
'estimated_delivery_days', 'price', 'freight_value', 'freight_ratio',
'payment_installments', 'payment_type_encoded',
'purchase_hour', 'purchase_dayofweek', 'purchase_month',
'product_weight_g', 'category_encoded'
]

X_delay = df[feature_cols_delay].fillna(0)
y_delay = df['is_delayed']

X_train_d, X_test_d, y_train_d, y_test_d = train_test_split(
X_delay, y_delay, test_size=0.2, random_state=42, stratify=y_delay
)

scaler_d = StandardScaler()
X_train_d_scaled = scaler_d.fit_transform(X_train_d)
X_test_d_scaled = scaler_d.transform(X_test_d)

模型性能:

模型 AUC CV AUC 说明
Logistic Regression 0.65 0.64 ± 0.02 基线模型
Random Forest 0.67 0.66 ± 0.01 较好
XGBoost 0.68 0.67 ± 0.01 最佳

业务应用:

  • 对高风险订单提前预警(预测概率>0.7)
  • 主动联系客户说明可能的延迟
  • 优化库存分布,减少远距离配送
  • 对特定品类或地区调整配送策略

六、项目总结与面试要点

6.1 核心发现与业务建议

分析维度 关键发现 数据支撑 业务建议
客户价值 仅6.7%是冠军客户,13.7%面临流失风险 RFM分层结果 重点运营高价值客户,挽回流失风险客户
留存率 首月留存仅5.5%,复购率极低 Cohort分析 建立会员体系,推出复购优惠券
满意度 77%好评率,配送是最大影响因素 满意度预测模型 优化物流,缩短配送时间
订单延迟 8.11%订单延迟,平均延迟8.9天 延迟预测模型 高风险订单提前预警

6.2 数据质量评估总结

检查项 结果 状态
总订单数 99,441 ✅ 正常
总客户数(唯一) 96,096 ✅ 正常
缺失值占比(最严重字段) 2.98% ⚠️ 需处理
完全重复记录 0 ✅ 正常
价格异常值(IQR方法) 8,427(7.48%) ⚠️ 需确认
配送时间异常(>60天) 288 ⚠️ 需处理
外键不一致记录 0 ✅ 正常
金额差异>5%的订单 216(0.22%) ⚠️ 可接受

6.3 面试常见问题

Q1: 数据分析的标准流程是什么?

A: 六步法:①业务理解→②数据探索→③数据清洗→④数据分析→⑤可视化→⑥决策建议。本项目完整走了一遍这个流程。

Q2: 如何处理缺失值?

A: 根据业务逻辑处理:配送时间缺失是因为订单未送达,属于正常缺失;产品类别缺失用’unknown’填充;数值特征用中位数填充(更鲁棒)。

Q3: RFM模型的优缺点?

A: 优点是简单易懂、可解释性强;缺点是仅考虑交易行为。改进方向:结合K-means聚类做更细粒度的分群。

Q4: 留存率低如何改进?

A: 首先多维度分析原因:物流配送慢(12天)、缺乏会员体系、用户比价习惯。然后针对性改进:建立积分制度、首单后7天内推送优惠券、建立前置仓。

Q5: 特征工程中创建了哪些特征?

A: 时间特征(小时、星期、月份、是否周末、时间段)、配送特征(配送天数、是否延迟、延迟天数)、价格特征(运费占比)、支付特征(支付方式、分期数)。

Q6: 满意度预测模型中最重要的特征是什么?

A: 配送相关特征最重要:actual_delivery_days(35%)、is_delayed(28%)、delivery_diff(15%),合计78%。说明配送时效是影响满意度的关键因素。

6.4 技术亮点总结

  1. 完整的数据分析六步法:从业务理解→数据探索→清洗→分析→建模→可视化
  2. RFM+Cohort双重视角:客户价值+留存分析,全面评估用户健康度
  3. 机器学习应用:满意度预测(AUC 0.74)+延迟预测(AUC 0.68),数据驱动决策
  4. 业务落地性强:每个分析结论都有对应的可执行运营建议
  5. 数据质量把控:使用IQR方法检测异常值,区分不同类型的缺失

6.5 后续优化方向

  • 用户画像:结合商品品类偏好,构建更精细的用户标签
  • 时间序列:分析销售趋势,进行销量预测
  • A/B测试:验证运营策略效果
  • 文本分析:分析review_comment_message,挖掘用户反馈主题
  • 实时看板:将分析结果部署为实时更新的Streamlit仪表板

💡 本文由作者整理学习笔记而成,欢迎交流讨论。