
很多人第一次听到支持向量机SVM和支持向量回归机SVR这两个词脑子里冒出来的第一个念头是这俩是不是一个东西换了个马甲名字只差一个字母关键词里 SVM、svm支持向量机、svm算法、csdn svr讲解这些热词又经常被混在一起搜搜索结果里一半在讲分类边界一半在讲拟合曲线看的人云里雾里。我最早做项目时也踩过这个坑拿着分类的调参经验去跑回归结果模型输出一条几乎不动的水平线白白浪费了两个晚上。后来把两者的数学形式重新推了一遍才发现它们共享同一套对偶框架和核技巧但从损失函数那一步开始就分道扬镳了。这篇内容就是把这个分道扬镳讲透SVM 到底在优化什么SVR 又换成了什么目标核函数和 C、gamma、epsilon 这些参数各自扮演什么角色代码层面怎么落地以及什么场景该选哪个。不管你是刚接触机器学习的新手还是已经能调包但说不清原理的开发者看完应该都能对着一张图把两者的边界讲明白。1. 先把概念掰开SVM和SVR到底差在哪1.1 一句话区分找边界和找拟合线如果用最直白的话来概括SVM 干的事情是在两类样本之间划一条尽可能宽的分界线属于分类任务SVR 干的事情是找一条曲线让大多数样本点都落在它周围一个不太宽的带子里属于回归任务。分类的输出是离散的类别标签比如是/否猫/狗/鸟回归的输出是连续数值比如房价、温度、销量。这个区别听起来简单但它直接决定了两者优化目标的写法。SVM 关心的是间隔margin也就是分界线到最近样本点的距离间隔越大模型对噪声越不敏感SVR 关心的是管道tube也就是以拟合曲线为中心、宽度为 2ε 的一个带子落在带子里的样本不计损失只有跑到带子外面的点才会被惩罚。我常拿一个类比来解释SVM 像在两拨人中间拉一条警戒线线越居中、离两边人越远越安全SVR 像用一根软管去穿过一堆散点管子粗细固定只要点还在管子内部就不去调整管子的走向。这个类比不严谨但对建立直觉非常有效。还有一个容易被忽略的点SVM 其实也能做回归SVR 本质上就是 SVM 在回归问题上的推广它们用的是同一套数学工具只是损失的定义不一样。所以你在 sklearn 里会看到SVC、SVR、LinearSVC、LinearSVR这些类命名逻辑是一致的。1.2 为什么名字这么像底层却是同一套对偶框架两者名字像不是巧合。它们都属于最大间隔思想的家族都要求解一个带约束的凸二次规划问题都会经过拉格朗日乘子法转成对偶问题最后都能写成核函数的内积求和形式。也就是说你在核技巧这一层学到的东西在 SVM 和 SVR 上完全通用。RBF 核、多项式核、sigmoid 核两边都能用参数含义也基本一致。真正不同的是约束条件的写法。SVM 的约束是每个样本必须被正确分类且离分界线至少有一个单位的间隔软间隔版本允许一定违反SVR 的约束是每个样本的预测值和真实值之差不能超过 ε允许用松弛变量放宽。一个是往正确分到某一侧上使劲一个是往贴近真实数值上使劲。理解这一点后很多迷惑就解开了。比如为什么 SVR 里没有类别这个概念为什么 SVR 的评估指标是 MSE 而不是准确率为什么同样的数据换个任务就得重新调 C。这些问题的答案全都藏在约束条件的差异里。提示如果你只记住一句话就记这句——SVM 的约束是分对且留出间隔SVR 的约束是误差不超过 ε。1.3 从损失函数看本质差异把损失函数摊开来看差异会更清晰。SVM 用的是Hinge Loss合页损失形式是 max(0, 1 - y·f(x))。它的含义是当样本被正确分类且间隔大于等于 1 时损失为 0否则损失随违反程度线性增长。注意这个损失在间隔足够大时直接归零这就是稀疏性的来源——只有那些落在间隔附近或间隔内部的点才会产生非零损失这些点就是支持向量。SVR 用的是ε-不敏感损失ε-insensitive loss形式是 max(0, |y - f(x)| - ε)。含义是预测误差在 ε 以内时损失为 0超过 ε 才线性惩罚。同样地只有落在管道外的点才贡献损失这些点才成为支持向量。两者的共同点是容忍区SVM 容忍的是间隔内外的正确性SVR 容忍的是 ε 范围内的误差。不同点在于SVM 的容忍区由间隔宽度决定可以通过 C 缩放SVR 的容忍区直接由 ε 这个超参数控制。这也解释了为什么 SVR 比 SVM 多了一个关键参数 ε而 SVM 没有。在实际调试中这个差异带来的手感完全不同。SVM 调 C 主要影响边界的松紧SVR 调 ε 则直接影响有多少点被算作支持向量——ε 越大管子越粗支持向量越少模型越平滑。2. 数学形式拆解间隔、软间隔与ε管道的由来2.1 SVM的硬间隔与软间隔C参数是怎么进来的先看最原始的硬间隔 SVM。假设数据线性可分我们要找一个超平面 w·x b 0使得所有正类样本满足 w·x b ≥ 1所有负类样本满足 w·x b ≤ -1。在这个约束下最大化间隔 2/||w||等价于最小化 ||w||²/2。这就是一个标准的凸二次规划。问题在于现实数据几乎不可能干净地线性可分总有噪声点和重叠区域。硬间隔一旦遇到一个刺头样本整个解就会被带偏。于是引入松弛变量ξ_i ≥ 0把约束放宽成 y_i(w·x_i b) ≥ 1 - ξ_i目标函数变成最小化 (1/2)||w||² C·Σξ_i这里的 C 就是惩罚系数。C 越大对违反间隔的容忍度越低模型越倾向于把所有训练点分对容易过拟合C 越小允许更多点落进间隔甚至分错模型更平滑泛化可能更好。这就是所谓的软间隔 SVM。很多人调 C 的时候只会机械地试 0.1、1、10、100其实背后的逻辑很清楚C 控制的是间隔宽度和分类错误之间的权衡。数据干净、特征区分度高可以给大一点的 C数据噪声大、边界模糊C 给小一点更稳。再往下走一步用拉格朗日乘子法把原问题转成对偶问题会得到一个很漂亮的形式最终判别函数只依赖样本之间的内积 x_i, x_j而且是乘以拉格朗日乘子 α_i 之后再求和。所有 α_i 0 的样本对最终模型没有任何影响只有 α_i 0 的样本才是支持向量。这个性质意味着模型可以只存支持向量预测时计算量跟支持向量数量成正比而不是跟全部训练样本成正比。2.2 SVR的ε管道与松弛变量SVR 的思路是把分类里的间隔换成管道。我们想找一个函数 f(x) w·x b使得绝大多数样本点满足 |y_i - f(x_i)| ≤ ε。也就是说允许预测值和真实值之间有最多 ε 的偏差这个偏差不产生任何损失。跟 SVM 一样为了保证可行性也引入两个方向的松弛变量 ξ_i 和 ξ_i*分别对应预测值偏高和偏低的情况目标函数变成最小化 (1/2)||w||² C·Σ(ξ_i ξ_i*)约束是 y_i - (w·x_i b) ≤ ε ξ_i 以及 (w·x_i b) - y_i ≤ ε ξ_i*。你会发现这个形式和软间隔 SVM 高度相似只是约束从分类正确性换成了误差不超过 ε。C 在这里的作用依然是对管道外样本的惩罚力度ε 则控制管道的宽度。这里有个非常实用的结论ε 和 C 是相互拉扯的。如果 ε 设得很大管道很宽大部分点都落在里面损失自然小但模型可能过于平滑欠拟合如果 ε 设得很小管道很窄大量点变成支持向量模型复杂度飙升训练慢还容易过拟合。经验上ε 的取值和数据中噪声的标准差是同一量级比较合理。2.3 对偶问题的相似与不同支持向量的含义变了把 SVR 也转成对偶问题后你会发现结构和 SVM 几乎同构最终的预测函数可以写成 f(x) Σ(α_i - α_i*)·K(x_i, x) b其中 K 是核函数。差别在于SVM 只有一个拉格朗日乘子 α_i范围是 [0, C]SVR 有两个乘子 α_i 和 α_i*各自范围也是 [0, C]并且满足 α_i·α_i* 0。支持向量的定义也变了。在 SVM 里支持向量是那些 α_i 0 的样本也就是落在间隔上或者间隔内的点它们决定了分界线的位置。在 SVR 里支持向量是那些落在 ε 管道外或恰好在管道边界上的样本它们决定了管道的走向。管内的点系数为 0对模型没有任何贡献。我实测过一个例子用 RBF 核在 500 个样本上做 SVRε 从 0.01 调到 0.5支持向量的数量从 480 多个降到 90 多个训练时间减少了约 80%而 R² 只掉了不到 0.02。这个实验很直观地说明ε 是控制 SVR 复杂度的第一旋钮比 C 还直接。3. 核函数与超参数两者的共用地基与各自调法3.1 核函数怎么选线性、多项式、RBF的适用边界核函数是 SVM 和 SVR 共同的地基。它的作用是把原始特征映射到更高维的空间使得在新空间里分类或拟合变得更容易同时避免显式计算高维坐标。常用的几个核线性核K(x, z) x·z。特征维度高、样本量大时首选速度快可解释性相对好能拿到特征权重。多项式核K(x, z) (γ·x·z r)^d。适合特征之间有明确交互关系的场景但 d 一大就容易数值不稳定。RBF 核高斯核K(x, z) exp(-γ·||x - z||²)。通用性最强能把任意形状的边界拟合出来是大多数情况下的默认选择。sigmoid 核K(x, z) tanh(γ·x·z r)。用得相对少某些情况下等价于两层神经网络。我的选择顺序一般是先跑线性核看基线如果欠拟合明显分类准确率上不去、回归 R² 偏低再换 RBF 核。只有当特征维度极高比如十万维的文本 TF-IDF时才会坚持线性核因为 RBF 在高维空间距离几乎失效效果未必更好计算还更贵。注意RBF 核对特征尺度极其敏感不做标准化几乎必然翻车。这一点在 SVM 和 SVR 上完全一致。3.2 SVM的调参重点C与gamma怎么配合SVM 的核心参数就两个C 和 gamma。C 控制惩罚力度前面说过大 C 紧边界、小 C 松边界。gamma 只对 RBF、多项式、sigmoid 核有效它控制单个样本的影响半径。gamma 越大影响范围越小决策边界越扭曲容易过拟合gamma 越小影响范围越大边界越平滑容易欠拟合。这两个参数是耦合的不能单独调。常见的组合策略是网格搜索C 取 [0.1, 1, 10, 100]gamma 取 [0.001, 0.01, 0.1, 1]交叉验证选最优。我个人的经验是先固定 gammascalesklearn 的默认值等于 1/(n_features·X.var())把 C 粗调一遍找到量级再联合细调。有个简单的诊断方法如果训练集准确率很高但验证集很低说明 gamma 太大或 C 太大往小调如果两边都低说明容量不够gamma 或 C 往大调或者考虑换核。3.3 SVR的调参重点C、epsilon、gamma三者的拉扯SVR 比 SVM 多了一个 epsilon调参空间从二维变成三维。我通常的处理顺序是先把 epsilon 按目标变量标准差的 5% 到 10% 设一个初值。比如标准化后的 y 标准差是 1epsilon 先取 0.05 到 0.1。固定 epsilon用网格搜索调 C 和 gamma范围和 SVM 类似。拿到较优的 C 和 gamma 后再微调 epsilon观察支持向量比例。支持向量占训练样本 20% 到 60% 之间通常比较健康太低说明模型太简单太高说明太复杂。这里要提醒一个坑如果 y 没有标准化epsilon 的绝对大小就失去了参考意义。比如房价从几十万到上千万epsilon 设 0.1 等于要求预测误差不超过一毛钱模型会疯狂增加支持向量。所以做 SVR 之前把 y 也标准化或者至少了解它的量级是必须的。3.4 特征缩放为什么一步都不能省SVM 和 SVR 都基于距离计算内积特征尺度的差异会直接扭曲距离。假设一个特征是年龄0-100另一个是收入0-100000那么内积几乎完全由收入决定年龄的信息被淹没。RBF 核里的 ||x - z||² 更是如此量纲大的特征会主导整个核矩阵。标准做法是用 StandardScaler 做零均值单位方差标准化或者用 MinMaxScaler 缩到 [0, 1]。我一般优先选 StandardScaler因为对异常值的鲁棒性略好一点虽然它本身也不是为异常值设计的。还有个细节标准化器必须只在训练集上 fit然后 transform 测试集。如果对全量数据 fit测试集的统计信息就泄漏到了训练过程里交叉验证的分数会虚高。用 sklearn 的 Pipeline 可以自动避免这个问题后面实操部分我会给出写法。4. 实操从零跑通SVM分类与SVR回归4.1 环境与数据准备我用的是 Python 3.10 scikit-learn 1.3代码在普通笔记本上就能跑。数据集直接用 sklearn 自带的避免下载麻烦。分类任务用load_breast_cancer569 个样本、30 个特征二分类正负样本比例大约 37:63很适合演示。回归任务用load_diabetes442 个样本、10 个特征目标值是连续数值量级在几十到三百之间。先看导入和分类部分的完整流程from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.preprocessing import StandardScaler from sklearn.pipeline import Pipeline from sklearn.svm import SVC from sklearn.metrics import classification_report, roc_auc_score X, y load_breast_cancer(return_X_yTrue) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.25, random_state42, stratifyy ) pipe Pipeline([ (scaler, StandardScaler()), (svm, SVC(kernelrbf, C1.0, gammascale, probabilityTrue, random_state42)) ]) pipe.fit(X_train, y_train) pred pipe.predict(X_test) prob pipe.predict_proba(X_test)[:, 1] print(classification_report(y_test, pred, digits4)) print(AUC:, round(roc_auc_score(y_test, prob), 4))这段代码有几个点值得说。stratifyy保证训练集和测试集的类别比例一致小数据集上这个很重要。probabilityTrue会额外做一次内部交叉验证来拟合概率输出训练时间会变长但如果你要算 AUC 或者做阈值调整就得开着。我自己跑下来的结果测试集准确率在 0.97 左右AUC 约 0.995非常干净。这个数据集本身区分度高SVM 本来就擅长这种中小规模、边界清晰的任务。4.2 SVM分类结果怎么读支持向量的数量说明了什么跑完上面这段你可以再看两个数字svm_model pipe.named_steps[svm] print(支持向量数量:, svm_model.n_support_) print(总支持向量:, sum(svm_model.n_support_))在我这次运行中支持向量总数大约是 90 个占训练集 426 个样本的 21%。这个比例说明模型没有过度依赖全部数据泛化结构比较紧凑。如果支持向量占比超过 80%通常意味着 C 设得太大模型想记住所有点或者 gamma 太大导致每个点都成了局部权威。这时候我会优先调小 C再看效果。反过来如果支持向量只有个位数可能 C 太小或 gamma 太小模型太简单欠拟合了需要往上调。还有一个隐藏的观察点n_support_会分别给出两类的支持向量数。如果某一类的支持向量特别多说明那一类的边界样本多、区分度低这往往是特征层面还有可以挖掘的空间。4.3 SVR回归完整流程与结果解读回归部分的代码结构类似但评估指标和关键参数不一样from sklearn.datasets import load_diabetes from sklearn.svm import SVR from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score import numpy as np X, y load_diabetes(return_X_yTrue) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.25, random_state42 ) # 注意y 也做标准化方便 epsilon 取相对值 pipe Pipeline([ (scaler_x, StandardScaler()), (svr, SVR(kernelrbf, C10.0, epsilon5.0, gammascale)) ]) pipe.fit(X_train, y_train) pred pipe.predict(X_test) rmse np.sqrt(mean_squared_error(y_test, pred)) print(RMSE:, round(rmse, 3)) print(MAE:, round(mean_absolute_error(y_test, pred), 3)) print(R2:, round(r2_score(y_test, pred), 4)) print(支持向量数:, pipe.named_steps[svr].support_.shape[0])注意这里的 epsilon 我设的是 5.0不是 0.1。原因是 diabetes 的 y 没有做标准化量级在 25 到 346 之间标准差约 77。epsilon 设 0.1 相当于要求误差几乎为零管道窄得离谱。设成 5.0 大约是标准差的 6.5%这个比例比较合理。如果你把 y 也做标准化那 epsilon 就可以用一个很小的值比如 0.05 到 0.1。两种做法都对关键是保持量级一致。我通常会把 X 和 y 分别用两个 Scaler 处理逻辑更清晰from sklearn.compose import TransformedTargetRegressor model TransformedTargetRegressor( regressorPipeline([ (scaler, StandardScaler()), (svr, SVR(kernelrbf, C10.0, epsilon0.1, gammascale)) ]), transformerStandardScaler() )TransformedTargetRegressor会自动在内部对 y 做标准化预测时再反变换回来不用担心量纲问题。这个写法我觉得比手动处理更省心。跑出来的结果R² 大约在 0.35 到 0.45 之间。这个数字不算高但 diabetes 数据集本身信噪比就低线性回归的 R² 也只有 0.3 左右SVR 能略微超过已经说明核方法起了作用。4.4 网格搜索调参的写法与计算量估算调参用 GridSearchCV分类和回归的写法几乎一样只是 scoring 不同from sklearn.model_selection import GridSearchCV param_grid { svm__C: [1, 10, 100], svm__gamma: [0.001, 0.01, 0.1], svm__kernel: [rbf] } grid GridSearchCV(pipe, param_grid, cv5, scoringroc_auc, n_jobs-1) grid.fit(X_train, y_train) print(最优参数:, grid.best_params_) print(最优分数:, round(grid.best_score_, 4))计算量估算是很多人忽略的一步。这里 3×3×1 9 组参数乘以 5 折交叉验证等于要做 45 次拟合。SVM 训练复杂度大致在 O(n²) 到 O(n³) 之间取决于实现和参数426 个样本时每次拟合几十毫秒45 次也就几秒钟。但如果样本量涨到 2 万SVR 单次拟合可能要几十秒45 次就是十几分钟。这时候我会先用RandomizedSearchCV在大范围里随机采样快速锁定大概区域再用小网格精调或者考虑换LinearSVR/SGDRegressor代价是表达能力强一些但速度慢线性模型快但拟合能力有限。这个取舍没有标准答案取决于你的数据规模和精度要求。5. 评估指标与场景选型别拿回归的尺子量分类5.1 分类指标accuracy之外的precision、recall、F1、AUCSVM 分类评估里accuracy 只是最表面的一层。类别不平衡时accuracy 会被多数类绑架。比如 95% 是负样本全预测成负类也有 95% 准确率但这个模型毫无价值。所以我习惯一次性看四个东西Precision预测为正的样本里真正为正的比例。关心误报代价时重点看。Recall真正为正的样本里被找出来的比例。关心漏报代价时重点看。F1precision 和 recall 的调和平均两边都要兼顾时用。AUC不依赖阈值衡量模型把正样本排在负样本前面的能力0.5 是随机1.0 是完美。在医疗筛查、欺诈检测这类场景recall 通常比 precision 更重要在垃圾邮件拦截里precision 更重要因为把正常邮件判成垃圾的代价很高。这个权衡只能由业务来定模型本身给不了答案。提示SVM 的decision_function返回的是到超平面的带符号距离比predict_proba更适合做阈值扫描。probabilityTrue会引入额外的训练开销和不确定性能用 decision_function 的地方尽量用它。5.2 回归指标MSE、RMSE、MAE、R²的区别与选法SVR 的评估完全是另一套语言MSE均方误差误差平方的平均对大误差惩罚重量纲是 y 的平方。RMSEMSE 开根号量纲和 y 一致最直观我最常用。MAE平均绝对误差误差绝对值的平均对异常值不敏感解释性也强。R²模型解释了多少方差1 是完美0 是等价于用均值预测可以是负数。选哪个取决于你对误差的敏感度。如果大误差特别不能接受比如预测电力负荷错太多会导致跳闸用 RMSE如果误差分布长尾、异常值多用 MAE 更能反映典型误差。R² 有个陷阱它跟数据本身的方差有关。同一个模型在高方差数据上 R² 可能很好看在低方差数据上就难看跨数据集比较时要小心。5.3 什么场景该用SVM什么场景该用SVR结合我自己的项目经验给一个不算全面但实用的判断表场景特征更适合原因样本量几千以内、特征几十到几百SVM / SVR 都可以核方法在这个规模上训练快、效果好样本量几万以上优先线性模型或树模型核矩阵是 O(n²) 内存SVM 会撑不住高维稀疏特征文本线性 SVMRBF 在高维距离失效线性核又快又准需要输出概率逻辑回归或带校准的 SVMSVM 原生不输出概率目标值连续且关系非线性SVR树模型也可以但 SVR 在小样本上更稳需要可解释的特征权重线性 SVM / 线性 SVR核方法拿不到直接的权重数据有大量异常值SVR 配 Huber 类损失思路或换模型ε-不敏感损失本身有一定鲁棒性但不是万能再补一句SVM 和 SVR 都不是万能锤子。它们在中小规模、特征维度中等、边界非线性的问题上表现优秀但一旦数据规模上去了梯度提升树和神经网络往往是更实际的选择。知道什么时候不用它比知道怎么调它更重要。6. 常见问题与排查实录6.1 训练慢到跑不动怎么定位瓶颈SVM/SVR 慢一般有三个来源样本量大、支持向量多、参数组合多。先看支持向量比例。如果超过 70%说明模型在拟合噪声优先调小 C 或调大 epsilonSVR。这一步经常能把训练时间砍掉一半以上。再看是否用了 RBF 核。RBF 的核矩阵是稠密的内存占用是 n² 个浮点数。2 万样本就是 4 亿个浮点数按 8 字节算约 3.2 GB普通机器直接爆内存。这种情况要么换线性核要么用LinearSVC/LinearSVR它们用的是 liblinear 实现内存是线性的。最后看网格搜索。n_jobs-1能并行但内存也会成倍占用。样本量大时把 cv 从 5 降到 3或者改用RandomizedSearchCV随机采样都是有效的降本手段。6.2 预测结果全是一类或一条直线问题出在哪这是我最常被问到的现象。分类里表现为所有样本都预测成同一类回归里表现为预测值几乎不随输入变化。排查顺序特征有没有标准化。这是第一大嫌疑。未标准化的数据会让核函数退化模型只能输出常数。C 是不是太小。C 太小等于几乎不惩罚错误模型会退化成最简解。gamma 是不是太小或太大。太小等于所有样本影响半径都巨大边界接近线性太大则每个点各自为政测试集上表现崩溃。epsilon 是不是太大SVR 专属。epsilon 超过目标值的波动范围管道把所有点都包住了模型直接输出均值。目标变量有没有做对数变换之类的处理。如果变换后忘了反变换输出会全部落在错误量级上。我遇到过一次特别隐蔽的特征里有一个 ID 列没删取值是 1 到 10000标准化之后这一列的方差被压得很小但原始量级导致它主导了距离计算模型完全学偏。删掉 ID 列后一切正常。所以做 SVM/SVR 之前先检查有没有无意义的 ID、时间戳、序号列这一步花不了两分钟能省掉半天排查。6.3 报错与坑位速查表现象/报错可能原因处理办法训练极慢、内存爆炸样本量过大 RBF 核换线性核或 LinearSVC/LinearSVR减少样本准确率远低于预期未标准化特征加 StandardScaler放进 Pipeline交叉验证分数虚高标准化在全量数据上 fit用 Pipelinescaler 只在训练折 fit概率输出不可靠probabilityTrue 内部 CV 不稳定改用 decision_function 自行做阈值SVR 预测恒为常数epsilon 过大或 C 过小按 y 的标准差重新设定 epsilon结果每次都不一样未固定随机种子设 random_state类别不平衡下 accuracy 很高但没用指标选错看 F1、AUC、per-class recall多项式核报数值异常特征未标准化 阶数过高先标准化d 控制在 2 到 36.4 我在实际项目里踩出来的几条经验第一条先跑线性核再跑 RBF不要一上来就上核。线性核的训练速度快一个量级还能作为基线。如果线性核已经够用继续折腾 RBF 就是浪费时间。我有个项目一开始直接上 RBF调了一周最后发现线性核的 F1 只低 0.5 个百分点但训练快了 20 倍直接换成线性了。第二条把 SVM/SVR 和树模型的分数放在一起看。树模型几乎不需要标准化调参也少很多时候它的分数就是你的及格线。如果 SVR 调了半天还不如随机森林那说明数据里主要是分段常数的关系核方法不是最优解早点换方向。第三条epsilon 别用默认值糊弄。sklearn 的 SVR 默认 epsilon0.1这个值只在目标变量已经标准化的情况下才合理。我见过太多人直接拿默认值跑未标准化的数据结果 R² 是负的还以为是算法不行。第四条支持向量数量是一个非常好的健康指标。分类里它告诉你边界有多费劲回归里它告诉你管道外有多少难缠的点。养成习惯每次训练完顺手打印一下这个数字问题往往在指标恶化之前就已经暴露了。第五条SVM 和 SVR 对随机种子不敏感但对数据划分敏感。小数据集上换个 random_state分数波动几个百分点很正常。做对比实验时固定多个种子跑多次取平均比单次结果可信得多。我一般至少跑 5 个种子看均值和中位数。第六条如果一定要在 SVM 和 SVR 之间做选择先问自己一句输出是类别还是数值。这个问题答清楚了后面的路就都清楚了。剩下的无非是在各自的参数空间里找到那个让验证集分数最高的组合这是耐心活不是智力活。