目录

AI机器学习十大算法

目录

经典算法笔记

K 近邻算法

简介

K 近邻算法(K-Nearest Neighbors,简称 KNN)是一种简单且常用的分类和回归算法。 K近邻算法属于监督学习的一种,核心思想是通过计算待分类样本与训练集中各个样本的距离,找到距离最近的K个样本,然后根据这K个样本的类别或值来预测待分类样本的类别或值。KNN 同样可以用于回归任务(KNN Regression)。

KNN 的基本原理

KNN算法的基本原理可以概括为以下几个步骤: 1.计算距离:计算待分类样本与训练集中每个样本的距离。常用的距离度量方法有欧氏距离、曼哈顿距离等。 2.选择K个最近邻:根据计算出的距离,选择距离最近的K个样本。 3.投票或平均:对于分类问题,K个最近邻中出现次数最多的类别即为待分类样本的类别;对于回归问题,K个 最近邻的值的平均值即为待分类样本的值。

KNN 的特点

  • 简单易理解:KNN 算法的原理非常简单,容易理解和实现。
  • 无需训练:KNN 是一种"懒惰学习"算法,不需要显式的训练过程,所有的计算都在预测时进行。
  • 对数据分布无假设:KNN不对数据的分布做任何假设,适用于各种类型的数据。
  • 计算复杂度高:由于KNN 需要在预测时计算所有样本的距离,当数据集较大时,计算复杂度会很高。

KNN算法的优缺点

  • 优点
    • 简单易用:KNN 算法的原理简单,易于理解和实现。
    • 无需训练:KNN 不需要显式的训练过程,所有的计算都在预测时进行。适用于多分类问题:KNN可以轻松处理多分类问题。
  • 缺点
    • 计算复杂度高:KNN 需要在预测时计算所有样本的距离,当数据集较大时,计算复杂度会很高。
    • 对噪声敏感:KNN 对噪声数据较为敏感,噪声数据可能会影响预测结果。
    • 需要选择合适的K值:K 值的选择对模型的性能有很大影响,选择合适的K 值是一个挑战。

5. KNN算法的实现步骤

  1. KNN分类模型实战:鸢尾花数据集分类
# ==============================================
# KNN分类模型实战:鸢尾花数据集分类
# 功能:使用KNN算法对鸢尾花数据集进行分类,并评估模型准确率
# 核心库说明:
# numpy - 数值计算基础库
# matplotlib - 绘图可视化(本脚本预留可视化接口,可按需启用)
# sklearn - 提供数据集、数据拆分、KNN模型、准确率评估等功能
# ==============================================

# 1. 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

# ---------------- 关键修复:配置matplotlib中文显示 ----------------
# 解决中文显示为方框的问题,适配Windows/Mac/Linux系统
def set_matplotlib_chinese_font():
    try:
        # Windows系统优先加载微软雅黑
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    except:
        try:
            # Mac系统加载苹方字体
            plt.rcParams['font.sans-serif'] = ['PingFang SC']
        except:
            # Linux系统加载文泉驿微米黑
            plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
    # 解决负号显示为方块的问题
    plt.rcParams['axes.unicode_minus'] = False

# 执行中文配置
set_matplotlib_chinese_font()

# 2. 加载数据集
# 使用sklearn内置的鸢尾花数据集(150个样本,4个特征,3类标签)
# 仅取前2个特征(萼片长度、萼片宽度),便于后续可视化(即使不绘图也不影响模型训练)
iris = datasets.load_iris()
X = iris.data[:, :2]  # 特征矩阵:取前2列特征
y = iris.target       # 标签向量:3类鸢尾花(0/1/2)

# 3. 数据预处理:拆分训练集和测试集
# test_size=0.3:测试集占30%,训练集占70%
# random_state=42:固定随机种子,保证每次运行结果一致
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# 4. 训练KNN模型
# n_neighbors=3:设置K值为3,即选取3个最近邻进行投票分类
knn = KNeighborsClassifier(n_neighbors=3)
# 用训练集数据训练模型
knn.fit(X_train, y_train)

# 5. 模型预测与评估
# 用训练好的模型对测试集进行预测
y_pred = knn.predict(X_test)
# 计算模型准确率(预测正确的样本数 / 总测试样本数)
accuracy = accuracy_score(y_test, y_pred)
# 输出准确率,保留4位小数
print(f"KNN模型的准确率: {accuracy:.4f}")

# 可视化分类结果
# 定义网格步长,用于绘制决策边界
h = 0.02
# 定义坐标轴范围(特征1和特征2的最小值/最大值,留出少量余量)
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

# 对网格中每个点进行预测,生成决策边界
Z = knn.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

# 绘制决策边界
plt.figure(figsize=(8, 6))
plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.Paired)
# 绘制训练集样本点(用x区分)
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, edgecolors='k', cmap=plt.cm.Paired, marker='x', label='训练集', alpha=0.8)
# 绘制测试集样本点(用空心圆区分)
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test, edgecolors='k', cmap=plt.cm.Paired, marker='o', s=100, label='测试集', facecolors='none', linewidth=2)
# 添加图例(关键!明确标注两类样本)
plt.legend(loc='upper right', fontsize=10)
plt.xlabel('萼片长度 (cm)')
plt.ylabel('萼片宽度 (cm)')
plt.title(f'KNN (K=3) 鸢尾花分类结果 (准确率: {accuracy:.4f})')
plt.show()

一、线性回归(Linear Regression)

1. 简介

线性回归是一种监督学习回归算法,核心是通过构建特征与目标值之间的线性关系模型,实现对连续型目标变量的预测。它是机器学习中最基础、最经典的算法之一,原理简单易懂,同时也是许多复杂回归模型的基础,广泛应用于房价预测、销量预估、气温预测等连续值预测场景。

根据特征数量的不同,线性回归可分为单变量线性回归(仅一个特征)和多变量线性回归(多个特征),核心思想均是找到最优线性参数,使模型预测值与真实值的误差最小化。

2. 基本原理

2.1 模型表达式

单变量线性回归模型表达式:y=wx+b y = wx + b ,其中 x x 为特征变量,y y 为目标变量,w w 为权重系数,b b 为偏置项,模型核心是求解最优的 w w 和 b b 。

多变量线性回归模型表达式:y=w1x1+w2x2+...+wnxn+b y = w_1x_1 + w_2x_2 + ... + w_nx_n + b ,可简化为矩阵形式 y=XW+b y = XW + b ,其中 X X 为特征矩阵(维度:样本数×特征数),W W 为权重向量,b b 为偏置项,适用于多特征场景。

2.2 核心目标

线性回归的核心目标是最小化预测值与真实值的误差,常用的误差度量方式为均方误差(MSE),即所有样本误差的平方和的平均值。均方误差公式如下:

MSE=1m∑i=1m(yi−y^i)2 MSE = \frac{1}{m} \sum_{i=1}^{m} (y_i - \hat{y}_i)^2

其中 m m 为样本数量,yi y_i 为第 i i 个样本的真实值,y^i \hat{y}_i 为模型对第 i i 个样本的预测值。模型训练过程就是求解 W W 和 b b ,使 MSE 达到最小值的过程。

2.3 参数求解方法

  • 最小二乘法(解析解):通过数学推导直接求解最优参数,适用于特征数量较少(通常小于1000)的场景。对于多变量线性回归,权重向量 W W 的解析解为 W=(XTX)−1XTy W = (X^TX)^{-1}X^Ty (需满足 XTX X^TX 可逆),偏置项 b b 可通过样本均值计算得出。

  • 梯度下降法(数值解):通过迭代更新参数以逼近最优解,适用于特征数量较多、XTX X^TX 不可逆的场景。核心逻辑是计算损失函数对各参数的梯度,沿梯度负方向逐步调整参数,直至损失函数收敛到最小值。

3. 特点

  • 原理简单:模型假设清晰,线性关系易于理解和解释,可直观得到各特征对目标变量的影响程度(通过权重系数)。

  • 训练高效:解析解可直接求解,梯度下降法迭代速度快,对小规模数据处理效率极高。

  • 对数据有假设:假设特征与目标变量呈线性关系,且误差服从正态分布,若数据存在非线性关系,模型效果较差。

  • 对异常值敏感:异常值会显著影响均方误差,导致参数估计偏差,降低模型泛化能力。

4. 优缺点

4.1 优点

  • 解释性强:权重系数可量化特征对目标的影响方向(正/负)和程度,适合需要解释预测逻辑的场景(如金融风控、医疗分析)。

  • 计算成本低:训练和预测过程的时间、空间复杂度低,可快速部署。

  • 可扩展性好:可通过特征工程(如多项式特征)适配轻度非线性数据,也可作为集成模型的基础组件。

4.2 缺点

  • 线性假设局限:无法捕捉特征与目标变量的非线性关系,对复杂数据拟合效果差。

  • 对多重共线性敏感:当特征间存在强相关性时,会导致权重系数不稳定,模型泛化能力下降。

  • 仅适用于连续型目标:无法直接处理分类任务,需结合其他方法扩展。

5. 实现步骤(实战:波士顿房价预测)


# ==============================================
# 线性回归模型实战:波士顿房价预测
# 功能:使用线性回归算法预测波士顿房价,评估模型拟合效果
# 核心库说明:
# numpy - 数值计算基础库
# matplotlib - 绘图可视化
# sklearn - 提供数据集、数据拆分、线性回归模型、评估指标等功能
# ==============================================

# 1. 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score

# ---------------- 配置matplotlib中文显示 ----------------
def set_matplotlib_chinese_font():
    try:
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    except:
        try:
            plt.rcParams['font.sans-serif'] = ['PingFang SC']
        except:
            plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
    plt.rcParams['axes.unicode_minus'] = False

set_matplotlib_chinese_font()

# 2. 加载数据集(波士顿房价数据集,506个样本,13个特征)
boston = load_boston()
X = boston.data  # 特征矩阵:13个特征(如人均犯罪率、住宅平均房间数等)
y = boston.target  # 目标变量:波士顿地区房屋中位数价格(单位:千美元)
print(f"数据集维度:特征数={X.shape[1]}, 样本数={X.shape[0]}")

# 3. 数据预处理:拆分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42  # 测试集占20%,固定随机种子
)

# 4. 训练线性回归模型(使用最小二乘法求解)
lr_model = LinearRegression()
lr_model.fit(X_train, y_train)  # 用训练集训练模型

# 输出模型参数
print("\n线性回归模型参数:")
print(f"偏置项 b = {lr_model.intercept_:.4f}")
print("权重系数 W:", np.round(lr_model.coef_, 4))

# 5. 模型预测与评估
y_train_pred = lr_model.predict(X_train)  # 训练集预测值
y_test_pred = lr_model.predict(X_test)    # 测试集预测值

# 计算评估指标
train_mse = mean_squared_error(y_train, y_train_pred)  # 训练集均方误差
test_mse = mean_squared_error(y_test, y_test_pred)      # 测试集均方误差
train_r2 = r2_score(y_train, y_train_pred)              # 训练集R²系数
test_r2 = r2_score(y_test, y_test_pred)                  # 测试集R²系数

print("\n模型评估结果:")
print(f"训练集均方误差(MSE):{train_mse:.4f}")
print(f"测试集均方误差(MSE):{test_mse:.4f}")
print(f"训练集R²系数:{train_r2:.4f}")
print(f"测试集R²系数:{test_r2:.4f}")  # R²越接近1,模型拟合效果越好

# 可视化:真实值与预测值对比(测试集)
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_test_pred, alpha=0.6, color='blue', label='真实值vs预测值')
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2, label='理想拟合线')
plt.xlabel('房屋真实价格(千美元)')
plt.ylabel('房屋预测价格(千美元)')
plt.title(f'线性回归模型:真实价格与预测价格对比(R²={test_r2:.4f})')
plt.legend()
plt.grid(alpha=0.3)
plt.show()

# 可视化:残差分布(预测值与真实值的差值)
residuals = y_test - y_test_pred
plt.figure(figsize=(10, 6))
plt.scatter(y_test_pred, residuals, alpha=0.6, color='green')
plt.axhline(y=0, color='red', linestyle='--', lw=2)
plt.xlabel('预测价格(千美元)')
plt.ylabel('残差(真实值-预测值)')
plt.title('残差分布(残差近似正态分布说明模型拟合合理)')
plt.grid(alpha=0.3)
plt.show()

二、逻辑回归(Logistic Regression)

1. 简介

逻辑回归虽名为“回归”,实则是一种监督学习分类算法,核心是通过Sigmoid函数将线性回归的输出映射到[0,1]区间,转化为分类概率,实现对二分类或多分类任务的预测。它是工业界应用最广泛的分类算法之一,尤其适用于风控建模、用户 churn 预测、疾病诊断等二分类场景,同时具备良好的解释性和高效的训练速度。

逻辑回归可分为二分类逻辑回归(默认)和多分类逻辑回归(通过One-vs-Rest或One-vs-One策略扩展),核心逻辑是基于线性模型输出分类概率,再通过阈值判断类别。

2. 基本原理

2.1 核心函数:Sigmoid函数

Sigmoid函数(也叫逻辑函数)是逻辑回归的核心,用于将线性回归的连续输出(z=XW+b z = XW + b )映射到[0,1]区间,输出值可解释为样本属于正类的概率。Sigmoid函数公式及特性如下:

σ(z)=11+e−z \sigma(z) = \frac{1}{1 + e^{-z}}

特性:当 z→+∞ z \to +\infty 时,σ(z)→1 \sigma(z) \to 1 ;当 z→−∞ z \to -\infty 时,σ(z)→0 \sigma(z) \to 0 ;当 z=0 z = 0 时,σ(z)=0.5 \sigma(z) = 0.5 。通过该函数,可将线性模型的输出转化为分类概率。

2.2 模型表达式与分类逻辑

二分类逻辑回归模型表达式(概率形式):

P(y=1∣X)=σ(XW+b)=11+e−(XW+b) P(y=1|X) = \sigma(XW + b) = \frac{1}{1 + e^{-(XW + b)}}

P(y=0∣X)=1−P(y=1∣X) P(y=0|X) = 1 - P(y=1|X)

分类逻辑:设定概率阈值(通常为0.5),若 P(y=1∣X)≥0.5 P(y=1|X) \geq 0.5 ,则预测样本为正类(y=1);否则为负类(y=0)。阈值可根据业务需求调整(如风控场景需提高正类识别率,可降低阈值)。

2.3 损失函数与参数求解

逻辑回归无法使用均方误差作为损失函数(会导致损失函数非凸,存在多个局部最小值),常用对数损失函数(Log Loss) 作为优化目标,公式如下(二分类场景):

Loss=−1m∑i=1m[yiln⁡(y^i)+(1−yi)ln⁡(1−y^i)] Loss = -\frac{1}{m} \sum_{i=1}^{m} [y_i \ln(\hat{y}_i) + (1 - y_i) \ln(1 - \hat{y}_i)]

其中 y^i=P(y=1∣Xi) \hat{y}_i = P(y=1|X_i) ,当 yi=1 y_i=1 时,损失项为 −ln⁡(y^i) -\ln(\hat{y}_i) ;当 yi=0 y_i=0 时,损失项为 −ln⁡(1−y^i) -\ln(1 - \hat{y}_i) ,核心是惩罚预测概率与真实标签偏差较大的样本。

参数求解:对数损失函数无解析解,需通过梯度下降法(批量梯度下降、随机梯度下降SGD等)迭代更新参数 W W 和 b b ,使损失函数最小化。

3. 特点

  • 解释性强:权重系数可反映特征对分类概率的影响程度,结合Sigmoid函数可量化特征对正类的贡献(正权重提升正类概率,负权重降低正类概率)。

  • 训练高效:模型参数少,梯度下降迭代速度快,适用于大规模数据集和高维特征场景。

  • 适合二分类:原生支持二分类,多分类需扩展策略,对极端不平衡数据敏感(需预处理)。

  • 假设边界线性:本质是线性分类器,仅能捕捉特征与分类结果的线性关系,对非线性数据需结合特征工程。

4. 优缺点

4.1 优点

  • 高效且轻量化:训练和预测速度快,内存占用低,可快速部署到线上系统。

  • 解释性优异:可通过权重系数、概率输出解释分类逻辑,满足合规性要求(如金融、医疗领域)。

  • 抗过拟合能力较强:通过正则化(L1、L2)可有效抑制过拟合,提升泛化能力。

  • 输出概率值:不仅能预测类别,还能输出分类概率,可用于风险评估(如用户违约概率)。

4.2 缺点

  • 线性假设局限:无法处理特征与分类结果的非线性关系,需通过多项式特征、核函数等扩展。

  • 对异常值敏感:异常值会影响参数估计,导致模型偏差,需提前处理异常值。

  • 对特征依赖性高:需手动进行特征工程(如去除多重共线性、离散化非线性特征),否则效果较差。

5. 实现步骤(实战:鸢尾花二分类)


# ==============================================
# 逻辑回归模型实战:鸢尾花二分类(取两类样本)
# 功能:使用逻辑回归算法实现二分类,评估模型性能并可视化决策边界
# 核心库说明:
# numpy - 数值计算基础库
# matplotlib - 绘图可视化
# sklearn - 提供数据集、模型、评估指标等功能
# ==============================================

# 1. 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

# ---------------- 配置matplotlib中文显示 ----------------
def set_matplotlib_chinese_font():
    try:
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    except:
        try:
            plt.rcParams['font.sans-serif'] = ['PingFang SC']
        except:
            plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
    plt.rcParams['axes.unicode_minus'] = False

set_matplotlib_chinese_font()

# 2. 加载数据集并预处理(鸢尾花数据集取前两类,二分类任务)
iris = load_iris()
# 取前2个特征(便于可视化),取标签为0和1的样本(两类鸢尾花)
mask = (iris.target == 0) | (iris.target == 1)
X = iris.data[mask, :2]  # 特征矩阵(萼片长度、萼片宽度)
y = iris.target[mask]    # 标签向量(0/1)
print(f"二分类数据集维度:特征数={X.shape[1]}, 样本数={X.shape[0]}")

# 3. 数据预处理:拆分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y  # stratify=y:保持训练集与测试集类别分布一致
)

# 4. 训练逻辑回归模型(加入L2正则化抑制过拟合)
lr_model = LogisticRegression(penalty='l2', C=1.0, random_state=42)
# penalty='l2':L2正则化;C=1.0:正则化强度倒数,C越小正则化越强
lr_model.fit(X_train, y_train)

# 输出模型参数
print("\n逻辑回归模型参数:")
print(f"偏置项 b = {lr_model.intercept_[0]:.4f}")
print(f"权重系数 W = {np.round(lr_model.coef_[0], 4)}")

# 5. 模型预测与评估
y_pred = lr_model.predict(X_test)  # 类别预测
y_pred_prob = lr_model.predict_proba(X_test)[:, 1]  # 正类(y=1)概率预测

# 计算评估指标
accuracy = accuracy_score(y_test, y_pred)  # 准确率
conf_matrix = confusion_matrix(y_test, y_pred)  # 混淆矩阵
class_report = classification_report(y_test, y_pred)  # 分类报告(精确率、召回率、F1值)

print("\n模型评估结果:")
print(f"准确率(Accuracy):{accuracy:.4f}")
print("混淆矩阵:")
print(conf_matrix)
print("分类报告:")
print(class_report)

# 可视化:决策边界
h = 0.02  # 网格步长
x_min, x_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
y_min, y_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

# 预测网格中每个点的类别,生成决策边界
Z = lr_model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

# 绘制决策边界和样本点
plt.figure(figsize=(10, 6))
plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.Paired)
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, edgecolors='k', cmap=plt.cm.Paired, marker='x', label='训练集')
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test, edgecolors='k', cmap=plt.cm.Paired, marker='o', s=100, label='测试集', facecolors='none')
plt.xlabel('萼片长度 (cm)')
plt.ylabel('萼片宽度 (cm)')
plt.title(f'逻辑回归二分类决策边界(准确率:{accuracy:.4f})')
plt.legend(loc='upper right')
plt.grid(alpha=0.3)
plt.show()

# 可视化:正类概率分布(测试集)
plt.figure(figsize=(10, 6))
plt.scatter(range(len(y_test)), y_pred_prob, c=y_test, cmap=plt.cm.Paired, alpha=0.8, s=80)
plt.axhline(y=0.5, color='red', linestyle='--', label='分类阈值(0.5)')
plt.xlabel('测试集样本索引')
plt.ylabel('正类(y=1)预测概率')
plt.title('测试集正类概率分布')
plt.legend()
plt.grid(alpha=0.3)
plt.show()

三、决策树(Decision Tree)

1. 简介

决策树是一种监督学习算法,可同时处理分类和回归任务,核心是通过模拟人类决策逻辑,树状结构表示决策过程,每个内部节点代表一个特征或属性的测试,每个分支代表测试的结果走向,每个叶节点代表一个类别或值。根节点代表整个数据集,内部节点代表特征判断条件,叶节点代表最终的预测结果(类别或数值)。它原理直观、无需特征归一化,是集成学习(如随机森林、GBDT)的核心基础组件,广泛应用于医疗诊断、金融风控、推荐系统等场景。

根据任务类型,决策树可分为分类决策树(如ID3、C4.5、CART)和回归决策树(仅CART),其中CART树(分类与回归树)是最常用的类型,可处理连续型和离散型特征。

2. 基本原理

2.1 工作原理

决策树通过递归地将数据集分割成更小的子集来构建树结构。具体步骤如下:

  • 选择最佳特征:根据某种标准(如信息增益、基尼指数等)选择最佳特征进行分割。

  • 分割数据集:根据选定的特征将数据集分成多个子集。

  • 递归构建子树:对每个子集重复上述过程,直到满足停止条件(如所有样本属于同一类别、达到最大深度等)。

  • 生成叶节点:当满足停止条件时,生成叶节点并赋予类别或值。

2.2 核心分裂准则

决策树的关键是选择最优特征和分裂阈值进行节点分裂,目标是使分裂后的数据“纯度”提升(分类任务)或误差减小(回归任务),常用准则如下:

  • 分类任务:

    • 信息增益(ID3算法):基于信息熵,衡量分裂后数据集不确定性减少的程度,信息增益越大,分裂效果越好。信息熵公式:H(D)=−∑k=1K∣Dk∣∣D∣log⁡2∣Dk∣∣D∣ H(D) = -\sum_{k=1}^{K} \frac{|D_k|}{|D|} \log_2 \frac{|D_k|}{|D|} ,信息增益公式:g(D,A)=H(D)−∑v=1V∣Dv∣∣D∣H(Dv) g(D,A) = H(D) - \sum_{v=1}^{V} \frac{|D_v|}{|D|} H(D_v) 。

    • 信息增益比(C4.5算法):解决信息增益偏好多取值特征的问题,通过除以特征自身的信息熵进行修正。

    • Gini系数(CART算法):衡量数据集的不纯度,Gini系数越小,数据纯度越高。公式:Gini(D)=1−∑k=1K(∣Dk∣∣D∣)2 Gini(D) = 1 - \sum_{k=1}^{K} \left( \frac{|D_k|}{|D|} \right)^2 。

  • 回归任务(CART算法):采用均方误差(MSE)或平均绝对误差(MAE),选择使子节点误差最小的特征和阈值进行分裂。

2.3 剪枝策略(防过拟合)

决策树易过拟合(树深度过深,捕捉噪声数据),需通过剪枝优化,分为两种策略:

  • 预剪枝:训练过程中限制树的生长,如设定最大深度、最小样本分裂数、最小样本叶节点数,简单高效但可能欠拟合。

  • 后剪枝:先生成完整决策树,再从叶节点向上剪枝,通过验证集误差判断是否保留分支,泛化能力更强但计算成本高(如CART树的成本复杂度剪枝)。

3. 特点

  • 直观易懂:树结构可可视化,决策逻辑清晰,无需专业背景即可解释预测过程(如“若年龄>30且收入>50万,则推荐高端产品”)。

  • 无需预处理:对特征尺度不敏感,无需归一化/标准化;可直接处理离散型和连续型特征,对缺失值有一定容错性。

  • 易过拟合:未剪枝的决策树易拟合噪声数据,泛化能力差,需依赖剪枝或集成学习优化。

  • 不稳定:特征微小变化可能导致树结构大幅改变,预测结果波动较大。

4. 优缺点

4.1 优点

  • 解释性极强:可直接生成决策规则,适合需要透明化预测逻辑的场景(如医疗、合规风控)。

  • 处理复杂数据:可捕捉特征间的非线性关系,无需手动特征工程。

  • 训练高效:单棵树训练过程简单,可快速生成模型,适合小规模数据集快速迭代。

4.2 缺点

  • 泛化能力弱:单棵树易过拟合,对复杂数据集预测精度有限,通常需集成使用。

  • 偏向多取值特征:信息增益准则下,多取值特征(如ID)易被优先选择,导致模型偏差。

  • 对不平衡数据敏感:样本类别分布不均时,模型易偏向多数类,需平衡样本后训练。

5. 实现步骤(实战:鸢尾花分类)


# ==============================================
# 决策树模型实战:鸢尾花多分类
# 功能:使用CART决策树实现多分类,可视化树结构并评估性能
# 核心库说明:
# sklearn - 提供数据集、决策树模型、评估指标、树可视化工具
# matplotlib - 绘图可视化
# graphviz - 树结构可视化(需提前安装:pip install graphviz)
# ==============================================

# 1. 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, plot_tree, export_graphviz
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import graphviz
from sklearn.preprocessing import LabelEncoder

# 配置中文显示
def set_matplotlib_chinese_font():
    try:
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    except:
        try:
            plt.rcParams['font.sans-serif'] = ['PingFang SC']
        except:
            plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
    plt.rcParams['axes.unicode_minus'] = False

set_matplotlib_chinese_font()

# 2. 加载数据集
iris = load_iris()
X = iris.data  # 4个特征
y = iris.target  # 3类标签(0/1/2)
feature_names = iris.feature_names
class_names = iris.target_names

# 3. 数据拆分
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)

# 4. 训练决策树模型(预剪枝优化)
dt_model = DecisionTreeClassifier(
    criterion='gini',  # 分裂准则:Gini系数
    max_depth=3,       # 最大深度(预剪枝)
    min_samples_split=5,  # 最小样本分裂数
    min_samples_leaf=2,   # 最小样本叶节点数
    random_state=42
)
dt_model.fit(X_train, y_train)

# 5. 模型评估
y_pred = dt_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)
class_report = classification_report(y_test, y_pred, target_names=class_names)

print(f"决策树模型准确率:{accuracy:.4f}")
print("\n混淆矩阵:")
print(conf_matrix)
print("\n分类报告:")
print(class_report)

# 6. 特征重要性分析(从业必备:识别关键特征)
feature_importance = dt_model.feature_importances_
importance_df = np.array([feature_names, feature_importance]).T
print("\n特征重要性排序:")
print(importance_df[np.argsort(feature_importance)[::-1]])

# 7. 可视化树结构(文本可视化)
plt.figure(figsize=(15, 10))
plot_tree(dt_model, filled=True, feature_names=feature_names, class_names=class_names, rounded=True, fontsize=10)
plt.title('CART决策树结构(最大深度=3)')
plt.show()

# 8. 可视化树结构(graphviz高清可视化)
dot_data = export_graphviz(
    dt_model, out_file=None, feature_names=feature_names, class_names=class_names,
    filled=True, rounded=True, special_characters=True
)
graph = graphviz.Source(dot_data)
graph.render("iris_decision_tree")  # 保存为PDF文件
graph.view()  # 打开可视化窗口

四、随机森林(Random Forest)

1. 简介

随机森林是一种集成学习算法,基于“Bagging(套袋法)”策略,通过构建多棵独立的决策树,再对所有树的预测结果进行投票(分类)或平均(回归),得到最终预测结果。它继承了决策树的直观性,同时通过“随机性”(样本随机抽样、特征随机选择)解决了单棵决策树过拟合、不稳定的问题,是工业界和竞赛中常用的高性能算法,适用于分类、回归、特征重要性评估等场景。

随机森林的核心是“随机”与“集成”:随机保证单棵树的多样性,集成通过多数投票降低方差,最终实现泛化能力的提升。

2. 基本原理

2.1 核心流程(Bagging+随机特征)

  1. 样本随机抽样(Bootstrap抽样):从原始训练集中,有放回地随机抽取m个样本(m与原样本数一致),形成多个不同的训练子集(每个子集对应一棵决策树),未被抽取的样本组成OOB(袋外样本),可用于无验证集评估模型。

  2. 特征随机选择:每棵决策树分裂时,从所有特征中随机选择k个特征(k通常为√总特征数),仅从这k个特征中选择最优分裂特征,进一步增强树的多样性。

  3. 构建单棵决策树:基于每个训练子集和随机选择的特征,构建多棵独立的决策树(通常不剪枝,依赖集成效果抑制过拟合)。

  4. 集成预测:分类任务采用“硬投票”(多数树预测的类别为最终结果)或“软投票”(基于树预测的概率加权平均);回归任务采用所有树预测值的平均值。

2.2 关键参数(从业必备)

  • n_estimators:决策树数量,数量越多泛化能力越强,但计算成本越高,通常取100-500。

  • max_features:每棵树分裂时随机选择的特征数,分类任务默认√总特征数,回归任务默认总特征数/3。

  • max_depth:单棵树的最大深度,控制树的复杂度,避免单棵树过拟合。

  • bootstrap:是否使用Bootstrap抽样,默认True,开启后使用OOB评估。

3. 特点

  • 泛化能力强:通过集成策略大幅降低单棵决策树的过拟合风险,对复杂数据适应性好。

  • 稳定性高:单棵树的预测波动被集成抵消,对特征微小变化不敏感。

  • 支持特征重要性评估:通过所有树的特征分裂贡献度,量化每个特征的重要性,辅助特征筛选。

  • 计算成本高:多棵树并行训练(可通过n_jobs参数加速),预测时需遍历所有树,内存占用较大。

4. 优缺点

4.1 优点

  • 性能优异:在分类、回归任务中均表现出色,无需复杂特征预处理,对缺失值、异常值有一定容错性。

  • 易于调参:核心参数少,鲁棒性强,默认参数即可达到较好效果,适合快速迭代。

  • 可解释性:虽不及单棵决策树,但可通过特征重要性分析提供决策依据。

4.2 缺点

  • 计算与内存消耗大:树数量多,训练和预测速度慢于单模型,不适用于实时在线预测场景。

  • 对极端不平衡数据敏感:默认投票机制偏向多数类,需通过样本加权或采样优化。

  • 难以解释单样本预测逻辑:集成结果无法追溯具体决策路径,不适用于需完全透明化的场景(如医疗合规)。

5. 实现步骤(实战:房价回归预测)


# ==============================================
# 随机森林模型实战:波士顿房价回归预测
# 功能:使用随机森林回归模型预测房价,评估拟合效果并分析特征重要性
# 核心库说明:
# sklearn - 提供数据集、随机森林模型、评估指标
# matplotlib - 绘图可视化
# ==============================================

# 1. 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score
import seaborn as sns

# 配置中文显示
def set_matplotlib_chinese_font():
    try:
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    except:
        try:
            plt.rcParams['font.sans-serif'] = ['PingFang SC']
        except:
            plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
    plt.rcParams['axes.unicode_minus'] = False

set_matplotlib_chinese_font()

# 2. 加载数据集
boston = load_boston()
X = boston.data
y = boston.target
feature_names = boston.feature_names

# 3. 数据拆分
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# 4. 训练随机森林回归模型
rf_model = RandomForestRegressor(
    n_estimators=200,  # 200棵决策树
    max_depth=8,       # 单棵树最大深度
    max_features='sqrt',  # 随机选择特征数=√总特征数
    bootstrap=True,    # 开启Bootstrap抽样
    oob_score=True,    # 启用OOB评估
    n_jobs=-1,         # 并行训练(使用所有CPU核心)
    random_state=42
)
rf_model.fit(X_train, y_train)

# 5. 模型评估
y_pred = rf_model.predict(X_test)
train_mse = mean_squared_error(y_train, rf_model.predict(X_train))
test_mse = mean_squared_error(y_test, y_pred)
train_r2 = r2_score(y_train, rf_model.predict(X_train))
test_r2 = r2_score(y_test, y_pred)
oob_r2 = rf_model.oob_score_  # OOB样本R²系数

print(f"训练集MSE:{train_mse:.4f},R²:{train_r2:.4f}")
print(f"测试集MSE:{test_mse:.4f},R²:{test_r2:.4f}")
print(f"OOB样本R²:{oob_r2:.4f}")  # 接近测试集R²说明模型无明显过拟合

# 6. 特征重要性分析与可视化
feature_importance = rf_model.feature_importances_
sorted_idx = np.argsort(feature_importance)[::-1]
sorted_features = [feature_names[i] for i in sorted_idx]
sorted_importance = feature_importance[sorted_idx]

plt.figure(figsize=(12, 6))
sns.barplot(x=sorted_importance, y=sorted_features, palette='viridis')
plt.xlabel('特征重要性')
plt.ylabel('特征名称')
plt.title('随机森林特征重要性排序')
plt.grid(axis='x', alpha=0.3)
plt.show()

# 7. 真实值与预测值对比可视化
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.6, color='green')
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
plt.xlabel('房屋真实价格(千美元)')
plt.ylabel('房屋预测价格(千美元)')
plt.title(f'随机森林回归:真实值vs预测值(R²={test_r2:.4f})')
plt.grid(alpha=0.3)
plt.show()

五、支持向量机(SVM)

1. 简介

支持向量机(Support Vector Machine,SVM)是一种监督学习分类算法,核心思想是在特征空间中找到一条最优分离超平面,使两类样本到超平面的距离(间隔)最大化,从而实现高效分类。它可通过核函数处理非线性数据,在小样本、高维数据场景(如文本分类、图像识别)中表现优异,是机器学习领域经典的“小样本学习”算法之一。

SVM的核心优势在于“最大化间隔”和“核技巧”,前者保证模型泛化能力,后者解决非线性分类问题,同时仅依赖少量“支持向量”(距离超平面最近的样本),训练效率高。

2. 基本原理

2.1 线性可分SVM(硬间隔)

当样本在特征空间中可被线性超平面完全分离时,SVM寻找“最大间隔超平面”。设超平面方程为 w⋅x+b=0 w \cdot x + b = 0 ,其中 w w 为法向量,b b 为偏置项。定义两类样本到超平面的最小距离为“间隔”,目标是最大化间隔 2∣∣w∣∣ \frac{2}{||w||} (等价于最小化 12∣∣w∣∣2 \frac{1}{2}||w||^2 ),同时满足约束条件 yi(w⋅xi+b)≥1 y_i(w \cdot x_i + b) \geq 1 (所有样本都在间隔外侧)。

距离超平面最近的样本称为“支持向量”,超平面仅由支持向量决定,其他样本不影响超平面位置,这是SVM的核心特性。

2.2 线性不可分SVM(软间隔)

实际数据多为线性不可分,引入“松弛变量”ξi≥0 \xi_i \geq 0 ,允许少量样本跨越间隔或超平面,目标函数变为 12∣∣w∣∣2+C∑i=1mξi \frac{1}{2}||w||^2 + C\sum_{i=1}^{m} \xi_i ,约束条件为 yi(w⋅xi+b)≥1−ξi y_i(w \cdot x_i + b) \geq 1 - \xi_i 。其中 C C 为惩罚系数,C C 越大对误分类样本惩罚越重,易过拟合;C C 越小惩罚越轻,易欠拟合。

2.3 核技巧(处理非线性数据)

对于非线性可分数据,SVM通过核函数将低维特征映射到高维特征空间,使数据在高维空间中线性可分。核函数无需显式计算高维映射,直接通过低维样本内积计算高维空间内积,降低计算成本。常用核函数:

  • 线性核(Linear):K(xi,xj)=xi⋅xj K(x_i,x_j) = x_i \cdot x_j ,适用于线性可分数据,等价于基本SVM。

  • 多项式核(Polynomial):K(xi,xj)=(xi⋅xj+1)d K(x_i,x_j) = (x_i \cdot x_j + 1)^d ,d d 为多项式次数,适用于轻度非线性数据。

  • 高斯核(RBF,径向基核):K(xi,xj)=exp⁡(−γ∣∣xi−xj∣∣2) K(x_i,x_j) = \exp(-\gamma||x_i - x_j||^2) ,γ \gamma 控制核函数宽度,适用于高度非线性数据,是最常用的核函数。

  • Sigmoid核:K(xi,xj)=tanh⁡(αxi⋅xj+β) K(x_i,x_j) = \tanh(\alpha x_i \cdot x_j + \beta) ,模拟神经网络激活函数,适用于特定非线性场景。

3. 特点

  • 泛化能力强:最大化间隔策略使模型对未知样本适应性好,在小样本、高维数据中优势明显。

  • 依赖核函数选择:核函数及参数(如 C C 、γ \gamma )对模型性能影响极大,需通过交叉验证调参。

  • 计算成本高:训练时需求解二次规划问题,大规模数据集(样本数>10万)训练速度慢,需优化(如SMO算法)。

  • 不输出概率:原生SVM仅输出类别,需通过 Platt缩放转化为概率,解释性较弱。

4. 优缺点

4.1 优点

  • 高维数据表现优:无需考虑特征维度与样本数的关系,适合文本、图像等高维场景。

  • 抗过拟合能力强:最大化间隔策略天然抑制过拟合,无需复杂正则化。

  • 对小样本友好:仅依赖支持向量,小样本数据集即可训练出高性能模型。

4.2 缺点

  • 大规模数据适配差:训练时间随样本数增长呈二次增长,不适用于超大规模数据集。

  • 调参复杂:核函数、C C 、γ \gamma 等参数需精细调参,无统一标准,依赖经验和交叉验证。

  • 对异常值敏感:软间隔中异常值会影响支持向量选择,导致超平面偏移,需提前处理异常值。

  • 多分类支持弱:原生SVM仅支持二分类,多分类需通过One-vs-Rest/One-vs-One扩展,计算成本更高。

5. 实现步骤(实战:鸢尾花二分类)


# ==============================================
# SVM模型实战:鸢尾花二分类(高斯核)
# 功能:使用SVM实现二分类,优化参数并可视化决策边界
# 核心库说明:
# sklearn - 提供SVM模型、数据集、交叉验证、评估指标
# matplotlib - 绘图可视化
# ==============================================

# 1. 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.preprocessing import StandardScaler  # SVM对特征尺度敏感,需归一化

# 配置中文显示
def set_matplotlib_chinese_font():
    try:
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    except:
        try:
            plt.rcParams['font.sans-serif'] = ['PingFang SC']
        except:
            plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
    plt.rcParams['axes.unicode_minus'] = False

set_matplotlib_chinese_font()

# 2. 加载数据集并预处理(二分类)
iris = load_iris()
mask = (iris.target == 0) | (iris.target == 1)
X = iris.data[mask, :2]  # 取前2个特征(可视化)
y = iris.target[mask]
feature_names = iris.feature_names[:2]

# 3. 特征归一化(SVM必备:高斯核对尺度敏感)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 4. 数据拆分
X_train, X_test, y_train, y_test = train_test_split(
    X_scaled, y, test_size=0.3, random_state=42, stratify=y
)

# 5. 网格搜索优化参数(从业必备:SVM参数敏感,需调参)
param_grid = {
    'C': [0.1, 1, 10, 100],  # 惩罚系数
    'gamma': [0.01, 0.1, 1, 10],  # 高斯核宽度
    'kernel': ['rbf']  # 高斯核
}
grid_search = GridSearchCV(
    estimator=SVC(random_state=42, probability=True),  # probability=True:输出概率
    param_grid=param_grid,
    cv=5,  # 5折交叉验证
    scoring='accuracy',
    n_jobs=-1
)
grid_search.fit(X_train, y_train)

# 输出最优参数
print(f"最优参数组合:{grid_search.best_params_}")
print(f"交叉验证最优准确率:{grid_search.best_score_:.4f}")

# 6. 训练最优SVM模型
svm_model = grid_search.best_estimator_
svm_model.fit(X_train, y_train)

# 7. 模型评估
y_pred = svm_model.predict(X_test)
y_pred_prob = svm_model.predict_proba(X_test)[:, 1]
accuracy = accuracy_score(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)
class_report = classification_report(y_test, y_pred)

print(f"\n测试集准确率:{accuracy:.4f}")
print("混淆矩阵:")
print(conf_matrix)
print("分类报告:")
print(class_report)

# 8. 可视化决策边界
h = 0.02
x_min, x_max = X_scaled[:, 0].min() - 0.5, X_scaled[:, 0].max() + 0.5
y_min, y_max = X_scaled[:, 1].min() - 0.5, X_scaled[:, 1].max() + 0.5
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

# 预测网格点类别
Z = svm_model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

# 绘制决策边界、支持向量
plt.figure(figsize=(10, 6))
plt.contourf(xx, yy, Z, alpha=0.3, cmap=plt.cm.Paired)
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, edgecolors='k', cmap=plt.cm.Paired, label='训练集')
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test, edgecolors='k', cmap=plt.cm.Paired, marker='o', s=100, label='测试集', facecolors='none')
# 标记支持向量
support_vectors = svm_model.support_vectors_
plt.scatter(support_vectors[:, 0], support_vectors[:, 1], s=150, facecolors='red', alpha=0.6, label='支持向量')
plt.xlabel(feature_names[0])
plt.ylabel(feature_names[1])
plt.title(f'SVM(高斯核)决策边界(准确率:{accuracy:.4f})')
plt.legend()
plt.grid(alpha=0.3)
plt.show()

六、朴素贝叶斯(Naive Bayes)

1. 简介

朴素贝叶斯是一种基于贝叶斯定理和特征条件独立假设的监督学习分类算法,核心是通过先验概率和似然概率计算后验概率,实现类别预测。它假设所有特征之间相互独立(“朴素”的核心含义),虽简化了计算,但在实际场景中仍有优异表现,尤其适用于高维、小样本数据(如文本分类、垃圾邮件识别、情感分析),具备训练速度快、内存占用低的优势。

根据特征分布的不同,朴素贝叶斯可分为高斯朴素贝叶斯(适用于连续特征)、多项式朴素贝叶斯(适用于离散特征、文本计数)、伯努利朴素贝叶斯(适用于二元离散特征),可按需适配不同数据类型。

2. 基本原理

2.1 核心定理:贝叶斯定理

贝叶斯定理描述了先验概率与后验概率的关系,公式如下:

P(Y=c∣X)=P(X∣Y=c)P(Y=c)P(X) P(Y=c|X) = \frac{P(X|Y=c)P(Y=c)}{P(X)}

其中:P(Y=c∣X) P(Y=c|X) 为后验概率(已知特征X时,样本属于类别c的概率);P(Y=c) P(Y=c) 为先验概率(样本属于类别c的概率);P(X∣Y=c) P(X|Y=c) 为似然概率(类别c下特征X出现的概率);P(X) P(X) 为证据因子(与类别无关,可忽略)。

2.2 特征条件独立假设

为简化计算,朴素贝叶斯假设所有特征在给定类别下相互独立,即 P(X∣Y=c)=∏i=1nP(Xi∣Y=c) P(X|Y=c) = \prod_{i=1}^{n} P(X_i|Y=c) (n为特征数)。此时后验概率公式简化为:

P(Y=c∣X)∝P(Y=c)∏i=1nP(Xi∣Y=c) P(Y=c|X) \propto P(Y=c) \prod_{i=1}^{n} P(X_i|Y=c)

预测时,选择后验概率最大的类别作为最终结果,即 Y^=arg⁡max⁡cP(Y=c)∏i=1nP(Xi∣Y=c) \hat{Y} = \arg\max_c P(Y=c) \prod_{i=1}^{n} P(X_i|Y=c) 。

2.3 三种常见模型

  • 高斯朴素贝叶斯(GaussianNB):假设连续特征服从正态分布,通过样本均值和方差估计分布参数,计算似然概率 P(Xi∣Y=c) P(X_i|Y=c) ,适用于连续特征场景(如身高、体重、房价特征)。

  • 多项式朴素贝叶斯(MultinomialNB):假设离散特征服从多项式分布,常用于文本分类(特征为单词计数或TF-IDF值),核心是统计类别下各特征的出现频率。

  • 伯努利朴素贝叶斯(BernoulliNB):假设特征为二元变量(0/1,如单词是否出现),仅关注特征是否存在,而非出现次数,适用于稀疏二元特征场景。

3. 特点

  • 训练高效:仅需统计先验概率和似然概率的参数,时间复杂度为O(mn)(m为样本数,n为特征数),无需迭代训练,适合大规模数据。

  • 对高维数据友好:无需担心维度灾难,在文本等高维场景中表现优于多数算法。

  • 假设严格:特征条件独立假设在实际中难以完全满足,可能导致模型偏差,影响预测精度。

  • 对缺失值不敏感:可通过统计现有样本的概率参数弥补缺失值影响,无需复杂预处理。

4. 优缺点

4.1 优点

  • 速度极快:训练和预测时间短,内存占用低,可快速部署到实时场景(如垃圾邮件实时过滤)。

  • 小样本表现优:依赖概率统计,无需大量样本即可训练,对小样本数据集适配性好。

  • 可解释性强:基于概率输出,能清晰反映每个特征对类别的贡献,适合需要解释逻辑的场景。

4.2 缺点

  • 独立假设局限:实际特征多存在相关性,违反独立假设会导致“朴素”偏差,复杂数据中精度低于集成算法。

  • 对异常值敏感:异常值会影响概率参数估计,尤其高斯朴素贝叶斯中,异常值会扭曲均值和方差。

  • 不适用于连续特征多且分布复杂的场景:高斯分布假设难以适配非正态连续特征,易导致似然概率估计偏差。

5. 实现步骤(实战:文本分类)


# ==============================================
# 朴素贝叶斯实战:新闻文本分类(多项式朴素贝叶斯)
# 功能:使用多项式朴素贝叶斯实现文本多分类,适配TF-IDF特征
# 核心库说明:
# sklearn - 提供数据集、文本预处理、模型、评估指标
# matplotlib - 绘图可视化
# ==============================================

# 1. 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import seaborn as sns

# 配置中文显示
def set_matplotlib_chinese_font():
    try:
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    except:
        try:
            plt.rcParams['font.sans-serif'] = ['PingFang SC']
        except:
            plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
    plt.rcParams['axes.unicode_minus'] = False

set_matplotlib_chinese_font()

# 2. 加载数据集(选取4类新闻,简化任务)
categories = ['alt.atheism', 'soc.religion.christian', 'comp.graphics', 'sci.med']
newsgroups = fetch_20newsgroups(
    subset='all', categories=categories, remove=('headers', 'footers', 'quotes'),
    random_state=42
)
X = newsgroups.data  # 文本数据
y = newsgroups.target  # 类别标签
target_names = newsgroups.target_names
print(f"文本样本数:{len(X)},类别数:{len(target_names)}")
print("类别名称:", target_names)

# 3. 文本预处理:TF-IDF特征提取(文本分类必备)
tfidf = TfidfVectorizer(
    stop_words='english',  # 去除英文停用词
    max_df=0.9,  # 过滤出现频率过高的词(避免冗余)
    min_df=5     # 过滤出现频率过低的词(避免噪声)
)
X_tfidf = tfidf.fit_transform(X)  # 转化为TF-IDF特征矩阵(稀疏矩阵)
print(f"TF-IDF特征维度:{X_tfidf.shape}")

# 4. 数据拆分
X_train, X_test, y_train, y_test = train_test_split(
    X_tfidf, y, test_size=0.3, random_state=42, stratify=y
)

# 5. 训练多项式朴素贝叶斯模型
nb_model = MultinomialNB(alpha=1.0)  # alpha:平滑系数,避免似然概率为0
nb_model.fit(X_train, y_train)

# 6. 模型评估
y_pred = nb_model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)
class_report = classification_report(y_test, y_pred, target_names=target_names)

print(f"\n文本分类准确率:{accuracy:.4f}")
print("\n混淆矩阵:")
print(conf_matrix)
print("\n分类报告:")
print(class_report)

# 7. 混淆矩阵可视化
plt.figure(figsize=(10, 8))
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues',
            xticklabels=target_names, yticklabels=target_names)
plt.xlabel('预测类别')
plt.ylabel('真实类别')
plt.title(f'朴素贝叶斯文本分类混淆矩阵(准确率:{accuracy:.4f})')
plt.xticks(rotation=45, ha='right')
plt.yticks(rotation=0)
plt.tight_layout()
plt.show()

# 8. 查看Top10关键词(从业必备:分析类别特征)
def show_top_words(model, feature_names, target_names, n_top_words=10):
    for i, target_name in enumerate(target_names):
        # 获取对应类别的权重系数(与词频概率相关)
        top_indices = model.coef_[i].argsort()[-n_top_words:]
        top_words = [feature_names[j] for j in top_indices]
        print(f"\n类别 {target_name} 的Top10关键词:{', '.join(top_words)}")

feature_names = tfidf.get_feature_names_out()
show_top_words(nb_model, feature_names, target_names)

七、主成分分析(PCA)

1. 简介

主成分分析(Principal Component Analysis,PCA)是一种无监督学习降维算法,核心是通过线性变换将高维特征映射到低维空间,在保留数据核心信息(方差最大)的同时,减少特征维度、去除冗余和噪声。它不依赖目标变量,仅通过数据自身的方差结构实现降维,广泛应用于数据可视化、特征预处理、噪声过滤等场景,是机器学习中最经典的降维工具之一。

PCA的核心目标是找到一组正交的“主成分”(新特征),其中第一主成分对应数据方差最大的方向,第二主成分对应与第一主成分正交且方差次大的方向,以此类推,通过选择前k个主成分实现降维。

2. 基本原理

2.1 核心步骤

  1. 特征标准化:PCA对特征尺度敏感,需先将所有特征归一化/标准化(均值为0,方差为1),避免尺度大的特征主导方差。

  2. 计算协方差矩阵:协方差矩阵反映特征间的线性相关性,维度为n×n(n为原特征数),元素 Cov(Xi,Xj) Cov(X_i,X_j) 表示特征 Xi X_i 与 Xj X_j 的协方差。

  3. 求解协方差矩阵的特征值和特征向量:特征向量对应主成分方向,特征值对应主成分的方差贡献度(特征值越大,该主成分保留的信息越多)。

  4. 选择主成分:按特征值从大到小排序,选择前k个特征向量(主成分),k的选择可通过方差贡献率(累计方差占比≥80%-90%)确定。

  5. 线性变换降维:将原特征矩阵与前k个特征向量组成的矩阵相乘,得到低维特征矩阵(维度:m×k,m为样本数)。

2.2 关键概念(从业必备)

  • 方差贡献率:单个主成分的特征值占所有特征值总和的比例,反映该主成分保留的信息占比。

  • 累计方差贡献率:前k个主成分的方差贡献率之和,通常需达到80%以上,确保降维后保留核心信息。

  • 正交性:主成分之间相互正交,避免特征冗余(协方差为0)。

3. 特点

  • 无监督降维:无需目标变量,仅依赖数据自身结构,通用性强。

  • 保留核心信息:优先保留方差最大的信息,最大限度减少数据损失。

  • 去除冗余与噪声:通过降维过滤特征间的冗余相关性,同时抑制部分噪声。

  • 线性变换:仅能捕捉线性关系,无法处理非线性数据的降维(需用核PCA扩展)。

4. 优缺点

4.1 优点

  • 降维效果显著:有效减少特征维度,降低后续模型的计算成本,避免维度灾难。

  • 计算高效:原理基于线性代数,计算过程清晰,对中大规模数据适配性好。

  • 辅助可视化:将高维数据降至2D/3D,便于直观观察数据分布和聚类情况。

4.2 缺点

  • 线性局限:仅适用于线性可分数据,非线性数据降维效果差(需核PCA)。

  • 解释性弱:主成分为原特征的线性组合,新特征缺乏明确的业务含义,难以解释。

  • 对异常值敏感:异常值会显著影响协方差矩阵和特征向量计算,导致降维偏差。

5. 实现步骤(实战:鸢尾花数据降维可视化)


# ==============================================
# PCA实战:鸢尾花数据降维与可视化
# 功能:使用PCA将4维特征降至2维,观察数据分布,验证降维效果
# 核心库说明:
# sklearn - 提供数据集、PCA模型、标准化工具
# matplotlib - 绘图可视化
# ==============================================

# 1. 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

# 配置中文显示
def set_matplotlib_chinese_font():
    try:
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    except:
        try:
            plt.rcParams['font.sans-serif'] = ['PingFang SC']
        except:
            plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
    plt.rcParams['axes.unicode_minus'] = False

set_matplotlib_chinese_font()

# 2. 加载数据集
iris = load_iris()
X = iris.data  # 4维特征
y = iris.target
target_names = iris.target_names
print(f"原数据维度:{X.shape},类别数:{len(target_names)}")

# 3. 特征标准化(PCA必备)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 4. 训练PCA模型降维(降至2维)
pca = PCA(n_components=2)  # n_components:目标维度
X_pca = pca.fit_transform(X_scaled)
print(f"降维后数据维度:{X_pca.shape}")

# 5. 分析方差贡献率(从业必备:评估降维效果)
explained_variance_ratio = pca.explained_variance_ratio_
cumulative_variance_ratio = np.cumsum(explained_variance_ratio)
print(f"第一主成分方差贡献率:{explained_variance_ratio[0]:.4f}")
print(f"第二主成分方差贡献率:{explained_variance_ratio[1]:.4f}")
print(f"累计方差贡献率:{cumulative_variance_ratio[1]:.4f}")  # 需≥80%

# 6. 降维后数据可视化
plt.figure(figsize=(10, 6))
colors = ['red', 'green', 'blue']
markers = ['o', 's', '^']
for i, (color, marker, target_name) in enumerate(zip(colors, markers, target_names)):
    plt.scatter(X_pca[y == i, 0], X_pca[y == i, 1], 
                color=color, marker=marker, label=target_name, alpha=0.7)
plt.xlabel(f'第一主成分(方差贡献率:{explained_variance_ratio[0]:.4f})')
plt.ylabel(f'第二主成分(方差贡献率:{explained_variance_ratio[1]:.4f})')
plt.title(f'PCA降维:鸢尾花数据2D可视化(累计方差贡献率:{cumulative_variance_ratio[1]:.4f})')
plt.legend()
plt.grid(alpha=0.3)
plt.show()

# 7. 验证降维对模型的影响(逻辑回归分类)
# 原始数据训练
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.3, random_state=42)
lr_original = LogisticRegression(random_state=42)
lr_original.fit(X_train, y_train)
y_pred_original = lr_original.predict(X_test)
acc_original = accuracy_score(y_test, y_pred_original)

# 降维数据训练
X_train_pca, X_test_pca, y_train, y_test = train_test_split(X_pca, y, test_size=0.3, random_state=42)
lr_pca = LogisticRegression(random_state=42)
lr_pca.fit(X_train_pca, y_train)
y_pred_pca = lr_pca.predict(X_test_pca)
acc_pca = accuracy_score(y_test, y_pred_pca)

print(f"\n原始数据逻辑回归准确率:{acc_original:.4f}")
print(f"PCA降维后逻辑回归准确率:{acc_pca:.4f}")
print("结论:降维后准确率基本持平,说明保留了核心信息,同时降低了特征维度")

八、梯度提升树(Gradient Boosting Tree, GBT)

1. 简介

梯度提升树是一种基于Boosting策略的集成学习算法,核心是通过“迭代训练弱分类器(通常为决策树)、逐步纠正前一轮模型的误差”实现性能提升。与Bagging(并行训练)不同,Boosting采用串行训练方式,每棵新树都聚焦于拟合前一轮模型的预测残差(或梯度),通过加权组合所有弱分类器,最终形成高精度的强分类器。

GBT可处理分类和回归任务,核心变种包括GBDT(梯度提升决策树,回归)、GBRT(梯度提升回归树)、XGBoost、LightGBM等(优化版GBT),广泛应用于竞赛、工业界(如风控、推荐、预测),是高性能模型的核心组件。

2. 基本原理

2.1 核心思想:梯度提升

Boosting的核心是“知错就改”:初始训练一个简单弱分类器(如深度为1的决策树,称为“决策树桩”),计算该模型的预测误差,下一棵决策树以“最小化误差”为目标训练,逐步修正误差,最后通过加权(误差小的树权重高)组合所有树的结果。

梯度提升将误差优化转化为“梯度下降”问题:把损失函数对预测值的负梯度作为残差的近似,每棵新树都拟合这个梯度,使模型沿损失函数的负梯度方向更新,逐步降低损失。

2.2 核心流程(回归任务)

  1. 初始化模型:通常以训练集目标值的均值作为初始预测值 F0(x)=yˉ F_0(x) = \bar{y} 。

  2. 迭代训练弱分类器: 计算第t轮的负梯度(残差近似):rti=−[∂L(yi,F(xi))∂F(xi)]F=Ft−1 r_{ti} = -\left[\frac{\partial L(y_i, F(x_i))}{\partial F(x_i)}\right]_{F=F_{t-1}} (L为损失函数,如MSE)。

  3. 用决策树拟合残差 rti r_{ti} ,得到第t棵弱分类器 ht(x) h_t(x) 。

  4. 计算学习率 η \eta (步长,控制每棵树的贡献,避免过拟合,通常取0.01-0.1),更新模型:Ft(x)=Ft−1(x)+ηht(x) F_t(x) = F_{t-1}(x) + \eta h_t(x) 。

  5. 组合所有弱分类器:最终模型为 F(x)=∑t=1Tηht(x) F(x) = \sum_{t=1}^{T} \eta h_t(x) (T为树的数量)。

2.3 关键参数(从业必备)

  • n_estimators:弱分类器数量(树的数量),过多易过拟合,需结合学习率调整。

  • learning_rate:学习率,控制每棵树的权重,与n_estimators负相关(学习率小,需更多树)。

  • max_depth:单棵树的最大深度,控制树的复杂度,避免过拟合。

  • subsample:每棵树训练时抽样的样本比例(0-1),用于防止过拟合,增加模型多样性。

3. 特点

  • 精度高:串行纠错机制使模型能精准拟合数据规律,复杂任务中表现优于随机森林。

  • 灵活性强:可适配不同损失函数(MSE、MAE、对数损失等),支持分类、回归、排序任务。

  • 易过拟合:串行训练依赖前序模型,树数量过多、深度过深易拟合噪声,需严格调参。

  • 训练成本高:串行训练无法并行,速度慢于随机森林,对大规模数据需优化(如XGBoost的并行预处理)。

4. 优缺点

4.1 优点

  • 预测精度优异:在分类、回归任务中均为顶级算法,竞赛中常作为基线模型。

  • 对非线性数据适配好:通过梯度迭代拟合复杂非线性关系,无需复杂特征工程。

  • 支持特征重要性评估:可量化特征对模型的贡献,辅助特征筛选和业务分析。

4.2 缺点

  • 训练速度慢:串行训练,树数量多时有较高时间成本,不适用于实时训练场景。

  • 调参复杂:参数(n_estimators、learning_rate、max_depth等)相互影响,需大量交叉验证。

  • 对异常值敏感:残差拟合机制会放大异常值的影响,需提前处理异常值。

5. 实现步骤(实战:房价回归预测)


# ==============================================
# GBT实战:波士顿房价回归预测(GBDT)
# 功能:使用梯度提升决策树预测房价,评估拟合效果并分析特征重要性
# 核心库说明:
# sklearn - 提供数据集、GBDT模型、评估指标
# matplotlib - 绘图可视化
# ==============================================

# 1. 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, r2_score
import seaborn as sns

# 配置中文显示
def set_matplotlib_chinese_font():
    try:
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    except:
        try:
            plt.rcParams['font.sans-serif'] = ['PingFang SC']
        except:
            plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
    plt.rcParams['axes.unicode_minus'] = False

set_matplotlib_chinese_font()

# 2. 加载数据集
boston = load_boston()
X = boston.data
y = boston.target
feature_names = boston.feature_names
print(f"数据集维度:{X.shape}")

# 3. 数据拆分
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# 4. 训练GBDT模型(调参优化)
gbt_model = GradientBoostingRegressor(
    n_estimators=200,  # 树的数量
    learning_rate=0.05,  # 学习率
    max_depth=5,  # 单棵树最大深度
    subsample=0.8,  # 样本抽样比例
    random_state=42
)
gbt_model.fit(X_train, y_train)

# 5. 模型评估
y_pred = gbt_model.predict(X_test)
train_mse = mean_squared_error(y_train, gbt_model.predict(X_train))
test_mse = mean_squared_error(y_test, y_pred)
train_r2 = r2_score(y_train, gbt_model.predict(X_train))
test_r2 = r2_score(y_test, y_pred)

# 5折交叉验证评估泛化能力
cv_scores = cross_val_score(gbt_model, X, y, cv=5, scoring='r2')

print(f"训练集MSE:{train_mse:.4f},R²:{train_r2:.4f}")
print(f"测试集MSE:{test_mse:.4f},R²:{test_r2:.4f}")
print(f"5折交叉验证平均R²:{cv_scores.mean():.4f},标准差:{cv_scores.std():.4f}")

# 6. 特征重要性分析与可视化
feature_importance = gbt_model.feature_importances_
sorted_idx = np.argsort(feature_importance)[::-1]
sorted_features = [feature_names[i] for i in sorted_idx]
sorted_importance = feature_importance[sorted_idx]

plt.figure(figsize=(12, 6))
sns.barplot(x=sorted_importance, y=sorted_features, palette='viridis')
plt.xlabel('特征重要性')
plt.ylabel('特征名称')
plt.title('GBDT特征重要性排序')
plt.grid(axis='x', alpha=0.3)
plt.show()

# 7. 真实值与预测值对比可视化
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.6, color='orange')
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
plt.xlabel('房屋真实价格(千美元)')
plt.ylabel('房屋预测价格(千美元)')
plt.title(f'GBDT回归:真实值vs预测值(R²={test_r2:.4f})')
plt.grid(alpha=0.3)
plt.show()

# 8. 学习曲线(观察树数量对模型的影响)
train_scores = []
test_scores = []
n_estimators_range = range(10, 210, 10)
for n in n_estimators_range:
    model = GradientBoostingRegressor(n_estimators=n, learning_rate=0.05, max_depth=5, random_state=42)
    model.fit(X_train, y_train)
    train_r2 = r2_score(y_train, model.predict(X_train))
    test_r2 = r2_score(y_test, model.predict(X_test))
    train_scores.append(train_r2)
    test_scores.append(test_r2)

plt.figure(figsize=(10, 6))
plt.plot(n_estimators_range, train_scores, 'b-', label='训练集R²')
plt.plot(n_estimators_range, test_scores, 'r-', label='测试集R²')
plt.xlabel('决策树数量')
plt.ylabel('R²系数')
plt.title('GBDT学习曲线(树数量对性能的影响)')
plt.legend()
plt.grid(alpha=0.3)
plt.show()

九、K-Means

1. 简介

K-Means是一种无监督学习聚类算法,核心是将数据集划分为K个互不重叠的簇,使每个簇内的样本相似度最大化(簇内方差最小化),簇间样本相似度最小化。它原理简单、实现高效,是最常用的聚类算法之一,适用于数据分组、用户画像、异常检测、图像分割等场景,无需标签即可挖掘数据的潜在分布结构。

K-Means的“K”是需手动指定的超参数(簇的数量),核心挑战在于合理选择K值,以及应对初始聚类中心对结果的影响。

2. 基本原理

2.1 核心流程(Lloyd算法)

  1. 指定簇数K:根据业务需求或数据特征确定K值(如通过肘部法则、轮廓系数选择)。

  2. 初始化聚类中心:从样本中随机选择K个样本作为初始聚类中心(或通过K-Means++优化初始化)。

  3. 迭代更新: 分配样本:计算每个样本到所有聚类中心的距离(通常为欧氏距离),将样本分配到距离最近的簇。

  4. 更新中心:计算每个簇内所有样本的均值,将该均值作为新的聚类中心。

  5. 终止条件:当聚类中心不再变化,或迭代次数达到阈值,或簇内方差变化小于阈值时,停止迭代。

2.2 关键概念与优化

  • 距离度量:常用欧氏距离(连续特征),也可使用曼哈顿距离(对异常值更鲁棒)、余弦相似度(文本聚类)。

  • K-Means++:优化初始聚类中心选择,使初始中心尽可能分散,避免局部最优解,提升聚类效果。

  • 簇内平方和(WCSS):衡量簇内样本的紧凑性,WCSS越小,簇内相似度越高,公式为 WCSS=∑i=1K∑x∈Ci∣∣x−μi∣∣2 WCSS = \sum_{i=1}^{K} \sum_{x \in C_i} ||x - \mu_i||^2 (μi \mu_i 为第i个簇的中心)。

3. 特点

  • 高效易用:时间复杂度低(O(mnKt),m为样本数,n为特征数,t为迭代次数),适合大规模数据。

  • 依赖K值:K值需手动指定,不合理的K值会导致聚类效果极差,需通过指标辅助选择。

  • 对初始中心敏感:随机初始化可能导致收敛到局部最优解,需多次运行或使用K-Means++。

  • 适用于凸聚类:对球形、紧凑的簇聚类效果好,对非凸、不规则簇效果差。

4. 优缺点

4.1 优点

  • 速度快:迭代过程简单,计算成本低,可处理百万级样本。

  • 扩展性强:对特征维度适配性好,可结合PCA降维后使用,提升效率。

  • 结果易解释:簇的含义可通过业务场景解读,适合用户画像等需落地的场景。

4.2 缺点

  • 需指定K值:无通用方法确定最优K,依赖经验和指标(肘部法则、轮廓系数)。

  • 对异常值敏感:异常值会扭曲聚类中心,影响整个簇的分配结果。

  • 仅适用于连续特征:离散特征需编码(如独热编码)后使用,效果可能受影响。

  • 无法处理非凸簇:对不规则形状、密度不均的簇,聚类效果差(需用DBSCAN等算法)。

5. 实现步骤(实战:客户分群)


# ==============================================
# K-Means实战:客户消费行为分群
# 功能:使用K-Means对客户消费数据聚类,确定最优K值,分析各簇特征
# 核心库说明:
# sklearn - 提供K-Means模型、评估指标
# matplotlib - 绘图可视化
# pandas - 数据处理
# ==============================================

# 1. 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score
from sklearn.decomposition import PCA

# 配置中文显示
def set_matplotlib_chinese_font():
    try:
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    except:
        try:
            plt.rcParams['font.sans-serif'] = ['PingFang SC']
        except:
            plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
    plt.rcParams['axes.unicode_minus'] = False

set_matplotlib_chinese_font()

# 2. 构造客户消费数据(模拟数据:消费金额、消费频率、客单价)
np.random.seed(42)
n_samples = 500
# 模拟3类客户
cluster1 = np.random.normal(loc=[5000, 20, 250], scale=[1000, 5, 50], size=(150, 3))
cluster2 = np.random.normal(loc=[15000, 8, 1875], scale=[2000, 3, 200], size=(200, 3))
cluster3 = np.random.normal(loc=[30000, 30, 1000], scale=[3000, 6, 300], size=(150, 3))
X = np.vstack([cluster1, cluster2, cluster3])
# 构造DataFrame
columns = ['消费金额', '消费频率', '客单价']
df = pd.DataFrame(X, columns=columns)
print(f"客户数据维度:{df.shape}")
print(df.describe())

# 3. 数据预处理:标准化(K-Means对尺度敏感)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df)

# 4. 确定最优K值(肘部法则+轮廓系数)
# 肘部法则:绘制WCSS随K的变化
wcss = []
silhouette_scores = []
k_range = range(2, 11)
for k in k_range:
    kmeans = KMeans(n_clusters=k, init='k-means++', random_state=42, n_init=10)
    kmeans.fit(X_scaled)
    wcss.append(kmeans.inertia_)  # inertia_:WCSS
    silhouette_scores.append(silhouette_score(X_scaled, kmeans.labels_))

# 肘部法则可视化
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(k_range, wcss, 'bo-')
plt.xlabel('簇数K')
plt.ylabel('簇内平方和(WCSS)')
plt.title('肘部法则确定最优K值')
plt.grid(alpha=0.3)
# 轮廓系数可视化
plt.subplot(1, 2, 2)
plt.plot(k_range, silhouette_scores, 'ro-')
plt.xlabel('簇数K')
plt.ylabel('轮廓系数')
plt.title('轮廓系数确定最优K值(越大越好)')
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()

# 5. 训练K-Means模型(最优K=3)
k_opt = 3
kmeans = KMeans(n_clusters=k_opt, init='k-means++', random_state=42, n_init=10)
cluster_labels = kmeans.fit_predict(X_scaled)
df['客户簇'] = cluster_labels  # 给数据添加簇标签

# 6. 聚类结果分析(各簇统计特征)
cluster_stats = df.groupby('客户簇')[columns].agg(['mean', 'std']).round(2)
print("\n各客户簇统计特征:")
print(cluster_stats)

# 7. 聚类结果可视化(PCA降至2维)
pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)
plt.figure(figsize=(10, 6))
colors = ['red', 'green', 'blue']
markers = ['o', 's', '^']
for i in range(k_opt):
    plt.scatter(X_pca[cluster_labels == i, 0], X_pca[cluster_labels == i, 1],
                color=colors[i], marker=markers[i], label=f'客户簇{i}', alpha=0.7)
# 绘制聚类中心
centers_pca = pca.transform(kmeans.cluster_centers_)
plt.scatter(centers_pca[:, 0], centers_pca[:, 1], s=200, color='black', marker='*', label='聚类中心')
plt.xlabel(f'第一主成分(方差贡献率:{pca.explained_variance_ratio_[0]:.4f})')
plt.ylabel(f'第二主成分(方差贡献率:{pca.explained_variance_ratio_[1]:.4f})')
plt.title('K-Means客户分群结果(PCA降维可视化)')
plt.legend()
plt.grid(alpha=0.3)
plt.show()

# 8. 业务解读(输出各簇客户特征)
for i in range(k_opt):
    cluster_data = df[df['客户簇'] == i][columns]
    print(f"\n客户簇{i}特征:")
    print(f"- 平均消费金额:{cluster_data['消费金额'].mean():.2f}元")
    print(f"- 平均消费频率:{cluster_data['消费频率'].mean():.2f}次/月")
    print(f"- 平均客单价:{cluster_data['客单价'].mean():.2f}元")
    if i == 0:
        print("- 业务标签:低频低消客户")
    elif i == 1:
        print("- 业务标签:高频高客单客户")
    else:
        print("- 业务标签:高频高消客户")

十、XGBoost

1. 简介

XGBoost(Extreme Gradient Boosting)是一种优化版的梯度提升树算法,基于GBT框架,通过引入正则化、并行处理、缺失值处理等优化策略,解决了传统GBT过拟合、训练慢、对异常值敏感等问题,是工业界和数据竞赛中最常用的高性能算法之一。它支持分类、回归、排序任务,在风控、推荐、预测等场景中表现优异,兼具精度和效率。

XGBoost的核心优势的是“极致优化”:在梯度提升基础上,加入L1/L2正则化抑制过拟合,采用并行预处理加速训练,对缺失值自动学习处理策略,同时支持自定义损失函数,灵活性极强。

2. 基本原理

2.1 核心优化点(相对于传统GBT)

  • 正则化优化:目标函数中加入L1正则化(惩罚权重绝对值)和L2正则化(惩罚权重平方),控制模型复杂度,抑制过拟合,目标函数为 Obj=∑i=1mL(yi,y^i)+∑t=1TΩ(ht) \text{Obj} = \sum_{i=1}^{m} L(y_i, \hat{y}_i) + \sum_{t=1}^{T} \Omega(h_t) ,其中 Ω(ht)=γT+12λ∣∣w∣∣2 \Omega(h_t) = \gamma T + \frac{1}{2}\lambda ||w||^2 (T为树的叶子节点数,w为叶子节点权重,γ、λ为正则化系数)。

  • 并行处理:传统GBT串行训练树,XGBoost在特征分裂前,对所有特征的增益进行并行计算,大幅提升训练速度(树的生成仍为串行)。

  • 缺失值处理:自动学习缺失值的分裂方向(左子树或右子树),无需手动填充缺失值,增强模型鲁棒性。

  • 梯度提升优化:使用二阶泰勒展开近似损失函数,更精准地捕捉梯度信息,加速收敛;同时引入学习率和子采样,进一步防止过拟合。

2.2 关键参数(从业必备)

  • n_estimators:树的数量,控制模型复杂度。

  • learning_rate:学习率,控制每棵树的贡献,与n_estimators配合使用。

  • max_depth:单棵树的最大深度,默认6,过大易过拟合。

  • reg_alpha(L1)、reg_lambda(L2):正则化系数,值越大正则化越强。

subsample:每棵树训练时抽样的样本比例(0-1),默认1,降低该值可增加多样性,防止过拟合。

colsample_bytree:每棵树训练时抽样的特征比例(0-1),默认1,配合subsample进一步提升模型鲁棒性。

gamma:叶子节点分裂的最小增益阈值,默认0,值越大越难分裂,抑制过拟合。

3. 特点

  • 精度卓越:二阶泰勒展开和正则化策略使模型拟合能力更强,泛化性能优于传统GBT。

  • 训练高效:特征分裂增益并行计算,结合缓存优化,训练速度远超传统梯度提升树,适配大规模数据。

  • 鲁棒性强:内置缺失值处理、正则化、子采样等机制,对异常值、过拟合的容忍度更高。

  • 灵活性高:支持自定义损失函数、评估指标,可适配分类、回归、排序等多种任务,兼容性强。

  • 可解释性较好:支持特征重要性评估、部分依赖图,能辅助业务解读模型逻辑。

4. 优缺点

4.1 优点

  • 性能顶尖:在各类数据竞赛和工业场景中,常作为基线模型或最终模型,预测精度领先多数算法。

  • 工程优化完善:提供丰富的参数调优空间,支持并行训练、分布式训练,适配不同数据规模(从万级到亿级样本)。

  • 容错性强:无需复杂的数据预处理(如缺失值填充、异常值剔除),模型可自动适配,降低开发成本。

  • 兼容性广:支持Python、R、Java等多语言,可无缝集成到各类线上系统,部署便捷。

4.2 缺点

  • 调参复杂:参数数量多且相互影响(如learning_rate与n_estimators、max_depth与gamma),需大量交叉验证优化。

  • 对资源要求较高:训练时内存消耗大于随机森林,大规模数据训练需配置充足的内存和CPU资源。

  • 易过拟合:若参数调优不当(如树过深、正则化不足),仍可能出现过拟合,需结合早停策略优化。

  • 对非结构化数据适配差:本质是基于结构化特征的树模型,无法直接处理图像、文本等非结构化数据,需先进行特征提取。

5. 实现步骤(实战:房价回归预测)


# ==============================================
# XGBoost实战:波士顿房价回归预测
# 功能:使用XGBoost回归模型预测房价,优化参数并评估性能,对比传统GBDT
# 核心库说明:
# xgboost - XGBoost官方库
# sklearn - 数据处理、评估指标、交叉验证
# matplotlib - 绘图可视化
# ==============================================

# 1. 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.metrics import mean_squared_error, r2_score
import xgboost as xgb
import seaborn as sns

# 配置中文显示
def set_matplotlib_chinese_font():
    try:
        plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    except:
        try:
            plt.rcParams['font.sans-serif'] = ['PingFang SC']
        except:
            plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei']
    plt.rcParams['axes.unicode_minus'] = False

set_matplotlib_chinese_font()

# 2. 加载数据集
boston = load_boston()
X = boston.data
y = boston.target
feature_names = boston.feature_names
print(f"数据集维度:{X.shape}")

# 3. 数据拆分与格式转换(XGBoost支持DMatrix格式,优化训练效率)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)
# 转换为DMatrix格式(XGBoost专用,支持缺失值、权重等特性)
dtrain = xgb.DMatrix(X_train, label=y_train, feature_names=feature_names)
dtest = xgb.DMatrix(X_test, label=y_test, feature_names=feature_names)

# 4. 初始参数训练(基准模型)
params = {
    'objective': 'reg:squarederror',  # 回归任务,损失函数为均方误差
    'eval_metric': 'rmse',            # 评估指标:均方根误差
    'learning_rate': 0.05,
    'max_depth': 5,
    'subsample': 0.8,
    'colsample_bytree': 0.8,
    'reg_alpha': 0.1,                 # L1正则化
    'reg_lambda': 1.0,                # L2正则化
    'gamma': 0.1,
    'seed': 42
}
# 训练模型,使用早停策略防止过拟合(验证集误差连续5轮不下降则停止)
watchlist = [(dtrain, 'train'), (dtest, 'test')]
xgb_model = xgb.train(
    params, dtrain, num_boost_round=500, evals=watchlist,
    early_stopping_rounds=5, verbose_eval=10  # 每10轮打印一次评估结果
)

# 5. 网格搜索优化参数(关键参数调优)
param_grid = {
    'learning_rate': [0.03, 0.05, 0.07],
    'max_depth': [4, 5, 6],
    'reg_alpha': [0.05, 0.1, 0.2],
    'gamma': [0.05, 0.1, 0.2]
}
# 使用sklearn接口的XGBoost,便于网格搜索
xgb_sklearn = xgb.XGBRegressor(
    objective='reg:squarederror',
    subsample=0.8, colsample_bytree=0.8,
    reg_lambda=1.0, seed=42, n_estimators=200
)
grid_search = GridSearchCV(
    estimator=xgb_sklearn, param_grid=param_grid,
    cv=5, scoring='r2', n_jobs=-1, verbose=1
)
grid_search.fit(X_train, y_train)

# 输出最优参数与结果
print(f"\n最优参数组合:{grid_search.best_params_}")
print(f"交叉验证最优R²:{grid_search.best_score_:.4f}")

# 6. 最优模型评估
best_xgb = grid_search.best_estimator_
y_pred = best_xgb.predict(X_test)
train_r2 = r2_score(y_train, best_xgb.predict(X_train))
test_r2 = r2_score(y_test, y_pred)
train_mse = mean_squared_error(y_train, best_xgb.predict(X_train))
test_mse = mean_squared_error(y_test, y_pred)

print(f"\n训练集MSE:{train_mse:.4f},R²:{train_r2:.4f}")
print(f"测试集MSE:{test_mse:.4f},R²:{test_r2:.4f}")

# 7. 特征重要性分析与可视化
feature_importance = best_xgb.feature_importances_
sorted_idx = np.argsort(feature_importance)[::-1]
sorted_features = [feature_names[i] for i in sorted_idx]
sorted_importance = feature_importance[sorted_idx]

plt.figure(figsize=(12, 6))
sns.barplot(x=sorted_importance, y=sorted_features, palette='viridis')
plt.xlabel('特征重要性')
plt.ylabel('特征名称')
plt.title('XGBoost特征重要性排序')
plt.grid(axis='x', alpha=0.3)
plt.show()

# 8. 真实值与预测值对比可视化
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.6, color='purple')
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
plt.xlabel('房屋真实价格(千美元)')
plt.ylabel('房屋预测价格(千美元)')
plt.title(f'XGBoost回归:真实值vs预测值(R²={test_r2:.4f})')
plt.grid(alpha=0.3)
plt.show()

# 9. 与传统GBDT对比(性能验证)
from sklearn.ensemble import GradientBoostingRegressor
gbt_model = GradientBoostingRegressor(
    n_estimators=200, learning_rate=0.05, max_depth=5,
    subsample=0.8, random_state=42
)
gbt_model.fit(X_train, y_train)
gbt_y_pred = gbt_model.predict(X_test)
gbt_test_r2 = r2_score(y_test, gbt_y_pred)
gbt_test_mse = mean_squared_error(y_test, gbt_y_pred)

print(f"\n传统GBDT测试集R²:{gbt_test_r2:.4f},MSE:{gbt_test_mse:.4f}")
print(f"XGBoost测试集R²:{test_r2:.4f},MSE:{test_mse:.4f}")
print("结论:XGBoost通过正则化和梯度优化,性能优于传统GBDT,泛化能力更强")

十一、总结与算法选型指南

1. 算法核心特性对比

本文覆盖了机器学习中经典的回归、分类、聚类、降维及集成算法,各算法核心特性差异显著,具体对比如下:

  • 基础线性模型(线性回归、逻辑回归):解释性极强、计算高效,适用于简单场景、需透明化逻辑的业务(如金融风控初步筛选),但无法处理非线性关系。

  • 树模型(决策树):直观易懂、无需预处理,可捕捉非线性关系,但易过拟合、稳定性差,仅适用于简单任务或作为集成模型基础。

  • 集成模型(随机森林、GBT、XGBoost):精度高、泛化能力强,适用于复杂任务(如精准预测、高价值风控),但计算成本高、调参复杂,XGBoost为工业界首选。

  • 其他分类算法(SVM、朴素贝叶斯):SVM适用于小样本、高维数据(如文本分类),朴素贝叶斯适用于高维、实时场景(如垃圾邮件过滤),但均有一定假设局限。

  • 无监督算法(PCA、K-Means):PCA用于降维、可视化,K-Means用于聚类分群(如用户画像),无需标签,但结果需结合业务解读。

2. 业务场景选型建议

  • 连续值预测(回归):简单场景选线性回归,复杂场景优先XGBoost,大规模数据可考虑LightGBM(XGBoost优化版,速度更快)。

  • 分类任务:二分类简单场景选逻辑回归,小样本高维选SVM,文本分类选朴素贝叶斯/逻辑回归,复杂精准分类选XGBoost/随机森林。

  • 无标签数据挖掘:数据降维/可视化用PCA,客户分群/数据分组用K-Means,不规则簇聚类选DBSCAN(补充算法)。

  • 实时场景:优先朴素贝叶斯、逻辑回归,避免集成模型,确保低延迟。

  • 合规性要求高:选线性回归、逻辑回归、决策树,可清晰解释预测逻辑,满足监管需求。

3. 实战优化技巧

  • 数据预处理:线性模型、SVM、PCA、K-Means必须做特征标准化;树模型可跳过,但需处理异常值(避免影响分裂)。

  • 防过拟合:树模型用剪枝、集成策略;线性模型用正则化;所有模型可结合交叉验证、早停策略。

  • 参数调优:优先调核心参数(如XGBoost的learning_rate、max_depth;K-Means的K值),再优化正则化、采样参数。

  • 模型评估:回归任务用MSE、R²;分类任务用准确率、精确率、召回率(不平衡数据);聚类任务用轮廓系数、肘部法则。

机器学习算法选型的核心是“适配业务场景”,而非追求高精度。实际应用中,建议从简单模型入手,逐步迭代为复杂模型,同时结合数据特性和业务需求优化,确保模型的可用性、可解释性和稳定性。

注:本文实战案例基于sklearn、xgboost等主流库,代码可直接复制运行(需提前安装对应依赖库),适合机器学习入门及进阶学习参考。

依赖库安装命令:pip install numpy matplotlib pandas scikit-learn xgboost seaborn graphviz

(注:文档部分内容可能由 AI 生成)

← 返回技术