Jiahong 的个人博客

凡事预则立,不预则废


  • Home

  • Tags

  • Archives

  • Navigation

  • Search

Python——partial函数的使用


整体说明

  • 在 Python 里,functools 模块中的 partial 函数能够用来创建新函数,这些新函数是对现有函数部分参数预先赋值后的版本

  • 借助这种方式,能简化函数调用,让代码更为简洁,常用在一些较为专业的底层框架中

  • 函数形式:

    1
    2
    3
    from functools import partial

    new_func = partial(func, *args, **kwargs)
    • func 代表原函数
    • args 和 kwargs 分别是要预先设置的位置参数和关键字参数
    • 调用 new_func 时,只需传入剩余未预先设置的参数就行

固定函数参数

  • 假设存在一个加法函数 add(a, b),现在要创建一个专门用于加 10 的新函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from functools import partial

    def add(a, b):
    return a + b

    add_ten = partial(add, 10) # 把 a 固定为 10

    print(add_ten(5)) # 输出 15(也就是 10 + 5)
    print(add_ten(10)) # 输出 20(也就是 10 + 10)
    print(add_ten(5, 20)) # 输出 25(此时 10 被 5 覆盖,函数计算的是 5 + 20)
    • 注意:固定的是第一个参数

处理关键字参数

  • 在处理关键字参数 Demo:

    1
    2
    3
    4
    5
    6
    7
    8
    def power(base, exponent):
    return base ** exponent

    square = partial(power, exponent=2) # 固定 exponent 为 2
    cube = partial(power, exponent=3) # 固定 exponent 为 3

    print(square(5)) # 输出 25(即 5^2)
    print(cube(5)) # 输出 125(即 5^3)
    • 注意:可通过关键字参数指明具体参数

需要注意的点

  • 参数顺序问题 :使用 partial 固定参数时,参数是按照位置依次绑定的

    • 比如 partial(func, 10) 会把 10 绑定到 func 的第一个参数上
  • 参数覆盖 :如果预先设置的参数在新函数调用时又被传入了新值,那么新传入的值会覆盖预先设置的值

    • 例如:
      1
      2
      3
      add_ten = partial(add, 10)
      print(add_ten(5)) # 输出 15
      print(add_ten(5, 20)) # 输出 25(此时 10 被 5 覆盖,函数计算的是 5 + 20)
  • 函数属性保留 :通过 partial 创建的新函数会保留原函数的一些属性

    • 像 __name__ 和 __doc__ 等函数属性还在

附录:与 Lambda 表达式的对比

使用 partial 和 lambda 都能实现参数固定的效果,但它们之间也有区别:

1
2
3
4
5
# 使用 partial
add_ten = partial(add, 10)

# 使用 lambda
add_ten_lambda = lambda x: add(10, x)
  • partial 函数在代码简洁性上表现更优,并且能够保留原函数的元信息
  • lambda 表达式则更为灵活,可以实现更复杂的逻辑

ML——损失函数总结

各种损失函数(Loss Function)总结,持续更新


名词概念

在机器学习和统计学中,成本函数(Cost Function)、经验风险(Empirical Risk)和损失函数(Loss Function)是三个密切相关但又有所区别的概念

  • 损失函数(Loss Function): 损失函数衡量的是单个训练样本的预测值与实际值之间的差异。它是模型预测误差的量化表示。常见的损失函数包括均方误差(Mean Squared Error, MSE)、交叉熵损失(Cross-Entropy Loss)等
  • 成本函数(Cost Function): 又名代价函数,等价于损失函数
  • 期望风险(Expected Risk):所有样本(训练样本+验证样本+测试样本+未知样本)的损失函数的期望,用于评估模型的泛化能力
  • 经验风险(Empirical Risk): 经验风险是在给定数据集上(一般是训练集),模型的平均损失。它是所有训练样本损失函数值的平均,用于评估模型在特定数据集上的表现。经验风险可以视为模型在有限数据集上的泛化能力的估计,本质是对期望风险的一种估计
  • 结构风险(Structural Risk):用于平衡模型对样本的拟合能力和复杂度
    $$
    结构风险 = 经验风险 + \alpha 正则化项
    $$
  • 注意:在一般的书籍或者博客论文中,尝尝也用 损失函数 或 成本函数 笼统的表达了 成本函数、经验风险、损失函数、成本函数、甚至结构风险 等所有相关概念 ,所以本文下面也会比较笼统称为损失函数

损失函数总体说明

  • 损失函数(Loss Function)又称为代价函数(Cost Function)
  • 损失函数用于评估预测值与真实值之间的不一致程度
  • 损失函数/成本函数是模型的优化目标函数,(神经网络训练的过程就是最小化损失函数的过程)
  • 损失函数/成本函数越小,说明预测值越接近于真实值,模型表现越好

各种损失函数介绍

平方损失函数

最常用的回归损失函数

  • 基本形式
    $$loss = (y - f(x))^{2}$$
  • 对应模型
    • 线性回归
      • 使用的均方误差来自于平方损失函数
        $$loss_{MSE} = \frac{1}{m}\sum_{i=1}^{m}(y_{i} - f(x_{i}))^2$$
    • 其他扩展,RMSE(Root Mean Squared Error,常用作指标而不是损失函数)
      $$loss_{RMSE} = \sqrt{\frac{1}{m}\sum_{i=1}^{m}(y_{i} - f(x_{i}))^2}$$

MSLE/RMSLE损失函数

  • MSLE,Mean Squared Logarithmic Error
    $$loss_{MSLE} = \frac{1}{m}\sum_{i=1}^{m} \left(\log(1+y_{i}) - \log(1+f(x_{i})) \right)^2$$
  • RMSLE,Root Mean Squared Logarithmic Error
  • 损失函数形式
    $$loss_{RMSLE} = \sqrt{\frac{1}{m}\sum_{i=1}^{m} \left(\log(1+y_{i}) - \log(1+f(x_{i})) \right)^2}$$
  • MSLE和RMSLE可缓解长尾变量导致的异常值问题

MAPE/MSPE/RMAPE/RMSPE损失函数

  • MAPE,Mean Absolute Percentage Error
    $$loss_{MAPE} = \frac{1}{m}\sum_{i=1}^{m} \left|\frac{y_i-f(x_i)}{y_i}\right|$$
  • MSPE,Mean Squared Percentage Error
    $$loss_{MSPE} = \frac{1}{m}\sum_{i=1}^{m} \left(\frac{y_i-f(x_i)}{y_i}\right)^2$$
  • RMAPE/RMSPE在MAPE/MSPE的基础上开根号即可
  • MAPE/MSPE/RMAPE/RMSPE都可缓解长尾变量导致的异常值问题

绝对值损失函数

最常用的回归损失函数

  • 基本形式
    $$loss = |y - f(x)|$$
  • 对应的经验风险:
    $$loss_{MAE} = \frac{1}{m}\sum_{i=1}^{m}|y_{i} - f(x_{i})|$$

交叉熵损失函数(对数似然损失函数)

最常见的损失函数交叉熵损失函数 ,又名对数似然损失函数

  • 基本形式(目标:在已知X时,样本标签Y出现的概率最大化,损失函数在概率前加个负号即可)
    $$loss=L(P_{\theta}(Y|X))=-logP_{\theta}(Y|X)$$
  • 二分类中的交叉熵损失函数:
    $$loss_{CE} = \frac{1}{N} \sum_{i}^{N}-y_ilogy_i’ - (1-y_i)log(1-y_i’)$$
    • 二分类中对于单个样本的损失一般写为:
      $$loss(x_i) = -y_ilogy_i’ - (1-y_i)log(1-y_i’)$$
    • 写成最容易看清楚的形式为:
      $$
      \begin{align}
      loss(x_i) &= -logy_i’, &\quad y_i = 1 \\
      loss(x_i) &= -log(1-y_i’), &\quad y_i = 0
      \end{align}
      $$
      • \(y_i\) 为样本 \(x_i\) 的真实类别
      • \(y_i’\) 为样本 \(x_i\) 在模型中的预测值(这个值在二分类中为Sigmoid函数归一化后的取值,代表样本分类为 \(y_i=1\) 的概率)
      • \(y_i’\) 也可表达为 \(p_{i,1}\),即样本 \(i\) 分类为1的概率
  • 多分类中的交叉熵损失函数:
    $$loss_{CE} = -\frac{1}{N} \sum_{i}^{N}\sum_{c=1}^{C} y_{i,c}\log p_{i,c}^{\theta}$$
    • \(y_{i,c} \in \{0, 1\}\):当样本 \(i\) 的真实分类是 \(c\) 时, \(y_{i,c}=1\),否则 \(y_{i,c}=0\)
    • \(p_{i,c}^{\theta}\):表示样本 \(i\) 为分类 \(c\) 的预估概率,由 \(y_{i,c} \in \{0, 1\}\) 可知损失函数不需要关注样本预测为其他错误类别的概率,仅关注真实样本对应类别的概率即可
    • 二分类的场景实际上是多分类的特定形式, \(1-y_i’\) 可以用来表示分类为0时的概率
  • 凡是极大似然估计作为学习策略的模型,损失函数都为交叉熵损失函数(对数似然损失函数)
    • 因为极大化似然函数等价于极小化对数似然损失函数,推导:
      $$
      \begin{align}
      \theta^{*} &= \mathop{\arg\max}_{\theta} \prod_i P_{\theta}(y_i|x_i) \\
      &= \mathop{\arg\max}_{\theta} \sum_i \log P_{\theta}(y_i|x_i) \\
      &= \mathop{\arg\min}_{\theta} - \sum_i \log P_{\theta}(y_i|x_i) \\
      &= \mathop{\arg\min}_{\theta} - \frac{1}{N} \sum_{i}^{N}\sum_{c=1}^{C} y_{i,c}\log p_{i,c}^{\theta}
      \end{align}
      $$
    • <<统计学习方法>>第十二章中LR使用的是极大似然估计但是对应的损失函数是逻辑斯蒂损失函数,这里可以证明LR中对数似然损失函数和逻辑斯蒂损失函数完全等价,证明见统计学习方法212页笔记
  • 对应模型
    • 所有使用极大似然估计的模型
      • 可以证明,极大似然估计法最大化样本出现概率的目标是最小化真实分布和预估分布的KL散度
        • 为了方便证明,下面把 \(P_{\theta}(y_i|x_i)\) 写作 \(P_{\theta}(x_i)\),这里 \(x_i\) 包含了样本的label( \(y_i\) )信息
          $$
          \begin{align}
          \theta^{*} &= \mathop{\arg\min}_{\theta} - \frac{1}{N} \sum_{i}^{N}\sum_{c=1}^{C} y_{i,c}\log p_{i,c}^{\theta} &\quad — 交叉熵损失函数\\
          &= \mathop{\arg\min}_{\theta} - \sum_i \log P_{\theta}(x_i) &\quad — 交叉熵损失函数\\
          &= \mathop{\arg\max}_{\theta} \sum_i \log P_{\theta}(x_i) \\
          &= \mathop{\arg\max}_{\theta} \prod_i P_{\theta}(x_i) &\quad — 极大似然法\\
          &= \mathop{\arg\max}_{\theta} \sum_i \log P_{\theta}(x_i) \\
          &\approx \mathop{\arg\max}_{\theta} \mathbb{E}_{x \sim P_{data}}\log P_{\theta}(x) \\
          &= \mathop{\arg\max}_{\theta} \int_{x} P_{data}(x) \log P_{\theta}(x) dx \\
          &= \mathop{\arg\max}_{\theta} \int_{x} P_{data}(x) \log P_{\theta}(x) dx - \int_{x} P_{data}(x) \log P_{data}(x) dx &\quad — 减去一项与\theta无关的项\\
          &= \mathop{\arg\max}_{\theta} \int_{x} P_{data}(x) \log \frac{P_{\theta}(x)}{P_{data}(x)} dx \\
          &= \mathop{\arg\max}_{\theta} -\int_{x} P_{data}(x) \log \frac{P_{data}(x)}{P_{\theta}(x)} dx \\
          &= \mathop{\arg\min}_{\theta} \int_{x} P_{data}(x) \log \frac{P_{data}(x)}{P_{\theta}(x)} dx \\
          &= \mathop{\arg\min}_{\theta} KL(P_{data}|| P_{\theta}) &\quad — KL散度\\
          \end{align}
          $$
        • 上式表明:似然函数最大化(极大似然法,对应交叉熵损失最小化),等价于最小化真实分布与预估分布的KL散度
        • 注:式中 \(x_i\) 样本表示<特征,标签>对, \(P_{\theta}(x_i)\) 表示在模型 \(\theta\) 下,真实<特征,标签>出现的概率
      • 同理,可以证明,最小化交叉熵损失函数的目标也是最小化真实分布和预估分布的KL散度
    • 最大化后验概率等价于最小化对数似然损失函数
      $$\theta^{\star} = \mathop{\arg\max}_{\theta} LL(\theta) = \mathop{\arg\min}_{\theta} -LL(\theta) = \mathop{\arg\min}_{\theta} -\log P(Y|X) = \mathop{\arg\min}_{\theta} -\sum_{i=1}^{N}\log p_{\theta}(y_{i}|x_{i})$$

指数损失函数

提升方法的损失函数

  • 基本形式
    $$loss=L(y,f(x))=e^{-yf(x)}$$
  • 对应模型
    • 提升方法

0-1损失函数

最理想的损失函数,但是不光滑,不可导

  • 基本形式
    $$loss=L(y,f(x))=0, \text{if} \ yf(x)>0 \\
    loss=L(y,f(x))=1, \text{if} \ yf(x)<0$$
  • 在由 \(f(x)\) 符号判断样本的类别的二分类问题中
    • 分类正确时总有 \(yf(x)>0\),损失为0
    • 分类错误时总有 \(yf(x)<0\),损失为1
  • 在特定的模型中,比如要求 \(f(x)=y\) 才算正确分类的模型中
    • 0-1损失函数可定义为如下
      $$loss=L(y,f(x))=0, \text{if} \ y=f(x) \\
      loss=L(y,f(x))=1, \text{if} \ y\neq f(x)$$

合页损失函数(Hinge 损失函数)

支持向量机的损失函数

  • 一般基本形式为
    $$loss = L(y,f(x))=[1-yf(x)]_{+}$$
    • \([z]_{+}\) 表示
      • \(z>0\) 时取 \(z\)
      • \(z\leq 0\) 时取0
  • 也可以写作(按单样本写并展开取正符号):
    $$L(y_i, f(x_i)) = \max(0, 1 - y_i \cdot f(x_i))$$
  • 损失函数分析:
    • 当 \( y_i \cdot f(x_i) \geq 1 \) 时,损失为 0,说明样本被正确分类且与边界的距离足够大(满足间隔要求),无需惩罚了
    • 当 \( y_i \cdot f(x_i) < 1 \) 时,损失为 \( 1 - y_i \cdot f(x_i) \),说明样本分类错误或距离边界太近,需要惩罚
  • 对应模型
    • 支持向量机

感知机的损失函数

感知机特有的损失函数<<统计学习方法>>

  • 基本形式
    $$loss=L(y,f(x))=[-yf(x)]_{+}$$
  • 与合页损失函数对比
    • 相当于函数图像整体左移一个单位长度
    • 合页损失函数比感知机的损失函数对学习的要求更高
    • 这使得感知机对分类正确的样本就无法进一步优化(分类正确的样本损失函数为0),学到的分类面只要能对样本正确分类即可(不是最优的,而且随机梯度下降时从不同点出发会有不同结果)
    • 而SVM则需要学到最优的才行,因为即使分类正确的样本,依然会有一个较小的损失,此时为了最小化损失函数,需要不断寻找,直到分类面为最优的分类面位置
  • 对应模型
    • 感知机

感知损失函数

与感知机没有任何关系

  • 基本形式
    $$L(y,f(x))=1, \text{if} \ \left | y-f(x)\right |>t \\
    L(y,f(x))=0, \text{if} \ \left | y-f(x)\right |< t$$
  • 这里”感知”的意思是在一定范围内认为 \(y\approx f(x)\),满足小范围差距时,损失函数为0

Focal Loss

本文原文为: ICCV 2017: Focal Loss for Dense Object Detection

  • 主要是为了解决正负样本严重失衡的问题
  • 是交叉熵损失函数的一种改进
  • 回归交叉熵损失函数的表达式为:
    $$
    \begin{align}
    loss(x_i) &= -logy_i’, &\quad y_i = 1 \\
    loss(x_i) &= -log(1-y_i’), &\quad y_i = 0
    \end{align}
    $$
  • Focal Loss的损失函数如下
    $$
    \begin{align}
    loss(x_i) &= -(1-y_i’)^\gamma logy_i’, &\quad y_i = 1 \\
    loss(x_i) &= -y_i^\gamma\log(1-y_i’), &\quad y_i = 0
    \end{align}
    $$
    • \(\gamma\) 的取值在原始论文中使用了 0, 0.5, 1, 2, 5 等
    • 当 \(\gamma > 0\) 时显然有
      • 预测值 \(y_i’\) 与真实标签 \(y_i\) 差异越大的样本,他们的损失权重越大( \(y_i=1\) 时,预测值和真实值的差异为 \(1-y_i’\), \(y_i=0\) 时,差异为 \(y_i’\) )
      • 预测值 \(y_i’\) 与真实标签 \(y_i\) 差异越小的样本,他们的损失权重越小
      • 以上两点给了模型重视分类错误样本的提示,模型会重视分类出错的样本
    • \(\gamma = 0\) 时Focal Loss退化为交叉熵损失函数
    • \(\gamma\) 越大,说明, 分类错误的样本占的损失比重越大
  • 实际使用中, 常加上 \(\alpha\) 平衡变量
    $$
    \begin{align}
    loss(x_i) &= -\alpha(1-y_i’)^\gamma logy_i’, &\quad y_i = 1 \\
    loss(x_i) &= -(1-\alpha)y_i^\gamma\log(1-y_i’), &\quad y_i = 0
    \end{align}
    $$
    • \(\alpha\) 用于平衡正负样本的重要性
    • \(\gamma\) 用于加强对难分类样本的重视程度
  • 假设正样本数量太少, 负样本数量太多, 那么该损失函数将降低负样本在训练中所占的权重, 可以理解为一种困难样本挖掘
    • 困难样本挖掘的思想就是找到分类错误的样本(难以分类的样本), 然后重点关注这些错误样本
  • 原论文中的实验结果:

Huber Loss

  • 总体来说:Huber损失函数是一种结合了均方误差(MSE)和平均绝对误差(MAE)优点的损失函数。它对小的残差表现得像MSE,对大的残差表现得更像MAE。这样可以减少异常值对模型的影响,同时保持梯度下降的有效性

  • Huber损失函数定义如下:
    $$ L_\delta(y, f(x)) = \begin{cases}
    \frac{1}{2}(y - f(x))^2 & \text{for } |y - f(x)| \leq \delta, \\
    \delta (|y - f(x)| - \frac{1}{2}\delta) & \text{otherwise}.
    \end{cases} $$

    • 其中 \(y\) 是目标变量, \(f(x)\) 是预测值,而 \(\delta\) 是一个超参数,用来控制从二次损失到线性损失转换的点
  • 在Python中实现Huber损失函数,可以使用如下的代码:

    1
    2
    3
    4
    5
    6
    7
    import numpy as np
    def huber_loss(y_true, y_pred, delta=1.0):
    residual = np.abs(y_true - y_pred)
    condition = residual <= delta
    small_res_loss = 0.5 * np.square(residual)
    large_res_loss = delta * (residual - 0.5 * delta)
    return np.where(condition, small_res_loss, large_res_loss)
  • 如果你使用的是深度学习框架比如TensorFlow或PyTorch,它们通常也内置了Huber损失函数,可以直接调用,例如在TensorFlow中:

    1
    2
    3
    import tensorflow as tf
    huber_loss_tf = tf.keras.losses.Huber(delta=1.0)
    loss_tf = huber_loss_tf(y_true_tf, y_pred_tf)
  • Huber Loss 也称为 Smooth_l1_loss

    • Smooth_l1_loss:它是一个“平滑”版本的L1损失,在误差较小时使用L2损失来提供平滑的梯度;相比于纯L1损失,smooth_l1_loss 在误差接近零时提供了更平滑的梯度变化,L1损失在误差为零时的梯度会发生突变(从-1变为1),而 smooth_l1_loss 使用平方误差部分避免了这种突变

岭回归

  • 基本思路是在最小二乘的基础上加上L2正则
    $$loss(\theta) = \frac{1}{m}\sum_{i=1}^{m}(y_{i} - f(x_{i}))^2 + \lambda \theta^2$$
  • 其中 \(\lambda \theta^2\) 项是L2正则项,也称为收缩惩罚项(shrinkage penalty)
    • 它试图缩小模型的参数,引入偏差来缓解参数估计中的方法问题,原始的最小二乘是无偏估计,但是引入了L2正则以后会变成有偏的,但是方差更小的参数估计
    • 实际上,shrinkage参数,也称为收缩参数 ,是统计学里面的一个概念,是用于缓解参数估计时离群点带来的问题

几个回归损失函数的对比

  • 参考链接补充:https://www.cnblogs.com/nxf-rabbit75/archive/2019/02/26/10440805.html

不同模型的损失函数

决策树的损失函数

  • 决策树有两个解释
    • if-then规则
    • 条件概率分布
  • <<统计学习方法>>: 决策树的损失函数是对数似然
    • 决策树可以看作是对不同概率空间的划分

Loss Function vs Cost Function

  • 损失函数(Loss Function)应用于一个特定的样本计算误差
  • 成本函数(Cost Function)是对所有样本而言的误差

损失函数相关思考

分类问题为什么不能用MSE?

  • 参考链接:
    • 为什么分类问题不使用MSE(平方损失函数)
    • 深究交叉熵损失(Cross-entropy)和平方损失(MSE)的区别
    • 为什么回归问题用MSE?
  • 原因:
    • 在sigmoid函数拟合概率的情况下,使用MSE会导致预估值接近0或者为1时的梯度都接近0,不利于模型学习收敛
    • 在sigmoid函数拟合概率的情况下,MSE是非凸优化问题,容易陷入局部最优;交叉熵损失则是凸优化问题,不会陷入局部最优
  • 最小化交叉熵损失函数等价于不做任何假设的极大似然估计 ,其本质是在最小化真实样本分布和预估分布的KL散度(这里的分布可以是已知X时,label的条件分布)
  • 最小化MSE损失函数等价于假设噪声服从高斯分布时的极大似然估计
    • 推导可参考:MSE的推导、MSE,MLE和高斯分布的关系、为什么回归问题用MSE?
    • 假设在回归问题中 \(y = z + \epsilon\),样本噪声 \(\epsilon\) 服从均值为0,方差为 \(\sigma\) 的高斯分布,即 \(\epsilon \sim N(0,\sigma)\),这里的 \(\sigma>0\)
    • 则有原始样本 \(y\) 服从均值为 \(z\) 方差为 \(\sigma\) 的高斯分布 \(y \sim N(z,\sigma)\),我们的目标是用模型拟合非噪声部分 \(y_{pred} = \theta^T x = z\),此时有 \(y = y_{pred} + \epsilon\),即 \(y\) 服从高斯分布 \(y \sim N(y_{pred},\sigma)\)
    • 正太分布的概率密度函数为 \(p(x) = \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{(x-u)^2}{2\sigma^2}}\),则此时单个样本出现的概率为 \(\frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{(y-\theta^T x)^2}{2\sigma^2}}\)
    • 用极大似然法估计参数 \(\theta\),即最大化多个样本的联合概率为:
      $$
      \begin{align}
      \theta^* &= \mathop{\arg\max}_\theta \prod_i \frac{1}{\sigma\sqrt{2\pi}} e^{-\frac{(y^i-\theta^T x^i)^2}{2\sigma^2}} \\
      &= \mathop{\arg\max}_\theta \prod_i e^{-\frac{(y^i-\theta^T x^i)^2}{2\sigma^2}} &\quad —去掉与\theta无关的常数项 \\
      &= \mathop{\arg\max}_\theta \sum_i -\frac{(y^i-\theta^T x^i)^2}{2\sigma^2} &\quad —取对数 \\
      &= \mathop{\arg\max}_\theta \sum_i -(y^i-\theta^T x^i)^2 &\quad —继续去除常数项 \\
      &= \mathop{\arg\min}_\theta \sum_i (y^i-\theta^T x^i)^2 \\
      \end{align}
      $$
    • 即当假设噪声服从高斯分布时,用极大似然法估计参数与MSE损失函数得到的参数相同

MSE和RMSE对反向传播过程一样吗?

  • 答案是不一样
    • MSE的梯度是:
      $$ \nabla_{w} loss_{MSE} = \frac{1}{M}\sum_{i=1}^M 2(f_w(x_i)-y_i) \cdot \nabla_{w}f_w(x_i) $$
    • RMSE的梯度是:
      $$ \nabla_{w} loss_{RMSE} = \frac{1}{2} \left(\frac{1}{M}\sum_{i=1}^M (f_w(x_i)-y_i)^2\right)^{-\frac{1}{2}} \cdot \frac{1}{M}\sum_{i=1}^M 2(f_w(x_i)-y_i) \cdot \nabla_{w}f_w(x_i) $$
  • 由于两者的梯度不同,所以两者对参数的影响也不同,由于 \(\frac{1}{2} \left(\frac{1}{M}\sum_{i=1}^M (f_w(x_i)-y_i)^2\right)^{-\frac{1}{2}}\) 不是固定值,所以MSE和RMSE对梯度的影响也不是简单的固定倍数关系
    • 可以简单理解为:
      • RMSE的梯度相当于在MSE的基础上乘以 \(\frac{1}{2} \left(\frac{1}{M}\sum_{i=1}^M (f_w(x_i)-y_i)^2\right)^{-\frac{1}{2}}\),在不同的Batch中,该值不同,Loss越大,该值越大,Loss越小,该值越小
  • MSE是在假设误差服从均值为0的正太分布(即 \(\epsilon \sim N(0,\sigma)\) )的基础上基于极大似然法求得的目标函数
  • 在同一个Batch内来看,RMSE与MSE的目标实际上是完全一致的,即MSE最小时,RMSE也最小;但是从不同Batch之间来看,RMSE的梯度系数不同无法实现在所有训练集上MSE最小
    • 当所有数据只有一个Batch时,RMSE和MSE对梯度的影响是常数倍数关系(基于所有样本计算Loss得到的常数)
  • 为了实现多次采样Batch后实现MSE(满足极大似然法推导结果),一般常用MSE作为损失函数,而不是RMSE,RMSE更多是一个指标

ML——模型评估指标总结

各种模型评估指标总结,持续更新


分类模型

  • 参考:https://www.cnblogs.com/zongfa/p/9431807.html

Accuracy,准确率

  • 公式:$$ \text{Accuracy} = \frac{TP+TN}{TP+TN+FP+FN} $$
  • 直观,但不利于不平衡样本

Recall,召回率

  • 公式:$$ \text{Recall} = \frac{TP}{TP+FN} $$

Precision,精确率

  • 公式:$$ \text{Precision} = \frac{TP}{TP+FP} $$

F1 Score

  • 公式:$$ \text{F1 Score} = \frac{2 * \text{Precision} * \text{Recall}}{\text{Precision}+\text{Recall}} $$
  • 综合考虑模型”求精“和”求全“的能力
  • 关键词:F1-Score, F1 Score, F1 分数

AUC

  • 形式化定义:AUC是ROC曲线下方的面积,其中ROC曲线的横坐标是伪阳性率(也叫假正类率,False Positive Rate),纵坐标是真阳性率(真正类率,True Positive Rate)
  • 本质:任意取两个样本,一个正样本和一个负样本( \( \forall x^+, x^-\) ),模型预测正样本为正的概率分为 \(Score_\theta(y=1|x^+)\),模型预测正样本为正的概率分为 \(Score_\theta(y=1|x^-)\),则AUC为:
    $$ AUC_\theta = P(Score_\theta(y=1|x^+)>Score_\theta(y=1|x^-))$$
  • 真实实现时,可以统计所有正负样本对,若正样本预估值大于负样本,则累计分数+1,最后用累计分数除以所有可能的正负样本对数量
    $$ AUC_\theta = \frac{Count(S_+>S_-)}{Count(S_+) * Count(S_-)}$$
  • 具体代码实现:
    • 将样本按照预估分数倒序排列,从大到小
    • 定义四个变量:正样本总数 \(M\),负样本总数 \(N\),已访问负样本数量 \(X=0\),正样本大于负样本的样本对数量 \(Z=0\)
    • 依次访问所有样本:
      • 若为正样本,则 \(Z = Z + (N-X)\)
      • 若为负样本,则 \(X = X + 1\)
    • 最后计算: \(AUC = \frac{Z}{M * N}\)

回归模型

  • 参考:https://www.cnblogs.com/HuZihu/p/10300760.html
  • 参考:https://blog.csdn.net/guolindonggld/article/details/87856780

MSE

  • MSE (Mean Square Error,均方误差)
  • 也常用作损失函数
    $$\text{MSE} = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2$$
    • \(n\):样本数量
    • \(y_i\):第 \(i\) 个样本的真实值
    • \(\hat{y}_i\):第 \(i\) 个样本的预测值

RMSE

  • RMSE (Root Mean Square Error,根均方误差)
    $$\text{RMSE} = \sqrt{\frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2}$$

MAE

  • MAE (Mean Absolute Error,平均绝对误差)
    $$\text{MAE} = \frac{1}{n} \sum_{i=1}^{n} |y_i - \hat{y}_i|$$

MAPE

  • MAPE (Mean Absolute Percentage Error,平均绝对百分比误差)
    $$\text{MAPE} = \frac{1}{n} \sum_{i=1}^{n} \left| \frac{y_i - \hat{y}_i}{y_i} \right| \times 100%$$
    • 注:这个指标对分母要求很高,分母存在极小值时指标波动会非常大
      • 比如当 \(y_i=0\) 时,MAPE 无定义,这是其核心缺陷

SMAPE

  • SMAPE (Symmetric Mean Absolute Percentage Error,对称平均绝对百分比误差)
    $$\text{SMAPE} = \frac{1}{n} \sum_{i=1}^{n} \frac{|y_i - \hat{y}_i|}{\frac{1}{2}(|y_i| + |\hat{y}_i|)} \times 100%$$
    • 结果范围为 \([0, 200%]\)
  • SMAPE 也有简化版定义:分母直接用 \(|y_i| + |\hat{y}_i|\),此时公式为
    $$\text{SMAPE} = \frac{2}{n} \sum_{i=1}^{n} \frac{|y_i - \hat{y}_i|}{|y_i| + |\hat{y}_i|} \times 100%$$
    • 结果范围为 \([0, 100%]\)
  • 两种形式均常见,均被广泛使用,需根据场景选择

WMAPE

  • WMAPE (Weighted Mean Absolute Percentage Error,加权平均绝对百分比误差)
    $$\text{WMAPE} = \frac{\sum_{i=1}^{n} |y_i - \hat{y}_i|}{\sum_{i=1}^{n} |y_i|} \times 100%$$
  • WMAPE 也有按自定义权重 \(w_i\) 的通用形式:
    $$\text{WMAPE} = \frac{\sum_{i=1}^{n} w_i |y_i - \hat{y}_i|}{\sum_{i=1}^{n} w_i |y_i|} \times 100%$$
    • 默认权重 \(w_i=1\) 时退化为之前的公式
    • WMAPE 解决了 MAPE 中 \(y_i=0\) 无定义的问题
  • WMAPE 是 MAPE 的加权改进版,避免了分母为 0 的问题,更适合实际业务场景

排序模型

  • 参考:https://www.cnblogs.com/by-dream/p/9403984.html

DCG

  • DCG(Discounted Cumulative Gain,累计收益折扣)
  • 核心作用:衡量排序结果的质量,考虑位置对价值的衰减(越靠前的结果权重越高)
    $$\text{DCG}_p = \sum_{i=1}^{p} \frac{\text{rel}_i}{\log_2(i + 1)}$$
  • 等价形式(更常用,便于与 IDCG 对齐):
    $$\text{DCG}_p = \text{rel}_1 + \sum_{i=2}^{p} \frac{\text{rel}_i}{\log_2(i)}$$
    • \(p\): 排序结果的截断位置(如 Top-10 则 \(p=10\))
    • \(\text{rel}_i\): 第 \(i\) 个位置结果的相关性分数(通常为非负整数,如0=不相关、1=相关、2=高度相关)
    • \(\log_2(i+1)$/$\log_2(i)\): 位置折扣因子,体现“越靠前的结果越重要”的特性
  • 补充:DCG 还有另一种常见形式(引入指数缩放相关性):
    $$\text{DCG}_p = \sum_{i=1}^{p} \frac{2^{\text{rel}_i} - 1}{\log_2(i + 1)}$$
    • 该形式会放大高相关性结果的权重,适用于对“高度相关结果”更敏感的场景(如搜索排序)

NDCG

  • NDCG(Normalized Discounted Cumulative Gain,归一化累计收益折扣)
  • 核心作用:将 DCG 归一化到 [0,1] 区间,消除不同查询/任务间的结果尺度差异,便于跨场景比较
    $$\text{NDCG}_p = \frac{\text{DCG}_p}{\text{IDCG}_p}$$
    • \(\text{IDCG}_p\)(Ideal DCG,理想累计收益折扣):将所有结果按相关性从高到低完美排序后得到的 \(\text{DCG}_p\),即当前数据集下的最大可能 DCG 值,计算公式为:
      $$\text{IDCG}_p = \sum_{i=1}^{|REL_p|} \frac{\text{rel}^*_i}{\log_2(i + 1)} \quad (\text{或对应DCG的等价形式})$$
      • \(\text{rel}^*_i\) 为第 \(i\) 个位置的理想相关性分数,\(|REL_p|\) 为前 \(p\) 个位置中理想排序的结果数量
  • NDCG 的取值范围为 \([0,1]\): \(\text{NDCG}_p=1\) 表示排序结果完全理想,\(\text{NDCG}_p=0\) 表示排序结果完全无价值;
  • 当所有结果均无相关性(\(\text{rel}_i=0\))时,\(\text{DCG}_p=\text{IDCG}_p=0\),此时约定 \(\text{NDCG}_p=1\);
  • DCG/NDCG 是排序任务(如推荐系统、搜索引擎)的核心评估指标, \(p\) 的选择需贴合业务场景(如推荐系统常用 Top-5/Top-10,搜索常用 Top-20)

AP(Average Precision)与 MAP(Mean Average Precision)

  • AP 和 mAP 指标可参考:

校准模型

  • 参考:推荐系统(2)—— 评估指标
  • 参考:阿里妈妈展示广告预估校准技术演进之路

COPC

  • COPC(Click over Predicted Click)
    • COPC = 实际的点击率/模型预测的点击率
    • COPC 主要衡量model整体预估的偏高和偏低,同样越接近1越好,一般情况下在1附近波动
    • COPC 指标在展示广告上应用多一些

PCOC

  • PCOC(Predicted Click over Click)
    • PCOC = 模型预估的点击率/实际点击率,与COPC用途相同
    • COPC的倒数

PCOC指标是校准之后的点击率与后验点击率(近似真实概率)的比值,越接近于1,意味着在绝对值上越准确,大于1为高估,小于1为低估,是一种常用的高低估评价指标。但是PCOC存在一定局限性,举个例子:2万个样本,其中1万个样本的预估概率是0.2,后验概率是0.4,计算出PCOC是0.2/0.4=0.5,是显著低估的,另1万个样本PCOC是0.8/0.6= 1.3,明显是高估的。所以校准效果并不好,但是样本放一起看,校准后概率是(0.2+0.8)/2=0.5,后验概率是(0.4+0.6)/2=0.5,整体PCOC是1.0,表现完全正常。所以单一PCOC指标不能表征样本各维度下的校准水平。


净胜率模型

  • ANLP
    • 参考:论文《Scalable Bid Landscape Forecasting in Real-time Bidding》
    • 链接:https://arxiv.org/pdf/2001.06587.pdf

ML——直推式学习和归纳式学习

本文解释 直推式学习(Transductive Learning) 和 归纳式学习(Inductive Learning) 的区别


归纳式学习 (Inductive Learning)

  • 一句话定义 :通过训练数据学习一个通用的模型 ,然后将该模型应用于未知的测试数据
  • 目标 :从具体样本中归纳(名字来源)出一般规律,适用于任何未来的数据
  • 特点 :
    • 训练阶段和测试阶段是分开的
    • 模型在训练时不知道测试数据的具体情况
  • 典型场景 :大多数监督学习任务(如图像分类、文本分类等)
  • 核心特点 :训练时测试数据不可见

直推式学习 (Transductive Learning)

  • 一句话定义 :利用训练数据和特定的测试数据(未标注)共同学习,直接(名字来源)预测这些测试数据的标签
  • 目标 :针对当前已知的测试数据优化预测,而非构建通用模型
  • 特点 :
    • 训练时已知测试数据的特征(但无标签),利用这些信息优化预测
    • 模型仅适用于当前的测试数据,不能直接泛化到新数据
  • 典型场景 :半监督学习、图节点分类(如社交网络用户分类)
  • 核心特点 :训练时测试数据可见

附录:举例-垃圾邮件分类

  • 任务定义 :判断邮件是否为垃圾邮件

归纳式学习

  • 仅用已标注的训练数据(带“垃圾/正常”标签的邮件)训练一个模型(如SVM、神经网络)
  • 将模型应用于未来收到的任何新邮件

直推式学习

  • 同时利用已标注邮件和未标注邮件的特征分布(如词频、发件人)训练模型
  • 模型发现未标注邮件中某些特征与训练数据中的垃圾邮件相似,直接预测它们的标签
  • 特别说明 :模型针对这批特定的测试邮件优化 ,但不保证对新邮件的效果

为什么需要直推式学习?

  • 一般来说,大部分场景都使用归纳式学习即可
  • 当测试数据分布与训练数据分布不同时,直推式学习可以通过利用测试数据的特征分布提升当前任务的性能,但牺牲泛化性
  • 特别地,当训练数据和测试数据本身具有一定结构(如图数据、时空数据)时,直推式学习可以利用这些结构信息对无标签的测试数据做预测

Math——假设检验

本文介绍各种常见假设检验方法及使用示例

  • 参考链接1:知乎:T检验、F检验、卡方检验详细分析及应用场景总结
  • 参考链接2:知乎视频:5分钟带你了解卡方检验

卡方检验

《概率论与数理统计》

p-value的含义

  • 在假设检验中,对p-value的的一种直观理解:在假设 \(H_0\):假设目标样本属于某个正太分布,这个样本不是从这个正太分布中采样的概率就是p值(即p值的本质是一个概率)
    • 进一步的理解,已知一个正太分布和一个目标样本,那么这个目标样本对应的p值就是:重新在这个正太分布中重新采样一个新样本,新样本离中心位置 \(u_0\) 的距离大于等于目标样本的概率(该概率就是正太分布的两边区间积分和)
    • p值越小,说明这个目标样本越不可能是从这个正太分布采样出来的,越应该拒绝原假设 \(H_0\) (即越应该接受 \(H_A\)

Math——奇异值分解-SVD

本文从不同角度给出奇异值分解的物理意义

  • 参考知乎回答1:奇异值的物理意义是什么?
  • 参考知乎回答2:人们是如何想到奇异值分解的?

公式说明

$$A=U\Sigma V^{T}$$

  • \(U,V\) 都是正交矩阵, \(\Sigma\) 是对角矩阵,对角上的元素是矩阵 \(A\) 的奇异值
  • 若保留对角元素最大的K个值
    • \(K=r=Rank(A)\) 时为紧奇异值分解,对应的是无损压缩,此时由于奇异值保留数量与原始矩阵相同,能做到对原始矩阵A的完全还原
    • \(K< r=Rank(A)\) 时为截断奇异值分解,对应的是有损压缩,此时由于奇异值保留数量比原始矩阵的小,做不到对原始矩阵A的完全还原,但是如果K足够大就能做到对矩阵A的较完美近似

图像处理方面

  • 直观上可以理解为奇异值分解是将矩阵分解为若干个秩一矩阵之和,用公式表示就是:
    $$A=\sigma_{1}u_{1}v_{1}^{T}+\sigma_{2}u_{2}v_{2}^{T}+…+\sigma_{r}u_{r}v_{r}^{T}$$
    • 式子中每一项的系数 \(\sigma\) 就是奇异值
    • \(u,v\) 都是列向量,每一个 \(uv^{T}\) 都是秩为1的矩阵
    • 奇异值按照从小到大排列
  • 从公式中按照从大到小排序后,保留前面系数最大的项目后效果
    • 对于一张450x333的图片,只需要保留前面的50项即可得到相当清晰的图像
    • 从保留项1到50,图片越来越清晰
  • 结论:
    • 奇异值越大的项,越能体现出来图片的效果 ,奇异值隐含着某种对于A矩阵来说很重要的信息
    • 加权的秩一矩阵能体现整个大矩阵的值,奇异值就是对应秩一矩阵对于A矩阵的权重

线性变换方面

几何含义

  • 对于任何的一个矩阵,我们要找到一组两两正交单位向量序列,使得矩阵作用在此向量序列上后得到新的向量序列保持两两正交.奇异值的几何含义为:这组变换后的新的向量序列的长度

更直观的几何含义

  • 公式:
    $$\mathbb{E}_{m}={y\in C^{m}: y=Ax, x\in C^{n},\left | x\right |_{2}=1}$$
  • 二维矩阵A:
    • 矩阵A将二维平面中的单位圆变换为椭圆,而两个奇异值正好是椭圆的半轴长度.
  • m维矩阵
    • 矩阵A将高维平面中的单位球变换为超椭球,矩阵的奇异值恰好就是超椭球的每条半轴长度.

奇异值分解的降维理解

代码编写

  • 代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    ##encoding=utf-8
    import numpy as np

    A = np.array([[4, 5, 6], [4, 5, 6], [8, 10, 12], [4, 5, 6]])

    print("原始矩阵:")
    print(A)

    U, Sigma, Vt = np.linalg.svd(A)
    U = np.array(U)
    Sigma = np.array(Sigma)
    Vt = np.array(Vt)

    print("分解后的原始U,S,V:")
    print(U)
    Sigma_ = np.zeros((4, 3), dtype=np.float64)
    Sigma_[:3][:3] = np.diag(Sigma)
    print Sigma_
    print(Vt)

    # 不做任何处理,直接恢复原始矩阵
    A_ = np.dot(np.dot(U, Sigma_), Vt)
    print(A_)

    # 原始矩阵的秩为1,所以可以拆解到只剩下一个奇异值,压缩到一维,也能完整恢复原始矩阵,实现将4x3的矩阵变成两个向量+一个数字,当矩阵维度变大时,这里的压缩会更加明显
    U = U[:, :1]
    Sigma_ = Sigma_[:1, :1]
    Vt = Vt[:1, :]

    print("降维后的U,S,V:")
    print(U)
    print(Sigma_)
    print(Vt)
    A_ = np.dot(np.dot(U, Sigma_), Vt)
    print("降维后的恢复矩阵,与原矩阵相同:")
    print(A_)
  • 结果

    原始矩阵:
    [[ 4 5 6]
    [ 4 5 6]
    [ 8 10 12]
    [ 4 5 6]]
    分解后的原始U,S,V:
    [[-3.77964473e-01 -9.25820100e-01 1.52792960e-16 0.00000000e+00]
    [-3.77964473e-01 1.54303350e-01 9.12870929e-01 0.00000000e+00]
    [-7.55928946e-01 3.08606700e-01 -3.65148372e-01 -4.47213595e-01]
    [-3.77964473e-01 1.54303350e-01 -1.82574186e-01 8.94427191e-01]]
    [[2.32163735e+01 0.00000000e+00 0.00000000e+00]
    [0.00000000e+00 1.22295087e-15 0.00000000e+00]
    [0.00000000e+00 0.00000000e+00 5.18334466e-32]
    [0.00000000e+00 0.00000000e+00 0.00000000e+00]]
    [[-0.45584231 -0.56980288 -0.68376346]
    [ 0.02454097 0.75988299 -0.64959647]
    [-0.88972217 0.31289378 0.3324033 ]]
    [[ 4. 5. 6.]
    [ 4. 5. 6.]
    [ 8. 10. 12.]
    [ 4. 5. 6.]]
    降维后的U,S,V:
    [[-0.37796447]
    [-0.37796447]
    [-0.75592895]
    [-0.37796447]]
    [[23.21637353]]
    [[-0.45584231 -0.56980288 -0.68376346]]
    降维后的恢复矩阵,与原矩阵相同:
    [[ 4. 5. 6.]
    [ 4. 5. 6.]
    [ 8. 10. 12.]
    [ 4. 5. 6.]]

Math——样本方差和总体方差的关系

本文介绍随机变量样本均值方差和整体均值方差的关系,同时还介绍样本和均值的方差和总体方差的关系

  • 其他参考链接:在统计学里如何理解样本均值的方差等于总体方差➗n? - 蘇雲的回答 - 知乎

样本方差与总体方差的关系

  • 其他证明方式:
    • 上式中,如果总体方差未知 ,想要用样本方差来作为总体方差的无偏估计 ,则样本方差的定义是应该是
      $$ S^2 = \frac{1}{n-1}\sum_i^n(X_i-\bar{X})^2$$
      • 注:分母必须是 \(n-1\) 时,样本方差才是总体方差的无偏估计

样本方差为什么要除以n-1?

  • 样本方差的定义:
    $$
    \sigma^2 \approx S^2 = \frac{1}{n-1}\sum_i^n(X_i-\bar{X})^2
    $$
  • 为什么样本方差是乘以 \(\frac{1}{n-1}\) 而不是 \(\frac{1}{n}\) ?
    • 因为这样使用 \(\frac{1}{n}\) 会低估总体方差,此时样本方差不是总体方差的无偏估计
    • 样本方差低估了总体方差的原因是因为从总体里面抽出来的数据会更倾向于集中,极端情况下,一个样本对应的方差为0
  • 换个视角想,是因为我们不知道总体的均值,所以计算方差时使用的均值也是从样本中求平均得到的,这使得我们基于该均值得到的方差不够离散(因为使用了样本均值,所以自由度需要减一),也就是低估了总体方差
    • 怎么理解自由度?
      • 采样一个样本以后无法计算方差,此时方差为0,因为此时均值就等于样本本身,此时自由度为0
      • 采样两个样本以后得到的方差只根第二个样本到第一个样本的距离有关(样本均值与这两个样本强相关),此时自由度为1
      • 当采样的样本数非常多(假设为n)时,实际上单个样本与均值的关系很小了,此时自由度为n-1
  • 当已知总体均值 \(\mu\) 时(个人理解:这里的 \(\mu\) 可以是其他采样方式下获得的近似均值,只要不跟当前用于计算方差的样本相关即可),样本方差可以使用:
    $$
    \sigma^2 \approx S^2 = \frac{1}{n-1}\sum_i^n(X_i-\mu)^2
    $$
  • 样本方差经过 \(\frac{1}{n-1}\) 修正以后可以用来估计总体方差(修正以后是总体方差的无偏估计)
    • 这个修正叫做贝塞尔修正
  • 证明 from :Bilibili-样本方差为什么除以n-1?

  • 单样本均值和多样本均值的关系

    问题定义

    • 考虑以下采样方式
      • 集合X :每次采样 B个样本 得到的样本集合
      • 集合Y :每次采样 1个样本 得到的样本集合
    • 问:多次采样时,集合X和B的均值和方差关系是什么?
      • 即:如果我们重复多次进行这样的采样(每次采B个或1个),那么:这两种采样方式得到的样本均值的期望(即平均值的平均值)和样本均值的方差(即平均值的波动程度)之间有什么关系?

    假设与符号定义

    • 假设我们从一个总体中采样,总体的均值为 \(\mu\),方差为 \(\sigma^2\)
    • 集合X :
      • 每次采样 B个样本 :\(X_1, X_2, \dots, X_B\)
      • 计算这B个样本的均值:\(\bar{X}_A = \frac{1}{B}\sum_{i=1}^B X_i\)
    • 集合Y :
      • 每次采样 1个样本 :\(Y_1\)
      • 其“均值”就是它自己:\(\bar{X}_B = Y_1\)
    • 我们重复多次这样的采样过程,得到一系列的 \(\bar{X}_A\) 和 \(\bar{X}_B\)

    均值关系

    • 集合X 的样本均值的期望:
      $$
      E[\bar{X}_A] = E\left[\frac{1}{B}\sum_{i=1}^B X_i\right] = \frac{1}{B} \sum_{i=1}^B E[X_i] = \frac{1}{B} \cdot B \mu = \mu
      $$
    • 集合Y 的样本均值的期望:
      $$
      E[\bar{X}_B] = E[Y_1] = \mu
      $$
    • 结论:两种采样方式得到的样本均值的期望是相同的 ,都等于总体均值 \(\mu\)

    方差关系

    • 集合X 的样本均值的方差:
      $$
      \text{Var}(\bar{X}_A) = \text{Var}\left(\frac{1}{B}\sum_{i=1}^B X_i\right) = \frac{1}{B^2} \sum_{i=1}^B \text{Var}(X_i) = \frac{1}{B^2} \cdot B \sigma^2 = \frac{\sigma^2}{B}
      $$
    • 集合Y 的样本均值的方差:
      $$
      \text{Var}(\bar{X}_B) = \text{Var}(Y_1) = \sigma^2
      $$
    • 结论:集合X 的样本均值的方差是 \(\frac{\sigma^2}{B}\),集合Y 的样本均值的方差是 \(\sigma^2\)
      • 也就是说,集合X 的样本均值的方差更小,是集合Y 的 \(\frac{1}{B}\)
    • 直观理解
      • 均值方面:无论你是采1个还是采B个,平均来看,它们的中心位置(期望)都是一样的,都是总体的均值
      • 方差方面:采B个样本求平均,相当于把单个样本的“噪声”给“平均掉”了,因此波动更小,方差更小;而采1个样本,没有“平均”的过程,波动就更大,方差也就更大

    附录:Python 中计算标准差/方差的默认实现

    • 在进行数据归一化(如 Z-score 标准化)时,计算标准差的分母是 \(n\)(总体标准差)还是 \(n-1\)(样本标准差,即无偏估计),在不同的 Python 科学计算库中默认行为是不同的
    • 各 Python 库的默认行为总结:
      • 1)NumPy (np.std) :默认分母为 \(n\)(即 ddof=0)
        • 注:这里控制分母的参数通常称为 ddof(Delta Degrees of Freedom,自由度偏差),分母的计算公式为 \(N - ddof\)
      • 2)Pandas (pd.Series.std / pd.DataFrame.std) :默认分母为 \(n-1\)(即 ddof=1)
      • 3)PyTorch (torch.std) :默认分母为 \(n-1\)(即 unbiased=True 或 correction=1)
        • 注:修改 unbiased=False 即可得到分母为 \(n\) 的结果
      • 注:各个库的默认行为不同可能会导致一些意想不到的问题
    • 在机器学习中进行 Z-score 归一化(\(\frac{x - \mu}{\sigma}\))时,通常数据量 \(n\) 都比较大,此时 \(n\) 和 \(n-1\) 的差别微乎其微
      • 但为了保证训练集和测试集处理逻辑的绝对一致性,建议在代码中显式指定参数(例如统一写死 ddof=0 或 unbiased=False),避免因为在不同库之间切换数据格式(如从 Pandas 转换到 PyTorch Tensor)而引入隐蔽的计算差异

    测试代码

    • 以下是包含 NumPy、Pandas 和 PyTorch 计算 \(n\) 和 \(n-1\) 标准差的完整测试代码
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      import numpy as np
      import pandas as pd
      import torch

      def test_std_behaviors():
      # 准备相同的测试数据
      data_list = [1.0, 2.0, 3.0, 4.0, 5.0]

      print("-" * 40)
      print("NumPy 标准差测试")
      print("-" * 40)
      arr = np.array(data_list)
      # NumPy 默认 ddof=0,分母为 n
      np_std_n = np.std(arr)
      # NumPy 设置 ddof=1,分母为 n-1
      np_std_n_minus_1 = np.std(arr, ddof=1)
      print(f"NumPy 默认分母 (n) : {np_std_n:.4f}")
      print(f"NumPy 指定分母 (n-1) : {np_std_n_minus_1:.4f} (使用 ddof=1)")

      print("\n" + "-" * 40)
      print("Pandas 标准差测试")
      print("-" * 40)
      series = pd.Series(data_list)
      # Pandas 默认 ddof=1,分母为 n-1
      pd_std_n_minus_1 = series.std()
      # Pandas 设置 ddof=0,分母为 n
      pd_std_n = series.std(ddof=0)
      print(f"Pandas 默认分母 (n-1): {pd_std_n_minus_1:.4f}")
      print(f"Pandas 指定分母 (n) : {pd_std_n:.4f} (使用 ddof=0)")

      print("\n" + "-" * 40)
      print("PyTorch 标准差测试")
      print("-" * 40)
      tensor = torch.tensor(data_list)
      # PyTorch 默认无偏估计 (unbiased=True),分母为 n-1
      # 注:在较新版本的 PyTorch 中,也可以使用 correction=1
      pt_std_n_minus_1 = torch.std(tensor)
      # PyTorch 设置有偏估计 (unbiased=False),分母为 n
      # 注:在较新版本的 PyTorch 中,也可以使用 correction=0
      pt_std_n = torch.std(tensor, unbiased=False)
      print(f"PyTorch 默认分母 (n-1): {pt_std_n_minus_1:.4f}")
      print(f"PyTorch 指定分母 (n) : {pt_std_n:.4f} (使用 unbiased=False)")

      if __name__ == "__main__":
      test_std_behaviors()


      # ----------------------------------------
      # NumPy 标准差测试
      # ----------------------------------------
      # NumPy 默认分母 (n) : 1.4142
      # NumPy 指定分母 (n-1) : 1.5811 (使用 ddof=1)
      #
      # ----------------------------------------
      # Pandas 标准差测试
      # ----------------------------------------
      # Pandas 默认分母 (n-1): 1.5811
      # Pandas 指定分母 (n) : 1.4142 (使用 ddof=0)
      #
      # ----------------------------------------
      # PyTorch 标准差测试
      # ----------------------------------------
      # PyTorch 默认分母 (n-1): 1.5811
      # PyTorch 指定分母 (n) : 1.4142 (使用 unbiased=False)

    Math——概率密度函数的理解

    本文介绍概率密度函数的理解


    概率密度函数的定义

    • 概率密度函数(Probability Density Function, PDF)是概率论和统计学中用来描述连续型随机变量的概率分布的一种函数。对于一个连续型随机变量 \(X\),其概率密度函数 \(f(x)\) 具有以下性质:

      • 非负性 :对于所有的实数 \(x\),有 \(f(x) \geq 0\)
      • 归一化 :在整个可能值域内, \(f(x)\) 的积分等于1,即 \(\int_{-\infty}^{\infty} f(x) , dx = 1\)
      • 概率计算 :如果 \(a < b\),那么随机变量 \(X\) 落在区间 \([a, b]\) 内的概率可以通过 \(f(x)\) 在该区间上的积分来计算,即 \(P(a \leq X \leq b) = \int_{a}^{b} f(x) , dx\)
    • 需要注意的是,概率密度函数 \(f(x)\) 在某一点的值并不直接表示该点的概率,因为对于连续型随机变量来说,取任何一个具体值的概率实际上是0。相反, \(f(x)\) 更多地用于描述随机变量落在某个区间的概率大小。通过观察 \(f(x)\) 的形状,可以了解随机变量取值的集中趋势和分散程度等特征


    概率密度函数在某点的值 \( f(x_0) = \frac{1}{2} \) 的意义

    • 当我们说概率密度函数 \( f(x) \) 在某点 \( x_0 \) 的值等于 \( \frac{1}{2} \),即 \( f(x_0) = \frac{1}{2} \),其意义如下:

    概率密度函数的值

    • 概率密度函数 \( f(x) \) 在某点 \( x_0 \) 的值 \( f(x_0) \) 并不直接表示在 \( x_0 \) 点取得某个具体值的概率。对于连续型随机变量,在某个具体点取值的概率实际上是零,即:
      $$ P(X = x_0) = 0 $$

    概率密度的意义

    • 概率密度函数 \( f(x) \) 在点 \( x_0 \) 的值 \( f(x_0) \) 表示在 \( x_0 \) 附近的值的相对可能性。更具体地说,它表示在 \( x_0 \) 附近的一个小区间的长度和该区间内的概率的比值。比如,对于一个非常小的区间 \( [x_0 - \epsilon, x_0 + \epsilon] \),其概率可以近似表示为:
      $$ P(x_0 - \epsilon \leq X \leq x_0 + \epsilon) \approx f(x_0) \cdot 2\epsilon $$

    例子

    • 假设一个随机变量 \( X \) 的概率密度函数在某点 \( x_0 \) 处为 \( \frac{1}{2} \),即 \( f(x_0) = \frac{1}{2} \) 。这意味着在 \( x_0 \) 附近的一个小区间内的概率可以近似计算。例如,对于一个非常小的区间 \( [x_0 - 0.01, x_0 + 0.01] \),其概率可以近似为:
      $$ P(x_0 - 0.01 \leq X \leq x_0 + 0.01) \approx \frac{1}{2} \cdot 0.02 = 0.01 $$

    总结

    • 概率密度函数 \( f(x) \) 在某点 \( x_0 \) 的值 \( f(x_0) = \frac{1}{2} \) 并不表示在 \( x_0 \) 处取值的概率,而是表示在 \( x_0 \) 附近的值的相对可能性
    • 对于连续型随机变量,在某个具体点取值的概率是零
    • 概率密度函数的值可以用于近似计算在某个小区间内的概率

    Math——调和级数的和

    调和级数的和是发散的,并不收敛,但是这又是一个非常常用的级数,本文总结了调和级数的和的求法


    一个事实

    • 调和级数的和与 n 的自然对数的差值收敛到欧拉-马歇罗尼常数
      $$
      \begin{align}
      lim_{n \to \infty}(\sum_{i=1}^{n}\frac{1}{i} - ln(n)) = \gamma
      \end{align}
      $$
      • \(\gamma\) 为欧拉-马歇罗尼常数
        • (欧拉常数又称欧拉-马斯克若尼常数,近似值为γ≈0.57721 56649 01532 86060 65120 90082 40243 10421 59335)

    证明

    • 事实上,调和级数的和为
      $$
      \begin{align}
      \sum_{i=1}^{n}\frac{1}{i} = ln(n) + \gamma + \epsilon_{n}
      \end{align}
      $$
      • \(\gamma\) 为欧拉-马歇罗尼常数
      • \(\epsilon_{n}\) 约等于 \(\frac{1}{2n}\),随着n的不断增大, \(\epsilon_{n}\) 趋于0

    补充

    • 两个不同的调和数之间的差值永远不是整数
    • 除了n=1时以外,没有任何一个调和数是整数

    Math——辛普森悖论

    本文介绍辛普森悖论


    辛普森悖论

    • 辛普森悖论指的是在分组比较中占优的一方,在合并数据后反而处于劣势的现象

    药物效果示例

    • 场景场景 :比较两种药物(A 和 B)对轻症和重症患者的治愈率

    • 分组数据 :

      • 轻症患者组 :
        • 药 A:治疗 10 人 ,治愈 9 人 -> 治愈率 90%
        • 药 B:治疗 100 人 ,治愈 80 人 -> 治愈率 80%
      • 重症患者组 :
        • 药 A:治疗 100 人 ,治愈 30 人 -> 治愈率 30%
        • 药 B:治疗 10 人 ,治愈 2 人 -> 治愈率 20%
    • 分组结论 :

      • 轻症组:药 A 的治愈率(90%)> 药 B(80%)
      • 重症组:药 A 的治愈率(30%)> 药 B(20%)
    • 合并数据 :

      • 药 A:总治愈 39 人(9 + 30),总治疗 110 人 -> 治愈率 35.5%
      • 药 B:总治愈 82 人(80 + 2),总治疗 110 人 -> 治愈率 74.5%
    • 悖论出现 :

    • 尽管药 A 在每个分组的治愈率都更高,但合并后药 B 的总治愈率却显著优于药 A。这是因为药 B 主要用于治愈率高的轻症患者(样本量 100 vs. 10),而药 A 更多用于治愈率低的重症患者(样本量 100 vs. 10),导致整体结果反转

    核心原因 :

    • 数据分组中存在混杂变量(此处为病情严重程度),且各组样本量差异巨大,合并时权重不同引发悖论

    什么药是真正优秀的?

    • 药 A才是真正疗效更好的,因为在任何场景下(不论轻症还是重症下),都是药 A 效果更好,之所以合并到一起统计出现悖论,是因为医生开药时存在刻意倾向导致的,给轻症患者更多的开了药 B,这相当于强行提高了药 B 的治愈率
    • 其他类似问题也出现在不同学院男女录取率上
    1…525354…67
    Joe Zhou

    Joe Zhou

    Stay Hungry. Stay Foolish.

    662 posts
    53 tags
    GitHub E-Mail
    © 2026 Joe Zhou
    Powered by Hexo
    |
    Theme — NexT.Gemini v5.1.4