1. Motivation

希望在设计回归方程时, 若考虑当前某点的作用, 希望距离该点临近的点提供更大的信息权重, 距离该点较远的点提供较小的信息权重.

1.1 Underfitting and Overfitting

  • underfitting
  • overfitting

2. LWR Loss Function

是人为设计的一个参数, 其中一种比较成熟的设计为高斯核:

其中称 为带宽, 用来控制 的衰减速度. 越大, 衰减越慢; 越小, 衰减越快.

若用矩阵形式表达, 则为:

3. Python Implementation

记数据样本量为 .

# coding = utf-8
import numpy as np
import scipy.stats as stats
from math import *
import matplotlib.pyplot as plt
 
def getw(x0, x, k):
    """
    :param x0: 1*m is the current sample point
    :param x: n*m is the whole sample set
    :param k: Gaussian kernel bandwidth, i.e. tau
    :return: w: n*n
    """
    w = np.zeros([m, m])
    for i in range(m):
        w[i, i] = exp((np.linalg.norm(x0 - x[i]) ** 2) / (-2 * k ** 2))
    return w
 
def getyvalue(x1, x, y, k):
    """
    :param x1: n*2
    :param x: m*2
    :param y: m*1
    :param k: Gaussian kernel bandwidth, i.e. tau
    """
    y_value = np.zeros(m)
    w = np.zeros([m, m])
 
    for i in range(m):
        w = getw(x[i], x, k)
        theta = np.linalg.inv(x1.T.dot(w).dot(x1)).dot(x1.T).dot(w).dot(y)
        y_value[i] = theta[0] + theta[1] * x[i]
    return y_value
 
if __name__ == "__main__":
    x = np.arange(1, 101)
    x = np.array([float(i) for i in x])
    y = x + [10 * sin(0.3 * i) for i in x] + stats.norm.rvs(size=100, loc=0, scale=1.5)
 
    x = x.reshape(-1, 1)
    x1 = np.c_[np.ones((100, 1)), x]
    y = y.reshape(-1, 1)
    m = len(x)
 
    y_lwlr = np.zeros(m)
    y_lwlr = getyvalue(x1, x, y, k=1.2)
    plt.figure(figsize=(12, 6))
    plt.scatter(x, y)
    plt.plot(x, y_lwlr, "r")
    plt.show()

说明:

  • 在上面的代码实现中, 并没有使用循环迭代收敛求解, 而是通过类似统计学的方法推导出 LWLR 的解析解, 直接通过矩阵计算完成. 代码中的循环都是为了生成矩阵元素等.
  • 全部计算流程和典型的 别无二致, 只不过相比之下多了几个关于 的运算.
  • 这个运算相当于每次提取一个样本, 和全部样本集合进行一个矩阵运算, 再通过 Gaussian 核得到一个权重, 记为权重矩阵的一个元素, 以此类推得到整个权重.