【机器学习精通】第1章 | 机器学习数学基础:从线性代数到概率统计

数学是机器学习的第一语言。掌握数学基础,才能真正理解算法背后的原理。


环境声明

在开始本章学习之前,请确保你的环境满足以下要求:

  • Python版本:Python 3.12+(建议使用3.10以上版本)
  • 核心库:NumPy 1.24+、SciPy 1.10+、Matplotlib 3.7+
  • 开发工具:PyCharm 或 VS Code
  • 操作系统:Windows / macOS / Linux(通用)
bash 复制代码
# 安装依赖
pip install numpy scipy matplotlib

学习目标

完成本章学习后,你将能够:

  1. 理解向量、矩阵的基本运算及其几何意义
  2. 掌握特征分解与SVD的数学原理
  3. 理解概率分布、期望、方差等核心概念
  4. 掌握假设检验的基本方法
  5. 理解PCA降维的数学推导过程
  6. 使用NumPy实现PCA算法

1. 线性代数核心概念

线性代数是机器学习的基石。从数据表示到算法实现,线性代数无处不在。

1.1 向量与矩阵基础

向量的定义

向量是既有大小又有方向的量。在机器学习中,一个样本的特征通常表示为一个向量。

列向量表示

x=[x1x2⋮xn]∈Rn \mathbf{x} = \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix} \in \mathbb{R}^n x= x1x2⋮xn ∈Rn

向量的基本运算

运算 公式 几何意义
加法 a+b\mathbf{a} + \mathbf{b}a+b 平行四边形法则
数乘 c⋅ac \cdot \mathbf{a}c⋅a 向量缩放
点积 a⋅b=∑i=1naibi\mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_ia⋅b=∑i=1naibi 投影长度
模长 ∣a∣=∑i=1nai2|\mathbf{a}| = \sqrt{\sum_{i=1}^{n} a_i^2}∣a∣=∑i=1nai2 向量长度
矩阵的定义

矩阵是按矩形排列的数表,是向量的推广。

A=[a11a12⋯a1na21a22⋯a2n⋮⋮⋱⋮am1am2⋯amn]∈Rm×n \mathbf{A} = \begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \end{bmatrix} \in \mathbb{R}^{m \times n} A= a11a21⋮am1a12a22⋮am2⋯⋯⋱⋯a1na2n⋮amn ∈Rm×n

矩阵的基本运算

python 复制代码
import numpy as np

# 向量定义
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

# 向量点积
dot_product = np.dot(a, b)  # 1*4 + 2*5 + 3*6 = 32
print(f"点积: {dot_product}")

# 向量模长
norm_a = np.linalg.norm(a)  # sqrt(1 + 4 + 9) = sqrt(14)
print(f"模长: {norm_a:.4f}")

# 矩阵定义
A = np.array([[1, 2], [3, 4], [5, 6]])  # 3x2矩阵
B = np.array([[7, 8], [9, 10]])         # 2x2矩阵

# 矩阵乘法
C = np.dot(A, B)  # 结果维度: 3x2
print(f"矩阵乘法结果:\n{C}")

1.2 特殊矩阵

在机器学习中,以下几类特殊矩阵尤为重要:

矩阵类型 定义 性质
单位矩阵 I\mathbf{I}I 对角线为1,其余为0 AI=A\mathbf{A}\mathbf{I} = \mathbf{A}AI=A
对角矩阵 D\mathbf{D}D 非对角线元素为0 特征值存储于对角线
对称矩阵 A\mathbf{A}A AT=A\mathbf{A}^T = \mathbf{A}AT=A 特征值为实数
正交矩阵 Q\mathbf{Q}Q QTQ=I\mathbf{Q}^T\mathbf{Q} = \mathbf{I}QTQ=I 保持向量长度不变
正定矩阵 xTAx>0\mathbf{x}^T\mathbf{A}\mathbf{x} > 0xTAx>0 所有特征值大于0

1.3 特征分解

特征分解是理解矩阵本质的重要工具。

特征值与特征向量

对于方阵 A\mathbf{A}A,如果存在非零向量 v\mathbf{v}v 和标量 λ\lambdaλ 满足:

Av=λv \mathbf{A}\mathbf{v} = \lambda\mathbf{v} Av=λv

则称 λ\lambdaλ 为特征值,v\mathbf{v}v 为对应的特征向量。

特征分解公式

A=VΛV−1 \mathbf{A} = \mathbf{V}\mathbf{\Lambda}\mathbf{V}^{-1} A=VΛV−1

其中:

  • Λ\mathbf{\Lambda}Λ 是由特征值构成的对角矩阵
  • V\mathbf{V}V 是由特征向量构成的矩阵

特征分解的几何意义

矩阵乘法 Ax\mathbf{A}\mathbf{x}Ax 可以理解为:先将向量 x\mathbf{x}x 变换到特征向量构成的坐标系(V−1x\mathbf{V}^{-1}\mathbf{x}V−1x),然后沿各坐标轴缩放(Λ\mathbf{\Lambda}Λ),最后变换回原坐标系(V\mathbf{V}V)。

python 复制代码
import numpy as np

# 定义对称矩阵
A = np.array([[4, 2], [2, 3]])

# 特征分解
eigenvalues, eigenvectors = np.linalg.eig(A)

print("特征值:", eigenvalues)
print("特征向量:\n", eigenvectors)

# 验证: A = V * Lambda * V^(-1)
Lambda = np.diag(eigenvalues)
V = eigenvectors
A_reconstructed = V @ Lambda @ np.linalg.inv(V)
print("重构矩阵:\n", A_reconstructed)

1.4 奇异值分解(SVD)

SVD是特征分解的广义形式,适用于任意矩阵(不限于方阵)。

SVD公式

对于矩阵 A∈Rm×n\mathbf{A} \in \mathbb{R}^{m \times n}A∈Rm×n,其SVD分解为:

A=UΣVT \mathbf{A} = \mathbf{U}\mathbf{\Sigma}\mathbf{V}^T A=UΣVT

其中:

  • U∈Rm×m\mathbf{U} \in \mathbb{R}^{m \times m}U∈Rm×m:左奇异向量矩阵(正交矩阵)
  • Σ∈Rm×n\mathbf{\Sigma} \in \mathbb{R}^{m \times n}Σ∈Rm×n:奇异值对角矩阵
  • V∈Rn×n\mathbf{V} \in \mathbb{R}^{n \times n}V∈Rn×n:右奇异向量矩阵(正交矩阵)

SVD与特征分解的关系

  • ATA\mathbf{A}^T\mathbf{A}ATA 的特征向量构成 V\mathbf{V}V
  • AAT\mathbf{A}\mathbf{A}^TAAT 的特征向量构成 U\mathbf{U}U
  • 奇异值是 ATA\mathbf{A}^T\mathbf{A}ATA 特征值的平方根
python 复制代码
import numpy as np

# 定义矩阵
A = np.array([[1, 2, 3], [4, 5, 6]])  # 2x3矩阵

# SVD分解
U, S, Vt = np.linalg.svd(A, full_matrices=False)

print("U矩阵:\n", U)
print("奇异值:", S)
print("V^T矩阵:\n", Vt)

# 重构矩阵
Sigma = np.diag(S)
A_reconstructed = U @ Sigma @ Vt
print("重构矩阵:\n", A_reconstructed)

2. 概率论基础

概率论为机器学习提供了处理不确定性的数学框架。

2.1 概率的基本概念

概率的定义

概率是描述随机事件发生可能性的数值,满足:

  • 非负性:P(A)≥0P(A) \geq 0P(A)≥0
  • 规范性:P(Ω)=1P(\Omega) = 1P(Ω)=1
  • 可加性:互斥事件的概率可相加
条件概率与贝叶斯定理

条件概率

P(A∣B)=P(A∩B)P(B),P(B)>0 P(A|B) = \frac{P(A \cap B)}{P(B)}, \quad P(B) > 0 P(A∣B)=P(B)P(A∩B),P(B)>0

贝叶斯定理

P(A∣B)=P(B∣A)⋅P(A)P(B) P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)} P(A∣B)=P(B)P(B∣A)⋅P(A)

贝叶斯定理在机器学习中应用广泛,如朴素贝叶斯分类器、贝叶斯优化等。

2.2 常见概率分布

离散型分布
分布 概率质量函数 期望 方差 应用场景
伯努利分布 P(X=k)=pk(1−p)1−kP(X=k) = p^k(1-p)^{1-k}P(X=k)=pk(1−p)1−k ppp p(1−p)p(1-p)p(1−p) 二分类问题
二项分布 P(X=k)=Cnkpk(1−p)n−kP(X=k) = C_n^k p^k(1-p)^{n-k}P(X=k)=Cnkpk(1−p)n−k npnpnp np(1−p)np(1-p)np(1−p) n次独立试验
泊松分布 P(X=k)=λke−λk!P(X=k) = \frac{\lambda^k e^{-\lambda}}{k!}P(X=k)=k!λke−λ λ\lambdaλ λ\lambdaλ 计数数据
连续型分布
分布 概率密度函数 期望 方差 应用场景
均匀分布 f(x)=1b−af(x) = \frac{1}{b-a}f(x)=b−a1 a+b2\frac{a+b}{2}2a+b (b−a)212\frac{(b-a)^2}{12}12(b−a)2 随机初始化
正态分布 f(x)=12πσe−(x−μ)22σ2f(x) = \frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(x-\mu)^2}{2\sigma^2}}f(x)=2π σ1e−2σ2(x−μ)2 μ\muμ σ2\sigma^2σ2 误差建模、先验分布
指数分布 f(x)=λe−λxf(x) = \lambda e^{-\lambda x}f(x)=λe−λx 1λ\frac{1}{\lambda}λ1 1λ2\frac{1}{\lambda^2}λ21 等待时间
python 复制代码
import numpy as np
from scipy import stats

# 正态分布
mu, sigma = 0, 1
normal_dist = stats.norm(mu, sigma)

# 概率密度函数
pdf_value = normal_dist.pdf(0)  # x=0处的密度
print(f"PDF at x=0: {pdf_value:.4f}")

# 累积分布函数
cdf_value = normal_dist.cdf(1.96)  # P(X <= 1.96)
print(f"CDF at x=1.96: {cdf_value:.4f}")

# 采样
samples = normal_dist.rvs(size=1000)
print(f"样本均值: {np.mean(samples):.4f}, 标准差: {np.std(samples):.4f}")

# 二项分布
n, p = 10, 0.5
binomial_dist = stats.binom(n, p)
prob = binomial_dist.pmf(5)  # P(X=5)
print(f"二项分布P(X=5): {prob:.4f}")

2.3 期望与方差

期望(Expectation)

期望是随机变量的加权平均值,代表长期实验的平均结果。

离散型

E[X]=∑ixi⋅P(X=xi) E[X] = \sum_{i} x_i \cdot P(X=x_i) E[X]=i∑xi⋅P(X=xi)

连续型

E[X]=∫−∞∞x⋅f(x)dx E[X] = \int_{-\infty}^{\infty} x \cdot f(x) dx E[X]=∫−∞∞x⋅f(x)dx

方差(Variance)

方差度量随机变量偏离期望的程度。

Var(X)=E[(X−E[X])2]=E[X2]−(E[X])2 Var(X) = E[(X - E[X])^2] = E[X^2] - (E[X])^2 Var(X)=E[(X−E[X])2]=E[X2]−(E[X])2

协方差与相关系数

协方差

Cov(X,Y)=E[(X−E[X])(Y−E[Y])] Cov(X, Y) = E[(X - E[X])(Y - E[Y])] Cov(X,Y)=E[(X−E[X])(Y−E[Y])]

相关系数

ρXY=Cov(X,Y)σXσY \rho_{XY} = \frac{Cov(X, Y)}{\sigma_X \sigma_Y} ρXY=σXσYCov(X,Y)

python 复制代码
import numpy as np

# 生成数据
np.random.seed(42)
X = np.random.randn(100)
Y = 2 * X + np.random.randn(100) * 0.5

# 期望
mean_X = np.mean(X)
mean_Y = np.mean(Y)

# 方差
var_X = np.var(X, ddof=1)  # 样本方差
var_Y = np.var(Y, ddof=1)

# 协方差矩阵
cov_matrix = np.cov(X, Y)
print("协方差矩阵:\n", cov_matrix)

# 相关系数矩阵
corr_matrix = np.corrcoef(X, Y)
print("相关系数矩阵:\n", corr_matrix)

2.4 最大似然估计

最大似然估计(MLE)是机器学习中参数估计的核心方法。

似然函数

给定样本 x=(x1,x2,...,xn)\mathbf{x} = (x_1, x_2, ..., x_n)x=(x1,x2,...,xn),似然函数定义为:

L(θ∣x)=∏i=1nf(xi;θ) L(\theta | \mathbf{x}) = \prod_{i=1}^{n} f(x_i; \theta) L(θ∣x)=i=1∏nf(xi;θ)

对数似然

为了方便计算,通常使用对数似然:

ℓ(θ)=log⁡L(θ∣x)=∑i=1nlog⁡f(xi;θ) \ell(\theta) = \log L(\theta | \mathbf{x}) = \sum_{i=1}^{n} \log f(x_i; \theta) ℓ(θ)=logL(θ∣x)=i=1∑nlogf(xi;θ)

正态分布的MLE示例

对于正态分布 N(μ,σ2)N(\mu, \sigma^2)N(μ,σ2),MLE估计为:

μ^=1n∑i=1nxi \hat{\mu} = \frac{1}{n}\sum_{i=1}^{n} x_i μ^=n1i=1∑nxi

σ^2=1n∑i=1n(xi−μ^)2 \hat{\sigma}^2 = \frac{1}{n}\sum_{i=1}^{n} (x_i - \hat{\mu})^2 σ^2=n1i=1∑n(xi−μ^)2

python 复制代码
import numpy as np
from scipy.optimize import minimize

# 生成正态分布样本
true_mu, true_sigma = 5, 2
np.random.seed(42)
samples = np.random.normal(true_mu, true_sigma, 1000)

# 定义负对数似然函数
def negative_log_likelihood(params, data):
    mu, sigma = params
    if sigma <= 0:
        return np.inf
    n = len(data)
    log_likelihood = -0.5 * n * np.log(2 * np.pi) - n * np.log(sigma) - \
                     np.sum((data - mu)**2) / (2 * sigma**2)
    return -log_likelihood

# 最大似然估计
result = minimize(negative_log_likelihood, [0, 1], args=(samples,))
mle_mu, mle_sigma = result.x

print(f"真实参数: mu={true_mu}, sigma={true_sigma}")
print(f"MLE估计: mu={mle_mu:.4f}, sigma={mle_sigma:.4f}")

3. 统计学基础

统计学提供了从数据中提取信息和做出推断的方法。

3.1 描述性统计

描述性统计用于总结和描述数据的基本特征。

统计量 定义 公式
均值 数据的平均值 xˉ=1n∑i=1nxi\bar{x} = \frac{1}{n}\sum_{i=1}^{n} x_ixˉ=n1∑i=1nxi
中位数 排序后中间位置的值 -
众数 出现频率最高的值 -
标准差 数据离散程度 s=1n−1∑i=1n(xi−xˉ)2s = \sqrt{\frac{1}{n-1}\sum_{i=1}^{n}(x_i - \bar{x})^2}s=n−11∑i=1n(xi−xˉ)2
四分位数 将数据分为四等份 Q1, Q2, Q3

3.2 假设检验

假设检验用于判断样本数据是否支持某个统计假设。

基本步骤
  1. 建立假设

    • 原假设 H0H_0H0:待检验的假设
    • 备择假设 H1H_1H1:与原假设对立的假设
  2. 选择检验统计量

  3. 确定显著性水平 α\alphaα(通常取0.05)

  4. 计算p值并做出决策

常见检验方法
检验类型 适用场景 检验统计量
Z检验 大样本均值检验 Z=Xˉ−μ0σ/nZ = \frac{\bar{X} - \mu_0}{\sigma/\sqrt{n}}Z=σ/n Xˉ−μ0
T检验 小样本均值检验 t=Xˉ−μ0s/nt = \frac{\bar{X} - \mu_0}{s/\sqrt{n}}t=s/n Xˉ−μ0
卡方检验 分类变量独立性 χ2=∑(O−E)2E\chi^2 = \sum \frac{(O-E)^2}{E}χ2=∑E(O−E)2
F检验 方差比较 F=s12s22F = \frac{s_1^2}{s_2^2}F=s22s12

3.3 置信区间

置信区间给出了估计值的不确定性范围。

均值的置信区间

对于正态分布样本,95%置信区间为:

xˉ±t0.025,n−1⋅sn \bar{x} \pm t_{0.025, n-1} \cdot \frac{s}{\sqrt{n}} xˉ±t0.025,n−1⋅n s

python 复制代码
import numpy as np
from scipy import stats

# 生成样本数据
np.random.seed(42)
sample = np.random.normal(100, 15, 50)

# 计算95%置信区间
confidence_level = 0.95
alpha = 1 - confidence_level
mean = np.mean(sample)
std_err = stats.sem(sample)  # 标准误

# 使用t分布
df = len(sample) - 1
t_critical = stats.t.ppf(1 - alpha/2, df)
margin_error = t_critical * std_err

ci_lower = mean - margin_error
ci_upper = mean + margin_error

print(f"样本均值: {mean:.2f}")
print(f"95%置信区间: [{ci_lower:.2f}, {ci_upper:.2f}]")

# 使用scipy直接计算
confidence_interval = stats.t.interval(
    confidence_level, df, loc=mean, scale=std_err
)
print(f"置信区间(函数计算): {confidence_interval}")

3.4 p值的解释

p值是在原假设为真的前提下,观察到当前样本或更极端样本的概率。

p值的解读

p值范围 结论
p < 0.01 极强证据拒绝原假设
0.01 <= p < 0.05 较强证据拒绝原假设
0.05 <= p < 0.1 弱证据
p >= 0.1 无充分证据拒绝原假设

注意:p值不是原假设为真的概率,也不是备择假设为真的概率。


4. 机器学习中的数学应用

4.1 PCA的数学原理

主成分分析(PCA)是一种经典的无监督降维算法,其核心思想是找到数据方差最大的方向。

PCA的数学推导

目标:将数据投影到低维空间,同时最大化保留方差。

设数据矩阵 X∈Rn×d\mathbf{X} \in \mathbb{R}^{n \times d}X∈Rn×d(n个样本,d个特征),已中心化(均值为0)。

第一步:计算协方差矩阵

C=1n−1XTX \mathbf{C} = \frac{1}{n-1}\mathbf{X}^T\mathbf{X} C=n−11XTX

第二步:特征分解

Cvi=λivi \mathbf{C}\mathbf{v}_i = \lambda_i\mathbf{v}_i Cvi=λivi

其中 λ1≥λ2≥...≥λd\lambda_1 \geq \lambda_2 \geq ... \geq \lambda_dλ1≥λ2≥...≥λd 是特征值,vi\mathbf{v}_ivi 是对应的特征向量。

第三步:选择主成分

选择前k个最大特征值对应的特征向量,构成投影矩阵 W=[v1,v2,...,vk]\mathbf{W} = [\mathbf{v}_1, \mathbf{v}_2, ..., \mathbf{v}_k]W=[v1,v2,...,vk]。

第四步:数据投影

Z=XW \mathbf{Z} = \mathbf{X}\mathbf{W} Z=XW

PCA与SVD的关系

PCA可以通过SVD高效计算:

X=UΣVT \mathbf{X} = \mathbf{U}\mathbf{\Sigma}\mathbf{V}^T X=UΣVT

其中 V\mathbf{V}V 的列向量就是PCA的主成分方向。

方差保留率

第i个主成分保留的方差比例为:

方差保留率i=λi∑j=1dλj \text{方差保留率}i = \frac{\lambda_i}{\sum{j=1}^{d}\lambda_j} 方差保留率i=∑j=1dλjλi

前k个主成分的累计方差保留率:

累计保留率=∑i=1kλi∑j=1dλj \text{累计保留率} = \frac{\sum_{i=1}^{k}\lambda_i}{\sum_{j=1}^{d}\lambda_j} 累计保留率=∑j=1dλj∑i=1kλi

4.2 梯度下降的数学推导

梯度下降是优化机器学习模型参数的核心算法。

梯度下降的原理

目标 :最小化损失函数 J(θ)J(\theta)J(θ)

更新规则

θt+1=θt−α∇J(θt) \theta_{t+1} = \theta_t - \alpha \nabla J(\theta_t) θt+1=θt−α∇J(θt)

其中:

  • α\alphaα 是学习率
  • ∇J(θ)\nabla J(\theta)∇J(θ) 是损失函数的梯度
线性回归的梯度下降

对于线性回归,损失函数为均方误差(MSE):

J(θ)=12m∑i=1m(hθ(x(i))−y(i))2 J(\theta) = \frac{1}{2m}\sum_{i=1}^{m}(h_\theta(x^{(i)}) - y^{(i)})^2 J(θ)=2m1i=1∑m(hθ(x(i))−y(i))2

其中 hθ(x)=θTxh_\theta(x) = \theta^T xhθ(x)=θTx。

梯度计算

∂J∂θj=1m∑i=1m(hθ(x(i))−y(i))xj(i) \frac{\partial J}{\partial \theta_j} = \frac{1}{m}\sum_{i=1}^{m}(h_\theta(x^{(i)}) - y^{(i)})x_j^{(i)} ∂θj∂J=m1i=1∑m(hθ(x(i))−y(i))xj(i)

向量化形式

∇J(θ)=1mXT(Xθ−y) \nabla J(\theta) = \frac{1}{m}\mathbf{X}^T(\mathbf{X}\theta - \mathbf{y}) ∇J(θ)=m1XT(Xθ−y)

python 复制代码
import numpy as np

def gradient_descent(X, y, theta, alpha, num_iters):
    """
    梯度下降算法实现
    
    参数:
    X: 特征矩阵 (m, n)
    y: 目标向量 (m,)
    theta: 参数向量 (n,)
    alpha: 学习率
    num_iters: 迭代次数
    """
    m = len(y)
    cost_history = []
    
    for i in range(num_iters):
        # 计算预测值
        predictions = X @ theta
        
        # 计算误差
        errors = predictions - y
        
        # 计算梯度
        gradient = (1/m) * (X.T @ errors)
        
        # 更新参数
        theta = theta - alpha * gradient
        
        # 计算损失(用于监控)
        cost = (1/(2*m)) * np.sum(errors**2)
        cost_history.append(cost)
    
    return theta, cost_history

5. 实战案例:使用NumPy实现PCA

本节将完整实现PCA算法,并将其应用于数据降维任务。

5.1 完整PCA实现

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

class PCA:
    """
    主成分分析(PCA)的NumPy实现
    
    参数:
    n_components: 保留的主成分数量
    """
    
    def __init__(self, n_components=None):
        self.n_components = n_components
        self.components_ = None      # 主成分(特征向量)
        self.explained_variance_ = None  # 各主成分的方差
        self.explained_variance_ratio_ = None  # 方差贡献率
        self.mean_ = None            # 特征均值
    
    def fit(self, X):
        """
        拟合PCA模型
        
        参数:
        X: 输入数据,形状为 (n_samples, n_features)
        """
        # 保存特征均值
        self.mean_ = np.mean(X, axis=0)
        
        # 数据中心化
        X_centered = X - self.mean_
        
        # 计算协方差矩阵
        n_samples = X.shape[0]
        cov_matrix = (X_centered.T @ X_centered) / (n_samples - 1)
        
        # 特征分解
        eigenvalues, eigenvectors = np.linalg.eigh(cov_matrix)
        
        # 按特征值从大到小排序
        idx = np.argsort(eigenvalues)[::-1]
        eigenvalues = eigenvalues[idx]
        eigenvectors = eigenvectors[:, idx]
        
        # 保存结果
        self.explained_variance_ = eigenvalues
        self.explained_variance_ratio_ = eigenvalues / np.sum(eigenvalues)
        
        # 确定保留的主成分数量
        if self.n_components is None:
            self.n_components = X.shape[1]
        
        self.components_ = eigenvectors[:, :self.n_components]
        
        return self
    
    def transform(self, X):
        """
        将数据投影到主成分空间
        
        参数:
        X: 输入数据
        
        返回:
        降维后的数据
        """
        X_centered = X - self.mean_
        return X_centered @ self.components_
    
    def fit_transform(self, X):
        """拟合模型并转换数据"""
        self.fit(X)
        return self.transform(X)
    
    def inverse_transform(self, X_reduced):
        """
        将降维后的数据还原到原始空间
        
        参数:
        X_reduced: 降维后的数据
        
        返回:
        还原后的数据
        """
        return X_reduced @ self.components_.T + self.mean_


# 使用示例
if __name__ == "__main__":
    # 生成示例数据
    np.random.seed(42)
    
    # 创建二维高斯数据,具有一定的相关性
    mean = [0, 0]
    cov = [[3, 2], [2, 2]]  # 协方差矩阵
    X = np.random.multivariate_normal(mean, cov, 300)
    
    # 应用PCA
    pca = PCA(n_components=2)
    X_pca = pca.fit_transform(X)
    
    # 输出结果
    print("=" * 50)
    print("PCA结果分析")
    print("=" * 50)
    print(f"原始数据维度: {X.shape}")
    print(f"降维后数据维度: {X_pca.shape}")
    print(f"\n特征值(方差): {pca.explained_variance_}")
    print(f"方差贡献率: {pca.explained_variance_ratio_}")
    print(f"累计方差贡献率: {np.cumsum(pca.explained_variance_ratio_)}")
    print(f"\n主成分方向:\n{pca.components_}")
    
    # 数据还原
    X_reconstructed = pca.inverse_transform(X_pca)
    reconstruction_error = np.mean((X - X_reconstructed)**2)
    print(f"\n重构误差: {reconstruction_error:.6f}")

5.2 降维效果可视化

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris

# 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target
target_names = iris.target_names

# 应用PCA降至2维
pca = PCA(n_components=2)
X_r = pca.fit_transform(X)

# 可视化
plt.figure(figsize=(10, 8))
colors = ['navy', 'turquoise', 'darkorange']

for color, i, target_name in zip(colors, [0, 1, 2], target_names):
    plt.scatter(X_r[y == i, 0], X_r[y == i, 1], 
                color=color, alpha=0.8, lw=2, label=target_name)

plt.legend(loc='best', shadow=False, scatterpoints=1)
plt.title('PCA of IRIS Dataset')
plt.xlabel(f'PC1 ({pca.explained_variance_ratio_[0]:.1%} variance)')
plt.ylabel(f'PC2 ({pca.explained_variance_ratio_[1]:.1%} variance)')
plt.grid(True, alpha=0.3)
plt.savefig('pca_iris_visualization.png', dpi=150, bbox_inches='tight')
plt.show()

# 方差贡献率分析
print("\n各主成分方差贡献率:")
for i, ratio in enumerate(pca.explained_variance_ratio_):
    print(f"  PC{i+1}: {ratio:.4f} ({ratio:.2%})")
print(f"累计贡献率: {np.sum(pca.explained_variance_ratio_):.2%}")

5.3 选择合适的主成分数量

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

def plot_variance_explained(pca, threshold=0.95):
    """
    绘制方差贡献率图,帮助选择主成分数量
    
    参数:
    pca: 拟合好的PCA对象
    threshold: 方差保留阈值
    """
    n_components = len(pca.explained_variance_ratio_)
    
    # 计算累计方差贡献率
    cumsum_ratio = np.cumsum(pca.explained_variance_ratio_)
    
    # 找到满足阈值的最小主成分数
    n_components_needed = np.argmax(cumsum_ratio >= threshold) + 1
    
    # 绘图
    plt.figure(figsize=(10, 6))
    
    # 单个方差贡献率
    plt.bar(range(1, n_components + 1), 
            pca.explained_variance_ratio_, 
            alpha=0.7, label='Individual')
    
    # 累计方差贡献率
    plt.plot(range(1, n_components + 1), 
             cumsum_ratio, 
             'ro-', label='Cumulative')
    
    # 阈值线
    plt.axhline(y=threshold, color='g', linestyle='--', 
                label=f'{threshold:.0%} threshold')
    plt.axvline(x=n_components_needed, color='g', linestyle='--')
    
    plt.xlabel('Number of Components')
    plt.ylabel('Explained Variance Ratio')
    plt.title('PCA Variance Explained')
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.savefig('pca_variance_explained.png', dpi=150, bbox_inches='tight')
    plt.show()
    
    print(f"保留{threshold:.0%}方差需要的主成分数: {n_components_needed}")
    
    return n_components_needed

# 示例使用
# n_needed = plot_variance_explained(pca, threshold=0.95)

6. 避坑小贴士

6.1 线性代数常见错误

  1. 矩阵维度不匹配

    • 在进行矩阵乘法前,务必检查维度
    • A(m,n) @ B(n,p) = C(m,p)
  2. 混淆矩阵乘法和逐元素乘法

    • np.dot(A, B)A @ B:矩阵乘法
    • A * B:逐元素乘法(Hadamard积)
  3. 忽视数值稳定性

    • 求逆矩阵时,条件数过大的矩阵会导致数值不稳定
    • 优先使用 np.linalg.solve 而非直接求逆

6.2 概率统计常见错误

  1. 混淆样本方差和总体方差

    • 样本方差分母为 n-1(无偏估计)
    • NumPy中 np.var(x, ddof=1) 计算样本方差
  2. 误解p值的含义

    • p值不是原假设为真的概率
    • p值小只说明数据与原假设不一致,不代表效应大小
  3. 忽视数据分布假设

    • t检验假设数据近似正态分布
    • 样本量小时,先检验正态性

6.3 PCA使用注意事项

  1. 数据必须中心化

    • PCA对数据的平移敏感
    • 实现时务必减去均值
  2. 特征缩放

    • 当特征量纲不同时,先进行标准化
    • 否则量纲大的特征会主导主成分
  3. 处理缺失值

    • PCA不能处理含缺失值的数据
    • 需先进行缺失值填充

7. 本章小结

本章系统介绍了机器学习所需的数学基础,核心要点如下:

线性代数

  • 向量与矩阵是数据的数学表示
  • 特征分解揭示矩阵的本质结构
  • SVD是更通用的矩阵分解方法

概率论

  • 概率分布建模随机现象
  • 期望和方差描述分布特征
  • 最大似然估计是参数估计的核心方法

统计学

  • 假设检验用于判断统计显著性
  • 置信区间量化估计的不确定性
  • p值是证据强度的度量

机器学习应用

  • PCA通过特征分解实现数据降维
  • 梯度下降利用导数信息优化参数
  • 数学原理是理解算法的关键

8. 思考与练习

基础练习

  1. 向量运算 :给定向量 a=[1,2,3]T\mathbf{a} = [1, 2, 3]^Ta=[1,2,3]T 和 b=[4,5,6]T\mathbf{b} = [4, 5, 6]^Tb=[4,5,6]T,计算:

    • 点积 a⋅b\mathbf{a} \cdot \mathbf{b}a⋅b
    • 叉积(如果是在3D空间)
    • 向量夹角的余弦值
  2. 矩阵分解 :对矩阵 A=[4223]\mathbf{A} = \begin{bmatrix} 4 & 2 \\ 2 & 3 \end{bmatrix}A=[4223] 进行特征分解,并验证 A=VΛV−1\mathbf{A} = \mathbf{V}\mathbf{\Lambda}\mathbf{V}^{-1}A=VΛV−1。

  3. 概率计算 :假设某班级学生身高服从正态分布 N(170,25)N(170, 25)N(170,25),计算:

    • 随机抽取一名学生身高超过180cm的概率
    • 身高在165cm到175cm之间的概率

进阶练习

  1. PCA实现:使用NumPy实现PCA算法,并在MNIST数据集上进行降维可视化(降至2维)。

  2. 梯度下降优化:实现带动量的梯度下降算法,比较其与标准梯度下降在收敛速度上的差异。

  3. 假设检验:收集一组样本数据,进行单样本t检验,判断样本均值是否显著不同于某个假设值。

挑战练习

  1. SVD应用:使用SVD进行图像压缩,比较不同保留奇异值数量对图像质量和压缩比的影响。

  2. MLE推导:推导泊松分布和指数分布的最大似然估计公式,并用Python实现。

  3. 协方差分析:分析多变量数据集的协方差矩阵,解释变量间的相关性结构。


学习建议:数学基础需要反复练习才能掌握。建议读者动手推导本章的公式,并运行所有代码示例。


本系列教程持续更新中,欢迎关注专栏获取更多机器学习深度内容。

相关推荐
Once_day1 小时前
AI实践(7)工具函数调用
人工智能·ai实践
qq_397562311 小时前
神经网络模型 , 转换RKNN格式(量化) .(演示)
人工智能·深度学习·神经网络
AsDuang1 小时前
Python 3.12 MagicMethods - 48 - __rmatmul__
开发语言·python
郑同学zxc1 小时前
机器学习17-tensorflow2 线性代数
线性代数·机器学习·tensorflow
啊哈哈121381 小时前
从零构建 Multi-Agent 系统:SQLAgent + RAGAgent + 智能路由实战
人工智能·python
墨染天姬2 小时前
【AI】PyTorch/TF 也会变成考古?
人工智能·pytorch·python
郑同学zxc4 小时前
机器学习18-tensorflow3
人工智能·机器学习
这张生成的图像能检测吗4 小时前
(论文速读)基于快速局域谱滤波的卷积神经网络
人工智能·神经网络·cnn·图神经网络·分类模型
wuxuand4 小时前
2026论文阅读——BayesAHDD:当贝叶斯决策规则遇上小样本单类分类
论文阅读·人工智能·分类·数据挖掘