使用Python 的局部加权线性回归
局部加权线性回归是结合基于 k 最近邻的机器学习的非参数回归方法。它被称为局部加权,因为对于查询点,函数是基于附近的数据来近似的,并且加权是因为贡献是由它与查询点的距离加权的。
局部加权回归 (LWR) 是一种非参数、基于内存的算法,这意味着它明确保留训练数据并在每次进行预测时使用它。
要解释局部加权线性回归,我们首先需要了解线性回归。线性回归可以用以下等式来解释:
让 (x i , y i ) 作为查询点,然后为了最小化线性回归中的成本函数:
通过计算 所以,它最小化上述成本函数。我们的输出将是:
因此,计算 \theta 的公式也可以是:
其中,beta 是线性向量的向量,X,Y 是矩阵,所有观测值的向量。
对于局部加权线性回归:
通过这样计算,它可以最小化上述成本函数。我们的输出将是:
这里, w(i)是与每个训练数据观察相关的权重。可以通过给定的公式计算:
或者这可以用矩阵计算的形式表示:
其中x(i)是训练数据的观测值,x 是计算距离的特定点, T(tau)是带宽。这里,T(tau) 决定了函数的适应度,如果函数是紧密拟合的,它的值会很小。所以,
然后,我们可以使用以下等式计算 \theta:
执行
- 对于这个实现,我们将使用散景。如果您想详细了解散景功能,请查看这篇文章
Python3
# Necessary imports
import numpy as np
from ipywidgets import interact
from bokeh.plotting import figure, show, output_notebook
from bokeh.layouts import gridplot
%matplotlib inline
output_notebook()
plt.style.use('seaborn-dark')
# function to perform lcally weighted linear regression
def local_weighted_regression(x0, X, Y, tau):
# add bias term
x0 = np.r_[1, x0]
X = np.c_[np.ones(len(X)), X]
# fit model: normal equations with kernel
xw = X.T * weights_calculate(x0, X, tau)
theta = np.linalg.pinv(xw @ X) @ xw @ Y
# "@" is used to
# predict value
return x0 @ theta
# function to perform weight calculation
def weights_calculate(x0, X, tau):
return np.exp(np.sum((X - x0) ** 2, axis=1) / (-2 * (tau **2) ))
# plot locally weighted regression for different bandwidth values
def plot_lwr(tau):
# prediction
domain = np.linspace(-3, 3, num=300)
prediction = [local_regression(x0, X, Y, tau) for x0 in domain]
plot = figure(plot_width=400, plot_height=400)
plot.title.text = 'tau=%g' % tau
plot.scatter(X, Y, alpha=.3)
plot.line(domain, prediction, line_width=2, color='red')
return plot
#define distribution
n = 1000
# generate dataset
X = np.linspace(-3, 3, num=n)
Y = np.abs(X ** 3 - 1)
# jitter X
X += np.random.normal(scale=.1, size=n)
# show the plots for different values of Tau
show(gridplot([
[plot_lwr(10.), plot_lwr(1.)],
[plot_lwr(0.1), plot_lwr(0.01)]
]))
- 从上图中我们可以注意到,带宽值较小时,模型拟合得更好,但有时会导致过度拟合。
参考:
- 斯坦福 CS 229