线性回归的一个问题是很可能出现欠拟合现象。局部加权线性回归可以解决线性回归中的欠拟合现象。在该算法中,我们对更靠近待预测点的点赋予更高的权重。权重类型可以自由选择,最常用的是使用高斯核:W是一个对角矩阵,其中第i项表达式为
则预测y值的回归系数θ如下:
其中k是需要用户给定的参数,k越小,则远离待预测点的点的权重衰减的越厉害。
绘制上述图表的代码如下:
代码语言:javascript复制import numpy as np
import matplotlib.pyplot as plt
X = np.linspace(0,1,100)
plt.title("不同的k值下的权重分布n假设正预测的点是 x=0.5",fontsize =16)
kList = [0.5, 0.1, 0.01]
for i, k in enumerate(kList):
plt.subplot(len(kList),1, i 1)
w = np.exp((0.5-X)**2 /(-2 * k*k))
plt.plot(X,w, label = "k = %f" % k)
plt.xlabel("x")
plt.ylabel("w")
plt.legend()
if i ==0:
plt.title("不同的k值下的权重分布n假设正预测的点是 x=0.5",fontsize =16)
plt.show()
我们还是使用上一篇中用的训练集,预测结果相当好:
局部加权线性回归的完整代码如下:
代码语言:javascript复制#@author: Peter
from numpy import *
import matplotlib.pyplot as plt
def loadDataSet(fileName):
#general function to parse tab -delimited floats
numFeat = len(open(fileName).readline().split('t')) - 1 #get number of fields
dataMat = []; labelMat = []
fr = open(fileName)
for line in fr.readlines():
lineArr =[]
curLine = line.strip().split('t')
for i in range(numFeat):
lineArr.append(float(curLine[i]))
dataMat.append(lineArr)
labelMat.append(float(curLine[-1]))
return dataMat,labelMat
def lwlr(testPoint,xArr,yArr,k):
xMat = mat(xArr); yMat = mat(yArr).T
m = shape(xMat)[0]
weights = mat(eye((m)))#用单位矩阵初始化对角线矩阵
for i in range(m): #next 2 lines create weights matrix
diffMat = testPoint - xMat[i,:] #
weights[i,i] = exp(diffMat*diffMat.T/(-2.0*k**2))
xTx = xMat.T * (weights * xMat)
if linalg.det(xTx) == 0.0:
print ("This matrix is singular, cannot do inverse")
return
ws = xTx.I * (xMat.T * (weights * yMat)) #weight
return testPoint * ws
def lwlrTest(testArr,xArr,yArr,k):
#loops over all the data points and applies lwlr to each one
m = shape(testArr)[0]
yHat = zeros(m)
for i in range(m):
yHat[i] = lwlr(testArr[i],xArr,yArr,k)
return yHat
def rssError(yArr,yHatArr):#平方误差
#yArr and yHatArr both need to be arrays
return ((yArr-yHatArr)**2).sum()
xArr,yArr = loadDataSet("ex0.txt") #训练集
X=mat(xArr)
Y=mat(yArr)
print("Y.shape: ", Y.shape)
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.scatter(array(xArr)[:,1], yArr,label="raw data")
#虚拟的测试集
n=200
B = linspace(array(xArr)[:,1].min(),array(xArr)[:,1].max(),n).reshape(n,1)
A = ones((n,1))
XTest = bmat("A B")
#print(XTest)
k= 0.02
yHat = lwlrTest(XTest, X, Y ,k) #Y的预测值
ax.plot(array(XTest)[:,1], yHat,color ="r", label="预测值")
plt.xlabel("X")
plt.ylabel("Y")
plt.legend(loc="lower right")
plt.title("局部加权线性回归 k= %fn(Locally Weighted Linear Regression)" % k,fontsize =16)
plt.show()
如果参数k取1.0,则和上一篇的结果类似,欠拟合:
如果参数k取0.005,则会出现过拟合现象——过于贴合原始数据,不能提取有效信息,泛化能力差: