'''
机器学习实战章8
一个矩阵x(样本数据属性矩阵)和y(样本数据y矩阵)可拟合出一条直线
标准线性回归只拟合出一条直线,局部加权线性回归共更新x矩阵m-1次,在相邻两个数据之间都回归出直线,共得到m-1条直线,连接起来就近似曲线了
改变lwlr()函数的k值,可以改变曲线的平滑度和拟合度,大家有兴趣可以试试
本代码使用的资源和文件在文末
'''
from numpy import *
'''
该函数解析用tab键分离的文本文件,若该文件内有m条数据
dataMat:如其名,属性矩阵,m x 2
labelMat:y值矩阵,m x 1
'''
def loadDataSet(fileName):
numFeat = len(open(fileName).readline().split('\t')) - 1 #获取属性数,前两列是属性,最后一列是y值
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 #函数有多个返回值其实是返回了一个tuple
"""
标准回归,计算最佳拟合直线
返回m x 1的回归系数矩阵
"""
def standRegres(xArr,yArr):
xMat = mat(xArr); yMat = mat(yArr).T
xTx = xMat.T*xMat
if linalg.det(xTx) == 0.0:#判断xTx矩阵行列式是否为0,linalg是numpy提供的线性代数库
print( "This matrix is 不可逆的, cannot 求逆")
return
ws = xTx.I * (xMat.T*yMat)
return ws
'''
加权局部线性回归
以待预测数据为中心对所有样本数据赋予一定的权重得到新x矩阵,相邻两点间回归出直线,上述过程重复m-1次,连接在一起近似平滑的曲线
k是参数,由用户指定,这也是lwlr中唯一要考虑的参数
testPoint: 1 * 2 一条测试数据,不是一个点
weights:m * m
xMat: m * 2
yMat: m * 1
ws: 2 * 1
'''
def lwlr(testPoint,xArr,yArr,k):
xMat = mat(xArr); yMat = mat(yArr).T
m = shape(xMat)[0] # m 样本数据数
weights = mat(eye((m))) #eye()创建m阶单位矩阵,是方阵,即该矩阵为每个样本点初始化了一个权重1
for j in range(m):
diffMat = testPoint - xMat[j,:] #样本点与待遇测点的距离
#exp():以e为底的指数函数。随着样本点与待预测点距离递增,权重以指数级衰减。这种设置权重的方法叫高斯核类型。
weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2))
xTx = xMat.T * (weights * xMat) # x = weights * xMat,相当于更新了x(样本)矩阵
if linalg.det(xTx) == 0.0:
print( "This matrix cannot do inverse")
return
ws = xTx.I * (xMat.T * (weights * yMat)) #求sei ta的算法式子也更新,得到回归系数(sei ta)2 * 1
return testPoint * ws # 返回lwlr对testPoint(样本数据)的预测值
'''
本函数对所有样本数据调用lwlr(),得到所有预测值
'''
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
"""
xarr,yarr是数组,loadDataSet()的返回值
"""
def show(xarr,yarr,yHat):
xMat = mat(xarr) # 数组转化成矩阵 m * 2
yMat = mat(yarr) # 数组转化成矩阵1 * m
#排序
strInd = xMat[:,1].argsort(0) #对样本x升序排序并返回索引
xSort = xMat[strInd][:,0,:]
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(xSort[:,1],yHat[strInd])# xSort是横坐标,yHat是对应的纵坐标,plot按索引顺序在相邻两点连线。如果不排序就会来回画
ax.scatter(xMat[:,1].flatten().A[0],yMat.T.flatten().A[0],s = 2,c = 'red') # 画出所有原始数据
plt.show()
xarr,yarr = loadDataSet("ex0.txt")
yHat = lwlrTest(xarr,xarr,yarr,0.03)
show(xarr,yarr,yHat)
"""
print(corrcoef(yHat.T,yMat))
corrcoef(yEstimate,yActual):计算真实值和预测值的相关性,两个参数都应是行向量
输出
[[1. 0.98647356]
[0.98647356 1. ]]
表示相关性为0.98647356
"""
机器学习实战代码百度云:提取码8569