本文核岭回归原理部分参考《数据挖掘——使用机器学习工具与技术》(原书第四版)一书7.2.4节。
核岭回归(Kernel Ridge Regression)
线性回归
对于普通的线性回归,我们在训练的时候是最小化平方误差损失函数:
∑
i
=
1
n
(
y
i
−
W
x
i
⃗
)
2
\sum_{i=1}^n (y_i-W\vec {x_i})^2
i=1∑n(yi−Wxi)2
其中W为参数矩阵。接下来我们要依次为线性回归加上“核”和“岭”。
添加“核”
对于一个给定测试样例,即我们训练好模型后打算预测结果的一个样例,线性回归模型的预测值表示为所有属性值的加权和(假设bias为0)。在加上“核”后,损失函数的形式变为:
∑
i
=
1
n
(
y
i
−
ψ
(
x
i
⃗
)
)
2
\sum_{i=1}^n(y_i-\psi(\vec {x_i}))^2
i=1∑n(yi−ψ(xi))2
其中
ψ
(
x
i
⃗
)
\psi(\vec {x_i})
ψ(xi)的含义为训练样例
x
i
⃗
\vec {x_i}
xi与每个用于训练的样例的核函数结果的加权和。每个训练样例
x
j
⃗
\vec {x_j}
xj都包含一个系数
α
j
\alpha_j
αj。因此损失函数可以展开为:
∑
i
=
1
n
(
y
i
−
∑
j
=
1
n
α
j
κ
(
x
j
⃗
,
x
i
⃗
)
)
2
\sum_{i=1}^n(y_i-\sum_{j=1}^n\alpha_j\kappa(\vec {x_j}, \vec {x_i}))^2
i=1∑n(yi−j=1∑nαjκ(xj,xi))2
这是二次损失函数,我们通过选择合适的
α
j
\alpha_j
αj使它达到最小值。但是,每个训练样例都会有一个系数,而不是每个属性对应一个系数,并且大多数数据集中样例的数量要远远大于属性的数量。这意味着当使用核函数获得非线性模型时,将会有很大的对训练数据过拟合的风险。因此我们要通过引入惩罚项,即正则化项,在拟合程度和模型复杂度之间进行权衡。
添加“岭”
添加“岭”其实就是添加正则化项,因为岭回归本质上就是在线性回归的基础上添加了一个L2正则化。添加正则化项之后,损失函数变为:
∑
i
=
1
n
(
y
i
−
∑
j
=
1
n
α
j
κ
(
x
j
⃗
,
x
i
⃗
)
)
2
+
λ
∥
ψ
∥
H
\sum_{i=1}^n(y_i-\sum_{j=1}^n\alpha_j\kappa(\vec {x_j}, \vec {x_i}))^2+\lambda∥\psi∥_ℋ
i=1∑n(yi−j=1∑nαjκ(xj,xi))2+λ∥ψ∥H
公式中第二个求和部分会惩罚大的系数,这会防止模型为单个训练样例赋予很大的权值而过于强调单个训练样例的作用,除非这会导致训练误差明显增大。参数
λ
\lambda
λ控制拟合程度和模型复杂度之间的权衡。
H
ℋ
H是希尔伯特空间(Hilbert space),
∥
⋅
∥
H
∥⋅∥_ℋ
∥⋅∥H是在希尔伯特空间下的2范式。
将正则化项展开,损失函数可以变化成如下形式:
∑
i
=
1
n
(
y
i
−
∑
j
=
1
n
α
j
κ
(
x
j
⃗
,
x
i
⃗
)
)
2
+
λ
∑
i
=
1
n
∑
j
=
1
n
α
i
α
j
κ
(
x
j
⃗
,
x
i
⃗
)
\sum_{i=1}^n(y_i-\sum_{j=1}^n\alpha_j\kappa(\vec {x_j}, \vec {x_i}))^2+\lambda\sum_{i=1}^n\sum_{j=1}^n\alpha_i\alpha_j\kappa(\vec {x_j}, \vec {x_i})
i=1∑n(yi−j=1∑nαjκ(xj,xi))2+λi=1∑nj=1∑nαiαjκ(xj,xi)
最后,由
α
1
,
α
2
,
…
,
α
n
\alpha_1, \alpha_2, …, \alpha_n
α1,α2,…,αn组成的向量
α
⃗
\vec \alpha
α的表达式为:
α
⃗
=
(
λ
I
+
K
)
y
⃗
\vec \alpha=(\lambda I+\Kappa)\vec y
α=(λI+K)y
其中
K
\Kappa
K是
n
×
n
n\times n
n×n的矩阵,
K
n
,
m
=
κ
(
x
n
⃗
,
x
m
⃗
)
\Kappa_{n,m}=\kappa(\vec {x_n}, \vec {x_m})
Kn,m=κ(xn,xm)。
y
⃗
\vec y
y是由
n
n
n个标签组成的向量。
与线性回归的比较
在典型的样例数多于属性数的情况下,核岭回归的计算成本要比标准线性回归高,这是因为要得到模型的系数向量需要使用矩阵求逆操作。标准线性回归需要求一个 m × m m\times m m×m矩阵的逆,复杂度为 O ( m 3 ) O(m^3) O(m3),其中 m m m为数据中属性的数量。核岭回归则需要 n × n n\times n n×n矩阵的逆,复杂度为 O ( n 3 ) O(n^3) O(n3),其中 n n n为训练样例中样例的个数。然而,在需要进行非线性拟合或者属性比训练样例多的情况下,使用核岭回归还是有优势的。
sklearn.kernel_ridge.KernelRidge
可以通过sklearn的官方文档学习用法,函数的参数都在官方文档中。
以使用参数为
σ
\sigma
σ的高斯核的核岭回归为例:
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)
sigma = 5
clf = KernelRidge(alpha=1.0, kernel='rbf', gamma=sigma ** -2)
clf.fit(X, y)
为什么kernel参数传入的是’rbf’?为什么要传入
σ
−
2
\sigma^{-2}
σ−2给gamma参数呢?
通过阅读源码发现,传给kernel参数的字符串必须是sklearn.metrics.pairwise.PAIRWISE_KERNEL_FUNCTIONS中定义的metric。具体定义的metric有:
其中的rbf在文档中的描述如下:
The function rbf_kernel computes the radial basis function (RBF) kernel between two vectors. This kernel is defined as:
k
(
x
,
y
)
=
e
x
p
(
−
γ
∥
x
−
y
∥
2
)
k(x,y)=exp(-\gamma∥x-y∥^2)
k(x,y)=exp(−γ∥x−y∥2)
where x
and y
are the input vectors. If
γ
=
σ
−
2
\gamma=\sigma^{-2}
γ=σ−2 the kernel is known as the Gaussian kernel of variance
σ
−
2
\sigma^{-2}
σ−2.
因此rbf kernel其实就是变形后的Gaussian kernel。