赞
踩
本关任务:编写一个利用局部加权计算回归系数的小程序。
为了完成本关任务,你需要掌握:1.局部加权算法的思想;2.局部加权的核心算法。
在局部加权算法中 ,我们给待预测点附近的每个点赋予一定的权重;然后与前面的类似,在这个子集上基于最小均方差来进行普通的回归。与kNN一样,这种算法每次预测均需要事先选取出对应的数据子集。 该算法解出回归系数w的形式如下:
其中w是一个矩阵,用来给每个数据点赋予权重。
def lwlr(testPoint,xArr,yArr,k=1.0):
xMat = np.mat(xArr); yMat = np.mat(yArr).T
m = np.shape(xMat)[0]
weights = np.mat(np.eye((m)))
for j in range(m): #next 2 lines create weights matrix
diffMat = testPoint - xMat[j,:] #difference matrix
weights[j,j] = np.exp(diffMat*diffMat.T/(-2.0*k**2)) #weighted matrix
xTx = xMat.T * (weights * xMat)
if np.linalg.det(xTx) == 0.0:
print ("This matrix is singular, cannot do inverse")
return
ws = xTx.I * (xMat.T * (weights * yMat)) #normal equation
return testPoint * w
根据提示,在右侧编辑器补充代码,利用局部加权计算回归系数。
根据所学完成右侧编程题。
- from matplotlib.font_manager import FontProperties
- import matplotlib.pyplot as plt
- import numpy as np
-
- # 加载数据
- def loadDataSet(fileName):
- """
- Parameters:
- fileName - 文件名
- Returns:
- xArr - x数据集
- yArr - y数据集
- """
- numFeat = len(open(fileName).readline().split('\t')) - 1
- xArr = []; yArr = []
- fr = open(fileName)
- for line in fr.readlines():
- lineArr =[]
- curLine = line.strip().split('\t')
- for i in range(numFeat):
- lineArr.append(float(curLine[i]))
- xArr.append(lineArr)
- yArr.append(float(curLine[-1]))
- return xArr, yArr
-
- # 使用局部加权线性回归计算回归系数w
- def lwlr(testPoint, xArr, yArr, k = 1.0):
- """
- Parameters:
- testPoint - 测试样本点
- xArr - x数据集
- yArr - y数据集
- k - 高斯核的k,自定义参数
- Returns:
- ws - 回归系数
- """
- xMat = np.mat(xArr); yMat = np.mat(yArr).T
- m = np.shape(xMat)[0]
- weights = np.mat(np.eye((m))) #创建权重对角矩阵
- for j in range(m): #遍历数据集计算每个样本的权重
- ##########
- diffMat = testPoint - xMat[j,:] #difference matrix
- weights[j,j] = np.exp(diffMat*diffMat.T/(-2.0*k**2)) #weighted matrix
- ##########
- xTx = xMat.T * (weights * xMat)
- if np.linalg.det(xTx) == 0.0:
- print("矩阵为奇异矩阵,不能求逆")
- return
- ws = xTx.I * (xMat.T * (weights * yMat)) #计算回归系数
- return testPoint * ws
-
- # 局部加权线性回归测试
- def lwlrTest(testArr, xArr, yArr, k=1.0):
- """
- Parameters:
- testArr - 测试数据集,测试集
- xArr - x数据集,训练集
- yArr - y数据集,训练集
- k - 高斯核的k,自定义参数
- Returns:
- ws - 回归系数
- """
- m = np.shape(testArr)[0] #计算测试数据集大小
- yHat = np.zeros(m)
- for i in range(m): #对每个样本点进行预测
- yHat[i] = lwlr(testArr[i],xArr,yArr,k)
- return yHat
-
- # 计算回归系数w
- def standRegres(xArr,yArr):
- """
- Parameters:
- xArr - x数据集
- yArr - y数据集
- Returns:
- ws - 回归系数
- """
- xMat = np.mat(xArr); yMat = np.mat(yArr).T
- xTx = xMat.T * xMat #根据文中推导的公示计算回归系数
- if np.linalg.det(xTx) == 0.0:
- print("矩阵为奇异矩阵,不能求逆")
- return
- ws = xTx.I * (xMat.T*yMat)
- return ws
-
-
- def rssError(yArr, yHatArr):
- """
- 误差大小评价函数
- Parameters:
- yArr - 真实数据
- yHatArr - 预测数据
- Returns:
- 误差大小
- """
- return ((yArr - yHatArr) **2).sum()
-
-
- if __name__ == '__main__':
- abX, abY = loadDataSet('./机器学习第8章/abalone.txt')
- print('训练集与测试集相同:局部加权线性回归,核k的大小对预测的影响:')
- yHat01 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 0.1)
- yHat1 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 1)
- yHat10 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 10)
- print('k=0.1时,误差大小为:',rssError(abY[0:99], yHat01.T))
- print('k=1 时,误差大小为:',rssError(abY[0:99], yHat1.T))
- print('k=10 时,误差大小为:',rssError(abY[0:99], yHat10.T))
- print('')
- print('训练集与测试集不同:局部加权线性回归,核k的大小是越小越好吗?更换数据集,测试结果如下:')
- yHat01 = lwlrTest(abX[100:199], abX[0:99], abY[0:99], 0.1)
- yHat1 = lwlrTest(abX[100:199], abX[0:99], abY[0:99], 1)
- yHat10 = lwlrTest(abX[100:199], abX[0:99], abY[0:99], 10)
- print('k=0.1时,误差大小为:',rssError(abY[100:199], yHat01.T))
- print('k=1 时,误差大小为:',rssError(abY[100:199], yHat1.T))
- print('k=10 时,误差大小为:',rssError(abY[100:199], yHat10.T))
- print('')
- print('训练集与测试集不同:简单的线性归回与k=1时的局部加权线性回归对比:')
- print('k=1时,误差大小为:', rssError(abY[100:199], yHat1.T))
- ws = standRegres(abX[0:99], abY[0:99])
- yHat = np.mat(abX[100:199]) * ws
- print('简单的线性回归误差大小:', rssError(abY[100:199], yHat.T.A))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。