【Python机器学习】回归——用线性回归找到最佳拟合直线

线性回归的优缺点:

优点:结果易于理解,计算上不复杂

缺点:对非线性的数据拟合不好

使用数据类型:数值型和标称型数据。

回归的目的是预测数值型的目标值。最直接的办法是依据输入写出一个目标值的计算公式。例如预测汽车的功率大小,可能会这么计算:

HorsePower=0.0015*annualSalary-0.99*hoursListeningToPublicRadio

这就是所谓的回归方程,其中的0.0015和-0.99称作回归系数,求这些回归系数的过程就是回归。一旦有了这些回归系数,再给定输入,做预测就非常容易了。具体的做法是用回归系数城西输入值,再将结果全部加在一起,就得到了预测值。

回归一般都是指线性回归。线性回归意味着可以将输入项分别乘以一些常量,再将结果加起来得到输出。

需要注意的是,存在另一种称为分线性回归的回归模型,该模型不认同上面的做法,比如认为输出可能是输入的乘积。这样,上面的功率计算公式也可以写做:

HorsePower=0.0015*annualSalary/hoursListeningToPublicRadio

这就是一个非线性回归的例子。

回归的一般方法:

1、收集数据:采用任意方法收集数据

2、准备数据:回归需要数值型数据,标称型数据将被转成二值型数据

3、分析数据:绘出数据的可视化二维图将有助于对数据做出理解和分析,在采用缩减法求得新回归数据之后,可以将新拟合线绘在图上作为对比

4、训练数据:找到回归系数

5、测试算法:使用R^{2}或者预测值和数据的拟合度,来分析模型的效果

6、使用算法:使用回归,可以在给定输入的时候预测出一个数值,这是对分类方法的提升,因为这样可以预测连续性数据而不仅仅是离散的类别标签

假定输入数据存放在矩阵X中,而回归系数存放在矩阵w中。那么,对于给定的数据X,预测结果将会通过Y_{1}=X_{1}^{T}w给出。现在的问题是,手里有一些X和对应的y,要找到w。一个常用的方法就是找出使误差最小的w。这里的误差是指预测y值和真实y值之间的差值,使用该误差的简单累加将使得正差值和负差值相互抵消,所以我们采用平方误差。

平方误差可以写做:

\sum_{i=1}^{m}(y_{i}-x{_{i}}^{T}w)^{2}

用矩阵表示还可以写做(y-Xw)^{T}(y-Xw)。如果对w求导,得到X^{T}(y-Xw),令其等于0,解出w如下:

\widehat{w}=(X^{T}X)^{-1}X^{T}y

w上方的小标记表示,这是当前可以估计出的w的最优解。从现有数据上估计出的w可能并不是数据中的真实w值,所以这里使用了一个“帽”符号来表示它仅仅是w的一个最佳估计。

指的注意的是,上述公式中包含(X^{T}X)^{-1},也就是需要对矩阵求逆,因此这个方程只在逆矩阵存在的时候适用。然而,矩阵的逆可能并不存在,因此必须要在代码中对此做出判断。

上述的最佳w求解是统计学中的常见问题,除了矩阵方法外还有很多其他方法可以解决。通过调用NumPy库里的矩阵方法,我们可以仅使用几行代码就完成所需功能。该方法也称作OLS,意思是“普通最小二乘法”。

针对下面的数据,试验怎样找到最佳拟合直线。

代码实现:

from numpy import *

def loadDataSet(fileName):
    numFeat=len(open(fileName).readline().split('\t'))-1
    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 standRegres(xArr,yArr):
    xMat=mat(xArr)
    yMat=mat(yArr).T
    xTx=xMat.T*xMat
    if linalg.det(xTx)==0.0:
        print('行列式为0')
        return
    ws=xTx.I*(xMat.T*yMat)
    return ws

代码中,第一个函数loadDataSet()用于打开一个用tab分隔的文本文件,默认文件每行的最后一个值是目标值。

第二个函数standRegres()用于计算最佳拟合直线。该函数首先读入x和y并将它们保存到矩阵中;然后计算x^{T}x,然后判断它的行列式是否为0,如果行列式为0,那么计算逆矩阵将会出现错误。NumPy提供一个线性代数的库linalg,其中包括很多有用的函数。可以直接调用linalg.det()来计算行列式。最后,如果行列式非零,计算并返回w。如果没有检查行列式是否为零就试图计算矩阵的逆,将会出现错误。

NumPy的线性代数库还提供一个函数来解未知矩阵,如果使用该函数,那么代码ws=xTx.T*(xMat.T*yMat)应该写成ws=linalg.solve(xMat,xMat.T*yMat.T)。

查看实际运行效果:


xArr,yArr=loadDataSet('ex0.txt')
print(xArr[0:2])
ws=standRegres(xArr,yArr)
print(ws)

变量ws存放的就是回归系数。在用内积来预测y的时候,第一维将乘以前面的常数X0,第二维将乘以输入变量X1.因为前面假定了X0=1,所以最终会得到y=ws[0]+ws[1]*X1。这里的y实际是预测出的,为了和真实的y值区分开来,我们将它记为yHat。下面使用新的ws值计算yHat:

xMat=mat(xArr)
yMat=mat(yArr)
yHat=xMat*ws

绘出数据集散点图和最佳拟合直线图:

import matplotlib.pyplot as plt
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(xMat[:,1].flatten().A[0],yMat.T[:,0].flatten().A[0])
xCopy=xMat.copy()
xCopy.sort(0)
yHat=xCopy*ws
ax.plot(xCopy[:,1],yHat)
plt.show()

几乎任意数据集都可以用上述方法建立模型。

为了评估模型的好坏,有一种方法可以计算预测值yHat序列和真实值y序列的匹配程度,那就是计算这两个序列的相关系数。

在Python中,NumPy库提供了相关系数的计算方法:可以通过命令corrcoef(yEstimate,yActual)来计算预测值和真实值的相关性:

yHat=xMat*ws
print(corrcoef(yHat.T,yMat))

该矩阵包含所有两两组合的相关系数。可以看到对角线上的数据为1.0,因为yMat和自己的匹配是最完美的,而yHat和yMat的相关系数为0.985。

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值