rayyantaimoor1/Ecommerce-customer-intelligence
GitHub: rayyantaimoor1/Ecommerce-customer-intelligence
基于 RFM 特征工程与无监督聚类算法的电商客户细分与异常检测流水线,提供 REST API 和交互式仪表板服务。
Stars: 0 | Forks: 0
# 电商客户智能:客户细分与异常检测
**电商企业如何识别不同的客户画像,并标记异常交易模式,从而优化精准营销并降低财务风险?**
基于 **UCI/Kaggle Online Retail 数据集**构建 —— 包含一家英国在线礼品零售商的约 54 万条真实交易明细(2010 年 12 月 – 2011 年 12 月),汇总为每位客户的 RFM (Recency, Frequency, Monetary) 特征,外加购物篮金额、产品多样性、取消率和客户存续期。
1. **客户细分** — K-Means 和层次聚类将客户分组为营销画像(例如 *"Champions"*(冠军)、*"At-Risk"*(流失风险))。
2. **异常检测** — DBSCAN 标记行为不符合任何密集簇的客户,作为潜在的欺诈/风险信号。
提供两种服务方式:
- **FastAPI** REST 端点 (`/predict-cluster`) 用于系统间的调用
- **Streamlit** 仪表板用于交互式的人工探索
## 将此仓库发布到 GitHub
如果您是在本地从此文件夹开始(尚未成为 git 仓库):
```
cd ecommerce-customer-intelligence
git init
git add .
git commit -m "Initial commit: customer segmentation + anomaly detection pipeline"
git branch -M main
git remote add origin https://github.com/rayyantaimoor1/Ecommerce-customer-intelligence.git
git push -u origin main
```
首先在 GitHub 上创建一个空仓库(**github.com → New repository**,不要使用 README 或 .gitignore 初始化它 —— 本项目已经包含了这两者,并且预填充的远程仓库会与您的首次推送产生冲突)。
GitHub 需要使用 **Personal Access Token** 而不是您的账户密码来进行通过 HTTPS 的 `git push`。如果提示输入凭据且您的常规密码失败,请在 **GitHub → Settings → Developer settings → Personal access tokens → Tokens (classic)** 处生成一个具有 `repo` 权限的 token,并使用该 token 作为密码。
`data/raw/OnlineRetail.csv`(约 34MB)被直接提交而不是被 gitignore,因此全新的克隆(例如克隆到 Colab 中)可以立即运行,无需单独的上传步骤 —— 参见下方的 **数据集**。
**另外值得了解的是:** `models/` 中的已训练模型工件(包括 `clustering_pipeline.joblib`)也已提交。这意味着克隆后,您可以直接跳转运行 FastAPI/Streamlit 应用,而无需先重新运行 notebooks —— 这对于快速演示非常有用。只有在您想针对不同数据重新训练或自行调整聚类参数时,才需要重新运行 notebooks。
## 项目结构
```
ecommerce-customer-intelligence/
├── data/
│ ├── raw/ # OnlineRetail.csv (committed to git — see Dataset)
│ └── processed/ # cleaned transactions, RFM features, cluster assignments
├── notebooks/ # cleaning → RFM engineering → PCA/t-SNE → clustering → export
├── colab/ # Colab-specific runner notebook (see "Running on Google Colab")
├── app/ # FastAPI service
├── dashboard/ # Streamlit multi-page dashboard
├── models/ # saved joblib artifacts (scaler, models, pipeline bundle)
├── src/ # shared preprocessing/feature/clustering code
├── reports/figures/ # saved plots from the notebooks
├── run_dashboard.bat # Windows: double-click to launch the Streamlit dashboard
├── run_api.bat # Windows: double-click to launch the FastAPI server
└── requirements.txt
```
## 数据集
`data/raw/OnlineRetail.csv` 被直接提交到此仓库(约 34MB),因此全新的 `git clone` 可以立即运行,无需单独的下载步骤。
列:`InvoiceNo`、`StockCode`、`Description`、`Quantity`、`InvoiceDate`、`UnitPrice`、`CustomerID`、`Country` —— 与标准的 UCI Online Retail / Kaggle "Online Retail Data Set from UCI ML Repo" schema 匹配。
想使用真实数据集而不是内置的数据集吗?从 [Kaggle](https://www.kaggle.com/datasets/vijayuv/onlineretail) 或 [UCI ML Repository](https://archive.ics.uci.edu/dataset/352/online+retail) 下载它,并覆盖 `data/raw/OnlineRetail.csv` —— 列名相同,因此 pipeline 中的其他内容无需更改。
**本 pipeline 处理的已知现实数据混乱问题:** 约 25% 的行没有 CustomerID(已丢弃 —— 无法归因于客户),一小部分取消的订单(`InvoiceNo` 以 `C` 开头,保留并用作取消率特征而不是丢弃),以及少量非产品库存代码(邮费、折扣、手动调整 —— 已丢弃)。
## 设置
```
# 1. Clone 仓库
git clone https://github.com/rayyantaimoor1/Ecommerce-customer-intelligence.git
cd ecommerce-customer-intelligence
# 2. 创建并激活环境(conda 示例)
conda create -n ecomm-clustering python=3.11
conda activate ecomm-clustering
# 3. 安装依赖
pip install -r requirements.txt
```
数据集已包含在 `data/raw/OnlineRetail.csv` 中 —— 除非您想替换为真实的 Kaggle/UCI 文件,否则无需单独下载(参见上方的 **数据集**)。
## 运行项目
### 1. 运行 notebooks(按顺序)
```
jupyter notebook notebooks/
```
按顺序运行:
1. `01_eda.ipynb` — 加载、清洗、探索原始交易日志
2. `02_rfm_feature_engineering.ipynb` — 将交易汇总为每个客户一行
3. `03_pca_tsne.ipynb` — 缩放、对偏态特征进行对数转换、使用 PCA/t-SNE 进行可视化
4. `04_kmeans_hierarchical.ipynb` — Elbow + Silhouette 选择 K,拟合 K-Means,绘制树状图
5. `05_dbscan_anomaly.ipynb` — k-distance 图调整 `eps`,拟合 DBSCAN,检查异常
6. `06_model_export.ipynb` — 将 scaler + model + 画像标签打包到一个 joblib 文件中
每个 notebook 都会从 `data/processed/` 或 `models/` 读取上一个 notebook 的保存输出。最后一个 notebook 导出 `models/clustering_pipeline.joblib`,下方两个应用都依赖于它。
### 2. 运行 FastAPI 服务
```
cd app
uvicorn main:app --reload
```
打开 **http://127.0.0.1:8000/docs** 查看交互式 Swagger UI,或直接调用它:
```
curl -X POST http://127.0.0.1:8000/predict-cluster \
-H "Content-Type: application/json" \
-d '{
"recency": 12, "frequency": 8, "monetary": 650.0,
"avg_basket_value": 81.25, "avg_items_per_basket": 6.5,
"unique_products": 22, "cancellation_rate": 0.05,
"customer_lifespan_days": 210
}'
```
### 3. 运行 Streamlit 仪表板
在单独的终端中:
```
cd dashboard
streamlit run Home.py
```
在 **http://localhost:8501** 自动打开。页面:
- **Customer Segments** — K-Means 画像的交互式散点图
- **Anomaly Detection** — DBSCAN 标记的异常值,支持 CSV 导出
- **Predict New Customer** — 调用已训练 pipeline 的实时表单
### 4. 在 Windows 上一键启动(在 notebooks 至少运行一次后)
项目根目录下有两个 `.bat` 文件用于双击启动,前提是 `models/clustering_pipeline.joblib` 已存在(即您至少运行过一次 notebooks 后):
- **`run_dashboard.bat`** — 激活 `ecomm-clustering` conda 环境并启动 Streamlit 仪表板,在您的默认浏览器中打开 `http://localhost:8501`。
- **`run_api.bat`** — 同上,但在 `http://127.0.0.1:8000` 启动 FastAPI 服务器(Swagger 文档位于 `/docs`)。
两者都会先检查 conda 环境和已训练的模型是否存在,如果不存在,会打印出明确的错误信息及后续步骤,而不是静默失败。
要求 `ecomm-clustering` conda 环境已存在(参见上方的 **设置**),并且 `conda` 必须在您的系统 PATH 中 —— 如果双击打开后又立即关闭了窗口,请右键单击 `.bat` 文件 → **Edit** 查看完整错误,或者在 **Anaconda Prompt** 中运行它,而不是从文件资源管理器中双击。
## 在 Google Colab 上运行(通过 GitHub)
如果您完全不想设置本地 Python 环境,或者想分享一个实时的、可点击的仪表板链接而不是截图,Colab 是一个不错的选择。一旦此仓库位于 GitHub 上,Colab 就可以使用 `git clone` 直接拉取它 —— 无需手动上传 zip 压缩包。它仍然在两个方面与本地机器有所不同,值得注意:
Colab 每次会话都会为您提供一个全新的虚拟机(除非您挂载 Google Drive,否则什么都不会持久化),并且 Streamlit 需要通过隧道连接到公共 URL,因为 Colab 不直接暴露端口。
**步骤:**
1. 直接打开 **https://colab.research.google.com/github/rayyantaimoor1/Ecommerce-customer-intelligence/blob/main/colab/Ecommerce_Customer_Intelligence_Colab.ipynb** —— 这会直接从您的 GitHub 仓库打开 Colab notebook,完全无需下载/上传步骤。
或者:**colab.research.google.com → File → Open notebook → GitHub 标签页** → 粘贴您的仓库 URL → 选择 notebook。
2. 从上到下运行各个单元格(**Runtime → Run all**,或一次运行一个以跟随进度):
- **挂载 Google Drive** — 这样您训练好的模型和处理过的数据就能在会话之间持久存在,而不是在虚拟机重置时消失。
- **克隆仓库** — 直接从 GitHub 将项目(包括内置的数据集)拉取到 Colab 虚拟机 / 您挂载的 Drive 中。
- **安装依赖项** — FastAPI、Streamlit 以及 Colab 默认未包含的其他几个库。
- **(可选)上传真实数据集**(如果您想用完整的 Kaggle/UCI 文件替换内置的 `OnlineRetail.csv`)。
- **运行所有六个 notebooks** — 无人值守地执行整个 pipeline,并报告每个 notebook 的 OK/FAILED。
- **使用公共链接启动仪表板** — 在 Colab 虚拟机内启动 Streamlit,然后使用 `localtunnel` 将其暴露在公共 URL 上。打开该 URL,在出现提示时输入打印的 IP 作为 "Tunnel Password",仪表板就会在您的浏览器中加载。
3. 只要您希望仪表板链接保持活动状态,就让最终的隧道单元格一直运行 —— 停止它(或关闭标签页)将结束会话。
**更新了代码并推送到 GitHub?** 重新运行克隆单元格 —— 它会进行拉取(如果文件夹已存在则 `git pull`,否则全新克隆),这样 Colab 始终运行的是您最新推送的版本,而不是陈旧的副本。
Colab notebook 在底部包含了一个针对最常见问题(隧道尚未加载、会话断开等)的故障排除部分。
## 方法论总结
| 阶段 | 技术 | 目的 |
|---|---|---|
| 数据清洗 | 丢弃缺失的 CustomerID、非产品行 | 处理已知的现实数据质量问题 |
| 特征工程 | RFM + 购物篮金额、产品多样性、取消率、客户存续期 | 将约 54 万笔交易汇总为每个客户一个特征向量 |
| 数据预处理 | 对偏态列进行 log1p 转换,然后进行 StandardScaler | 零售消费/频率严重右偏;如果不进行此操作,少数批发账户将主导每一个基于距离的模型 |
| 可视化 | PCA(8→3 个主成分解释 90% 方差)、t-SNE | 在建模前确认存在可聚类的结构 |
| 客户细分 | K-Means(Elbow + Silhouette)、层次聚类(Dendrogram) | 寻找 K,分配营销画像 |
| 异常检测 | DBSCAN(k-distance 图用于调整 `eps`) | 将异常客户标记为噪音 |
| 服务 | FastAPI + Streamlit | 实时预测,同时支持 API 和 UI |
## 值得了解的关键建模经验(也值得在面试中提及)
直接在原始 RFM 值上运行 K-Means 会使 silhouette score 强烈倾向于 **K=2** —— 但这种划分仅仅是“少数极端批发规模的账户”与“其他所有人”之间的对比,这在统计上是干净的,但对营销没有实际指导意义。在缩放之前对偏态列(Frequency、Monetary、AvgBasketValue、AvgItemsPerBasket、UniqueProducts)进行对数转换可以解决此问题,并产生一个真正有用的 K=4,包含截然不同且可解释的画像。这是 RFM 聚类中一个真实且常见的陷阱 —— 有关前后对比,请参见 notebook 03。
## 注意事项 / 局限性
- 该数据集没有真实的欺诈标签 —— DBSCAN 的“噪音”点是异常行为的代理指标,而不是经过验证的欺诈模型。对于带标签的欺诈检测基准测试,请将此方法与诸如 Credit Card Fraud Detection(Kaggle, mlg-ulb)等数据集结合使用,并针对已知的欺诈案例评估 precision/recall。
- K-Means 是实际进行实时服务的模型,因为它天然支持对全新数据点进行预测(`.predict()`)。DBSCAN 和层次聚类不支持这种方式,因此它们仅用于离线/仪表板分析。
- FastAPI/Streamlit 应用期望的是每个客户预先聚合的 RFM 风格特征,而不是原始交易行 —— 从交易日志中计算这些特征是一项批处理操作(参见 notebook 02),而不是在每次 API 调用时执行的操作。
## 许可证
MIT —— 参见 `LICENSE`。
标签:Apex, AV绕过, FastAPI, Kubernetes, RFM模型, 客户细分, 异常检测, 机器学习, 电商数据分析, 逆向工具