机器学习实战——标准线性回归和加权线性回归算法

'''
机器学习实战章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

发布了97 篇原创文章 · 获赞 42 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/LVGAOYANH/article/details/105269503
今日推荐