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

线性回归的优缺点:

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

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

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

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

HorsePower=0.0015*annualSalary-0.99*hoursListeningToPublicRadio

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

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

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

HorsePower=0.0015*annualSalary/hoursListeningToPublicRadio

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

回归的一般方法:

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

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

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

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

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

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

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

平方误差可以写做:

用矩阵表示还可以写做。如果对w求导,得到,令其等于0,解出w如下:

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

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

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

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

代码实现:

python 复制代码
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并将它们保存到矩阵中;然后计算,然后判断它的行列式是否为0,如果行列式为0,那么计算逆矩阵将会出现错误。NumPy提供一个线性代数的库linalg,其中包括很多有用的函数。可以直接调用linalg.det()来计算行列式。最后,如果行列式非零,计算并返回w。如果没有检查行列式是否为零就试图计算矩阵的逆,将会出现错误。

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

查看实际运行效果:

python 复制代码
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:

python 复制代码
xMat=mat(xArr)
yMat=mat(yArr)
yHat=xMat*ws

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

python 复制代码
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)来计算预测值和真实值的相关性:

python 复制代码
yHat=xMat*ws
print(corrcoef(yHat.T,yMat))

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

相关推荐
懒大王爱吃狼23 分钟前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
劲夫学编程23 分钟前
leetcode:杨辉三角
算法·leetcode·职场和发展
毕竟秋山澪25 分钟前
孤岛的总面积(Dfs C#
算法·深度优先
秃头佛爷1 小时前
Python学习大纲总结及注意事项
开发语言·python·学习
浮生如梦_2 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
深度学习lover2 小时前
<项目代码>YOLOv8 苹果腐烂识别<目标检测>
人工智能·python·yolo·目标检测·计算机视觉·苹果腐烂识别
API快乐传递者3 小时前
淘宝反爬虫机制的主要手段有哪些?
爬虫·python
励志成为嵌入式工程师4 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉5 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer5 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法