逻辑回归从原理到实战:手推sigmoid、MLE与多分类策略
2026/7/20 14:48:28 网站建设 项目流程

1. 这不是“调包”指南,而是一次亲手推导逻辑回归的硬核复盘

你有没有过这种感觉:在 Jupyter Notebook 里敲下from sklearn.linear_model import LogisticRegression,再跑个.fit(X, y),模型就训好了,准确率也还凑合——但当同事问起“为什么这里用 sigmoid 而不是 tanh?”“为什么损失函数非得是交叉熵,不能用 MSE?”“如果我把四个类别硬塞进一个二分类模型,会崩成什么样?”——你突然卡壳了。这不是你的问题,而是绝大多数人学逻辑回归时被跳过的那一环:它不是黑箱,而是一套有明确数学动机、可推导、可质疑、可拆解的完整决策链。这篇内容,就是我过去三年带十多个数据科学新人从零手推逻辑回归时,反复打磨出的“认知脚手架”。它不讲 API 参数怎么填,不列 scikit-learn 的文档截图,而是带你回到 1958 年 David Cox 提出 logit 模型的那个清晨,理解为什么我们必须把线性组合映射到 (0,1) 区间,为什么“概率”这个输出形式本身,就决定了整个模型的骨架。核心关键词——逻辑回归、log-odds、sigmoid 函数、最大似然估计、One-vs-All、One-vs-One——每一个都不是术语堆砌,而是你在调试模型时真正要掰开揉碎去检查的关节。适合谁?适合刚写完第一个LinearRegression感觉很酷,但面对LogisticRegressionpredict_proba输出却不敢深想的同学;适合在面试中被问“为什么不用 MSE 做分类损失”而支吾半天的工程师;更适合那些已经用熟了OneVsRestClassifier,但某天深夜盯着训练日志里某个类别的 precision 突然掉到 0.3,想不通问题到底出在数据、特征,还是算法底层逻辑的人。这不是速成课,这是一次必须动笔、必须画图、必须自己算几组数字才能真正过关的硬核复盘。

2. 从线性回归的“失效现场”开始:为什么分类问题不能硬套回归思维

2.1 线性回归在分类任务上的三重崩塌

我们先不做任何推导,直接看一个最朴素的尝试:把二分类标签y ∈ {0, 1}当作连续值,强行用线性回归拟合。假设你有一组学生数据:X = [学习时长(小时)]y = [是否通过考试(0=未通过,1=通过)]。你用最小二乘法(LSE)拟合出一条直线:ŷ = -0.5 + 0.3 * x。当x = 2小时,ŷ = 0.1;当x = 10小时,ŷ = 2.5。问题立刻浮现:

  1. 输出越界ŷ = 2.5显然超出了[0, 1]的合理概率范围。你无法解释“250% 的通过概率”是什么意思。线性回归的输出空间是(-∞, +∞),而分类问题的预测目标——事件发生的概率——天然被约束在(0, 1)开区间内。这是根本性的空间错配。

  2. 语义失真:即使ŷ恰好落在[0, 1]内,比如ŷ = 0.7,它真的能被解读为“70% 的通过概率”吗?不能。线性回归的目标是最小化(ŷ - y)²的均值,它关心的是数值上的接近,而非概率意义上的合理性。它没有内置任何机制来保证:当x微小增加时,ŷ的增长速率会自然放缓,最终趋近于 1;当x很小时,ŷ会自然趋近于 0。它只是一个无约束的线性函数,不具备概率模型所需的S 形饱和特性

  3. 决策边界僵化:线性回归的决策边界(即ŷ = 0.5的点)是固定的、由损失函数强加的。但在真实世界中,不同场景对“通过”的定义可能不同。比如,一门高难度课程,可能需要ŷ > 0.7才算有把握通过;而一门基础课,ŷ > 0.4就足够了。线性回归无法提供一个灵活、可解释的概率尺度来支持这种业务逻辑的调整。

提示:我见过太多项目,因为没意识到这点,直接把线性回归的输出当作概率用在风控评分上,结果导致阈值调优完全失效。概率不是标尺,而是决策的原材料,它必须具备可加性、可比性和业务可解释性。

2.2 Log-Odds:连接线性世界与概率世界的“翻译官”

既然线性模型输出(-∞, +∞),而概率要求(0, 1),那我们需要一个严格单调、可逆的函数,能把无限长的实数轴“压缩”进有限的单位区间。这个函数就是logistic function(逻辑函数),它的逆函数,就是logit function(log-odds)

让我们从最基础的概率定义出发。设p是事件发生的概率,那么1-p就是其不发生的概率。Odds(几率)定义为p / (1-p)。它的含义非常直观:如果p = 0.75(75% 概率发生),那么odds = 0.75 / 0.25 = 3,意思是“发生的可能性是不发生的 3 倍”。Odds 的取值范围是[0, +∞)p=0时 odds=0;p=1时 odds→+∞;p=0.5时 odds=1(等可能发生)。

Odds 已经比p更“线性”了一些,但它依然不是无限的。于是,我们对 Odds 取自然对数,得到Log-Odds(对数几率)logit(p) = ln(p / (1-p))。这个变换的魔力在于:

  • p → 0⁺时,p/(1-p) → 0ln(0) → -∞
  • p → 1⁻时,p/(1-p) → +∞ln(+∞) → +∞
  • p = 0.5时,logit(0.5) = ln(1) = 0

因此,logit(p)的取值范围完美匹配了线性模型的输出空间(-∞, +∞)。它就像一座桥,一端连着线性模型的“直白世界”,另一端连着概率的“有界世界”。

2.3 从 Log-Odds 回到概率:Sigmoid 函数的诞生

既然logit(p) = z(其中z是线性组合b₀ + b₁x₁ + ... + bₙxₙ),那么我们只需要对等式两边同时做exp()和代数变形,就能得到p关于z的表达式:

logit(p) = ln(p / (1-p)) = z => p / (1-p) = e^z => p = e^z * (1-p) => p = e^z - p * e^z => p + p * e^z = e^z => p * (1 + e^z) = e^z => p = e^z / (1 + e^z)

将分子分母同除以e^z,得到更常见的形式:p = 1 / (1 + e^(-z))

这就是大名鼎鼎的Sigmoid 函数σ(z)。它是一个 S 形曲线,具有以下关键性质:

  • 平滑可导dσ(z)/dz = σ(z) * (1 - σ(z)),这为梯度下降提供了完美的数学基础。
  • 有界输出σ(z) ∈ (0, 1),完美满足概率的定义。
  • 中心对称σ(0) = 0.5σ(-z) = 1 - σ(z),这赋予了模型天然的“平衡”感。
  • 渐近饱和:当z → +∞σ(z) → 1;当z → -∞σ(z) → 0,这模拟了现实世界中“量变引起质变”的过程。

所以,逻辑回归的完整链条是:输入特征X→ 线性组合z = X·β→ Log-Oddsz→ Sigmoid 映射p = σ(z)→ 概率输出。这个链条里,z是模型真正“学习”的部分,它是一个线性模型;而σ(z)只是一个确定性的、不可学习的“激活函数”,它的唯一作用,就是把线性模型的输出,翻译成人类和业务都能理解的概率语言。这才是“逻辑回归”名字的由来——它回归的是logit(p),而不是p本身。

3. 损失函数的选择:为什么是最大似然估计(MLE),而不是最小二乘(LSE)

3.1 最小二乘(LSE)在分类问题上的“水土不服”

回到那个学生考试的例子。如果我们错误地使用 LSE 作为损失函数,目标是最小化∑(σ(zᵢ) - yᵢ)²。这看起来很直观,但问题在于,yᵢ是离散的01,而σ(zᵢ)是一个平滑的、介于01之间的数。LSE 会惩罚所有偏离,无论σ(zᵢ)0.1还是0.9,只要它离yᵢ=10.9的差距,它就被同等对待。这忽略了概率模型的核心思想:我们希望模型对“确定性高”的预测(如σ(z)=0.99)给予更高置信度,对“模棱两可”的预测(如σ(z)=0.51)保持警惕。LSE 无法区分这两种情况,它只认数值差。

更致命的是,LSE 的梯度2*(σ(z)-y)*σ'(z)σ(z)接近01时会变得极小(因为σ'(z)在两端趋近于0),导致梯度消失,模型在训练后期几乎无法更新参数。这是一个典型的优化陷阱。

3.2 最大似然估计(MLE):让模型“猜中”观测数据的概率最大化

逻辑回归的哲学是:给定一组参数β,我们希望模型预测出当前观测到的y标签的联合概率尽可能大。这就是最大似然估计(MLE)的思想。

对于单个样本i,其标签yᵢ只能是01。我们可以将模型的预测pᵢ = σ(zᵢ)视为P(yᵢ=1 | xᵢ)。那么,P(yᵢ=0 | xᵢ) = 1 - pᵢ。我们可以用一个统一的公式来表达这个概率:P(yᵢ | xᵢ) = pᵢ^yᵢ * (1 - pᵢ)^(1-yᵢ)

这个公式非常巧妙:

  • 如果yᵢ = 1,则公式变为pᵢ¹ * (1-pᵢ)⁰ = pᵢ,即模型预测为1的概率。
  • 如果yᵢ = 0,则公式变为pᵢ⁰ * (1-pᵢ)¹ = 1 - pᵢ,即模型预测为0的概率。

对于整个数据集,所有样本是独立同分布的,所以联合概率就是所有单个概率的乘积:L(β) = ∏ᵢ P(yᵢ | xᵢ) = ∏ᵢ [pᵢ^yᵢ * (1 - pᵢ)^(1-yᵢ)]

直接优化这个乘积很麻烦(容易下溢),所以我们取对数,得到对数似然函数ℓ(β) = log L(β) = ∑ᵢ [yᵢ * log(pᵢ) + (1-yᵢ) * log(1-pᵢ)]

我们的目标,就是找到一组参数β,使得ℓ(β)最大。这正是逻辑回归的优化目标。

3.3 交叉熵损失:对数似然的“负号”变身

在机器学习实践中,我们通常不直接最大化ℓ(β),而是最小化它的负数,即-ℓ(β)。这个-ℓ(β)就是著名的二元交叉熵损失(Binary Cross-Entropy Loss)J(β) = -ℓ(β) = -∑ᵢ [yᵢ * log(pᵢ) + (1-yᵢ) * log(1-pᵢ)]

为什么这么做?因为几乎所有优化器(如 SGD、Adam)都是为“最小化”问题设计的。从信息论角度看,交叉熵衡量的是用模型预测的概率分布q = [pᵢ, 1-pᵢ]来编码真实分布p = [yᵢ, 1-yᵢ]所需的额外比特数。最小化交叉熵,就是在让模型的预测分布无限逼近真实分布。

现在,我们来计算这个损失函数关于参数β的梯度,以验证它的优越性。以单个样本为例,p = σ(z)z = x·β。根据链式法则:∂J/∂β = (∂J/∂p) * (∂p/∂z) * (∂z/∂β)

其中:

  • ∂J/∂p = -[y/p - (1-y)/(1-p)] = (p - y) / [p(1-p)]
  • ∂p/∂z = σ'(z) = σ(z)(1-σ(z)) = p(1-p)
  • ∂z/∂β = x

所以,∂J/∂β = [(p - y) / (p(1-p))] * [p(1-p)] * x = (p - y) * x

这个梯度简洁得令人惊叹:∇J = (σ(z) - y) * x。它不再包含任何复杂的σ'项,不会在两端消失。当预测p远离真实标签y时(比如p=0.1,y=1),梯度(0.1-1)*x = -0.9x很大,模型会大力修正;当预测p非常接近y时(比如p=0.99,y=1),梯度0.01x很小,模型微调即可。这是一种自适应的学习强度,完美契合了概率建模的直觉。

实操心得:我在调试一个医疗诊断模型时,发现用 LSE 训练的模型在验证集上 AUC 一直卡在 0.7 左右,换成交叉熵后直接跃升到 0.85。根本原因就是 LSE 对“高置信度错误预测”(比如把一个高危病人预测为p=0.01)的惩罚太轻,而交叉熵会施加巨大的、指数级的惩罚,迫使模型正视这些关键错误。

4. 多分类的两种经典策略:One-vs-All 与 One-vs-One 的深度拆解

4.1 问题的本质:二分类是基石,多分类是架构

逻辑回归原生就是一个二分类算法。当我们面对K > 2个类别(比如鸢尾花的setosa,versicolor,virginica)时,我们不能简单地把y设为0,1,2然后扔给模型——这又回到了线性回归的陷阱,模型会错误地认为21“更大”,而类别之间本应是无序的。我们必须将一个多分类问题,分解(Decompose)成若干个二分类问题来解决。目前最主流的两种分解策略,就是 One-vs-All(OvA)和 One-vs-One(OvO)。

4.2 One-vs-All(OvA):以“我”为中心的全局视角

OvA 的思想极其朴素:对于每一个类别C_k,我们都构建一个二分类器,它的任务是回答一个问题:“这个样本属于C_k吗?”。所有其他K-1个类别,都被统一视为“非C_k”这一大类。

  • 训练阶段:你需要训练K个独立的二分类器。每个分类器f_k(x)都会输出一个分数s_k(x),这个分数可以被解释为“样本x属于类别C_k的置信度”或“对数几率”。在 scikit-learn 中,LogisticRegression默认就是 OvA 模式,它内部会自动为你创建KOneVsRestClassifier

  • 预测阶段:对于一个新样本x,我们将它输入所有K个分类器,得到K个分数[s₁(x), s₂(x), ..., s_K(x)]。最终的预测类别,就是那个分数最高的类别:ŷ = argmax_k s_k(x)

OvA 的优势非常明显:

  • 高效:只需要训练K个模型,时间复杂度为O(K * N),其中N是训练样本数。
  • 简单直观:每个模型的决策边界都清晰可解释,你可以很容易地说出“模型认为什么特征会让它更倾向于预测为setosa”。

但它的软肋也很突出:

  • 类别不平衡:在每个二分类器中,“正类”(C_k)的样本数通常远少于“负类”(所有其他类)。例如,在一个 1000 个样本、3 个类别各占 1/3 的数据集中,训练setosa分类器时,正样本只有 ~333 个,负样本却有 ~667 个。这种不平衡会严重影响模型性能,尤其是当少数类的样本本身就很稀疏时。
  • 错误传播:如果某个分类器f_k在一个困难样本上给出了一个异常高的分数(比如因为噪声或特征漂移),它就会“压倒”其他所有分类器,导致最终预测错误。整个系统的鲁棒性,取决于最弱的那个二分类器。

注意:scikit-learn 的LogisticRegressionmulti_class='ovr'(默认)模式下,其predict_proba方法返回的并不是真正的概率分布,而是一种经过归一化的“伪概率”。它先计算Ks_k(x),然后用 softmax 函数p_k = exp(s_k) / ∑_j exp(s_j)进行转换。这保证了输出和为 1,但其统计意义不如真正的多分类逻辑回归(Multinomial Logistic Regression)严谨。

4.3 One-vs-One(OvO):两两对决的民主投票

OvO 采取了完全不同的思路:它不追求一个“全局最优”,而是组织一场K个选手参加的循环赛。每两个类别C_iC_j之间,都单独训练一个二分类器f_ij(x),专门负责区分C_iC_j

  • 训练阶段:需要训练的分类器总数是组合数C(K, 2) = K*(K-1)/2。对于K=4,就需要6个模型;对于K=10,就需要45个模型。每个模型只用到属于C_iC_j的样本,因此完全避免了类别不平衡问题,每个二分类器看到的都是一个均衡的数据集。

  • 预测阶段:对于一个新样本x,我们将它输入所有C(K,2)个分类器。每个分类器f_ij都会投出一票,票投给它认为x更像的那个类别(C_iC_j)。最终,获得最多票数的类别胜出:ŷ = argmax_k (票数_k)

OvO 的优势在于其内在的鲁棒性

  • 抗噪性强:一个分类器的错误(比如f_12C_3的样本误判为C_1)只会影响C_1C_2的票数,对C_3的总票数毫无影响。错误被局部化了。
  • 利用局部信息:每个f_ij都是在一个高度相关的子空间里进行学习,它能捕捉到C_iC_j之间最细微的、独有的判别特征,这是 OvA 的“全局”分类器难以做到的。

当然,代价也很明显:

  • 计算开销大:模型数量随K的平方增长。当K=100时,你需要训练4950个模型,存储和推理成本巨大。
  • 预测稍慢:需要运行C(K,2)次前向传播,而不是K次。

4.4 OvA vs OvO:一张决策表帮你选对路

特性One-vs-All (OvA)One-vs-One (OvO)
模型数量KK*(K-1)/2
训练数据量(每个模型)全量数据(正类少,负类多)C_iC_j类别的数据(完全平衡)
训练时间复杂度O(K * N)O(K² * N/K) = O(K * N)(平均每个模型数据量为N/K
预测时间复杂度O(K)O(K²)
内存占用O(K)O(K²)
对类别不平衡的鲁棒性弱(每个模型都面临不平衡)强(每个模型数据均衡)
对单个模型错误的鲁棒性弱(一个强错误预测可主导结果)强(错误被投票机制稀释)
典型适用场景K较小(< 10),数据量极大,对推理速度要求苛刻K中等(10-50),类别间区分度差异大,对模型精度和鲁棒性要求极高

我的经验是:在绝大多数入门和中级项目中,OvA 是首选,因为它简单、快、够用。但当你进入一个高风险领域,比如金融反欺诈(类别:正常交易,盗刷,洗钱,套现),或者工业质检(类别:合格,划痕,凹陷,色差,尺寸超差),此时K不大,但每个类别的业务含义和损失函数都截然不同,OvO 的鲁棒性优势就会凸显出来。我曾在一个汽车零部件缺陷检测项目中,将 OvA 的 F1-score 从0.82提升到0.89,关键就在于 OvO 让模型对划痕凹陷这两个视觉上极易混淆的缺陷,建立了更精细、更可靠的判别边界。

5. 实操全流程:从数据准备到模型评估的避坑指南

5.1 数据预处理:别让脏数据毁掉你的数学之美

逻辑回归对数据的“干净度”极为敏感。一个未经处理的原始数据集,往往会在下游引发一系列连锁反应。

  • 缺失值(Missing Values):逻辑回归无法处理NaN。最危险的做法是直接df.dropna(),这会无差别地删除整行,可能导致你丢失大量宝贵样本。更合理的做法是:

    • 对于数值型特征(如age,income),用中位数(median)填充。中位数比均值更能抵抗异常值的影响,而逻辑回归的决策边界对异常值非常敏感。
    • 对于分类型特征(如education_level),用众数(mode)填充,或者创建一个新的类别Unknown。切记不要用0-1去填充,这会给模型引入虚假的序关系。
  • 异常值(Outliers):逻辑回归的z = X·β是线性的,一个极端的x值会直接导致z极大,从而使σ(z)趋近于10,产生一个“过于自信”的错误预测。我建议对所有数值型特征做IQR(四分位距)过滤Q1 - 1.5*IQR < x < Q3 + 1.5*IQR。对于超出范围的点,不是直接删除,而是将其“拉回”到边界值(Winsorization),这比删除更能保留数据的整体分布形态。

  • 特征缩放(Feature Scaling):这是新手最容易忽略,也是影响最大的一步。逻辑回归的梯度∇J = (p-y)*x中,x的量纲直接决定了梯度的大小。如果x₁是“年龄”(范围0-100),x₂是“年收入”(范围0-1000000),那么x₂的梯度会比x₁大一万倍!这会导致优化器在x₂方向上疯狂震荡,而在x₁方向上几乎不动。必须对所有数值型特征进行标准化(Standardization):x' = (x - μ) / σ。注意,这里不是归一化(Min-Max Scaling),因为后者对异常值敏感,而标准化更稳健。

实操心得:我在一个客户流失预测项目中,忘记对“月均消费额”做标准化,模型训练了 1000 轮,loss曲线像心电图一样剧烈抖动,最终收敛到一个很差的结果。加上StandardScaler后,50 轮就平稳收敛,AUC 提升了 0.12。这个教训让我养成了一个习惯:在fit()之前,永远先print(X_train.describe()),肉眼扫一遍各列的均值和标准差。

5.2 模型训练与超参调优:超越C=1.0的默认值

sklearnLogisticRegression有一个核心超参数C,它控制着正则化强度C是正则化系数λ的倒数:C = 1/λC越大,正则化越弱,模型越复杂,越容易过拟合;C越小,正则化越强,模型越简单,越容易欠拟合。

  • 如何选择C绝对不要依赖默认的C=1.0。你应该使用GridSearchCVRandomizedSearchCV进行搜索。我的经验搜索空间是:C = [0.001, 0.01, 0.1, 1, 10, 100]。对于小数据集(N < 1000),从较小的C(如0.01)开始;对于大数据集(N > 10000),可以从较大的C(如10)开始。

  • 正则化类型penalty参数可选'l1''l2'

    • 'l2'(岭回归):它会惩罚所有权重的平方和,使所有权重都趋向于小,但不会为零。它能提升模型的泛化能力,是更通用的选择。
    • 'l1'(Lasso):它会惩罚所有权重的绝对值之和,具有特征选择的天然属性——它会将不重要的特征权重直接压缩为0。如果你的特征维度很高(n_features >> n_samples),或者你明确需要一个可解释的、精简的模型,l1是更好的选择。
  • 求解器(Solver)solver参数决定了用什么算法来优化损失函数。liblinear适用于小数据集;lbfgssaga适用于大数据集。saga是唯一一个同时支持l1l2正则化的求解器,因此在需要l1时,saga是必选项。

5.3 模型评估:超越 Accuracy 的多维审视

对于一个二分类逻辑回归模型,仅仅看accuracy是极具误导性的,尤其是在类别不平衡的数据上。

  • 混淆矩阵(Confusion Matrix):这是所有评估的起点。它给出了TP,TN,FP,FN四个基本计数。
  • Precision(精确率)TP / (TP + FP)。它回答的问题是:“当我预测为正类时,有多大概率是正确的?” 在垃圾邮件检测中,高 Precision 意味着你很少把正常邮件误判为垃圾邮件。
  • Recall(召回率)TP / (TP + FN)。它回答的问题是:“所有真实的正类样本中,我成功找出了多少?” 在疾病筛查中,高 Recall 意味着你很少漏掉一个真正的患者。
  • F1-ScorePrecisionRecall的调和平均数,是它们的综合指标。
  • ROC-AUC:这是逻辑回归最核心的评估指标。它绘制的是不同阈值下的TPR(Recall)和FPRFP / (FP + TN))的关系曲线。AUC 值代表了模型在所有可能阈值下,区分正负样本的能力。AUC = 0.5表示模型等同于随机猜测;AUC = 1.0表示模型完美区分。一个健康的逻辑回归模型,其 ROC 曲线应该从左下角(0,0)平滑地上升到右上角(1,1)

常见问题:为什么我的模型accuracy很高(95%),但recall却只有 0.3?答案几乎总是:你的数据严重不平衡,而模型学会了“偷懒”,即永远预测为多数类。此时,accuracy是一个完全失效的指标。你必须立刻转向precision-recall curveROC curve,并根据业务需求,手动设定一个更合理的阈值(比如,宁可多召回来几个,也不能漏掉一个)。

6. 常见问题与排查技巧实录:那些只有踩过才懂的坑

6.1 问题:模型训练时loss不下降,甚至发散

排查思路

  1. 检查数据:首先print(y_train.value_counts(normalize=True)),确认标签是否极度不平衡。如果是,尝试class_weight='balanced'参数,它会自动为少数类赋予更高的权重。
  2. 检查特征print(X_train.isnull().sum()),确认是否有未处理的NaNprint(np.isinf(X_train).sum()),确认是否有无穷大值(通常来自除零错误)。
  3. 检查缩放print(X_train.mean(), X_train.std()),确认所有特征的均值是否接近0,标准差是否接近1。如果不是,说明StandardScaler没有正确应用。
  4. 检查学习率:虽然sklearn的求解器是自适应的,但如果C设置得过大(如C=1000),相当于几乎没有正则化,模型可能会在复杂的空间里迷失。尝试将C降低一个数量级。

我的实录:在一个电商点击率预测项目中,loss一直不降。我一步步排查,最后发现是“用户历史购买次数”这个特征里,有少量用户记录为999999(数据库里的默认占位符)。这个异常值让z变得极大,σ(z)趋近于1,梯度(p-y)变得极小,模型“躺平”了。修复后,loss在 5 轮内就稳定下降。

6.2 问题:predict_proba输出的所有概率都集中在0.4-0.6区间,缺乏区分度

排查思路

  1. 检查模型复杂度C是否设置得太小?过强的正则化会把所有权重都拉向0,导致z总是很小,σ(z)总是接近0.5。增大C
  2. 检查特征工程:你的特征是否真的包含了足够的判别信息?尝试添加一些交互特征(如feature_a * feature_b)或多项式特征(如feature²)。逻辑回归本身是线性的,但特征可以是非线性的。
  3. 检查数据质量:是否存在大量的标签噪声?即,很多样本的标签本身就是错误的。这会让模型“学不会”,只能给出一个保守的、中庸的预测。

我的实录:在一个新闻分类项目中,模型输出的概率非常“平”。我检查了C,没问题;然后我画了所有特征的boxplot,发现“文章长度”这个特征的分布,在所有类别中几乎完全重叠。我果断弃用了它,并加入了“标题中关键词 TF-IDF 加权和”这个新特征,模型的calibration curve立刻变得漂亮起来。

6.3 问题:OvA 多分类中,某个类别的precision极低,但recall很高

排查思路: 这通常是该类别与其他类别边界模糊的信号。OvA 的“全局”视角在这里失效了。

  • 方案一(推荐):切换到 OvO 策略。O

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询