
机器学习里有一类问题几乎占了业务场景的大半壁江山就是分类。垃圾邮件识别、信用卡欺诈检测、图片内容识别、疾病风险预测、用户流失预警这些看似风马牛不相及的领域落到算法层面核心都是同一件事给定一个样本判断它属于哪一个类别。这篇笔记是机器学习系列第三篇专门聊分类问题。我会从分类任务的定义讲起把常见的分类算法挨个过一遍说清楚它们各自擅长什么、短板在哪再重点讲讲实际工程里最要命的评估指标选择和数据处理坑点。适合刚看完回归问题、准备进入分类领域的学习者也适合正在做期末复习、需要把零散知识串成体系的同学。内容偏实战数学推导只保留最核心的直觉尽量让你读完就能上手而不是停留在背公式的层面。1. 分类问题的本质从这个例子你就懂了1.1 一张表搞懂分类和回归的边界很多新手最大的困惑不是“分类怎么实现”而是“什么时候该用分类什么时候该用回归”。有个特别直观的判断方式看输出值有没有“顺序含义”。房价预测3万一平和5万一平之间是连续的、可比较的这是回归。天气预测明天是否下雨只有“下雨”和“不下雨”两种结果你不能说“下雨”比“不下雨”大多少这是分类。再比如预测一个用户会不会流失“会”和“不会”没有大小之分这也是分类。严格一点说分类问题的训练集长这样输入特征 x1, x2, ..., xn 输出标签 y ∈ {C1, C2, ..., Ck}目标是学到一个映射函数 f(x) → y让新来的样本能够被自动归入正确的类别。二分类是最基础的情形也就是 y 只取两个值通常记作 0 和 1或者 -1 和 1。多分类可以看作二分类的扩展做法上要么是“一对多”要么是“一对一”后面细聊。1.2 为什么回归模型不能直接拿来分类有人会问既然线性回归能输出一个数值那加个阈值不就能做分类了吗比如输出大于 0.5 判为正类小于 0.5 判为负类。理论上确实可以这么做但实际上一旦遇到异常值就很容易翻车。回归模型的目标是最小化所有样本的均方误差这意味着它会被那些偏离很远的样本强烈牵制。我之前做个一个很简单的演示拿一组带明显离群点的数据跑线性回归再把输出切分成两类结果分类边界被那个离群点拽得歪七扭八准确率直接从 90% 掉到 70%。原因在于回归的损失函数是“差多少算多少”而分类更关心的是“方向对不对”。你预测 0.6 和预测 0.9只要都超过阈值判的都是正类但回归会硬要把 0.6 拧到 0.9 附近白白浪费模型容量。这就是为什么分类需要专门的模型和专门的损失函数。2. 六大核心分类算法选型指南这一节我按“原理直觉 → 适用场景 → 关键参数”的结构把最常见的分类算法逐一拆解。注意我没有按“谁更先进”排序而是按“你应该从哪个学起”来排。2.1 逻辑回归名字里带回归却是分类的头号主力逻辑回归虽然名字里有“回归”两个字但它是个彻彻底底的分类算法。它的核心思路是先把线性组合的结果通过 Sigmoid 函数压缩到 (0,1) 区间得到样本属于正类的概率然后设一个阈值通常 0.5做判定。Sigmoid 的公式是p 1 / (1 exp(-z)) z w1*x1 w2*x2 ... b这个设计妙在哪Sigmoid 在 z0 附近斜率大稍微变化一点概率就明显波动这让决策边界附近的样本对模型参数特别敏感而在远离边界的地方概率被压到接近 0 或 1梯度趋近于零模型会自动“不太关心”那些已经分得很清楚的样本。这种特性特别适合分类——模型把主要精力集中在边界附近。实操层面逻辑回归的三个要点特征必须做标准化或归一化尤其当特征量纲差异大的时候比如一个特征是年龄另一个特征是收入否则梯度下降收敛会特别慢。用正则化控制过拟合常用 L2特征极多且稀疏时用 L1还能顺便做特征选择。决策阈值不一定要用 0.5。如果业务更看重“别漏掉正例”可以把阈值调低更看重“预测为正的得准”就调高阈值。后面讲评估指标时细说。逻辑回归的优点是训练快、可解释强系数直接告诉你每个特征对风险概率是正向还是负向作用。短板是决策边界是线性的遇到非线性数据需要自己构造交叉特征或高阶特征否则性能天花板很低。如果你刚入门建议无论如何先跑通一个逻辑回归作为 baseline再对比其他模型的提升幅度。2.2 决策树一边问问题一边做决定决策树的思路最好理解——它模仿人类做决定的过程。根节点先问一个最优问题比如“年龄是否大于 30”是的走左边不是走右边每个节点再继续问下一个问题直到把样本分到叶子节点叶子节点的类别就是预测结果。关键在于“每次问什么问题、以什么顺序问”。常见的选择标准有两个ID3/C4.5 用信息增益Information GainCART 用基尼系数Gini Impurity。两者的逻辑都是追求“分完之后子节点内部更纯”。我用基尼举例某个节点的基尼不纯度计算方式Gini(D) 1 - Σ(p_i)^2完美分类时某个类别概率为 1Gini0类别均匀分布时Gini 最大说明“最混乱”。选出那个能让 Gini 下降最多的特征和阈值作为当前的划分点。决策树的优势是几乎不需要特征标准化能自动处理数值型和分类型特征模型天然可解释——可视化之后直接就是规则集。但它有个臭名昭著的毛病单棵树极其容易过拟合只要树足够深它能把训练样本记到“背下来”的程度。控制手段包括限制最大深度max_depth、限制叶子节点最少样本数min_samples_leaf、限制分裂最少样本数min_samples_split。实际使用中我基本不用单棵决策树做最终模型都是拿它当集成学习的基学习器用。但理解决策树本身非常重要因为随机森林和梯度提升树的底层都建立在“用树划特征空间”这个思想上。2.3 支持向量机找一条最稳健的边界SVM 的直觉很有意思之前那些算法都是“找一条能分开两类的线就行”SVM 会追问一句“哪条线最好”它的答案是距离两边最近的样本点都最远的线——也就是“最大间隔”的那一条。那些恰好站在间隔边缘上的样本点被称为支持向量它们决定了最终模型长什么样。这里最容易让新手困惑的是“核技巧”。所谓核函数本质是“把样本从低维映射到高维让原本线性不可分的数据变得线性可分”但计算时不需要真的去算高维映射直接用核函数就能得到高维空间里的内积结果。最常见的几个核核函数适用情形关键参数线性核数据量大、特征维度高、线性可分C多项式核有先验的多项式关系degree, C, coef0RBF高斯核特征维度适中、非线性强C, gammaRBF 是最常用的默认选择但 gamma 这个参数非常敏感。gamma 太大每个样本的影响范围很小边界非常曲折容易过拟合gamma 太小影响范围过大边界过于平滑容易欠拟合。调 gamma 和 C 没有捷径老老实实画学习曲线或者用网格搜索。SVM 的另一个痛点是训练复杂度。经典的 SMO 算法还好但当样本量上了十万级用 scikit-learn 里的 SVC 训练速度会明显变慢。样本量大的时候我更倾向于用 SGD 版本的 SVM或者干脆换树模型。2.4 K近邻最懒的算法最实用的兜底方案KNN 恐怕是最没有“训练过程”的算法。它不学习任何参数把训练数据记下来预测的时候拿新样本和所有训练样本算距离挑距离最近的 K 个样本投票决定类别。距离通常用欧氏距离但计算前一定要做特征缩放不然特征 A 的量纲是 0~1特征 B 的量纲是 0~10000B 会完全主导距离计算。K 值的选择直接决定偏差方差平衡。K 太小只参考最近的一个样本对噪声极度敏感K 太大把远处很多不相关样本也拉进来投票边界被抹平。一个粗略的经验规则是 K 取奇数避免平票然后用交叉验证选值别拍脑袋。KNN 的实际应用场景主要是推荐系统找相似用户、异常检测这些小规模任务。它的缺点在高维场景下尤其明显——高维空间里所有样本的距离都差不多“最近邻”不再有区分度这种现象叫“维度灾难”。在面试中这是一个高频追问点记住KNN 在特征维度超过 20 甚至更少的时候就要小心了。2.5 朴素贝叶斯算概率但做了个“天真”的假设朴素贝叶斯基于贝叶斯定理核心是计算后验概率 P(类别 | 特征)然后挑概率最大的类别。公式写出来很简单P(C|X) P(C) * P(X|C) / P(X)分母 P(X) 对所有类别都是一个常数比大小的时候可以忽略。真正麻烦的是 P(X|C)——在特征维度很高的时候联合概率分布根本没法从有限样本里估计。朴素贝叶斯的“朴素”之处就是假设所有特征在给定类别条件下是相互独立的于是P(X|C) P(x1|C) * P(x2|C) * ... * P(xn|C)这个假设在实际数据中几乎不可能严格成立——比如一封邮件里“免费”和“点击”两个词显然不是独立的。但神奇的是即便假设不成立朴素贝叶斯在很多任务上的表现依然能打尤其适合文本分类。实际使用时的三个注意点连续特征要假设分布形式通常高斯分布概率算出来经常极小工程实现都用对数概率避免下溢如果某个特征在某个类别下没出现过概率为 0 会直接毁掉整条乘积链所以必须做拉普拉斯平滑也就是在计数上加个小常数。我自己的经验是朴素贝叶斯最适合做“快速上线的文本分类方案”。当线上资源紧张或者数据只有几百条标注样本朴素贝叶斯往往比复杂模型跑得更稳更省事。2.6 集成学习把一堆弱模型拧成一股绳集成学习是目前工业界最实用的一套方法论核心就一句话“三个臭皮匠顶个诸葛亮”。随机森林和梯度提升树是最常用的两大流派它们的思路差异非常关键。随机森林属于 Bagging。它同时训练多棵决策树每棵树用有放回抽样Bootstrap得到的不同子集训练每棵树做分裂时只从随机选取的特征子集里找最优特征。这相当于“让每棵树各看一面然后集体投票”。随机性保证了树和树之间的差异足够大投票之后方差被显著压低。它对异常值和噪声的容忍度很高调参压力小默认参数通常就表现不错。梯度提升树属于 Boosting。它挨个训练树后一棵树专门去拟合前一棵树没搞定的残差。XGBoost、LightGBM、CatBoost 都是这个思路的工程优化版本。Boosting 的拟合能力极强几乎是目前表格数据上默认的最强方案但代价是对噪声比较敏感——如果数据里有很多标注错误的样本Boosting 会努力去拟合这些错误反而把模型带偏。这时候要么清洗数据要么调低学习率、增加正则项来抑制过拟合。选型建议是这样的数据集干净、想要最高精度优先 XGBoost/LightGBM数据里有不少噪声、想要稳健结果优先随机森林业务上需要解释特征重要性两者都能给但随机森林的重要性估算更稳定。3. 评估指标分类模型好不好的唯一裁判分类模型的评估比回归复杂得多。回归看一个 R² 或 MSE 就行分类却有一整套指标体系。最大的坑是准确率Accuracy并不是万能的。我当时第一个分类项目就用准确率做唯一指标结果在严重不平衡的数据上做出了 95% 的“好成绩”细看才发现模型把所有样本都预测成了多数类——这个模型本质上是个废品。3.1 混淆矩阵与四个核心指标混淆矩阵是理解一切分类指标的地基。二分类场景下把真实类别和预测类别两两组合得到四种情况预测为正类预测为负类真实为正类TP真正例FN假负例真实为负类FP假正例TN真负例基于这四个数字可以算出一组指标。准确率Accuracy (TPTN) / 总数只能看整体对错。精确率Precision TP / (TPFP)回答“你预测为正的那些里有多少是真对的”重视的是少报假警报。召回率Recall TP / (TPFN)回答“真正的正例里你捞回了多少”重视的是别漏掉目标。F1 值是精确率和召回率的调和平均公式F1 2 * Precision * Recall / (Precision Recall)3.2 指标选择必须跟着业务走评估指标从来不是数学问题而是业务问题。做信用卡反欺诈正类是“欺诈交易”每十万笔里可能只有几笔是欺诈你宁愿把很多正常交易拦下来引发用户投诉也不想让一笔欺诈溜过——这时候召回率优先F2召回权重更高比 F1 更合适。做搜索排序用户搜“iPhone”你返回的十条结果里如果混进三条“手机壳”用户直接划走这时精确率优先宁可少推荐也不能推荐错。做医学筛查漏诊的后果远严重于误诊也是召回率优先。阈值的移动直接改变精确率和召回率的权衡阈值调高预测为正的门槛变高正例预测少了精确率升、召回率降阈值调低正例预测多了召回率升、精确率降。ROC 曲线和 PR 曲线就是描述这种权衡的工具。具体比赛中优先看 PR 曲线因为类别不平衡时 ROC 曲线容易过于乐观数据相对均衡ROC-AUC 可以放心用。AUC 的含义是“随机抽一个正样本和一个负样本模型给正样本打分更高的概率”AUC0.5 相当于瞎猜AUC0.8 以上是比较理想的状态。3.3 多分类的评估要点多分类的评估思路是先把多分类拆成多个二分类再看。最简单的是 macro 平均每个类分别算指标再取平均这种办法平等对待每个类别但会被小类别的表现拖累。加权平均weighted按各类样本数加权更像整体视角。如果你的任务存在严重类别不平衡最好每个类单独看尤其关注样本最少的那个类的精确率和召回率。那种“全局准确率 92%”的漂亮数字在小类别上可能是 20% 的召回率一叶障目。4. 真实项目里避不开的数据问题算法只占项目的一部分真实数据比课本数据脏得多。这一节讲三个高频问题噪声、类别不平衡、特征工程。每一个单独拎出来都可能比调模型更影响最终效果。4.1 噪声数据先清洗再谈训练噪声数据指三类情况标注错误、特征取值异常、重复或矛盾样本。标注错误最常见也最致命——分类是靠标签学习的标签错了模型就是错的。检测标注错误的一个简单办法先用随机森林训练拿到每个样本的预测概率把“预测概率很高但真实标签相反”的样本拎出来人工审查。其实就是用模型的“惊讶”来找疑似错误标注能省下大量人工翻数据的精力。特征取值的异常一般分成两种情况。连续特征超出正常范围的极端值能真的确认是录入错误就替换或删除否则做一次极值裁剪比如把超过 99.9 分位数的值截断比留着强。类别特征出现“训练集没见过的新值”在预测阶段经常直接崩掉稳妥的办法是统一归为“未知”类别让模型学一个“未知”的应对方式。这里必须强调噪声处理不是越激进越好。我见过有人把离群点全删了结果模型在真实场景表现很差——因为真实场景全是离群点。删之前先搞清楚这个异常值是测量误差还是真实存在但少见的极端情况。拿不准的时候优先对树模型更友好它对个别离群点不太敏感或者改用鲁棒性更强的损失函数。4.2 类别不平衡别让多数类统治你的模型不平衡问题的根源在于模型默认目标是“整体准确率最大化”少数类贡献的错误比例太小被整体损失稀释模型直接摆烂把所有样本都归为多数类照样拿高准确率。应对手段从数据层面讲过采样复制少数类样本、欠采样丢弃多数类样本、SMOTE在少数类样本之间插值生成新样本是三大常规操作。SMOTE 比简单复制更聪明——它在相邻的少数类样本连线上合成新样本增加了样本多样性。但要注意SMOTE 不能跨验证集否则会把合成样本的信息泄漏进验证过程得到虚高的分数。从算法层面讲一个最直接的改动是给模型加类别权重scikit-learn 里几乎所有分类器都有 class_weightbalanced 选项原理是让少数类的误分类惩罚更大。XGBoost 里对应的是 scale_pos_weight 参数。这个改动通常比你费劲采样效果更直接而且几乎不增加代码成本。我的处理顺序是先调 class_weight不行再说采样采样的优先级是 SMOTE 优先于过采样过采样优先于欠采样。欠采样虽然能加速训练但丢数据丢得心疼只有在数据量足够大的时候才考虑。4.3 特征工程与标准化这件事值得花一半时间特征工程是机器学习项目里被讨论最少但收益最高的一件事。我的经验是新手容易把时间全花在调模型参数上但真正让准确率从 0.8 涨到 0.9 的往往是特征。几个基础操作按优先级排数值特征做缺失值填充中位数比均值更抗离群点、类别特征做目标编码或独热编码、长尾分布的特征做对数变换把偏态拉正。有些特征虽然单看和标签关系不大但把两个特征组合成“比例”反而有信息量这种需要结合业务去思考比如“消费金额 / 消费次数”得到客单价比两个原始特征分开给模型更高效。标准化这件事逻辑回归、SVM、KNN 这类基于距离或梯度的模型必须做决策树和随机森林不需要梯度提升树也不需要。做标准化时保证只基于训练集的统计量再应用到验证集和测试集搞反了就是数据泄漏。5. 从零到一怎么学好分类问题分类问题学得好不好不在于能背出多少个算法的公式而在于能不能在遇到新数据集时快速做出体系化的决策数据是干净还是脏类别是否平衡特征是什么类型该选树模型还是线性模型该用哪个评估指标这些决策链条贯穿每一个真实项目。如果你是自学、准备期末、或者刚开始找机器学习相关工作我给的路径是先用逻辑回归和决策树跑通分类流程掌握混淆矩阵、精确率召回率这些概念然后在 Kaggle 或天池上找一个表格类的二分类比赛完整走一遍数据处理到模型的流程。接着尝试把随机森林和 XGBoost 跑起来观察在同一个数据集上的效果差异把调参经验记录下来。最后再回头看 SVM 和朴素贝叶斯——这两个算法目前用得少但面试高频、概念经典忽视不得。课程资源方面吴恩达的机器学习课程里分类部分讲得清楚适合建立整体直觉李航的《统计学习方法》适合推敲细节尤其 SVM 的推导值得反复看。上手练习的话可以在本地装好 scikit-learn把 iris 或手写数字数据集玩熟也可以用一些在线实训平台分步闯关。这里我不推荐只刷题不跑实验分类的很多坑比如 class_weight 加了反而掉分、标准化忘了做导致 SVM 收敛慢都是“做了才知道”的经验型知识。期末考试自习的话把握三条主线第一每个算法回答“它解决什么问题、它的假设是什么、它的损失函数长什么样、它怎么防止过拟合”四个问题能答得上来基本够用第二把评估指标的定义和公式默写出来尤其能够在给定混淆矩阵时手算 Precision、Recall、F1第三能画出决策树、SVM、随机森林之间的关系图谱——是从哪出发、为了解决什么问题、用什么策略改进。主线通了细节查漏即可。最后再分享一个小技巧。我之前做分类项目时养成一个习惯任何模型先建立一个“极度简单的 baseline”比如用全部特征训练逻辑回归、固定评估指标、固定随机种子。后面每次改进都要和这个 baseline 对比。这样做的好处是你能清楚知道每个操作特征工程、调参、换模型到底带来了多少提升而不是糊里糊涂地跑出一堆结果却不知道哪个操作起了作用。有一次我把特征工程做完发现逻辑回归从 0.85 涨到了 0.91这个上涨幅度甚至超过了后来 XGBoost 调参的效果。这件事给我的教训很深分类问题的天花板往往不在模型而在数据和特征的理解上。希望你少踩我踩过的坑。