【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=ws0+ws1*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。

相关推荐
dialect_28 分钟前
KMP算法
开发语言·c++·算法
reikocao36 分钟前
卡尔曼滤波的动态机制:P如何改变融合权重
算法
漂流瓶jz1 小时前
UVA-1612 猜名次 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·题解·排序·aoapc·算法竞赛入门经典
前端精髓1 小时前
结构化输出with_structured_output(抽卡)
python·langchain
吞下星星的少年·-·2 小时前
Div.2 CF 1130B题(构造,贪心)
算法·贪心·构造
尹人入圣2 小时前
目前热门的IP驱动产业新场景新工具
网络·python·网络协议·tcp/ip
是main不是漫3 小时前
【双指针——移动零】数组划分类题目的入门基石
c++·算法
Nuanyt3 小时前
Agent 学习笔记(下篇三):上线工程、进阶选择与操作界面(Stage 7 / 7.5 / 8 + 延伸路线)
笔记·python·学习·memory·aiagent·harness
吴卫斌3 小时前
定投ETF实战指南(四):行业/主题ETF——定投的“进攻端“
开发语言·python·股票·量化
2601_967987373 小时前
Python——入门级(定义功能def函数)
python·函数·可变参数·默认参数·关键字参数