🎓 毕业项目 — 端到端数据分析:数据→建模→部署

从零到一,完成一个真实的数据分析项目

📥 数据获取
🔍 EDA探索
🔧 特征工程
🤖 模型训练
📊 评估优化
🚀 部署上线

📖 项目概述:加州房价预测

本项目使用加州1990年人口普查数据,预测各街区的房屋中位数价格。这是一个经典的回归问题,涵盖数据分析全流程的7个步骤。

端到端数据分析Pipeline: ┌─────────────────────────────────────────────────────────────┐ │ 1. 数据获取 → sklearn.datasets / CSV / API / 数据库 │ │ 2. EDA探索 → 分布/相关性/异常值/缺失值 │ │ 3. 特征工程 → 衍生特征/编码/标准化/特征选择 │ │ 4. 模型训练 → 基线模型 → 高级模型 → 调参 │ │ 5. 评估优化 → RMSE/MAE/R² + 交叉验证 │ │ 6. 模型解释 → 特征重要性/SHAP/可视化 │ │ 7. 部署上线 → Streamlit / Flask / Docker │ └─────────────────────────────────────────────────────────────┘ 核心原则: ✅ 先简单后复杂 (基线模型优先) ✅ 先分析后建模 (EDA驱动决策) ✅ 先验证后部署 (交叉验证防过拟合) ✅ 先功能后优化 (可工作 > 完美)

📥 第1步:数据获取

from sklearn.datasets import fetch_california_housing
import pandas as pd

data = fetch_california_housing()
df = pd.DataFrame(data.data, columns=data.feature_names)
df['MedHouseVal'] = data.target

print(f"数据集大小: {df.shape}")  # (20640, 9)
print(f"特征: {list(data.feature_names)}")
# ['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms',
#  'Population', 'AveOccup', 'Latitude', 'Longitude']
print(df.describe().round(2))
特征含义范围单位
MedInc收入中位数0.5-15.0万美元
HouseAge房屋年龄中位数1-52
AveRooms平均房间数0.85-141.9
AveBedrms平均卧室数0.33-34.07
Population人口3-35682
AveOccup平均入住率0.69-1243人/户
Latitude纬度32.5-42.0
Longitude经度-124~-114
MedHouseVal房价中位数(目标)0.15-5.0万美元

🔍 第2步:EDA探索

# 缺失值检查
print(f"缺失值: {df.isnull().sum().sum()}")  # 0

# 目标变量统计
print(f"均值: {df['MedHouseVal'].mean():.3f}")   # 2.069
print(f"中位数: {df['MedHouseVal'].median():.3f}") # 1.797
print(f"标准差: {df['MedHouseVal'].std():.3f}")   # 1.154

# 与目标变量的相关性
corr_with_target = df.corr()['MedHouseVal'].drop('MedHouseVal').sort_values(ascending=False)
for feat, corr in corr_with_target.items():
    bar = '█' * int(abs(corr) * 30)
    print(f"  {feat:>12}: {corr:+.3f} {bar}")
    
# 关键发现:
# MedInc(+0.688) → 收入是最强预测因子!
# AveRooms(+0.152) → 房间数有正相关
# Latitude(-0.144) → 纬度越高房价越低(北加州较便宜)

🔧 第3步:特征工程

# 衍生特征(业务直觉驱动)
df['RoomsPerPerson'] = df['AveRooms'] / (df['Population'] / df['HouseAge'].clip(1))
df['BedroomRatio'] = df['AveBedrms'] / df['AveRooms']   # 卧室占比
df['PopDensity'] = df['Population'] / df['AveRooms'].clip(0.1)  # 人口密度

print(f"原始特征: 8个 → 增加后: 11个")
print(f"新增: RoomsPerPerson(人均房间), BedroomRatio(卧室占比), PopDensity(人口密度)")
特征工程是数据科学中投入产出比最高的环节。好的特征可以让简单模型超越复杂模型!

🤖 第4步:模型训练

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

X = df.drop('MedHouseVal', axis=1)
y = df['MedHouseVal']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

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

# 模型对比
models = {
    'LinearRegression': LinearRegression(),
    'Ridge': Ridge(alpha=1.0),
    'RandomForest': RandomForestRegressor(n_estimators=100, max_depth=10, random_state=42),
    'GradientBoosting': GradientBoostingRegressor(n_estimators=100, max_depth=5, learning_rate=0.1, random_state=42),
}

for name, model in models.items():
    model.fit(X_train_scaled, y_train)
    y_pred = model.predict(X_test_scaled)
    rmse = np.sqrt(mean_squared_error(y_test, y_pred))
    r2 = r2_score(y_test, y_pred)
    print(f"{name:>20}: RMSE={rmse:.4f}, R²={r2:.4f}")
模型RMSEMAE评价
LinearRegression0.72790.52590.5956基线
Ridge0.72790.52590.5956≈基线
RandomForest0.54610.36800.7724显著提升
GradientBoosting0.49140.32840.8157🏆最优

📊 第5步:评估优化

# 最优模型深入评估
best_model = models['GradientBoosting']

# 交叉验证
from sklearn.model_selection import cross_val_score
cv_scores = cross_val_score(best_model, scaler.transform(X), y, cv=5, scoring='r2')
print(f"5折CV R²: {cv_scores.mean():.4f} ± {cv_scores.std():.4f}")

# 特征重要性
feature_names = list(X.columns)
importances = best_model.feature_importances_
sorted_idx = np.argsort(importances)[::-1]
for i in sorted_idx[:8]:
    bar = '█' * int(importances[i] * 50)
    print(f"  {feature_names[i]:>15}: {importances[i]:.4f} {bar}")

# 预测示例
sample = X_test_scaled[:5]
preds = best_model.predict(sample)
for i in range(5):
    err = abs(preds[i] - y_test.iloc[i])
    print(f"  样本{i+1}: 实际={y_test.iloc[i]:.3f}, 预测={preds[i]:.3f}, 误差={err:.3f}")
GradientBoosting特征重要性: MedInc (收入中位数) ██████████████████████████████ 0.573 AveOccup (入住率) ██████ 0.130 Longitude (经度) █████ 0.105 Latitude (纬度) ████ 0.099 HouseAge (房龄) ██ 0.042 BedroomRatio (卧室占比) █ 0.017 AveRooms (平均房间) █ 0.014 AveBedrms (平均卧室) █ 0.009 → 收入是最强预测因子(57.3%重要性)! → 位置(经纬度)也很重要(20.4%) → 衍生特征BedroomRatio也进入了Top8

🚀 第6-7步:部署上线

# model_deploy.py — Streamlit部署
import streamlit as st
import numpy as np
import pickle

# 加载模型和scaler
with open('model.pkl', 'rb') as f:
    model = pickle.load(f)
with open('scaler.pkl', 'rb') as f:
    scaler = pickle.load(f)

st.title("🏠 加州房价预测")

# 输入特征
MedInc = st.slider("收入中位数(万$)", 0.5, 15.0, 3.5)
HouseAge = st.slider("房屋年龄(年)", 1, 52, 25)
AveRooms = st.slider("平均房间数", 1.0, 20.0, 5.0)
AveBedrms = st.slider("平均卧室数", 0.1, 5.0, 1.0)
Population = st.slider("人口", 3, 35000, 1500)
AveOccup = st.slider("平均入住率", 0.5, 10.0, 3.0)
Latitude = st.slider("纬度", 32.5, 42.0, 36.0)
Longitude = st.slider("经度", -124.0, -114.0, -119.0)

if st.button("🔮 预测房价"):
    features = np.array([[MedInc, HouseAge, AveRooms, AveBedrms,
                          Population, AveOccup, Latitude, Longitude,
                          AveRooms/(Population/max(HouseAge,1)),
                          AveBedrms/AveRooms,
                          Population/max(AveRooms,0.1)]])
    scaled = scaler.transform(features)
    pred = model.predict(scaled)[0]
    st.success(f"预测房价: ${pred*100000:,.0f}")

# 部署步骤:
# 1. 保存模型: pickle.dump(model, open('model.pkl','wb'))
# 2. 保存scaler: pickle.dump(scaler, open('scaler.pkl','wb'))
# 3. 运行: streamlit run app.py
# 4. 分享: 部署到Streamlit Cloud / Docker
部署架构: 开发环境 生产环境 ────────── ────────── Jupyter Notebook → Streamlit/Dash App 探索性代码 → 工程化代码 手动执行 → 自动化Pipeline 本地数据 → 数据库/API 部署选项: ├── Streamlit Cloud (免费, 最简单) ├── Docker + 云服务器 (灵活) ├── AWS SageMaker (企业级) ├── Hugging Face Spaces (AI应用) └── Vercel/Railway (全栈)

🎓 课程回顾:35课知识图谱

数据分析与可视化 · 35课知识体系: 第01-10课: Python基础 ├── Python数据基础 / Jupyter / NumPy ├── Pandas(基础/清洗/分组/合并) └── 可视化(Matplotlib/Seaborn/Plotly) 第11-15课: 统计学基础 ├── 描述统计 / 概率分布 / 相关分析 ├── 泰坦尼克实战 └── 回归基础 第16-25课: 统计推断 & 机器学习 ├── 概率论 / 假设检验 / A/B测试 ├── 线性回归 / 逻辑回归 ├── 决策树 / 随机森林 / XGBoost └── 聚类 / 降维 第26-35课: 高级主题 & 毕业项目 ├── 梯度提升 / 神经网络 / PyTorch ├── NLP / 时间序列 / 异常检测 ├── 推荐系统 / 地理空间 / 仪表盘 └── 🎓 毕业项目(端到端Pipeline)

📐 2024-2025 数据分析师技能图谱

🏆 成就解锁:端到端数据分析毕业项目!
加州房价预测完整Pipeline:20640条数据→8特征+3衍生→4模型对比→GradientBoosting最优(R²=0.8157, RMSE=0.4914)→5折CV R²=0.6744→收入是最强预测因子(57.3%)→Streamlit部署!恭喜毕业!🎓
Python验证通过 — 端到端Pipeline:数据获取(20640×9)→EDA(0缺失, MedInc相关+0.688)→特征工程(+3特征)→4模型对比(Linear→GBDT, R²从0.60→0.82)→最优GBDT(R²=0.8157, CV=0.6744)→特征重要性Top3: MedInc(57.3%), AveOccup(13.0%), Longitude(10.5%)→Streamlit部署模板完成!🎓

📝 毕业后进阶方向

  1. Kaggle竞赛:参加真实数据科学竞赛,与全球选手切磋
  2. 大模型应用:学习LLM Fine-tuning、RAG、Agent开发
  3. MLOps:MLflow/DVC/Kubeflow,模型生命周期管理
  4. 数据工程:Airflow/dbt/Spark,数据Pipeline构建
  5. 专业深耕:NLP/CV/时序/推荐,选择一个方向深入
  6. 开源贡献:参与开源项目,建立技术影响力
  7. 数据产品:从分析到产品,构建自己的数据应用
📚 进阶学习资源:
• Hands-On Machine Learning (Géron, 2022) — 最佳实战书
• Kaggle Learn: https://www.kaggle.com/learn — 免费课程
• Fast.ai: https://www.fast.ai/ — 深度学习实战
• Andrew Ng's Courses: https://www.deeplearning.ai/ — 系统学习
• 机器学习面试: https://huyenchip.com/machine-learning-interview/
• 本课程代码: 全部经过Python实机验证 ✅