scikit-learn 内核岭回归(KernelRidge)完全指南:从闭式解原理到与 SVR 的实战对比
scikit-learn 内核岭回归KernelRidge完全指南从闭式解原理到与 SVR 的实战对比【免费下载链接】scikit-learnscikit-learn: machine learning in Python项目地址: https://gitcode.com/gh_mirrors/sc/scikit-learn导读内核岭回归Kernel Ridge RegressionKRR是 scikit-learn 中一类将经典岭回归Ridge Regression与核技巧kernel trick相结合的回归算法。它在核诱导的特征空间中学习线性函数从而在原始空间中获得非线性拟合能力。本文以 doc/modules/kernel_ridge.rst 为核心脉络结合 sklearn/kernel_ridge.py 源码、_solve_cholesky_kernel求解器实现与官方对比示例系统讲解 KRR 的数学原理、KernelRidge的完整参数语义、预计算核矩阵用法以及它与支持向量回归SVR在训练速度、预测速度与模型稀疏性上的关键差异。读完本文你将能熟练配置KernelRidge完成回归任务并能依据数据规模在 KRR 与 SVR 之间做出合理选型。内核岭回归是什么KRR 由 [M2012]Kevin P. Murphy 的《Machine Learning: A Probabilistic Perspective》第 14.4.3 节pp. 492-493提出其本质是带 L2 正则的最小二乘回归线性岭回归与核技巧的结合。它学习的是核与数据共同诱导的特征空间中的线性函数当使用非线性核时这一线性函数对应回原始空间便成为非线性函数。这是 doc/modules/kernel_ridge.rst 对 KRR 核心思想的精确定义也是整个sklearn.kernel_ridge模块的设计出发点。从模型形式上KernelRidge学习到的模型与支持向量回归SVRsklearn.svm.SVR完全相同两者的差别集中在损失函数KRR使用平方误差损失squared error loss配合 L2 正则SVR使用ε-不敏感损失ε-insensitive loss同样配合 L2 正则。损失函数的选择直接导致了两个关键的工程后果下文会分别从闭式解与稀疏性两个角度展开KernelRidge的拟合存在闭式解对中等规模数据集通常显著快于 SVRKRR 学习到的模型是**非稀疏dense**的因此在预测阶段往往比学会了稀疏模型的 SVR 更慢。在 sklearn/kernel_ridge.py 的类文档字符串docstring中这一段原理说明被原样复述说明用户指南与 API 文档在数学定义上保持一致是理解该估计器的最权威入口。KernelRidge 源码实现剖析类定义与参数约束KernelRidge定义在 sklearn/kernel_ridge.py 中继承自MultiOutputMixin, RegressorMixin, BaseEstimator因此天然具备 scikit-learn 估计器的fit/predict/score接口并且内置对多元回归multi-output regression的支持当y是形状为(n_samples, n_targets)的二维数组时可直接使用。其构造函数的完整签名为KernelRidge( alpha1, *, kernellinear, gammaNone, degree3, coef01, kernel_paramsNone, )与参数一一对应的校验规则定义在_parameter_constraintssklearn/kernel_ridge.pyalphaInterval(Real, 0, None, closedleft)或 array-like即非负实数kernel必须是PAIRWISE_KERNEL_FUNCTIONS中的字符串键或precomputed也可以是可调用对象gamma非负实数或Nonedegree非负实数coef0实数kernel_params字典或None。PAIRWISE_KERNEL_FUNCTIONS字典定义于 sklearn/metrics/pairwise.py包含以下合法核字符串kernel 取值底层函数说明additive_chi2additive_chi2_kernel加法卡方核要求非负特征chi2chi2_kernel卡方核要求非负特征linearlinear_kernel线性核退化为线性岭回归polynomial/polypolynomial_kernel多项式核受degree、gamma、coef0控制rbfrbf_kernel高斯径向基核受gamma控制laplacianlaplacian_kernel拉普拉斯核受gamma控制sigmoidsigmoid_kernelSigmoid 核受gamma、coef0控制cosinecosine_similarity余弦相似度核precomputed—直接传入预计算的核矩阵参数语义结合源码alpha正则化强度默认1.0。正则化能够改善问题条件数conditioning并降低估计的方差取值越大正则越强。文档中特别指出alpha对应其他线性模型中1 / (2C)的角色例如LogisticRegression或LinearSVC中的C。当传入数组时表示对不同目标target使用不同的惩罚因此数组长度必须与目标数一致数学表达式参见Ridge的文档sklearn/linear_model/_ridge.py 中给出的目标函数||y - Xw||^2_2 alpha * ||w||^2_2。kernel核函数默认linear。该参数直接透传给pairwise_kernels。若为字符串必须是上述PAIRWISE_KERNEL_FUNCTIONS中的键或precomputed若为precomputedX被假定为核矩阵若为可调用对象它会对每对样本行调用并返回单个数值。注意sklearn.metrics.pairwise中的可调用对象操作的是矩阵而非单样本因此不能用作kernel的可调用值此时应改用标识该核的字符串。gamma默认None。RBF、Laplacian、polynomial、exponential chi2 与 sigmoid 核的 gamma 参数默认值的具体解释留给核函数自身其他核忽略此参数。degree默认3。多项式核的阶数其他核忽略。coef0默认1。多项式核与 sigmoid 核的零系数其他核忽略。kernel_params默认None。当kernel为可调用对象时以关键字参数形式传入核函数的附加参数。核矩阵构造_get_kernel核心私有方法_get_kernelsklearn/kernel_ridge.py负责构造核矩阵def _get_kernel(self, X, YNone): if callable(self.kernel): params self.kernel_params or {} else: params {gamma: self.gamma, degree: self.degree, coef0: self.coef0} return pairwise_kernels(X, Y, metricself.kernel, filter_paramsTrue, **params)可以推断其关键设计当kernel为字符串时gamma/degree/coef0三个参数会一并传给pairwise_kernels并由filter_paramsTrue自动过滤掉当前核不使用的参数当kernel为可调用对象时只透传kernel_params。因此gamma等参数对不相关核自动失效这一行为是filter_params机制的直接结果用户无需手动判断核的类型。fit 的闭式解流程fit方法sklearn/kernel_ridge.py的流程如下通过validate_data校验并转换输入支持(csr, csc)稀疏输入与多输出y若提供了sample_weight且不是单个浮点数调用_check_sample_weight校验调用self._get_kernel(X)构造训练核矩阵K将alpha转为至少一维数组若y是一维则重塑为(n_samples, 1)当kernel precomputed时置copyTrue随后调用_solve_cholesky_kernel(K, y, alpha, sample_weight, copy)求解对偶系数dual_coef_保存X_fit_并返回self。其中求解器_solve_cholesky_kernel位于 sklearn/linear_model/_ridge.py注释中直接写出了求解目标# dual_coef inv(X X^t alpha*Id) y即对偶系数的闭式解。其实现要点包括对核矩阵主对角线加上alpha[0]对应K alpha * I的岭项若所有alpha相同one_alpha可一次性求解多目标问题否则为每个目标分别求解使用linalg.solve(K, y, assume_apos, overwrite_aFalse)利用核矩阵的正定性求解若抛出LinAlgError例如alpha0导致奇异核矩阵则回退到最小二乘lstsq求解并发出Singular matrix in solving dual problem警告直接支持sample_weight通过sw sqrt(sample_weight)对y与核矩阵K做对称缩放这一分支之所以必须显式支持是因为K可能是预计算的核矩阵。对应地predictsklearn/kernel_ridge.py先检查是否已拟合再对新样本与X_fit_计算交叉核矩阵K self._get_kernel(X, self.X_fit_)最后执行np.dot(K, self.dual_coef_)得到预测值。训练得到的属性拟合完成后KernelRidge暴露以下属性dual_coef_形状(n_samples,)或(n_samples, n_targets)的核空间权重向量表示即闭式解中的对偶系数X_fit_训练数据预测时也必须保留当kernel precomputed时则为形状(n_samples, n_samples)的预计算训练核矩阵n_features_in_拟合时看到的特征数量0.24 版本起feature_names_in_当X的特征名全为字符串时记录特征名1.0 版本起。完整可运行的实战示例下面是一个最小可运行示例与 sklearn/kernel_ridge.py 文档字符串中的示例一致 from sklearn.kernel_ridge import KernelRidge import numpy as np n_samples, n_features 10, 5 rng np.random.RandomState(0) y rng.randn(n_samples) X rng.randn(n_samples, n_features) krr KernelRidge(alpha1.0) krr.fit(X, y) KernelRidge(alpha1.0)预计算核矩阵用法当kernelprecomputed时训练与预测阶段传入的X都应是核矩阵。测试用例 sklearn/tests/test_kernel_ridge.py 验证了如下等价关系——用pairwise_kernels(X, X, metrickernel)构造核矩阵后KernelRidge(kernelprecomputed).fit(K, y).predict(K)与KernelRidge(kernelkernel).fit(X, y).predict(X)的结果几乎一致assert_array_almost_equal。另一用例 sklearn/tests/test_kernel_ridge.py 还验证了预计算模式下传入的核矩阵不会被原地修改copyTrue的作用。预测阶段传入预计算核矩阵时其形状应为(n_samples, n_samples_fitted)其中n_samples_fitted是训练样本数。样本权重fit(X, y, sample_weightsw)支持按样本加权。测试用例 sklearn/tests/test_kernel_ridge.py 验证了带权重的KernelRidge(kernellinear)与Ridge(solvercholesky)结果一致且预计算核模式下同样支持。稀疏输入fit与predict均接受(csr, csc)稀疏矩阵通过accept_sparse与__sklearn_tags__中tags.input_tags.sparse True声明sklearn/tests/test_kernel_ridge.py 对 CSR/CSC 两种容器均有验证。多输出回归y形状为(n_samples, n_targets)时直接支持多目标预测sklearn/tests/test_kernel_ridge.py。与 SVR 的对比闭式解 vs 稀疏解损失函数差异这是 doc/modules/kernel_ridge.rst 反复强调的核心对比维度维度KernelRidgeSVR损失函数平方误差损失ε-不敏感损失正则化L2L2拟合方式闭式解矩阵求逆二次规划迭代优化模型稀疏性非稀疏所有样本参与预测稀疏仅支持向量参与预测ε 0 时拟合速度中等规模数据上更快大训练集上扩展性更好预测速度慢稠密计算快稀疏计算官方示例中的量化结论官方示例 examples/miscellaneous/plot_kernel_ridge_regression.py 构造了一个人造数据集正弦目标函数y sin(X)并对每第 5 个样本点叠加强噪声。示例包含三部分实验其结论与用户指南中的说明相互印证注意示例注释中的数字与用户指南略有出入应以后者即示例代码内最新注释为准模型对比对KernelRidge(kernelrbf, gamma0.1)用网格搜索优化alpha ∈ {1e0, 0.1, 1e-2, 1e-3}与gamma ∈ logspace(-2, 2, 5)对SVR(kernelrbf, gamma0.1)优化C ∈ {1e0, 1e1, 1e2, 1e3}与同样的gamma网格。两者学习到的函数非常相似但示例注释指出网格搜索下拟合 KRR 大约比 SVR 快 3-4 倍。训练/预测时间曲线对KernelRidge(kernelrbf, alpha0.01, gamma10)与SVR(kernelrbf, C1e2, gamma10)在sizes logspace(1, 3.8, 7)的 7 个训练规模下记录训练与预测时间。结论是KRR 在中等规模几千样本以内训练更快训练集更大时 SVR 扩展性更好预测阶段由于稀疏解SVR 理论上对任意规模都应更快——但示例也指出实际并非必然如此因为两者核函数计算的实现细节不同KRR 即便计算了更多算术运算也可能与 SVR 相当甚至更快。学习曲线使用LearningCurveDisplay对比SVR(kernelrbf, C1e1, gamma0.1)与KernelRidge(kernelrbf, alpha0.1, gamma0.1)在 100 个样本上的 MSE 学习曲线。用户指南 doc/modules/kernel_ridge.rst 对 SVR 稀疏性的表述是当 ε 0 时 SVR 学会稀疏模型示例中仅约 1/3 的训练样本被选为支持向量若 ε 0SVR 将对应稠密模型。因此 SVR 的稀疏程度、进而预测速度取决于其epsilon与C参数。选型建议基于官方文档中等规模训练集约 1000 样本以内优先考虑KernelRidge拟合更快大规模训练集或对预测延迟敏感、希望模型稀疏优先考虑SVR合理设置 ε 0需要不确定性估计或自动核超参数调优可考虑GaussianProcessRegressorKernelRidge的 See Also 推荐。小结与进一步探索KernelRidge是 scikit-learn 中将岭回归闭式解与核技巧结合的经典估计器它继承了线性岭回归的可解析求解特性又通过核函数获得非线性建模能力代价是模型非稀疏预测阶段需要遍历全部训练样本。与其最直接的对照是SVR两者模型形式一致、损失函数不同从而在训练速度、预测速度与稀疏性上形成互补。若希望深入验证本文的结论可在当前仓库中阅读 doc/modules/kernel_ridge.rst 获取权威用户指南阅读 sklearn/kernel_ridge.py 查看完整实现与 docstring查看 sklearn/linear_model/_ridge.py 中对偶问题 Cholesky 求解器实现运行 examples/miscellaneous/plot_kernel_ridge_regression.py 复现 KRR 与 SVR 的对比实验阅读 sklearn/tests/test_kernel_ridge.py 了解线性核与Ridge的等价性、预计算核、样本权重、稀疏与多输出等测试覆盖。此外KernelRidge的 See Also 还推荐了Ridge线性岭回归、RidgeCV带内置交叉验证的岭回归、GaussianProcessRegressor提供核超参数自动调优与预测不确定性可作为不同需求下的替代方案继续探索。参考文献Kevin P. Murphy,Machine Learning: A Probabilistic Perspective, chapter 14.4.3, pp. 492-493, The MIT Press, 2012。【免费下载链接】scikit-learnscikit-learn: machine learning in Python项目地址: https://gitcode.com/gh_mirrors/sc/scikit-learn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考