欢迎光临
我们一直在努力

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

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


环境声明

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

  • Python版本:Python 3.12+(建议使用3.10以上版本)
  • 核心库:NumPy 1.24+、SciPy 1.10+、Matplotlib 3.7+
  • 开发工具:PyCharm 或 VS Code
  • 操作系统:Windows / macOS / Linux(通用)

# 安装依赖
pip install numpy scipy matplotlib


学习目标

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

  • 理解向量、矩阵的基本运算及其几何意义
  • 掌握特征分解与SVD的数学原理
  • 理解概率分布、期望、方差等核心概念
  • 掌握假设检验的基本方法
  • 理解PCA降维的数学推导过程
  • 使用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=x1x2xnRn

    向量的基本运算:

    运算公式几何意义
    加法 a+b\\mathbf{a} + \\mathbf{b}a+b 平行四边形法则
    数乘 c⋅ac \\cdot \\mathbf{a}ca 向量缩放
    点积 a⋅b=∑i=1naibi\\mathbf{a} \\cdot \\mathbf{b} = \\sum_{i=1}^{n} a_i b_iab=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=a11a21am1a12a22am2a1na2namnRm×n

    矩阵的基本运算:

    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]]) # 3×2矩阵
    B = np.array([[7, 8], [9, 10]]) # 2×2矩阵

    # 矩阵乘法
    C = np.dot(A, B) # 结果维度: 3×2
    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=V1

    其中:

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

    特征分解的几何意义:

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

    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}ARm×n,其SVD分解为:

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

    其中:

    • U∈Rm×m\\mathbf{U} \\in \\mathbb{R}^{m \\times m}URm×m:左奇异向量矩阵(正交矩阵)
    • Σ∈Rm×n\\mathbf{\\Sigma} \\in \\mathbb{R}^{m \\times n}ΣRm×n:奇异值对角矩阵
    • V∈Rn×n\\mathbf{V} \\in \\mathbb{R}^{n \\times n}VRn×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 特征值的平方根

    import numpy as np

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

    # 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(AB)=P(B)P(AB),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(AB)=P(B)P(BA)P(A)

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

    2.2 常见概率分布

    离散型分布
    分布概率质量函数期望方差应用场景
    伯努利分布 P(X=k)=pk(1−p)1−kP(X=k) = p^k(1-p)^{1-k}P(X=k)=pk(1p)1k ppp p(1−p)p(1-p)p(1p) 二分类问题
    二项分布 P(X=k)=Cnkpk(1−p)n−kP(X=k) = C_n^k p^k(1-p)^{n-k}P(X=k)=Cnkpk(1p)nk npnpnp np(1−p)np(1-p)np(1p) 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)=ba1 a+b2\\frac{a+b}{2}2a+b (b−a)212\\frac{(b-a)^2}{12}12(ba)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πσ1e2σ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 等待时间

    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]=ixiP(X=xi)

    连续型:

    E[X]=∫−∞∞x⋅f(x)dx
    E[X] = \\int_{-\\infty}^{\\infty} x \\cdot f(x) dx
    E[X]=xf(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[(XE[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[(XE[X])(YE[Y])]

    相关系数:

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

    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=1nf(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=1nlogf(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=1nxi

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

    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ˉ=n1i=1nxi
    中位数 排序后中间位置的值
    众数 出现频率最高的值
    标准差 数据离散程度 s=1n−1∑i=1n(xi−xˉ)2s = \\sqrt{\\frac{1}{n-1}\\sum_{i=1}^{n}(x_i – \\bar{x})^2}s=n11i=1n(xixˉ)2
    四分位数 将数据分为四等份 Q1, Q2, Q3

    3.2 假设检验

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

    基本步骤
  • 建立假设

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

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

  • 计算p值并做出决策

  • 常见检验方法
    检验类型适用场景检验统计量
    Z检验 大样本均值检验 Z=Xˉ−μ0σ/nZ = \\frac{\\bar{X} – \\mu_0}{\\sigma/\\sqrt{n}}Z=σ/nXˉμ0
    T检验 小样本均值检验 t=Xˉ−μ0s/nt = \\frac{\\bar{X} – \\mu_0}{s/\\sqrt{n}}t=s/nXˉμ0
    卡方检验 分类变量独立性 χ2=∑(O−E)2E\\chi^2 = \\sum \\frac{(O-E)^2}{E}χ2=E(OE)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,n1ns

    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}XRn×d(n个样本,d个特征),已中心化(均值为0)。

    第一步:计算协方差矩阵

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

    第二步:特征分解

    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=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λji=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=1m(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)}
    θjJ=m1i=1m(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)

    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实现

    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 降维效果可视化

    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 选择合适的主成分数量

    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 线性代数常见错误

  • 矩阵维度不匹配

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

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

    • 求逆矩阵时,条件数过大的矩阵会导致数值不稳定
    • 优先使用 np.linalg.solve 而非直接求逆
  • 6.2 概率统计常见错误

  • 混淆样本方差和总体方差

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

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

    • t检验假设数据近似正态分布
    • 样本量小时,先检验正态性
  • 6.3 PCA使用注意事项

  • 数据必须中心化

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

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

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

  • 7. 本章小结

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

    线性代数:

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

    概率论:

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

    统计学:

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

    机器学习应用:

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

    8. 思考与练习

    基础练习

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

    • 点积 a⋅b\\mathbf{a} \\cdot \\mathbf{b}ab
    • 叉积(如果是在3D空间)
    • 向量夹角的余弦值
  • 矩阵分解:对矩阵 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=V1

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

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

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

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

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

  • 挑战练习

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

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

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


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


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

    赞(0)
    未经允许不得转载:171主机测评 » 【机器学习精通】第1章 | 机器学习数学基础:从线性代数到概率统计
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址