3、分类算法体系.md 20 KB

机器学习分类算法体系详解

1. sklearn转换器和预估器

3.1.1 转换器 - 特征工程的父类

  1. 实例化

    from sklearn.preprocessing import StandardScaler
    scaler = StandardScaler()
    
  2. fit_transform()

    • fit():计算每列的均值和标准差
    • transform():执行标准化 (x - mean) / std

      x_train_scaled = scaler.fit_transform(x_train)
      x_test_scaled = scaler.transform(x_test)
      

3.1.2 估计器(sklearn机器学习算法的实现)

  1. 实例化

    from sklearn.neighbors import KNeighborsClassifier
    knn = KNeighborsClassifier(n_neighbors=5)
    
  2. 模型训练

    knn.fit(x_train, y_train)  # 生成模型
    
  3. 模型评估

    • 直接比对预测值与真实值

      y_pred = knn.predict(x_test)
      accuracy = (y_pred == y_test).mean()
      
    • 计算准确率

      score = knn.score(X_test, y_test)
      

2. K-近邻算法

3.2.1 核心原理

  • K值选择
    • k=1:易受异常点影响
    • k=样本数:退化为多数表决
  • 距离公式
    • 欧氏距离、曼哈顿距离、闵可夫斯基距离

3.2.2 案例:鸢尾花分类

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler


def knn_iris():
    """
    鸢尾花数据集
    :return:
    """
    # 1. 加载数据集
    iris = load_iris()

    # 2. 数据集划分
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=42)

    # 3. 特征工程 标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)  # fit_transform训练集
    x_test = transfer.transform(x_test)  # transform测试集

    # 4. KNN 算法预估
    estimator = KNeighborsClassifier(n_neighbors=3)
    estimator.fit(x_train, y_train)

    # 5. 模型评估
    # 方法一: 直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("直接比对真实值和预测值:\n", y_test == y_predict)

    # 方法二: 计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率: \n", score)
    return None


if __name__ == '__main__':
    knn_iris()

3.2.3 总结

  • 优点:简单易实现,无需训练
  • 缺点:计算量大,需手动调参
  • 适用场景:小数据集(几千~几万样本)

3.2.4 案例:预测facebook签到位置

facebook_sample.py


3. 模型选择与调优

3.3.1 交叉验证

K折交叉验证:将数据分为K份,轮流作为验证集

from sklearn.model_selection import cross_val_score
scores = cross_val_score(knn, X, y, cv=5)

3.3.2 网格搜索调参

from sklearn.model_selection import GridSearchCV
param_grid = {'n_neighbors': [1,3,5,7,9]}
grid = GridSearchCV(knn, param_grid, cv=5)
grid.fit(X, y)
print(grid.best_params_)  # 输出最优参数
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV


# noinspection DuplicatedCode
def knn_iris_grid_search_cv():
    """
    鸢尾花数据集 KNN算法 网格搜索
    :return:
    """
    # 1. 加载数据集
    iris = load_iris()

    # 2. 数据集划分
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)

    # 3. 特征工程 标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)  # fit_transform训练集
    x_test = transfer.transform(x_test)  # transform测试集

    # 4. KNN 算法预估
    estimator = KNeighborsClassifier()

    # 加入网格搜索与交叉验证
    # 参数准备
    param_grid = {"n_neighbors": [1, 3, 5, 7, 9, 11]}
    estimator = GridSearchCV(estimator, param_grid=param_grid, cv=10)
    estimator.fit(x_train, y_train)

    # 5. 模型评估
    # 方法一: 直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("直接比对真实值和预测值:\n", y_test == y_predict)

    # 方法二: 计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率: \n", score)

    # 6. 获取最佳参数
    print("最佳参数: \n", estimator.best_params_)
    print("最佳结果: \n", estimator.best_score_)
    print("最佳估计器: \n", estimator.best_estimator_)
    print("交叉验证结果: \n", estimator.cv_results_)
    return None


if __name__ == '__main__':
    knn_iris_grid_search_cv()


4. 朴素贝叶斯算法详解

3.4.1、核心原理与公式

朴素贝叶斯(Naive Bayes)是基于贝叶斯定理特征条件独立假设的分类算法。其核心公式为:

$$ P(Y|X) = \frac{P(X|Y) \cdot P(Y)}{P(X)}
$$

  • 贝叶斯定理:计算后验概率 $P(Y|X)$(给定特征 $X$ 时类别 $Y$ 的概率)。
  • 朴素假设:特征 $X = (x_1, x_2, ..., x_n)$ 在给定类别 $Y$ 下条件独立,即:

$$

P(X|Y) = \prod_{i=1}^n P(x_i|Y)  

$$

这一假设简化了计算,但牺牲了部分准确性。

3.4.2、分类决策规则

通过比较后验概率选择最大概率的类别:

$$ \hat{y} = \arg\maxY P(Y) \prod{i=1}^n P(x_i|Y)
$$

由于分母 (P(X)) 对所有类别相同,实际计算中可忽略。

3.4.3、示例与计算步骤

案例:天气预测是否打球
数据集:

天气 温度 湿度 风速 是否打球
晴朗 炎热
晴朗 炎热
多云 炎热
... ... ... ... ...

预测新样本:天气=晴朗,温度=凉爽,湿度=正常,风速=强

  1. 计算先验概率

    • $P(是) = 6/10 = 0.6$
    • $P(否) = 4/10 = 0.4$
  2. 计算条件概率(拉普拉斯平滑):

    • $P(晴朗|是) = (2+1)/(6+3) = 0.333$
    • $P(凉爽|是) = (3+1)/(6+3) = 0.444$
  3. 后验概率比较

    • $P(是|特征) \propto 0.6 \times 0.333 \times 0.444 \times ... \approx 0.022$
    • $P(否|特征) \propto 0.4 \times 0.75 \times 0.25 \times ... \approx 0.0094$
    • 结论:预测为“是”。

3.4.4、优缺点分析

优点

  1. 计算高效,适合高维数据(如文本)。
  2. 对小规模数据表现良好,对缺失值不敏感。

缺点

  1. 特征独立性假设通常不成立,可能影响准确性。
  2. 对输入数据分布偏差敏感(需平滑处理)。

3.4.5、代码实现(Python)

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB

# 加载数据
iris = load_iris()
X, y = iris.data, iris.target

# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# 训练模型
model = GaussianNB()
model.fit(X_train, y_train)

# 预测与评估
print("准确率:", model.score(X_test, y_test))

3.4.6、应用场景

  1. 文本分类:垃圾邮件过滤、情感分析。
  2. 医学诊断:基于症状预测疾病。
  3. 推荐系统:用户行为建模。

3.4.7、扩展:拉普拉斯平滑

为避免零概率问题,对条件概率进行平滑:

$$ P(x_i|Y) = \frac{\text{count}(x_i,Y) + α}{\text{count}(Y) + α \cdot N} $$

其中 $α=1$为平滑参数,$N$ 为特征可能取值数。
通过上述分析可见,朴素贝叶斯虽假设简单,但在实际应用中常因高效性和鲁棒性表现出色。理解其数学基础与适用场景是合理使用的关键。

3.4.8 总结

  • 优点:计算高效,适合文本分类
  • 缺点:依赖特征独立性假设

5. 决策树算法详解

3.5.1、核心原理与结构

决策树是一种基于树状结构的监督学习算法,通过递归划分特征空间实现分类或回归任务。其核心结构包括:

  • 根节点:起始节点,包含全部数据。
  • 内部节点:特征测试节点(如“年龄≥30?”)。
  • 叶节点:最终决策结果(如“批准贷款”)。

工作原理
从根节点开始,根据特征取值选择分支,递归划分数据集,直到满足停止条件(如纯度达标或达到最大深度)。

3.5.2、关键算法与公式

  1. ID3算法(信息增益)

    • 熵(Entropy):衡量数据不确定性,其中 $p_i$ 为类别 $i$ 的概率。
    • 信息增益:选择使熵减少最多的特征
      示例:贷款数据集中,“信贷情况”的信息增益最高,优先作为根节点。
  2. C4.5算法(信息增益率)
    解决 $ID3$ 偏向多值特征的问题:,其中 $H_A(D)$为特征 $A$ 的熵,避免选择取值过多的特征。

  3. CART算法(基尼指数)

    • 基尼指数:衡量数据不纯度,值越小,数据越纯净。$CART$ 支持分类(基尼指数)和回归(均方误差)任务。(sklearn 默认选择)

3.5.3、构建步骤与示例

案例:贷款审批预测
数据集包含特征:年龄、收入、信用评分、是否有房。
步骤

  1. 计算根节点熵
    总样本15个,批准9个,拒绝6个。

  2. 选择最优特征

    • 计算各特征信息增益(如“信贷情况”增益0.179最高)。
    • 若特征为连续值(如收入),需找到最佳分割点(如收入≥50k)。
  3. 递归构建子树

    • 根节点为“信贷情况”,分支为“一般”“好”“非常好”。
    • 子节点继续选择最优特征(如“有房”),直至叶节点纯度达标。

生成树结构

根节点:信贷情况 ≥ 一般?  
├─ 是 → 叶节点:批准(准确率90%)  
└─ 否 → 内部节点:有房?  
   ├─ 是 → 叶节点:批准  
   └─ 否 → 叶节点:拒绝  

3.5.4、优缺点分析

优点

  1. 可解释性强:规则直观,如“收入≥50k且信用好→批准”。
  2. 处理混合数据:支持数值和类别特征,无需标准化。
  3. 特征重要性明确:自动筛选关键特征(如“有房”比“年龄”更重要)。

缺点

  1. 易过拟合:树过深时对噪声敏感,需剪枝(预剪枝/后剪枝)。
  2. 不稳定:数据微小变化可能导致结构剧变。
  3. 偏向多值特征:ID3算法易受高基数特征影响。

3.5.5、剪枝策略

  1. 预剪枝

    • 提前停止分裂(如最大深度=3、最小样本分裂数=5)。
    • 优点:计算快,避免欠拟合风险。
    • 缺点:可能过早停止,损失精度。
  2. 后剪枝

    • 先生成完整树,再自底向上剪除冗余分支。
    • 使用损失函数 $C_α(T) = C(T) + α|T|$,平衡误差与复杂度。
    • 优点:泛化能力更强,适合小数据集。

3.5.6、鸢尾花代码示例(Python)

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier


def decision_tree_iris():
    """
    鸢尾花数据集 决策树算法
    :return:
    """
    # 1) 加载数据集
    iris = load_iris()

    # 2) 数据集划分
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)

    # 3) 特征工程

    # 4) 决策树算法预估
    estimator = DecisionTreeClassifier(criterion="gini", max_depth=None, random_state=None)
    estimator.fit(x_train, y_train)

    # 5) 模型评估
    # 方法一: 直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("直接比对真实值和预测值:\n", y_test == y_predict)

    # 方法二: 计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率: \n", score)
    return None


if __name__ == '__main__':
    decision_tree_iris()

3.5.7、应用场景

  1. 分类任务

    • 医疗诊断(根据症状预测疾病)。
    • 金融风控(评估贷款违约风险)。
  2. 回归任务

    • 房价预测(基于面积、地段等特征)。
    • 销售额估算(根据广告投入、季节因素)。

通过特征选择、树结构优化和剪枝策略,决策树在可解释性与性能间取得平衡,是理解复杂数据关系的有力工具。

3.5.8、泰坦尼克号--特殊示例

titanic_sample.py


6. 随机森林算法详解

3.6.1、核心原理与公式

随机森林(Random Forest)是一种基于集成学习决策树的算法,通过组合多棵树的预测结果提升模型性能。其核心包含三个关键点:

  1. Bagging(自助采样)
    从原始数据集中有放回地随机抽取样本(约63.2%的数据用于训练单棵树),生成多个子数据集。
    公式

    $$ \text{Bootstrap采样} = \text{随机选择} \ N \ \text{个样本(允许重复)} $$

  2. 随机特征选择
    每个节点分裂时,仅从全部特征中随机选择 $m$ 个候选特征(通常 $m = \sqrt{\text{总特征数}}$),避免树间高度相似。

  3. 集成策略

    • 分类任务:多数投票(Majority Voting)
    • 回归任务:预测均值(Mean Averaging)

3.6.2、算法步骤与示例

案例:鸢尾花分类

数据集包含4个特征(花萼长/宽、花瓣长/宽)和3个类别(Setosa、Versicolour、Virginica)。

步骤

  1. 生成多棵决策树

    • 每棵树使用不同的Bootstrap样本训练。
    • 节点分裂时随机选择2个特征(总特征数=4)。
  2. 预测新样本

    • 输入样本
    • 每棵树独立预测类别,最终通过投票确定结果。

Python代码实现

from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split


# noinspection DuplicatedCode
def random_forest_iris():
    """
    鸢尾花数据集 随机森林算法
    :return:
    """
    # 1) 加载数据集
    iris = load_iris()

    # 2) 数据集划分
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)

    # 3) 特征工程

    # 4) 随机森林算法预估
    estimator = RandomForestClassifier(n_estimators=10, random_state=22, max_features="sqrt")  # n_estimators: 树的数量
    # 加入网格搜索与交叉验证
    param_grid = {"n_estimators": [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]}
    estimator = GridSearchCV(estimator, param_grid=param_grid, cv=10)
    estimator.fit(x_train, y_train)

    # 5) 模型评估
    # 方法一: 直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("直接比对真实值和预测值:\n", y_test == y_predict)

    # 方法二: 计算准确率
    score = estimator.score(x_test, y_test)
    print("准确率: \n", score)

    # 6. 获取最佳参数
    print("最佳参数: \n", estimator.best_params_)
    print("最佳结果: \n", estimator.best_score_)
    print("最佳估计器: \n", estimator.best_estimator_)
    print("交叉验证结果: \n", estimator.cv_results_)


if __name__ == '__main__':
    random_forest_iris()

3.6.3、关键特性与优势

特性 说明
抗过拟合 通过随机采样和特征选择降低方差,避免单棵树过拟合。
并行化训练 各树独立训练,支持多线程加速(n_jobs参数)。
特征重要性评估 基于特征在分裂时的贡献度(如基尼指数下降)自动排序。
处理缺失值 通过替代分裂机制(Surrogate Splits)自动处理缺失数据。

3.6.4、超参数调优

参数 作用 推荐范围
n_estimators 树的数量,影响模型稳定性 100-500
max_depth 单树最大深度,防止过拟合 5-30
max_features 节点分裂时考虑的特征数 sqrt(分类)、log2
min_samples_split 内部节点分裂所需最小样本数 2-20
bootstrap 是否使用自助采样 True(默认)

网格搜索示例

from sklearn.model_selection import GridSearchCV

param_grid = {
    'n_estimators': [50, 100, 200],
    'max_depth': [5, 10, None],
    'max_features': ['sqrt', 'log2']
}
grid_search = GridSearchCV(RandomForestClassifier(), param_grid, cv=5)
grid_search.fit(X_train, y_train)
print("最佳参数:", grid_search.best_params_)

3.6.5、优缺点分析

优点

  1. 高准确性:集成多棵树减少噪声影响,优于单棵决策树。
  2. 鲁棒性:对缺失值、异常值不敏感,适合复杂数据。
  3. 特征洞察:直接输出特征重要性,辅助特征工程。

缺点

  1. 计算成本高:树数量多时训练耗时,内存占用大。
  2. 可解释性弱:集成结果难以追溯单棵树决策路径。
  3. 偏差问题:对简单数据可能过拟合(需调整max_depth)。

3.6.6、应用场景

  1. 分类任务

    • 金融风控:信用评分、欺诈检测(如信用卡交易异常识别)。
    • 医疗诊断:基于症状预测疾病(如癌症类型分类)。
  2. 回归任务

    • 房价预测:结合房屋面积、地段等特征。
    • 销量估算:根据广告投入、季节因素预测销量。
  3. 特征工程

    • 自动筛选关键特征(如电商用户行为分析)。

3.6.7、扩展:随机森林的变种

  1. Extra Trees(极端随机树)
    • 节点分裂时随机选择特征和切分点,进一步降低方差。
  2. Isolation Forest(孤立森林)
    • 专用于异常检测,通过随机分割快速隔离异常点。
  3. Quantile Regression Forests
    • 支持分位数预测,适用于不确定性量化。

3.6.8、与梯度提升树(GBDT)对比

特性 随机森林 梯度提升树(如XGBoost)
训练方式 并行独立训练多棵树 串行训练,每棵树修正前序错误
偏差-方差权衡 主要降低方差 同时降低偏差和方差
参数敏感性 相对低(默认参数效果较好) 高(需精细调参如学习率、树深度)
适用场景 快速原型开发、高维数据 高精度需求、中小规模数据

总结

随机森林通过Bagging随机特征选择实现高效集成,在多数场景下表现出色。其优势在于抗过拟合特征可解释性,但需注意计算成本和模型复杂度。对于需要更高精度的任务,可结合梯度提升树进一步优化。

3.6.9、泰坦尼克号--特殊示例

titanic_sample_random_forest.py

附:算法对比

算法 优点 缺点 适用场景
KNN 无需训练,简单直观 计算量大,需调参 小数据集
朴素贝叶斯 高效,适合文本 特征独立性假设 文本分类
决策树 可解释性强 易过拟合 结构化数据分类
随机森林 高准确率,抗过拟合 计算成本高 大数据集,高维特征