前言
线性回归只能拟合线性曲面(广义曲面)。如果回归任务中的输出变量
1. 局部加权线性回归模型
当两个样本点的特征向量相近时,它们的输出变量通常相近,即具有相似的性质。现在我们有
首先应该想一想,我们怎样衡量距离呢?欧氏距离(2范数)是一种常用的衡量方式,即:
我们使用以下公式为训练集中的第
这里显得很突兀。不知道为什么,直接给了这样一个公式。我不知道为什么。该算法经常使用这样的函数来赋予权重。对于那些不想深入理论研究的人,我认为是形而上学。酒吧!当然,这绝对不是形而上学。这样做应该有一定的理论基础,但我暂时不明白。
对于一个给定的特征向量作为输入,我们想要预测它的输出变量,使用下面的加权损失函数:
这很自然,它是一个简单的加权求和。当最小化这样一个损失函数时,算法肯定会寻求使样本点的损失越接近
其中权重矩阵
优化这个损失函数的过程就是算法的训练过程。在优化这个损失函数之后,参数
2. 求解方法
梯度下降法是一种很常见的优化方法。当然这里也可以使用梯度下降法。主要目的是解决损失函数的梯度。求解梯度其实就是求导,求导:
这样,也可以使用梯度下降法。我不会在这里多说。只看正规方程的方法,令其导数为
值得注意的是,局部加权线性回归的时间成本非常高,因为对于每一个需要预测的点,我们都需要对应的权重矩阵并单独训练。普通的线性回归算法只需要训练一次就可以预测所有的点。
局部加权线性回归的优点是它几乎可以拟合任何形状。只要选择合适的超参数
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()
拟合曲线如下:
只要选择合适的超参数
文章出处登录后可见!