(三)局部加权线性回归


前言

​ 线性回归只能拟合线性曲面(广义的曲面),如果一个回归任务中的输出变量 y    ( y ∈ R ) y\,\,\left( y\in \mathbb{R} \right) y(yR) 关于特征向量 x = ( x 0 , x 1 , ⋯   , x n )    ( x ∈ R n + 1 , x 0 = 1 ) x=\left( x_0,x_1,\cdots ,x_n \right) \,\,\left( x\in \mathbb{R} ^{n+1},x_0=1 \right) x=(x0,x1,,xn)(xRn+1,x0=1) 不是线性的,那怎样拟合可以比较好呢?局部加权线性回归是一种方法。

1. 局部加权线性回归模型

​ 当两个样本点的特征向量距离较近时,它们的输出变量通常比较接近,也就是说它们具有相似的性质。现在我们有 m m m 个训练样本点 ( x ( 1 ) , y ( 1 ) ) , ( x ( 2 ) , y ( 2 ) ) , ⋯   , ( x ( m ) , y ( m ) ) \left( x^{\left( 1 \right)},y^{\left( 1 \right)} \right) ,\left( x^{\left( 2 \right)},y^{\left( 2 \right)} \right) ,\cdots ,\left( x^{\left( m \right)},y^{\left( m \right)} \right) (x(1),y(1)),(x(2),y(2)),,(x(m),y(m)) 构成训练集。那么当我们给一个特征向量 x x x 时,要根据训练集中的信息预测出它的输出变量 y y y ,距离 x x x 越近的训练集中的样本点越应该被重视。换句话说,我们需要给训练集中的每个样本点一个权值,距离 x x x 越近的样本点的权值应该越大,这是赋权的一个原则,那么具体应该如何赋权呢?

​ 首先应该想一想,我们怎样衡量距离呢?欧氏距离(2范数)是一种常用的衡量方式,即:
d i s t ( x , x ( i ) ) = ∥ x − x ( i ) ∥ 2 dist\left( x,x^{\left( i \right)} \right) =\left\| x-x^{\left( i \right)} \right\| _2 dist(x,x(i))=xx(i)2
我们用下面的公式给训练集中第 i i i 样本点赋权值:
w i = exp ⁡ ( − ∥ x − x ( i ) ∥ 2 2 2 σ 2 ) w_i=\exp \left( -\frac{\left\| x-x^{\left( i \right)} \right\| _{2}^{2}}{2\sigma ^2} \right) wi=exp(2σ2xx(i)22)
这里似乎很突兀,还不知道为什么,直接就给出了这样的公式,我也不太清楚为什么,这个算法经常使用这样的函数来赋权,对于不是很想深入理论研究的我姑且认为是玄学吧!当然肯定不是玄学,这样做应该是有一定理论依据的,不过我就暂时不了解了。

​ 对于给定的特征向量作为输入,我们要预测它的输出变量,使用下面的经过加权处理后的损失函数:
J ( θ ) = 1 2 ∑ i = 1 m w i ( h θ ( x ( i ) ) − y ( i ) ) 2 J\left( \theta \right) =\frac{1}{2}\sum_{i=1}^m{w_i\left( h_{\theta}\left( x^{\left( i \right)} \right) -y^{\left( i \right)} \right) ^2} J(θ)=21i=1mwi(hθ(x(i))y(i))2
这里还是挺自然的,就是一个简单的加权求和,最小化这样的损失函数时,算法肯定会寻找使得距离 x x x 越近的样本点的损失越小 θ \theta θ ,也就是说算法更加重视了那些距离 x x x 近的点,这也有利于更准确地预测 y y y 。该函数使用矩阵的方式写出来就是:
J ( θ ) = 1 2 ( X θ − y ) T W ( X θ − y ) J\left( \theta \right) =\frac{1}{2}\left( X\theta -y \right) ^TW\left( X\theta -y \right) J(θ)=21(Xθy)TW(Xθy)
其中权值矩阵 W = d i a g ( w 1 , w 2 , ⋯   , w m ) W=\mathrm{diag}\left( w_1,w_2,\cdots ,w_m \right) W=diag(w1,w2,,wm)

​ 优化这个损失函数的过程就是该算法的训练过程。优化这个损失函数后,就可以使用得到参数 θ \theta θ ,进而使用 h θ ( x ) h_{\theta}\left( x \right) hθ(x) 预测输出变量 y y y 。 如果我们有 K K K 个特征向量需要被预测,记这 K K K 个特征向量为 x ( m + 1 ) , x ( m + 2 ) , ⋯   , x ( m + K ) x^{\left( m+1 \right)},x^{\left( m+2 \right)},\cdots ,x^{\left( m+K \right)} x(m+1),x(m+2),,x(m+K) ,那么对于每一个特征向量 x ( m + i )    ( 1 ⩽ i ⩽ K ) x^{\left( m+i \right)}\,\,\left( 1\leqslant i\leqslant K \right) x(m+i)(1iK) 我们都要计算一次权值矩阵,然后然后优化损失函数得到 θ \theta θ ,进而预测输出变量 y ( m + i ) y^{\left( m+i \right)} y(m+i)

2. 求解方法

​ 梯度下降法是一种很常用的优化方法,这里当然也可以使用梯度下降法,主要就是求解出损失函数的梯度,求解梯度实际上也就是求导数,对其求导:
∂ J ( θ ) ∂ θ = X T W ( X θ − y ) = X T W X θ − X T W y \frac{\partial J\left( \theta \right)}{\partial \theta}=X^TW\left( X\theta -y \right) =X^TWX\theta -X^TWy θJ(θ)=XTW(Xθy)=XTWXθXTWy
这样也就可以使用梯度下降法了,这里就不多说了,直接看正规方程的方法,令其导数为 0 0 0 可以解出该函数的极小值点:
θ = ( X T W X ) − 1 X T W y \theta =\left( X^TWX \right) ^{-1}X^TWy θ=(XTWX)1XTWy
​ 值得注意的是,局部加权线性回归时间代价十分高,因为对于每一个需要预测的点,我们都要求出相对应的权值矩阵并且单独训练。而普通的线性回归算法只需要训练一次即可预测所有的点。

​ 局部加权线性回归的好处就是它几乎可以拟合任意形状,只要超参数 σ \sigma σ 选取合适,那么该算法可以拟合的较好。实际生活中,数据的输出变量和特征向量是线性关系的情况不多,因此纯线性回归模型可能适用性不强,但是局部加权线性回归可以对非线性的数据分布做出较好的拟合。

3. 代码实现

​ 写出局部加权线性回归函数。

import numpy as np

def calweight(a, b): # 求解权值的函数
    sigma = 0.3
    return np.exp(-np.linalg.norm(a-b)**2 / (2*sigma**2))

def LWLR(X_train, y_train, X_test): # 局部加权线性回归
    X_train = np.insert(X_train,0,1,axis=1)
    X_test = np.insert(X_test, 0, 1, axis = 1)
    y_pred = np.empty(X_test.shape[0]) # 预测值
    
    for k in range(X_test.shape[0]): # 对所有的需要预测的特征向量先训练再预测
        # 求解权值矩阵   
        w = np.empty(X_train.shape[0])
        for i in range(X_train.shape[0]):
            w[i] = calweight(X_test[k], X_train[i])
        W = np.diag(w) #权值矩阵
        
        theta=np.dot(np.linalg.pinv(np.dot(np.dot(X_train.T,W),X_train)),np.dot(np.dot(X_train.T,W),y_train))
        y_pred[k] = np.dot(theta,X_test[k]) # 预测
        
    return y_pred

​ 创造数据,使用该函数拟合回归曲线。

import matplotlib.pyplot as plt

def CreateData():
    X = np.arange(0,10,0.1)
    y = np.empty(X.shape[0])
    for i in range(X.shape[0]):
        y[i] = X[i]**3 - 10*X[i]**2 + X[i] + np.random.uniform(-10,10)
    return X[:,np.newaxis], y

np.random.seed(0)
X, y = CreateData()
plt.scatter(X, y) # 可视化
X_test = np.arange(0.05,10,0.1) #测试集,目的是通过其画出拟合曲线
X_test = X_test[:,np.newaxis]
y_pred = LWLR(X, y, X_test)
plt.plot(X_test, y_pred, color='red') # 画出拟合曲线
plt.show()

​ 拟合曲线如下:

σ = 2 \sigma=2 σ=2 ,欠拟合
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WzORBBCH-1649518311531)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220409232637020.png)]

σ = 1 \sigma=1 σ=1 ,感觉在底部稍微有点欠拟合
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0XDdB77Z-1649518311532)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220409232613867.png)]

σ = 0.5 \sigma=0.5 σ=0.5 ,拟合效果不错
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7vrHO9ef-1649518311533)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220409232833861.png)]

σ = 0.1 \sigma=0.1 σ=0.1 ,有些过拟合
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZcBEpWDs-1649518311533)(C:\Users\Lenovo\AppData\Roaming\Typora\typora-user-images\image-20220409232553246.png)]

​ 只要超参数 σ \sigma σ 选取合适,很多情况下都会有较好的拟合效果。

  • 5
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值