【机器学习】用QR分解求最小二乘法的最优闭式解

写在前面

今天刷知乎,看到张皓在面试官如何判断面试者的机器学习水平?的回答里面讲到了关于用矩阵的QR分解求解最小二乘法闭式解的问题,碰巧前几天《矩阵分析》课堂上刚讲到QR分解,觉得挺有意思,值得深究,遂产生写本篇博文的动机。另外本人知识水平理解能力有限,如有错漏请各位大侠批评指正。

QR分解

先来看看维基百科上怎么说:

QR分解法是三种将矩阵分解的方式之一。这种方式,把矩阵分解成一个半正交矩阵与一个上三角矩阵的积。QR分解经常用来解线性最小二乘法问题。QR分解也是特定特征值算法即QR算法的基础。

定义

实数矩阵的QR分解是把矩阵A分解为:
在这里插入图片描述
这里的Q是正交矩阵(意味着QTQ = E)而R是上三角矩阵(即矩阵R的对角线下面的元素全为0)。为了便于理解,这里引用一下daniel-D的图:
Q是mxm的正交矩阵,R是mxn的上三角矩阵
这个将A分解成这样的矩阵Q和R的过程就是QR分解,QR分解可用于求解矩阵A的特征值、A的逆等问题。具体参考血影雪梦大神的博文。

QR的求解

QR 分解的实际计算有很多方法,例如 Givens 旋转、Householder 变换,以及 Gram-Schmidt 正交化等等。每一种方法都有其优点和不足。对于QR分解的求解这里不再展开论述,在python中可以用numpy库实现:

import numpy as np
Q, R = np.linalg.qr(A)

线性回归模型

给定数据集 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) } D=\{(\boldsymbol x_1,y_1),(\boldsymbol x_2,y_2),...,(\boldsymbol x_m,y_m)\} D={(x1,y1),(x2,y2),...,(xm,ym)}其中 x i = ( x i 1 ; x i 2 ; . . . ; x i d ) , y i ∈ R \boldsymbol x_i=(x_{i1};x_{i2};...;x_{id}),y_i\in\mathbb R xi=(xi1;xi2;...;xid),yiR.即样本由 d d d个属性描述。“线性回归”(linear regression)试图学得一个线性模型以尽可能准确地预测实值输出标记。
线性回归试图学得的模型为: f ( x i ) = w T x i + b , 使 得 f ( x i ) ≃ y i f(\boldsymbol x_i)=\boldsymbol w^T\boldsymbol x_i+b, 使得f(\boldsymbol x_i)\simeq y_i f(xi)=wTxi+b,使f(xi)yi
这称为“多元线性回归”(multivariate linear regression)
可以利用最小二乘法来对参数 w 和 b \boldsymbol w和b wb进行估计。我们知道均方误差是回归任务中最常用的性能度量,即通常所说的损失函数,这里的损失函数可以表示为:
J ( w , b ) = 1 2 ∑ i = 1 m ( f ( x i ) − y i ) 2 = 1 2 ∑ i = 1 m ( y i − w x i − b ) 2 J(\boldsymbol w,b)=\frac{1}{2} \sum_{i=1}^m (f(\boldsymbol x_i)-y_i)^2 = \frac{1}{2} \sum_{i=1}^m(y_i-\boldsymbol wx_i-b)^2 J(w,b)=21i=1m(f(xi)yi)2=21i=1m(yiwxib)2
因此我们可试图让均方误差最小化,求出最优闭式解,即
( w ∗ , b ∗ ) = arg ⁡ m i n ( w , b ) J ( w , b ) (\boldsymbol w^*,b^*) = \arg min_{(\boldsymbol w,b)} J(\boldsymbol w,b) (w,b)=argmin(w,b)J(w,b)
在处理大型数据集时,我们一般都把参数和训练数据进行向量化(vectorization),即吸入矩阵中,再对矩阵进行计算,数据的向量化能给计算速度带来非常大的提升。具体做法是:对于训练参数,把 w 和 b 吸 收 入 向 量 形 式 w ^ = ( b ; w ) \boldsymbol w和b吸收入向量形式\hat \boldsymbol w=(b; \boldsymbol w) wbw^=(b;w),即在列向量 w \boldsymbol w w的第一个元素前插入偏置项 b b b,此时的参数 w ^ \hat \boldsymbol w w^变成 ( d + 1 ) × 1 (d+1)\times 1 (d+1)×1的列向量;即
w ^ = [ b w 1 ⋮ w d ] \hat \boldsymbol w= \begin{bmatrix} b \\ w_1 \\ \vdots \\ w_d \end{bmatrix} w^=bw1wd
对于训练数据集 D D D,我们把 D D D吸入一个 m × ( d + 1 ) m\times(d+1) m×(d+1)大小的矩阵 X \boldsymbol X X中,矩阵 X \boldsymbol X X的第一列用全为1的元素填充,即
X = [ 1 x 11 ⋯ x 1 d 1 x 21 ⋯ x 2 d ⋮ ⋮ ⋱ ⋮ 1 x m 1 ⋯ x m d ] = [ 1 x 1 T 1 x 2 T ⋮ ⋮ 1 x m T ] \boldsymbol X=\begin{bmatrix} 1 &x_{11} & \cdots & x_{1d} \\ 1 &x_{21} & \cdots & x_{2d} \\ \vdots & \vdots &\ddots & \vdots \\ 1 &x_{m1} & \cdots & x_{md} \end{bmatrix}= \begin{bmatrix} 1 &\boldsymbol x_1^T \\ 1 &\boldsymbol x_2^T \\ \vdots & \vdots \\ 1 &\boldsymbol x_m^T \end{bmatrix} X=111x11x21xm1x1dx2dxmd=111x1Tx2TxmT
相应地,我们也把标记(label)写成向量形式:
y = [ y 1 y 2 ⋮ y m ] \boldsymbol y= \begin{bmatrix} y_1 \\ y_2 \\ \vdots \\ y_m \end{bmatrix} y=y1y2ym
至此,所有数据已经向量化完。经过向量化后,线性回归模型的损失函数可表示为:
J ( w , b ) = J ( w ^ ) = 1 2 ( X w ^ − y ) T ( X w ^ − y ) J(\boldsymbol w, b) =J(\hat \boldsymbol w) =\frac{1}{2}(\boldsymbol X \hat \boldsymbol w-\boldsymbol y)^T(\boldsymbol X \hat \boldsymbol w - \boldsymbol y) J(w,b)=J(w^)=21(Xw^y)T(Xw^y)
J ( w ^ ) J(\hat\boldsymbol w) J(w^)对参数 w ^ \hat\boldsymbol w w^进行求导:
∂ J ( w ^ ) ∂ w ^ = X T ( X w ^ − y ) \frac{\partial J(\hat\boldsymbol w)}{\partial \hat\boldsymbol w}=\boldsymbol X^T(\boldsymbol X \hat\boldsymbol w - \boldsymbol y) w^J(w^)=XT(Xw^y)
令导数为零即可得到最优闭式解
w ^ ∗ = ( X T X ) − 1 X T y \hat\boldsymbol w^* = (\boldsymbol X^T \boldsymbol X)^{-1} \boldsymbol X^T \boldsymbol y w^=(XTX)1XTy
重点来了,那么我们怎样才能高效求解这个 w ^ ∗ \hat\boldsymbol w^* w^ 呢?

下面介绍的内容才是本篇文章的核心

用QR分解求解最优闭式解

本文的前面已经介绍过QR分解的定义与求法了,这里我们直接应用。
根据QR分解的定义,我们可以将训练集矩阵 X \boldsymbol X X分解为
X = Q R \boldsymbol X = QR X=QR
代入上面的最优闭式解的式子得到
w ^ ∗ = ( X T X ) − 1 X T y ⇒ X T X w ^ ∗ = X T y ⇒ R T Q T Q R w ^ ∗ = R T Q T y ⇒ R T R w ^ ∗ = R T Q T y ⇒ R w ^ ∗ = Q T y ⇒ w ^ ∗ = R − 1 Q T y \begin{array}{lcl} \quad \quad \hat\boldsymbol w^* = (\boldsymbol X^T \boldsymbol X)^{-1} \boldsymbol X^T \boldsymbol y\\ \\ \Rightarrow \quad \boldsymbol X^T \boldsymbol X \hat\boldsymbol w^* = \boldsymbol X^T \boldsymbol y\\ \\ \Rightarrow \quad R^T Q^T Q R \hat\boldsymbol w^* = R^T Q^T \boldsymbol y\\ \\ \Rightarrow \quad R^T R \hat \boldsymbol w^*=R^T Q^T \boldsymbol y\\ \\ \Rightarrow \quad R \hat \boldsymbol w^* = Q^T \boldsymbol y \\ \\ \Rightarrow \quad \hat\boldsymbol w^* = R^{-1} Q^T \boldsymbol y \end{array} w^=(XTX)1XTyXTXw^=XTyRTQTQRw^=RTQTyRTRw^=RTQTyRw^=QTyw^=R1QTy

至此,我们已经用QR分解求得了最优闭式解的表达式。可以看到,仅需知道Q和R就能求出最小二乘法的最优闭式解,so easy!

看到这里可能有的人就要问了,为什么不直接用 w ^ ∗ = ( X T X ) − 1 X T y \hat\boldsymbol w^* = (\boldsymbol X^T \boldsymbol X)^{-1} \boldsymbol X^T \boldsymbol y w^=(XTX)1XTy进行最优闭式解的求解呢?用上面这种解法有什么好处?
解答这个问题,要从矩阵的条件数说起。

矩阵的条件数

先说一下矩阵的奇异值分解
我们知道对于任意 m × n m\times n m×n 的矩阵 X \boldsymbol X X,均可以进行奇异值分解: X = U Σ V H \boldsymbol X =U \Sigma V^H X=UΣVH,其中 U U U m × m m \times m m×m阶的酉矩阵, Σ \Sigma Σ m × n m \times n m×n阶非负实数对角矩阵,而 V H V^H VH,即 V V V的共轭转置,是 n × n n \times n n×n阶的酉矩阵。 Σ \Sigma Σ对角线上的元素 σ i \sigma_i σi就是矩阵 X \boldsymbol X X的奇异值。

对于条件数,维基百科这样说:

“数值分析中,一个问题的条件数是该数量在数值计算中的容易程度的衡量,也就是该问题的适定性。一个低条件数的问题称为良置的,而高条件数的问题称为病态(或者说非良置)的”

上面这句话可能不太好理解,我们只要记住这一点就行:通常情况下,矩阵的条件数越低越好。由于计算机的计算不是精确的,条件数越高,计算精度的误差对解的影响也越大。
矩阵 X \boldsymbol X X的条件数定义为:
κ ( X ) = ∥ X − 1 ∥ ⋅ ∥ X ∥ \boldsymbol \kappa(\boldsymbol X) = \left \| \boldsymbol X^{-1} \right \| \cdot \| \boldsymbol X \| κ(X)=X1X
∥ ⋅ ∥ \| \cdot \| 是矩阵2范数,则 κ ( X ) = σ max ⁡ ( X ) σ min ⁡ ( X ) \boldsymbol \kappa(\boldsymbol X) =\frac{ \boldsymbol \sigma _{\max} (\boldsymbol X)}{\boldsymbol \sigma _{\min} (\boldsymbol X)} κ(X)=σmin(X)σmax(X)
其中 σ max ⁡ ( X ) \boldsymbol \sigma _{\max} (\boldsymbol X) σmax(X) σ min ⁡ ( X ) \boldsymbol \sigma _{\min} (\boldsymbol X) σmin(X)分别是矩阵 X \boldsymbol X X的极大极小奇异值。
回到上面最优闭式解的求解的问题,如果我们直接拿 w ^ ∗ = ( X T X ) − 1 X T y \hat\boldsymbol w^* = (\boldsymbol X^T \boldsymbol X)^{-1} \boldsymbol X^T \boldsymbol y w^=(XTX)1XTy进行求解,其条件数:
κ ( X T X ) = κ ( V Σ T U T U Σ V H ) = κ ( V Σ 2 V H ) = κ ( X ) 2 \boldsymbol \kappa(\boldsymbol X^T \boldsymbol X) = \boldsymbol\kappa (V \Sigma^T U^T U \Sigma V^H) =\boldsymbol \kappa (V \Sigma ^2 V^H) = \boldsymbol \kappa (\boldsymbol X)^2 κ(XTX)=κ(VΣTUTUΣVH)=κ(VΣ2VH)=κ(X)2
也就是说,矩阵 X T X \boldsymbol X^T \boldsymbol X XTX的条件数是矩阵 X \boldsymbol X X条件数的平方!这和我们想要条件数尽量低的愿望相违背。而使用QR分解将闭式解的求解等价为解 R w ^ ∗ = Q T y R \hat \boldsymbol w^* = Q^T \boldsymbol y Rw^=QTy,这就巧妙的绕过了条件数被平方的操作。

实验

我们将这种解法应用到吴恩达的《机器学习》课程上的房价预测的数据集上。这里直接放出代码

import numpy as np
import matplotlib.pyplot as plt



if __name__ == '__main__':

    data = np.loadtxt('ex1data1.txt', delimiter=',')  # load data
    X = data[:, 0]
    y = data[:, 1]  # 注意这里得到的y的shape为(m, ),要把它reshape为(m,1)
    y = np.reshape(y, (y.shape[0], 1))
    
    plt.scatter(X, y, marker='x', c='r')
    # 在X的第一列之前插入元素全为1的列
    X = np.column_stack(
        (np.ones((X.shape[0], 1)), np.reshape(X, (X.shape[0], 1))))
    #QR分解
    Q, R = np.linalg.qr(X)
    w = np.linalg.linalg.inv(R).dot(Q.T).dot(y)
    print(w)
    plt.plot(X[:, 1], np.dot(X, w), '-')
    plt.show()

运行结果

w = [-3.895, 1.193]
在这里插入图片描述

完。

Refrences:
《机器学习》周志华
https://www.cnblogs.com/daniel-D/p/3208534.html
https://www.zhihu.com/people/hao-zhang-0214/activities
https://blog.csdn.net/u014046022/article/details/78877369?utm_source=blogxgwz3
https://zh.wikipedia.org/wiki/%E6%9D%A1%E4%BB%B6%E6%95%B0
https://zh.wikipedia.org/wiki/%E9%85%89%E7%9F%A9%E9%98%B5
https://zh.wikipedia.org/wiki/QR%E5%88%86%E8%A7%A3

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值