📜  使用Python 的局部加权线性回归

📅  最后修改于: 2022-05-13 01:58:09.228000             🧑  作者: Mango

使用Python 的局部加权线性回归

局部加权线性回归是结合基于 k 最近邻的机器学习的非参数回归方法。它被称为局部加权,因为对于查询点,函数是基于附近的数据来近似的,并且加权是因为贡献是由它与查询点的距离加权的。

局部加权回归 (LWR) 是一种非参数、基于内存的算法,这意味着它明确保留训练数据并在每次进行预测时使用它。

要解释局部加权线性回归,我们首先需要了解线性回归。线性回归可以用以下等式来解释:

\hat{y} = \theta_{0} +  \theta_{1} * x

让 (x i , y i ) 作为查询点,然后为了最小化线性回归中的成本函数:



J(\theta ) = \sum_{i=1}^{m}\left ( y^{(i)}-\theta^{T} x^{(i)} \right )^{2}通过计算 \theta 所以,它最小化上述成本函数。我们的输出将是: \theta^{T} x

因此,计算 \theta 的公式也可以是:

\theta = \left ( X^{T}X \right )^{-1}X^{T}Y

其中,beta 是线性向量的向量,X,Y 是矩阵,所有观测值的向量。

对于局部加权线性回归:

J(\theta ) = \sum_{i=1}^{m} w^{i}\left ( y^{(i)}-\theta^{T} x^{(i)} \right )^{2}通过这样计算,它可以最小化上述成本函数。我们的输出将是: \theta^{T} x

这里, w(i)是与每个训练数据观察相关的权重。可以通过给定的公式计算:

w^{(i)} = e^{-(\frac{\left \| x^{(i)} - x  \right \|^{2}}{2\tau^{2}})}

或者这可以用矩阵计算的形式表示:

w^{(i)} = e^{-(\frac{\left ( x^{(i)} - x  \right )^{T} \left ( x^{(i)} - x  \right )}{2\tau^{2}})}

带宽的影响

其中x(i)是训练数据的观测值,x 是计算距离的特定点, T(tau)是带宽。这里,T(tau) 决定了函数的适应度,如果函数是紧密拟合的,它的值会很小。所以,

|x^{i} -x | \approx 1 \, then \, w^i \approx 1 \\ |x^{i} -x | \approx 0 \, then \, w^i \approx 0

然后,我们可以使用以下等式计算 \theta:

\theta = (X^{T}WX)^{-1}X^{T}WY

执行

  • 对于这个实现,我们将使用散景。如果您想详细了解散景功能,请查看这篇文章
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)]
]))


具有不同带宽值的 LWR 图

  • 从上图中我们可以注意到,带宽值较小时,模型拟合得更好,但有时会导致过度拟合。

参考:

  • 斯坦福 CS 229