🧠 算法实战教程
← 返回导航页

中高级算法实战教程

从数学原理到 Python 实现,从业务场景到闭环落地
覆盖树模型、概率模型、集成学习、深度学习、时序预测、图像识别等 14 个核心算法,每个算法均配有原理详解、完整代码、真实案例和闭环解决方案
14
核心算法
4
算法大类
14
实战案例
全量
Python 代码
🌲 树模型 📊 集成学习 🎯 概率与统计 🤖 深度学习与时序
🌲 第一大类:树模型决策树 · 随机森林 · XGBoost
🌳1. 决策树 (Decision Tree)Classification & Regression Tree核心算法

📖 核心原理

决策树是一种基于树结构的监督学习算法,通过递归地选择最优特征对数据进行分割,构建出一棵可解释的决策路径。其核心思想是:每次分裂选择能让子节点"最纯"的特征和切分点

🔑 三个关键概念:
① 信息增益(ID3算法):选择使信息增益最大的特征进行分裂。信息增益 = 父节点熵 - 加权子节点熵。
② 信息增益率(C4.5算法):解决ID3偏向取值多的特征的问题,用增益除以特征自身的信息量。
③ 基尼系数(CART算法):Gini = 1 - Σpᵢ²,值越小表示节点越纯。CART是二分树,分类和回归都适用。
熵的计算: H(D) = -Σ pᵢ · log₂(pᵢ)     信息增益: Gain(D, A) = H(D) - Σ(|Dᵥ|/|D|) · H(Dᵥ)     基尼系数: Gini(D) = 1 - Σ pᵢ²

树生长过程:从根节点开始 → 遍历所有特征和切分点 → 计算分裂指标 → 选择最优切分 → 递归生长 → 达到停止条件(最大深度/最小样本数/纯度阈值)→ 剪枝防止过拟合。

优点:可解释性强,可视化直观;无需特征归一化;能处理缺失值;自动特征选择
⚠️缺点:容易过拟合;对噪声敏感;不稳定(数据微小变化可能导致完全不同的树);偏向多值特征
🐍 Python 实现(scikit-learn)
# ========== 决策树分类 ==========
from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor, plot_tree
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import accuracy_score, classification_report
import matplotlib.pyplot as plt

# 1. 数据准备
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 2. 基础模型训练
dt = DecisionTreeClassifier(
    criterion='gini',      # 分裂标准:gini / entropy
    max_depth=5,            # 最大深度(核心防过拟合参数)
    min_samples_split=10,   # 内部节点最少样本数
    min_samples_leaf=5,     # 叶节点最少样本数
    max_features='sqrt',    # 每次分裂考虑的特征数
    random_state=42
)
dt.fit(X_train, y_train)

# 3. 评估
y_pred = dt.predict(X_test)
print(f'准确率: {accuracy_score(y_test, y_pred):.4f}')
print(classification_report(y_test, y_pred))

# 4. 特征重要性
importances = dt.feature_importances_
for name, imp in zip(feature_names, importances):
    print(f'{name}: {imp:.4f}')

# 5. 可视化决策树
plt.figure(figsize=(20, 10))
plot_tree(dt, feature_names=feature_names, class_names=class_names, 
          filled=True, rounded=True, fontsize=10)
plt.show()

# 6. 超参数调优(防止过拟合)
param_grid = {
    'max_depth': [3, 5, 7, 10, None],
    'min_samples_split': [2, 5, 10, 20],
    'min_samples_leaf': [1, 3, 5, 10],
    'criterion': ['gini', 'entropy']
}
grid = GridSearchCV(DecisionTreeClassifier(random_state=42), 
                    param_grid, cv=5, scoring='accuracy')
grid.fit(X_train, y_train)
print(f'最优参数: {grid.best_params_}')
print(f'最优CV分数: {grid.best_score_:.4f}')

# ========== 决策树回归 ==========
dt_reg = DecisionTreeRegressor(max_depth=5, min_samples_leaf=10, random_state=42)
dt_reg.fit(X_train, y_train)
print(f'回归 R²: {dt_reg.score(X_test, y_test):.4f}')

🎯 应用场景

🏦
信用评分/风控
贷款审批规则引擎,可解释性强是核心优势
👤
用户分层
根据行为特征自动生成用户分群规则
🏥
医疗诊断
基于症状和检验结果的辅助诊断系统
📊
业务规则发现
从历史数据中挖掘"什么情况下用户会流失"等规则

💼 实战案例:酒店客户流失预警规则引擎

背景:某OTA平台需要识别高流失风险酒店客户,并生成可解释的预警规则给运营团队执行。

特征构建
近30天登录天数、订单数、核销率、最近下单距今天数、优惠券使用率、浏览-下单转化率
训练决策树
max_depth=4限制树深度,min_samples_leaf=100确保规则稳定
规则提取
从决策树路径中提取"IF-THEN"规则,共8条核心规则
运营落地
将规则转化为自动化标签+触达策略
📊 业务效果:提取的规则可解释性100%(运营团队可直接理解);精准识别出32%的高风险用户(覆盖了76%的真实流失);规则引擎上线后,流失率从12.3%降至8.7%(-3.6pp),挽回GMV预估增长8%。
🌲2. 随机森林 (Random Forest)Bagging + 特征随机核心算法

📖 核心原理

随机森林是 Bagging(Bootstrap Aggregating)的经典代表。它通过两个随机性来降低方差和过拟合:① 样本随机:每棵树用 Bootstrap 抽样(有放回)从原始数据中抽取训练集;② 特征随机:每次分裂时只从随机选择的一部分特征中找最优切分。

🔑 为什么有效?
降低方差:多棵树的平均减少了单棵决策树的高方差问题
降低相关性:特征随机性让每棵树长得不同,降低了树之间的相关性(相关性越低,集成效果越好)
OOB误差:每棵树约有36.8%的样本未被抽中(Out-Of-Bag),可直接用作验证集,无需额外划分
泛化误差公式:泛化误差 ≤ ρ · σ²(ρ=树间相关性,σ²=单棵树方差)→ 降低ρ和σ都能提升性能
🐍 Python 实现
from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor
from sklearn.model_selection import cross_val_score
import numpy as np

# ========== 随机森林分类 ==========
rf = RandomForestClassifier(
    n_estimators=100,        # 树的数量(越大越稳定,但边际收益递减)
    max_depth=10,            # 树的最大深度
    min_samples_split=5,     # 内部节点最小样本数
    min_samples_leaf=2,      # 叶节点最小样本数
    max_features='sqrt',     # 每次分裂考虑的特征数(分类默认sqrt,回归默认所有)
    bootstrap=True,          # 是否使用Bootstrap抽样
    oob_score=True,          # 是否计算OOB评分
    n_jobs=-1,               # 并行计算
    random_state=42
)
rf.fit(X_train, y_train)

# OOB评分(无需验证集)
print(f'OOB Score: {rf.oob_score_:.4f}')

# 特征重要性
importances = rf.feature_importances_
indices = np.argsort(importances)[::-1]
for i in indices[:10]:
    print(f'{feature_names[i]}: {importances[i]:.4f}')

# ========== 关键参数调优 ==========
from sklearn.model_selection import RandomizedSearchCV

param_dist = {
    'n_estimators': [50, 100, 200, 300],
    'max_depth': [5, 10, 15, 20, None],
    'min_samples_split': [2, 5, 10],
    'min_samples_leaf': [1, 2, 4],
    'max_features': ['sqrt', 'log2', None]
}
random_search = RandomizedSearchCV(
    RandomForestClassifier(random_state=42),
    param_dist, n_iter=30, cv=5, scoring='roc_auc', n_jobs=-1
)
random_search.fit(X_train, y_train)
print(f'最优参数: {random_search.best_params_}')

# ========== 学习曲线(判断是否需要更多树)==========
train_scores, test_scores = [], []
n_estimators_range = range(10, 200, 10)
for n in n_estimators_range:
    rf_temp = RandomForestClassifier(n_estimators=n, random_state=42)
    rf_temp.fit(X_train, y_train)
    train_scores.append(rf_temp.score(X_train, y_train))
    test_scores.append(rf_temp.score(X_test, y_test))
# 画出 n_estimators vs 准确率曲线,找到拐点

# ========== 回归版本 ==========
rf_reg = RandomForestRegressor(
    n_estimators=100, max_depth=10, 
    min_samples_leaf=5, n_jobs=-1, random_state=42
)
rf_reg.fit(X_train, y_train)
print(f'回归 R²: {rf_reg.score(X_test, y_test):.4f}')

💼 实战案例:酒店GMV预测模型

背景:预测未来7天各城市×各品类的酒店GMV,为运营资源调配和预算分配提供依据。

特征工程
历史7/14/30天GMV、同比增长率、节假日标记、天气数据、竞对价格、城市活动日历
随机森林回归
200棵树,max_depth=12,用OOB评估,特征重要性Top10分析
模型解释
SHAP分析+部分依赖图(PDP),解释各因素如何影响GMV
业务闭环
预测→资源调配→实际GMV→偏差分析→特征回补→模型迭代
📊 业务效果:预测MAPE 12.3%(vs 人工经验预测18.5%);特征重要性Top3:历史7天GMV(35%)、节假日标记(22%)、竞对价格指数(15%);上线后资源利用率提升15%,GMV超额完成率从82%提升至94%。
3. XGBoost (Extreme Gradient Boosting)Gradient Boosting 进阶王者算法

📖 核心原理

XGBoost 是 Gradient Boosting 的工程优化版,在 Kaggle 竞赛和工业界被广泛使用。核心创新在于目标函数中加入了正则化项来防止过拟合,并使用二阶泰勒展开来更精确地逼近损失函数。

🔑 XGBoost vs 传统GBDT 的四大优化:
① 正则化:目标函数 = 损失函数 + γ·T + ½λ·||w||²(T=叶节点数,w=叶节点权重)→ 同时控制树的复杂度和叶节点权重
② 二阶导数:用损失函数的二阶泰勒展开,比GBDT的一阶梯度更精确
③ 列抽样:类似随机森林的特征随机性,降低过拟合并加速计算
④ 缺失值处理:自动学习缺失值的最优分裂方向(默认左/右分支)
XGBoost 目标函数: Obj = Σ L(yᵢ, ŷᵢ) + Σ Ω(fₖ)    正则化项: Ω(f) = γ·T + ½λ Σ wⱼ²
🐍 Python 实现(xgboost 库)
import xgboost as xgb
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score, roc_auc_score, mean_squared_error
import numpy as np

# ========== XGBoost 分类 ==========
xgb_clf = xgb.XGBClassifier(
    n_estimators=100,        # 树的数量
    max_depth=6,             # 树的最大深度(典型值3-10)
    learning_rate=0.1,       # 学习率(典型值0.01-0.3)
    subsample=0.8,           # 每棵树用的样本比例(防止过拟合)
    colsample_bytree=0.8,    # 每棵树用的特征比例
    reg_alpha=0.1,           # L1正则化(稀疏特征时有用)
    reg_lambda=1.0,          # L2正则化(默认1)
    gamma=0,                 # 分裂所需的最小损失减少量
    min_child_weight=1,      # 叶节点最小样本权重和
    scale_pos_weight=1,      # 正负样本不平衡时的权重调整
    eval_metric='logloss',   # 评估指标
    early_stopping_rounds=20, # 早停轮数
    random_state=42,
    n_jobs=-1
)

# 训练(使用 eval_set 做早停)
xgb_clf.fit(
    X_train, y_train,
    eval_set=[(X_test, y_test)],
    verbose=False
)

# 评估
y_pred = xgb_clf.predict(X_test)
y_proba = xgb_clf.predict_proba(X_test)[:, 1]
print(f'准确率: {accuracy_score(y_test, y_pred):.4f}')
print(f'AUC: {roc_auc_score(y_test, y_proba):.4f}')

# 特征重要性(三种方式)
# weight: 特征被用于分裂的次数
# gain: 特征在所有分裂中的平均增益
# cover: 特征覆盖的样本数
importance = xgb_clf.get_booster().get_score(importance_type='gain')

# ========== XGBoost 回归 ==========
xgb_reg = xgb.XGBRegressor(
    n_estimators=200, max_depth=7, learning_rate=0.05,
    subsample=0.8, colsample_bytree=0.8,
    reg_alpha=0.1, reg_lambda=1.0,
    early_stopping_rounds=30, random_state=42
)
xgb_reg.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)
y_pred_reg = xgb_reg.predict(X_test)
print(f'RMSE: {np.sqrt(mean_squared_error(y_test, y_pred_reg)):.4f}')

# ========== 超参数调优(关键参数)==========
# 调参顺序建议:n_estimators→max_depth+min_child_weight→gamma→subsample+colsample→reg_alpha+reg_lambda→learning_rate
from sklearn.model_selection import GridSearchCV

param_grid = {
    'max_depth': [3, 5, 7],
    'min_child_weight': [1, 3, 5],
    'gamma': [0, 0.1, 0.2],
    'subsample': [0.6, 0.8, 1.0],
    'colsample_bytree': [0.6, 0.8, 1.0]
}
grid = GridSearchCV(xgb.XGBClassifier(n_estimators=100, learning_rate=0.1, random_state=42),
                    param_grid, cv=5, scoring='roc_auc', n_jobs=-1)
grid.fit(X_train, y_train)
print(f'最优参数: {grid.best_params_}')

# ========== 自定义损失函数(示例:Focal Loss)==========
def focal_loss(y_pred, dtrain, alpha=0.25, gamma=2.0):
    y_true = dtrain.get_label()
    grad = ...  # 自定义一阶梯度
    hess = ...  # 自定义二阶梯度
    return grad, hess
# xgb_clf.fit(X_train, y_train, obj=focal_loss)

🎯 调参指南(工业级)

参数作用典型范围调参策略
n_estimators树的数量100-1000用早停确定最优值,不要手动设
max_depth树的深度3-10先浅后深,数据量大可设深些
learning_rate学习率/收缩率0.01-0.3越小需要越多树,0.1是好的起点
subsample行采样比例0.6-1.00.8是常用值,防过拟合利器
colsample_bytree列采样比例0.6-1.0同上,两者结合效果更好
reg_alpha/reg_lambdaL1/L2正则化0-10高维稀疏数据增大L1,一般数据用L2
gamma分裂最小增益0-0.5越大越保守,防止过拟合
scale_pos_weight正负样本权重=负样本/正样本样本不平衡时关键参数

💼 实战案例:用户核销概率预测 + 优惠券智能发放

背景:某酒旅平台需要预测用户下单后的核销概率,并基于预测结果智能决定是否发放额外优惠券来提升核销率。

样本构造
历史订单数据,正样本=已核销,负样本=未核销(含过期未用),特征120+维
XGBoost训练
scale_pos_weight处理不平衡,AUC达0.87,KS=0.42
智能策略
核销概率<0.3→发大额券;0.3-0.6→发小额券;>0.6→不发券(自然核销)
效果验证
AB测试:实验组核销率+8.2pp,券成本仅增3%,净GMV提升12%
📊 业务闭环:①预测→②分层→③差异化发券→④核销数据回流→⑤模型迭代。上线后月度核销率从38%提升至47%,优惠券ROI从1.8提升至2.6,月度节省无效券成本约120万。
📊 第二大类:集成学习LightGBM · CatBoost · 集成策略对比
💡4. LightGBMGOSS + EFB 高效Boosting速度之王

📖 核心原理

LightGBM(微软开源)通过两项核心创新实现比XGBoost更快的训练速度:① GOSS(基于梯度的单边采样):保留梯度大的样本(训练不足的),随机采样梯度小的样本,大幅减少数据量但不损失精度。② EFB(互斥特征捆绑):将互斥的稀疏特征捆绑成一个特征,减少特征维度。③ Leaf-wise生长策略:每次选择增益最大的叶子进行分裂(而非XGBoost的Level-wise逐层生长),在相同分裂次数下误差更低。

🔑 Leaf-wise vs Level-wise:
• Level-wise(XGBoost):每一层的所有叶子同时分裂 → 平衡但低效
• Leaf-wise(LightGBM):每次选增益最大的叶子分裂 → 更高效但可能过拟合(需要max_depth控制)
• 直方图算法:将连续特征离散化为256个bin,分裂计算从O(N)降至O(#bins)
🐍 Python 实现(lightgbm 库)
import lightgbm as lgb
from sklearn.metrics import accuracy_score, mean_squared_error
import numpy as np

# ========== LightGBM 分类 ==========
lgb_clf = lgb.LGBMClassifier(
    n_estimators=200,
    max_depth=7,
    num_leaves=31,           # 叶子数(核心参数!≈2^max_depth)
    learning_rate=0.05,
    min_child_samples=20,    # 叶节点最少样本数
    subsample=0.8,
    colsample_bytree=0.8,
    reg_alpha=0.1,
    reg_lambda=1.0,
    boosting_type='gbdt',    # gbdt / dart / goss
    objective='binary',      # 目标函数
    metric='auc',
    random_state=42,
    n_jobs=-1,
    verbose=-1
)

lgb_clf.fit(
    X_train, y_train,
    eval_set=[(X_test, y_test)],
    eval_metric='auc',
    callbacks=[lgb.early_stopping(50), lgb.log_evaluation(0)]
)

y_pred = lgb_clf.predict(X_test)
y_proba = lgb_clf.predict_proba(X_test)[:, 1]
print(f'AUC: {roc_auc_score(y_test, y_proba):.4f}')

# 特征重要性
lgb.plot_importance(lgb_clf, max_num_features=15, figsize=(10, 6))

# ========== LightGBM 回归 ==========
lgb_reg = lgb.LGBMRegressor(
    n_estimators=300, num_leaves=63, max_depth=8,
    learning_rate=0.03, min_child_samples=30,
    subsample=0.8, colsample_bytree=0.8,
    random_state=42, verbose=-1
)
lgb_reg.fit(X_train, y_train, eval_set=[(X_test, y_test)],
            eval_metric='rmse',
            callbacks=[lgb.early_stopping(50)])
print(f'RMSE: {np.sqrt(mean_squared_error(y_test, lgb_reg.predict(X_test))):.4f}')

# ========== 使用GOSS(更快)==========
lgb_goss = lgb.LGBMClassifier(
    boosting_type='goss',    # 梯度单边采样,更快
    n_estimators=200, num_leaves=31,
    top_rate=0.2,            # 保留大梯度样本比例
    other_rate=0.1,          # 小梯度样本采样比例
    random_state=42
)

# ========== 使用DART(防过拟合)==========
lgb_dart = lgb.LGBMClassifier(
    boosting_type='dart',    # Dropouts meet Multiple Additive Regression Trees
    n_estimators=200, num_leaves=31,
    drop_rate=0.1,           # 每轮丢弃树的比例
    random_state=42
)

🎯 XGBoost vs LightGBM 对比

维度XGBoostLightGBM
生长策略Level-wise(逐层)Leaf-wise(最优叶子)
训练速度较慢(大样本下)快3-10倍
内存占用较高低(直方图算法)
类别特征需手动编码原生支持(categorical_feature)
过拟合风险较低较高(需max_depth+num_leaves控制)
小数据集表现好可能过拟合
大数据集较慢优势明显

💼 实战案例:大规模城市GMV排序预测(百万级样本)

背景:覆盖300+城市×20品类×365天,样本量500万+,需要快速训练并预测各城市品类的GMV排名,指导运营资源分配。

数据预处理
500万样本,200+特征,LightGBM原生支持类别特征,无需OneHot编码
LightGBM训练
num_leaves=127, GOSS模式,训练仅需8分钟(vs XGBoost 35分钟)
排序预测
预测各城市×品类GMV排名,Top20城市获得重点资源倾斜
效果评估
预测排名与真实排名的Spearman相关系数0.91
📊 技术亮点:500万样本训练仅8分钟(内存占用<2GB),预测Spearman ρ=0.91,Top10城市命中率90%。业务上实现了资源从"撒胡椒面"到"精准投放"的转变,人效提升3倍。
🐱5. CatBoostOrdered Boosting 无偏梯度类别之王

📖 核心原理

CatBoost(Yandex开源)解决了传统GBDT的两个核心问题:① 预测偏移(Prediction Shift):传统方法用相同数据计算梯度和建树,导致过拟合。CatBoost用Ordered Boosting(对每个样本只用"之前"的样本计算梯度)。② 类别特征处理:使用Ordered TS(目标统计编码),根据排序顺序动态计算类别统计量,避免数据泄露。

🔑 三大核心优势:
开箱即用:默认参数通常就很优秀,调参需求最小
类别特征原生支持:直接传入类别列索引,无需任何编码
克服预测偏移:Ordered Boosting + Ordered TS 有效防止过拟合
🐍 Python 实现(catboost 库)
from catboost import CatBoostClassifier, CatBoostRegressor, Pool
from sklearn.metrics import accuracy_score, roc_auc_score

# ========== CatBoost 分类 ==========
# 标识类别特征列索引
cat_features = [0, 2, 5]  # 城市、品类、渠道等列的索引

cb_clf = CatBoostClassifier(
    iterations=500,          # 迭代次数
    depth=6,                 # 树深度(典型值4-10)
    learning_rate=0.03,
    l2_leaf_reg=3,           # L2正则化系数
    border_count=128,        # 数值特征分箱数
    random_seed=42,
    eval_metric='AUC',
    early_stopping_rounds=50,
    verbose=100,             # 每100轮打印一次
    task_type='CPU'          # CPU / GPU
)

cb_clf.fit(
    X_train, y_train,
    cat_features=cat_features,
    eval_set=(X_test, y_test),
    plot=True               # 自动画训练曲线
)

y_pred = cb_clf.predict(X_test)
y_proba = cb_clf.predict_proba(X_test)[:, 1]
print(f'AUC: {roc_auc_score(y_test, y_proba):.4f}')

# 特征重要性
cb_clf.get_feature_importance(prettified=True)

# ========== CatBoost 回归 ==========
cb_reg = CatBoostRegressor(
    iterations=800, depth=8, learning_rate=0.03,
    l2_leaf_reg=5, random_seed=42,
    early_stopping_rounds=50, verbose=100
)
cb_reg.fit(X_train, y_train, cat_features=cat_features,
           eval_set=(X_test, y_test))

# ========== 使用 Pool 对象(推荐方式)==========
train_pool = Pool(X_train, y_train, cat_features=cat_features)
test_pool = Pool(X_test, y_test, cat_features=cat_features)

cb_model = CatBoostClassifier(iterations=500, depth=6, random_seed=42)
cb_model.fit(train_pool, eval_set=test_pool, early_stopping_rounds=50)

# ========== 模型分析 ==========
# SHAP分析
cb_model.get_feature_importance(train_pool, type='ShapValues')

# 模型保存与加载
cb_model.save_model('catboost_model.cbm')
# cb_model.load_model('catboost_model.cbm')

💼 实战案例:多品类用户偏好预测

背景:酒旅平台需要预测用户对酒店/民宿/门票/周边游等10+品类的偏好,特征是高度类别化的(城市、品类、用户等级、渠道等50%以上是类别特征)。

📊 关键发现:CatBoost在类别特征>40%的场景下,比XGBoost/LightGBM的AUC高2-5pp。训练速度虽然比LightGBM慢,但默认参数即可达到接近最优的效果,大幅降低调参成本。最终多标签分类macro-F1=0.78,个性化推荐CTR提升23%。
🎯 第三大类:概率与统计模型朴素贝叶斯 · SVM · Prophet
🎲6. 朴素贝叶斯 (Naive Bayes)条件概率 + 特征独立假设经典算法

📖 核心原理

朴素贝叶斯基于贝叶斯定理,并做了一个"朴素"的假设:所有特征之间相互独立。虽然这个假设在实际中几乎不成立,但算法在很多场景下表现仍然出色,且训练速度极快。

贝叶斯定理: P(Y|X) = P(X|Y) · P(Y) / P(X)
朴素假设下: P(X|Y) = P(x₁|Y) · P(x₂|Y) · ... · P(xₙ|Y)
🔑 三种常见变体:
① 高斯朴素贝叶斯(GaussianNB):假设连续特征服从正态分布,适用于数值型特征
② 多项式朴素贝叶斯(MultinomialNB):适用于离散计数特征(如文本词频)
③ 伯努利朴素贝叶斯(BernoulliNB):适用于二值特征(出现/不出现)
🐍 Python 实现
from sklearn.naive_bayes import GaussianNB, MultinomialNB, BernoulliNB
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score, classification_report
import numpy as np

# ========== 高斯朴素贝叶斯(数值特征)==========
gnb = GaussianNB(var_smoothing=1e-9)  # 方差平滑,防止零方差
gnb.fit(X_train, y_train)
y_pred = gnb.predict(X_test)
y_proba = gnb.predict_proba(X_test)  # 输出概率
print(f'准确率: {accuracy_score(y_test, y_pred):.4f}')

# ========== 多项式朴素贝叶斯(文本分类)==========
from sklearn.feature_extraction.text import CountVectorizer
# 文本→词频矩阵
vectorizer = CountVectorizer(max_features=5000)
X_counts = vectorizer.fit_transform(texts)
mnb = MultinomialNB(alpha=1.0)  # 拉普拉斯平滑
mnb.fit(X_counts, labels)

# 查看每个类别的Top关键词
feature_names = vectorizer.get_feature_names_out()
for i, class_label in enumerate(mnb.classes_):
    top_indices = np.argsort(mnb.feature_log_prob_[i])[-10:][::-1]
    top_words = [feature_names[idx] for idx in top_indices]
    print(f'类别 {class_label}: {top_words}')

# ========== 混合类型特征处理 ==========
# 对于既有数值又有类别的数据,可用Pipeline
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler

# 先对数值特征做标准化,再喂给GaussianNB
preprocessor = ColumnTransformer([
    ('num', StandardScaler(), numerical_cols)
])
pipeline = Pipeline([
    ('preprocessor', preprocessor),
    ('classifier', GaussianNB())
])
pipeline.fit(X_train, y_train)

# ========== 半监督学习(部分数据无标签)==========
# 用已标注数据训练 → 预测未标注数据 → 将高置信度样本加入训练集 → 迭代
gnb = GaussianNB()
for iteration in range(5):
    gnb.fit(X_labeled, y_labeled)
    probas = gnb.predict_proba(X_unlabeled)
    confidence = np.max(probas, axis=1)
    high_conf_idx = confidence > 0.95
    # 将高置信度样本加入训练集
    X_labeled = np.vstack([X_labeled, X_unlabeled[high_conf_idx]])
    y_labeled = np.hstack([y_labeled, gnb.predict(X_unlabeled[high_conf_idx])])
    X_unlabeled = X_unlabeled[~high_conf_idx]

💼 实战案例:用户评论情感分类(好评/差评自动打标)

背景:每天数万条酒店评论需要自动分类为好评/中评/差评,需要轻量级模型实现实时分类。

文本预处理
jieba分词+去停用词+CountVectorizer转词频矩阵
MultinomialNB
训练3分类模型,alpha=0.5拉普拉斯平滑
关键词提取
从每个类别提取Top20特征词,用于业务解读
闭环应用
自动打标→差评预警→客服介入→问题归因→商家整改
📊 业务效果:分类准确率89%,推理速度<1ms/条;差评关键词:"卫生差""隔音不好""前台态度"等帮助定位了服务质量短板;差评自动预警后,平均响应时间从4小时缩短至15分钟。
📐7. 支持向量机 (SVM)最大间隔 + 核技巧经典算法

📖 核心原理

SVM的核心思想是:找到一个超平面,使不同类别之间的"间隔"最大化。通过核函数(Kernel Trick),SVM能将线性不可分的数据映射到高维空间,使其在高维中线性可分,而无需显式计算高维映射。

🔑 三大核心概念:
① 最大间隔超平面:最优分类面 = argmax{2/||w||},等价于 min ½||w||² + C·Σξᵢ
② 核技巧(Kernel Trick):K(x, x') = φ(x)·φ(x'),直接用核函数计算高维内积,无需显式映射
③ 软间隔:引入松弛变量ξ和惩罚系数C,允许少量样本被错分,C越大对错分惩罚越重
线性核: K(x,x') = x·x'    RBF核: K(x,x') = exp(-γ||x-x'||²)    多项式核: K(x,x') = (γ·x·x' + r)^d
🐍 Python 实现
from sklearn.svm import SVC, SVR
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline

# ========== SVM分类(关键:特征必须标准化!)==========
pipeline = Pipeline([
    ('scaler', StandardScaler()),  # SVM对尺度敏感!
    ('svm', SVC(kernel='rbf', C=1.0, gamma='scale', 
                probability=True, random_state=42))
])
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
y_proba = pipeline.predict_proba(X_test)

# ========== 不同核函数对比 ==========
kernels = ['linear', 'poly', 'rbf', 'sigmoid']
for kernel in kernels:
    svm = SVC(kernel=kernel, C=1.0, gamma='scale', random_state=42)
    svm.fit(X_train_scaled, y_train)
    score = svm.score(X_test_scaled, y_test)
    print(f'{kernel}: {score:.4f}')

# ========== 超参数调优(RBF核)==========
param_grid = {
    'C': [0.01, 0.1, 1, 10, 100],        # 惩罚系数
    'gamma': [0.001, 0.01, 0.1, 1, 'scale', 'auto'],  # RBF核宽度
    'kernel': ['rbf', 'linear']
}
grid = GridSearchCV(SVC(random_state=42), param_grid, 
                    cv=5, scoring='accuracy', n_jobs=-1)
grid.fit(X_train_scaled, y_train)
print(f'最优参数: {grid.best_params_}')
print(f'最优CV分数: {grid.best_score_:.4f}')

# ========== SVM回归 ==========
svr = SVR(kernel='rbf', C=1.0, epsilon=0.1, gamma='scale')
svr.fit(X_train_scaled, y_train)
print(f'R²: {svr.score(X_test_scaled, y_test):.4f}')

# ========== 大数据集下用LinearSVC(更快)==========
from sklearn.svm import LinearSVC
linear_svc = LinearSVC(C=1.0, max_iter=10000, dual=False, random_state=42)
linear_svc.fit(X_train_scaled, y_train)

🎯 应用场景与局限性

适用场景:小样本高维数据(如基因表达、文本分类);需要明确决策边界的场景;数据维度 > 样本数的场景
⚠️不适用场景:样本量>10万(训练慢);特征维度极高且稀疏(线性模型更合适);需要概率输出(可用probability=True但慢)

💼 实战案例:酒店服务质量异常检测

背景:用One-Class SVM检测异常酒店(刷单、虚假点评、服务质量突变),特征维度高但异常样本少。

📊 代码片段:OneClassSVM(nu=0.05, kernel='rbf', gamma=0.01) → 用正常酒店数据训练,异常阈值=决策函数<-0.5。精准识别了Top50异常酒店中的43家(86%准确率),帮助风控团队提前发现并处理了刷单团伙。
🔮8. Prophet(Facebook 时序预测)趋势+周期+节假日分解业务利器

📖 核心原理

Prophet 是 Facebook 开源的时序预测框架,专为业务时间序列设计。它将时序分解为三个可解释的组件:趋势(Trend)+ 周期性(Seasonality)+ 节假日效应(Holidays),加上一个误差项。

Prophet 模型: y(t) = g(t) + s(t) + h(t) + εₜ
g(t)=趋势(分段线性或逻辑增长),s(t)=周期性(傅里叶级数),h(t)=节假日效应
🔑 为什么业务分析首选 Prophet?
自动处理缺失值和异常值:无需预处理,对业务数据友好
节假日效应:原生支持中国法定节假日、618/双11等自定义大促
趋势变点检测:自动识别业务策略生效或外部冲击的时间点
可解释性:每个组件独立可视化,方便向管理层解释"为什么预测这个数"
🐍 Python 实现
from prophet import Prophet
import pandas as pd
import matplotlib.pyplot as plt

# ========== 数据准备 ==========
# Prophet要求两列:ds(日期)和y(数值)
df = pd.DataFrame({
    'ds': pd.date_range('2024-01-01', periods=365, freq='D'),
    'y': daily_gmv_values  # 每日GMV
})

# ========== 添加中国节假日 ==========
from prophet.make_holidays import make_holidays_df
# 获取中国节假日(春节、国庆等)
chinese_holidays = make_holidays_df(
    year_list=[2024, 2025, 2026],
    country='CN'
)

# 添加自定义大促日期
custom_events = pd.DataFrame({
    'holiday': '双11',
    'ds': pd.to_datetime(['2024-11-11', '2025-11-11']),
    'lower_window': -7,  # 提前7天预热
    'upper_window': 3,   # 延后3天
})

# ========== 模型训练 ==========
model = Prophet(
    growth='linear',              # 趋势类型:linear / logistic
    seasonality_mode='additive',  # 周期性模式:additive / multiplicative
    yearly_seasonality=True,      # 年周期(傅里叶级数阶数默认10)
    weekly_seasonality=True,      # 周周期(默认3阶)
    daily_seasonality=False,      # 日周期(小时级数据才开)
    holidays=pd.concat([chinese_holidays, custom_events]),
    changepoint_prior_scale=0.05, # 趋势灵活性(越大越灵活,越容易过拟合)
    seasonality_prior_scale=10.0, # 周期性强度
    holidays_prior_scale=10.0,    # 节假日效应强度
    interval_width=0.95,          # 置信区间宽度
)

model.fit(df)

# ========== 预测 ==========
future = model.make_future_dataframe(periods=90)  # 预测未来90天
forecast = model.predict(future)

# ========== 可视化 ==========
# 1. 整体预测图
model.plot(forecast)
plt.title('GMV 预测(含置信区间)')
plt.show()

# 2. 组件分解图
model.plot_components(forecast)
plt.show()

# 3. 趋势变点
from prophet.plot import add_changepoints_to_plot
fig = model.plot(forecast)
add_changepoints_to_plot(fig.gca(), model, forecast)

# ========== 评估 ==========
from prophet.diagnostics import cross_validation, performance_metrics

# 时间序列交叉验证
df_cv = cross_validation(
    model, initial='180 days',  # 初始训练窗口
    period='30 days',           # 每次向前滚动
    horizon='30 days'           # 预测视野
)

# 评估指标
df_metrics = performance_metrics(df_cv)
print(df_metrics[['horizon', 'rmse', 'mape', 'mae']].head())

# ========== 预测结果解读 ==========
print(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(7))

💼 实战案例:酒店预订量90天滚动预测

背景:某OTA需要预测未来90天各城市的酒店预订量,用于运营资源调配和库存管理。

数据聚合
按城市聚合历史2年的每日预订量,标注节假日
Prophet建模
每个城市独立建模,批量训练200+个模型
趋势监控
检测变点→自动标记策略生效时间点
预警机制
实际值超出置信区间→自动告警→触发归因分析
📊 业务效果:30天预测MAPE 11.2%,90天MAPE 18.5%。节假日预测准确率显著优于ARIMA(春节预测误差仅5% vs ARIMA的22%)。预测驱动的库存管理使超售率下降40%,空房损失减少15%。
🤖 第四大类:深度学习与时序预测CNN · 迁移学习 · LSTM · ARIMA · 异常检测
🖼️9. CNN 卷积神经网络(图像识别)卷积 + 池化 + 全连接深度学习

📖 核心原理

CNN通过卷积层提取局部特征(边缘、纹理、形状),池化层降维和增强平移不变性,全连接层做分类/回归。核心优势是参数共享和局部连接,大幅减少参数量。

🔑 核心组件:
① 卷积层:用多个卷积核(滤波器)在图像上滑动,提取不同的特征图。输出尺寸 = (W-F+2P)/S + 1
② 池化层:MaxPooling取局部最大值,降维+保留强特征;AveragePooling取均值
③ Batch Normalization:加速训练,防止梯度消失
④ Dropout:随机丢弃神经元,防止过拟合
🐍 Python 实现(TensorFlow/Keras)
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, models
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# ========== 基础CNN模型 ==========
model = models.Sequential([
    # 卷积块1
    layers.Conv2D(32, (3,3), activation='relu', padding='same', input_shape=(224,224,3)),
    layers.BatchNormalization(),
    layers.Conv2D(32, (3,3), activation='relu', padding='same'),
    layers.BatchNormalization(),
    layers.MaxPooling2D((2,2)),
    layers.Dropout(0.25),
    
    # 卷积块2
    layers.Conv2D(64, (3,3), activation='relu', padding='same'),
    layers.BatchNormalization(),
    layers.Conv2D(64, (3,3), activation='relu', padding='same'),
    layers.BatchNormalization(),
    layers.MaxPooling2D((2,2)),
    layers.Dropout(0.25),
    
    # 卷积块3
    layers.Conv2D(128, (3,3), activation='relu', padding='same'),
    layers.BatchNormalization(),
    layers.MaxPooling2D((2,2)),
    layers.Dropout(0.25),
    
    # 全连接层
    layers.GlobalAveragePooling2D(),
    layers.Dense(256, activation='relu'),
    layers.BatchNormalization(),
    layers.Dropout(0.5),
    layers.Dense(num_classes, activation='softmax')
])

model.compile(
    optimizer=keras.optimizers.Adam(learning_rate=0.001),
    loss='categorical_crossentropy',
    metrics=['accuracy']
)
model.summary()

# ========== 数据增强(防过拟合+提升泛化)==========
train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=20,      # 随机旋转
    width_shift_range=0.2,  # 水平平移
    height_shift_range=0.2, # 垂直平移
    shear_range=0.2,        # 剪切变换
    zoom_range=0.2,         # 随机缩放
    horizontal_flip=True,   # 水平翻转
    fill_mode='nearest'
)

# ========== 训练 ==========
history = model.fit(
    train_datagen.flow(X_train, y_train, batch_size=32),
    validation_data=(X_test, y_test),
    epochs=50,
    callbacks=[
        keras.callbacks.EarlyStopping(patience=10, restore_best_weights=True),
        keras.callbacks.ReduceLROnPlateau(factor=0.5, patience=5, min_lr=1e-6)
    ]
)

# ========== Grad-CAM 可视化(看模型关注哪里)==========
import cv2, numpy as np
def grad_cam(model, img, layer_name):
    grad_model = keras.Model(
        [model.inputs], 
        [model.get_layer(layer_name).output, model.output]
    )
    with tf.GradientTape() as tape:
        conv_outputs, predictions = grad_model(img)
        class_idx = tf.argmax(predictions[0])
        loss = predictions[:, class_idx]
    grads = tape.gradient(loss, conv_outputs)
    # ...生成热力图叠加到原图...

💼 实战案例:酒店图片质量自动审核

背景:酒店上传的房间图片需要自动审核:是否为真实酒店照片?图片质量是否合格(模糊/过暗/有水印)?房型是否匹配?

数据标注
10万张图片标注:合格/模糊/非酒店/有水印/过暗
CNN训练
5分类模型,数据增强,准确率92.3%
自动审核
图片上传→CNN分类→合格直接过,不合格自动退回+原因
闭环优化
人工抽检→错误反馈→模型迭代
📊 业务效果:审核效率从人工5分钟/张→自动0.3秒/张;日均处理量从200张→50000张;人工审核团队从15人缩减至3人(只做抽检);酒店图片合规率从67%提升至94%。
🔄10. 迁移学习 (Transfer Learning)预训练 + 微调深度学习

📖 核心原理

迁移学习利用在大规模数据集(如ImageNet的1400万张图片)上预训练的模型,将其学到的通用特征(边缘、纹理、形状)迁移到自己的任务中。核心策略:冻结预训练层 + 替换分类头 + 微调顶层

🔑 三种迁移策略:
① 特征提取器:冻结全部预训练层,只训练新的分类头(数据少时用)
② 部分微调:冻结底层(通用特征),微调高层(任务特定特征)(数据中等时用)
③ 全量微调:以极小学习率微调整个网络(数据充足时用,效果最好)
🐍 Python 实现(ResNet50 + 微调)
import tensorflow as tf
from tensorflow import keras

# ========== 使用预训练模型(ResNet50)==========
base_model = keras.applications.ResNet50(
    weights='imagenet',          # 加载ImageNet权重
    include_top=False,           # 去掉原始分类头
    input_shape=(224, 224, 3)
)

# 冻结底层(策略:先冻结全部训练分类头,再解冻部分微调)
base_model.trainable = False

# 构建新分类头
model = keras.Sequential([
    base_model,
    keras.layers.GlobalAveragePooling2D(),
    keras.layers.Dense(512, activation='relu'),
    keras.layers.BatchNormalization(),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(num_classes, activation='softmax')
])

model.compile(
    optimizer=keras.optimizers.Adam(1e-3),
    loss='categorical_crossentropy',
    metrics=['accuracy']
)

# 第一阶段:只训练分类头
history1 = model.fit(train_data, epochs=10, validation_data=val_data)

# 第二阶段:解冻顶层进行微调
base_model.trainable = True
# 冻结前100层,只微调后面
for layer in base_model.layers[:100]:
    layer.trainable = False

model.compile(
    optimizer=keras.optimizers.Adam(1e-5),  # 极小学习率
    loss='categorical_crossentropy',
    metrics=['accuracy']
)

history2 = model.fit(train_data, epochs=20, validation_data=val_data,
                     callbacks=[keras.callbacks.EarlyStopping(patience=5)])

# ========== 常用预训练模型选择 ==========
# ResNet50/101/152:通用性强,最经典
# EfficientNetB0-B7:效率高,准确率好
# MobileNetV2/V3:轻量级,适合移动端
# ConvNeXt:2020s新架构,SOTA性能
# ViT (Vision Transformer):适合大数据集

efficientnet = keras.applications.EfficientNetB3(
    weights='imagenet', include_top=False, input_shape=(300,300,3)
)

# ========== 数据量不同时的策略 ==========
# <1000张/类:只训练分类头(base_model.trainable=False)
# 1000-10000张/类:解冻最后几层微调
# >10000张/类:可以全量微调

💼 实战案例:酒店房型图片自动分类

背景:酒店上传的图片需要自动分类到对应房型(大床房/双床房/套房/loft等),每类仅200-500张标注图片。

📊 技术方案:EfficientNetB3预训练 → 冻结→训练分类头(10epoch)→解冻最后30层微调(20epoch)→准确率从零训练的72%提升至94.6%。关键:用数据增强(旋转/翻转/亮度调整)将200张扩增至2000张等效数据量。
11. LSTM 长短期记忆网络遗忘门 + 输入门 + 输出门深度学习

📖 核心原理

LSTM解决了传统RNN的梯度消失/爆炸问题,通过三个门控机制(遗忘门、输入门、输出门)和一个细胞状态来控制信息的流动和记忆。

🔑 三个门的职责:
① 遗忘门(Forget Gate):fₜ=σ(Wf·[hₜ₋₁,xₜ]+bf) → 决定丢弃哪些旧信息
② 输入门(Input Gate):iₜ=σ(Wi·[hₜ₋₁,xₜ]+bi),C̃ₜ=tanh(Wc·[hₜ₋₁,xₜ]+bc) → 决定存储哪些新信息
③ 输出门(Output Gate):oₜ=σ(Wo·[hₜ₋₁,xₜ]+bo) → 决定输出什么
④ 细胞状态更新:Cₜ = fₜ·Cₜ₋₁ + iₜ·C̃ₜ → 长期记忆的更新
🐍 Python 实现(TensorFlow/Keras)
import numpy as np
from tensorflow import keras
from tensorflow.keras import layers
from sklearn.preprocessing import MinMaxScaler

# ========== 时序数据准备(滑动窗口)==========
def create_sequences(data, seq_length=30):
    """将时序数据转为监督学习格式"""
    X, y = [], []
    for i in range(len(data) - seq_length):
        X.append(data[i:i+seq_length])
        y.append(data[i+seq_length])
    return np.array(X), np.array(y)

# 数据标准化
scaler = MinMaxScaler()
data_scaled = scaler.fit_transform(data.reshape(-1, 1))

# 创建序列
seq_length = 30  # 用过去30天预测下一天
X, y = create_sequences(data_scaled, seq_length)
X = X.reshape(X.shape[0], X.shape[1], 1)  # (样本数, 时间步, 特征数)

# ========== LSTM模型 ==========
model = keras.Sequential([
    layers.LSTM(64, return_sequences=True, input_shape=(seq_length, 1)),
    layers.Dropout(0.2),
    layers.LSTM(32, return_sequences=False),
    layers.Dropout(0.2),
    layers.Dense(16, activation='relu'),
    layers.Dense(1)
])

model.compile(
    optimizer=keras.optimizers.Adam(learning_rate=0.001),
    loss='mse',
    metrics=['mae']
)

history = model.fit(
    X_train, y_train,
    validation_data=(X_test, y_test),
    epochs=100,
    batch_size=32,
    callbacks=[
        keras.callbacks.EarlyStopping(patience=15, restore_best_weights=True),
        keras.callbacks.ReduceLROnPlateau(factor=0.5, patience=5)
    ]
)

# ========== 多步预测(预测未来N天)==========
def multi_step_forecast(model, last_sequence, steps=7):
    """用最后已知序列,逐步预测未来steps天"""
    predictions = []
    current_seq = last_sequence.copy()
    for _ in range(steps):
        pred = model.predict(current_seq.reshape(1, seq_length, 1), verbose=0)
        predictions.append(pred[0,0])
        # 将预测值加入序列,滑动窗口
        current_seq = np.append(current_seq[1:], pred)
    return scaler.inverse_transform(np.array(predictions).reshape(-1,1))

# ========== BiLSTM(双向LSTM,更好捕捉上下文)==========
from tensorflow.keras.layers import Bidirectional

model_bilstm = keras.Sequential([
    Bidirectional(layers.LSTM(64, return_sequences=True), input_shape=(seq_length, 1)),
    layers.Dropout(0.2),
    Bidirectional(layers.LSTM(32)),
    layers.Dropout(0.2),
    layers.Dense(16, activation='relu'),
    layers.Dense(1)
])

💼 实战案例:酒店每日订单量7天滚动预测

背景:结合历史订单量+天气+节假日+竞对价格等多维特征,用LSTM做短期精准预测。

📊 对比结果:LSTM(7天MAE=8.2%) vs Prophet(7天MAE=10.5%) vs ARIMA(7天MAE=12.1%)。LSTM在短期预测上优势明显,且能融合多维特征(天气、竞对价格等Prophet不易处理的连续外生变量)。
📈12. ARIMA / SARIMA(经典时序模型)自回归 + 差分 + 移动平均经典算法

📖 核心原理

ARIMA是经典时序预测的基石。AR(自回归)=用过去值预测未来,I(差分)=使序列平稳,MA(移动平均)=用过去误差修正预测。SARIMA加入了季节性成分,适用于有明显季节性模式的业务数据。

ARIMA(p,d,q): (1-φ₁B-...-φₚBᵖ)(1-B)^d·yₜ = (1+θ₁B+...+θqB^q)εₜ
SARIMA(p,d,q)(P,D,Q)s: 在ARIMA基础上×季节性成分,s=周期长度
🐍 Python 实现(statsmodels + pmdarima)
import pandas as pd
import numpy as np
from statsmodels.tsa.arima.model import ARIMA
from statsmodels.tsa.statespace.sarimax import SARIMAX
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
from statsmodels.tsa.stattools import adfuller
import pmdarima as pm

# ========== 平稳性检验 ==========
def check_stationarity(series):
    result = adfuller(series.dropna())
    print(f'ADF统计量: {result[0]:.4f}')
    print(f'p值: {result[1]:.4f}')
    return result[1] < 0.05

# ========== ACF/PACF 确定 p,q ==========
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
plot_acf(series, lags=40, ax=axes[0])
plot_pacf(series, lags=40, ax=axes[1])
plt.show()

# ========== 自动搜索最优参数 ==========
auto_model = pm.auto_arima(
    train_series,
    seasonal=True, m=7,          # 周周期=7天
    start_p=0, max_p=5,
    start_q=0, max_q=5,
    start_P=0, max_P=3,
    start_Q=0, max_Q=3,
    trace=True,                  # 打印搜索过程
    error_action='ignore',
    suppress_warnings=True,
    stepwise=True
)
print(auto_model.summary())

# ========== SARIMAX(含外生变量)==========
model = SARIMAX(
    train_series,
    exog=exog_train,            # 外生变量:节假日、天气等
    order=(2, 1, 2),            # ARIMA(p,d,q)
    seasonal_order=(1, 1, 1, 7), # (P,D,Q,s) s=7表示周周期
    enforce_stationarity=False,
    enforce_invertibility=False
)
results = model.fit(disp=False)
print(results.summary())

# 预测
forecast = results.get_forecast(steps=30, exog=exog_forecast)
forecast_mean = forecast.predicted_mean
forecast_ci = forecast.conf_int(alpha=0.05)

# ========== 残差诊断 ==========
residuals = results.resid
# Ljung-Box检验:残差是否为白噪声
from statsmodels.stats.diagnostic import acorr_ljungbox
lb_test = acorr_ljungbox(residuals, lags=[10, 20, 30])
print(lb_test)  # p>0.05说明残差是白噪声,模型充分提取了信息

🎯 Prophet vs ARIMA vs LSTM 选型指南

维度ARIMAProphetLSTM
数据量需求50+点100+点(1年+)1000+点
节假日处理需手动构造原生支持需特征工程
多维特征有限支持(exog)有限支持天然支持
可解释性中等弱(黑盒)
短期预测中等
长期预测中等
缺失值敏感鲁棒需处理
🔍13. 孤立森林 (Isolation Forest)基于路径长度的异常检测核心算法

📖 核心原理

Isolation Forest 基于一个直觉:异常点是"少而不同的",因此更容易被随机分割隔离。通过构建多棵随机二叉树,用样本被隔离所需的平均路径长度来衡量异常程度——路径越短,越可能是异常。

异常分数: s(x, n) = 2^(-E[h(x)]/c(n))     接近1=异常,接近0.5=正常
c(n) = 二叉搜索树中n个节点的平均路径长度(归一化常数)
🐍 Python 实现
from sklearn.ensemble import IsolationForest
import numpy as np

# ========== 孤立森林异常检测 ==========
iso_forest = IsolationForest(
    n_estimators=100,         # 树的数量
    contamination=0.05,       # 预期的异常比例(核心参数)
    max_samples='auto',       # 每棵树用的样本数
    max_features=1.0,         # 每棵树用的特征比例
    bootstrap=False,          # 是否用Bootstrap
    random_state=42,
    n_jobs=-1
)

# 训练(注意:无监督,y不需要!)
iso_forest.fit(X)

# 预测:1=正常,-1=异常
anomaly_labels = iso_forest.predict(X)
anomaly_scores = iso_forest.decision_function(X)  # 负值越大=越异常

# 获取异常样本
anomalies = X[anomaly_labels == -1]
print(f'异常样本数: {len(anomalies)} / {len(X)} ({len(anomalies)/len(X)*100:.1f}%)')

# ========== 确定最优contamination ==========
# 用业务规则交叉验证:已知某天是正常/异常的
# 调整contamination使误报率和漏报率达到平衡
from sklearn.metrics import precision_recall_curve

# ========== 多维度异常监控 ==========
# 对每个维度独立检测,再综合判断
dimensions = ['GMV', '订单量', '核销率', '客单价']
all_anomalies = pd.DataFrame()
for dim in dimensions:
    iso = IsolationForest(contamination=0.05, random_state=42)
    scores = iso.fit_predict(X[[dim]])
    all_anomalies[dim+'_anomaly'] = (scores == -1).astype(int)

# 综合判断:>=2个维度异常才告警
all_anomalies['alert'] = all_anomalies.sum(axis=1) >= 2

# ========== 特征重要性(SHAP解释)==========
import shap
explainer = shap.TreeExplainer(iso_forest)
shap_values = explainer.shap_values(X)
shap.summary_plot(shap_values, X)

💼 实战案例:城市×品类GMV异常监控

背景:监控300+城市×20品类的每日GMV,自动检测异常波动并触发告警。

特征构建
每日GMV+订单量+核销率+客单价+同比变化率,5维特征
孤立森林
contamination=0.03,n_estimators=200
告警分级
异常分数<-0.1且≥2维异常→橙色告警;<-0.2且≥3维→红色告警
归因联动
异常告警→自动触发贡献度分解→定位根因维度
📊 业务效果:异常检测精确率87%(vs 人工阈值规则62%),告警量从日均50+降至8条(降噪84%),异常发现平均提前1.5天,帮助运营团队从"被动响应"转为"主动预防"。
🔗14. DBSCAN 密度聚类基于密度的空间聚类核心算法

📖 核心原理

DBSCAN 基于密度的聚类,不需要预设聚类数K。核心概念:核心点(邻域内≥MinPts个点)、边界点、噪声点。通过密度可达性将点连接成簇,自动识别任意形状的聚类并标记噪声。

🔑 两个关键参数:
① ε (eps):邻域半径,决定"多近算邻居"。太大→多个簇合并;太小→大部分点变噪声
② MinPts:核心点所需的最小邻居数。经验值=2×特征维度
选择eps的技巧:画K距离图(每个点到其第K近邻的距离排序),找"肘部"拐点
🐍 Python 实现
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import NearestNeighbors
import numpy as np

# ========== 确定最优 eps(K距离图)==========
def find_optimal_eps(X, min_pts=5):
    neighbors = NearestNeighbors(n_neighbors=min_pts)
    neighbors_fit = neighbors.fit(X)
    distances, _ = neighbors_fit.kneighbors(X)
    # 取每个点到第min_pts近邻的距离,排序
    k_distances = np.sort(distances[:, -1])
    # 画K距离图,找拐点
    plt.plot(k_distances)
    plt.xlabel('Points sorted by distance')
    plt.ylabel(f'{min_pts}-th nearest distance')
    plt.title('K-Distance Graph (找肘部)')
    plt.show()
    return k_distances

# ========== DBSCAN 聚类 ==========
# 数据标准化(DBSCAN对尺度敏感!)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

dbscan = DBSCAN(
    eps=0.5,           # 邻域半径(根据K距离图确定)
    min_samples=5,     # 核心点最少邻居数
    metric='euclidean',
    n_jobs=-1
)
labels = dbscan.fit_predict(X_scaled)

# labels=-1 表示噪声点
n_clusters = len(set(labels)) - (1 if -1 in labels else 0)
n_noise = list(labels).count(-1)
print(f'聚类数: {n_clusters}, 噪声点: {n_noise} ({n_noise/len(labels)*100:.1f}%)')

# ========== 聚类可视化(PCA降维)==========
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

plt.figure(figsize=(10, 8))
colors = plt.cm.tab20(np.linspace(0, 1, n_clusters))
for i in range(n_clusters):
    plt.scatter(X_pca[labels==i, 0], X_pca[labels==i, 1], 
                c=[colors[i]], label=f'Cluster {i}', s=20, alpha=0.7)
plt.scatter(X_pca[labels==-1, 0], X_pca[labels==-1, 1], 
            c='red', marker='x', label='Noise', s=40)
plt.legend()
plt.title(f'DBSCAN: {n_clusters} clusters, {n_noise} noise points')
plt.show()

# ========== 噪声分析(噪声点有什么特征?)==========
noise_df = pd.DataFrame(X, columns=feature_names)
noise_df['label'] = labels
noise_only = noise_df[noise_df['label'] == -1]
print(noise_only.describe())  # 噪声点的统计特征

# ========== HDBSCAN(DBSCAN的进阶版,自动选eps)==========
# pip install hdbscan
import hdbscan
hdb = hdbscan.HDBSCAN(
    min_cluster_size=10,     # 最小簇大小
    min_samples=5,           # 核心点参数
    metric='euclidean',
    cluster_selection_method='eom'  # eom/leaf
)
hdb_labels = hdb.fit_predict(X_scaled)
print(f'HDBSCAN 聚类数: {len(set(hdb_labels))-1}')

💼 实战案例:商家异常经营行为检测

背景:平台上有部分商家存在刷单、虚假交易等异常经营行为,需要从订单量×核销率×客单价×评分×退款率等维度识别异常商家集群。

特征工程
7维商家特征:订单量/核销率/客单价/评分/退款率/回复率/在售商品数
DBSCAN聚类
K距离图确定eps=1.2,min_samples=8
噪声分析
噪声点=异常商家,分析其共性特征
风控闭环
异常商家→风控审核→确认违规→处罚→特征回补模型
📊 业务效果:识别出3个正常商家集群+1个异常噪声群(占3.2%)。异常商家特征:高订单量+低核销率+高退款率,典型的刷单模式。风控团队审核后确认率91%,月均发现违规商家200+。
🗺️综合实战:算法选型速查表Cheat Sheet

📊 按业务需求选算法

业务需求推荐算法选型理由
客户流失预测XGBoost / LightGBM处理不平衡数据好,特征重要性可解释
用户分层/画像K-Means + DBSCANK-Means分层,DBSCAN找异常群
销量/GMV预测(短期)LSTM / LightGBM可融合多维特征,短期精度高
销量预测(中长期+可解释)Prophet节假日处理好,趋势分解清晰
异常检测(多维)Isolation Forest无需标注,自动适应数据分布
图片审核/分类迁移学习(EfficientNet)小样本场景,预训练模型效果好
文本情感分类朴素贝叶斯 / BERT小样本用NB(快),大样本用BERT(准)
规则引擎/可解释决策决策树唯一可100%解释的模型
策略效果评估(非随机)DID / PSM准实验方法,因果推断
高维稀疏数据分类SVM / 逻辑回归维度>样本时SVM优势明显

📊 按数据特征选算法

数据特征推荐算法注意事项
样本量<1000SVM、朴素贝叶斯、决策树避免深度学习,用简单模型+交叉验证
样本量>100万LightGBM、CatBoost训练速度是瓶颈,优先LightGBM
类别特征>50%CatBoost、LightGBMCatBoost原生支持,LightGBM需指定categorical_feature
特征维度>样本数SVM、Lasso回归用L1正则化做特征选择
样本严重不平衡XGBoost(scale_pos_weight)调整权重+SMOTE过采样
时序数据(有季节性)Prophet、SARIMAProphet对节假日更友好
图像/视频数据迁移学习(ResNet/EfficientNet)务必用预训练模型
文本数据朴素贝叶斯(快)/BERT(准)根据精度要求和数据量选择

💼 综合案例:从数据到决策的完整闭环

场景:某OTA平台季度经营分析全流程,涉及用户分层、GMV预测、异常检测、策略建议。

① 用户分层
K-Means + DBSCAN
RFM特征→5个用户群+异常用户识别
② GMV预测
Prophet + XGBoost
Prophet趋势+节假日,XGBoost融合多维特征
③ 异常检测
Isolation Forest
多维度监控→异常告警→归因分析
④ 策略建议
决策树规则提取
从XGBoost提取IF-THEN规则→运营执行
📊 整体效果:用户分群精准度提升40% → 差异化运营使GMV+18% → 异常检测使损失减少60% → 规则引擎使人效提升3倍。整个闭环从数据分析到业务决策的周期从2周缩短至3天。