{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c86fa423",
   "metadata": {},
   "source": [
    "# 客户细分 — RFM + K-Means\n",
    "\n",
    "对应案例: [客户细分](/docs/case-studies/marketing/customer-segmentation-case/)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6795d131",
   "metadata": {},
   "source": [
    "## 1. 模拟 RFM 数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3d699481",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np, pandas as pd, matplotlib.pyplot as plt\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.cluster import KMeans\n",
    "np.random.seed(42)\n",
    "n=1000\n",
    "df=pd.DataFrame({\n",
    "    'recency':np.concatenate([np.random.exponential(5,150),np.random.exponential(30,400),np.random.exponential(60,250),np.random.exponential(10,200)]),\n",
    "    'frequency':np.concatenate([np.random.poisson(15,150),np.random.poisson(5,400),np.random.poisson(3,250),np.random.poisson(1,200)]),\n",
    "    'monetary':np.concatenate([np.random.lognormal(6,0.3,150),np.random.lognormal(4.5,0.5,400),np.random.lognormal(4,0.5,250),np.random.lognormal(3.5,0.5,200)])\n",
    "})\n",
    "df['recency']=df['recency'].clip(1,180).astype(int)\n",
    "df['frequency']=df['frequency'].clip(1,50).astype(int)\n",
    "df['monetary']=df['monetary'].clip(10).round(2)\n",
    "print(df.describe())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "05161ff8",
   "metadata": {},
   "source": [
    "## 2. K-Means 聚类"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "740427f1",
   "metadata": {},
   "outputs": [],
   "source": [
    "scaler=StandardScaler()\n",
    "rfm=scaler.fit_transform(df[['recency','frequency','monetary']])\n",
    "rfm[:,0]=-rfm[:,0]  # recency 越小越好\n",
    "km=KMeans(n_clusters=4,random_state=42,n_init=10)\n",
    "df['cluster']=km.fit_predict(rfm)\n",
    "print(df.groupby('cluster').agg(count=('recency','count'),avg_recency=('recency','mean'),avg_freq=('frequency','mean'),avg_monetary=('monetary','mean')).round(1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d436dec",
   "metadata": {},
   "source": [
    "## 3. 可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f7f6a47c",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.decomposition import PCA\n",
    "pca=PCA(2); rfm2d=pca.fit_transform(rfm)\n",
    "plt.figure(figsize=(10,8))\n",
    "for c in range(4):\n",
    "    m=df['cluster']==c\n",
    "    plt.scatter(rfm2d[m,0],rfm2d[m,1],label=f'Cluster {c}',alpha=0.6)\n",
    "plt.scatter(pca.transform(km.cluster_centers_)[:,0],pca.transform(km.cluster_centers_)[:,1],c='red',s=200,marker='X')\n",
    "plt.legend(); plt.title('Customer Segments'); plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "73f8082d",
   "metadata": {},
   "source": [
    "---\n",
    "*更多分析见 [案例文档](/docs/case-studies/marketing/customer-segmentation-case/)*"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.10.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
