线性回归与均方误差优化

在数据分析中,经常需要确定变量X和Y之间的关系,并用一条直线来表示这种关系。但是,问题在于如何确定这条直线能够最好地代表X和Y之间的关系。为了解决这个问题,可以使用均方误差(Mean Squared Error,简称MSE)作为衡量标准。在线性回归中,MSE实际上就是成本函数。均方误差是预测值与真实值之间差的平方和,输出是一个单一数值,代表成本。因此,具有最小成本函数或MSE的直线就是X和Y之间关系的最佳表示。一旦找到了斜率和截距,使得这条直线的误差最小,就可以使用这条直线来预测Y值。

本文将介绍如何计算不同直线的误差/成本,并找到成本函数,进而用于预测。如果对以音视频形式学习概念更感兴趣,有整个文章的视频解释。如果不感兴趣,可以继续阅读。

知道任何直线都可以用两个参数表示:斜率(β)和截距(b)。一旦有了直线,总是可以计算这条直线与底层数据点之间的误差(也称为成本或损失),目标是找到误差最小的直线。这基本上变成了一个优化问题。让通过一个练习来看看不同值的β和b的误差是多少,然后问题是如何找到这两个参数的最优化值。

导入库

首先,将导入必要的库,包括matplotlib、pandas和scikit-learn来计算误差:

import matplotlib.pyplot as plt import pandas as pd from sklearn.metrics import mean_squared_error as mse

创建样本数据

创建了一个关于经验和薪水的数据集。创建了一个列表,然后简单地将其转换为Pandas DataFrame:

import pandas as pd # 创建样本数据集 experience = [1.2,1.5,1.9,2.2,2.4,2.5,2.8,3.1,3.3,3.7,4.2,4.4] salary = [1.7,2.4,2.3,3.1,3.7,4.2,4.4,6.1,5.4,5.7,6.4,6.2] data = pd.DataFrame({ "salary" : salary, "experience" : experience }) print(data.head())

可以看到数据集的前五行。

绘制数据

现在让通过探索薪水和经验之间的关系来探索数据集。让使用Matplotlib绘制这个关系:

plt.scatter(data.experience, data.salary, color = 'red', label = '数据点') plt.xlim(1,4.5) plt.ylim(1,7) plt.xlabel('经验') plt.ylabel('薪水') plt.legend()

可以看到经验和薪水之间的线性关系。这就是预期的。那么现在让开始绘制使用不同β和b值的直线。

使用参数的小值开始绘制直线

首先,将取β=0.1和b=1.1,将使用这两个参数创建一条直线,并将其绘制在散点图上。现在,取值并应用这种关系来创建每条直线,然后将这些直线绘制在上述创建的散点图上。

beta = 0.1 # 保持截距不变 b = 1.1 # 存储预测点 line1 = [] # 为每个数据点生成预测 for i in range(len(data)): line1.append(data.experience[i]*beta + b) # 绘制直线 plt.scatter(data.experience, data.salary, color = 'red') plt.plot(data.experience, line1, color = 'black', label = '直线') plt.xlim(1,4.5) plt.ylim(1,7) plt.xlabel('经验') plt.ylabel('薪水') plt.legend()

MSE = mse(data.salary, line1)

已经为β=0.1和b=1.1绘制了这条直线,这条直线的MSE是2.69。现在可以看到直线的斜率非常小,所以想尝试一个更大的斜率,而不是β=0.1,让将其改为β=1.5:

beta = 1.5

这是β=1.5和b=1.1的直线,这条直线的MSE是6.40。可以看到更好的斜率,但它可能比实际想要的要大。所以正确的值可能在0.1和1.5之间,让试试β=0.8:

beta = 0.8

这是β=0.8和b=1.1的直线,可以看到均方误差已经降到了0.336。已经尝试了三条不同的直线,每条直线都有不同的MSE;第一条是2.69,第二条是6.4,第三条是0.33。现在可以继续尝试各种β值。所以现在可以尝试不同的Beta值,并看看β和均方误差(MSE)之间的关系,对于固定值的截距即b。所以不改变b。

在一系列Beta值上计算成本函数

让创建一个称之为Error的函数,这个函数的作用是对于给定的β值,它基本上给了这些数据点的MSE。这里b是固定的,尝试不同的Beta值。

def Error(Beta, data): # b是常数 b = 1.1 salary = [] experience = data.experience # 循环计算预测薪水变量 for i in range(len(data.experience)): tmp = data.experience[i] * Beta + b salary.append(tmp) MSE = mse(data.salary, salary) return MSE

现在要尝试所有0到1.5之间的Beta值,增量为0.01,然后将所有内容附加到一个列表中:

slope = [i/100 for i in range(0,150)] Cost = [] for i in slope: cost = Error(Beta = i, data = data) Cost.append(cost)

可视化Beta相对于成本

当这个完成后,只需将其转换为这个就是数据框架:

Cost_table = pd.DataFrame({ 'Beta' : slope, 'Cost' : Cost }) Cost_table.head()

这个数据框架显示,对于Beta值为0.00,得到的成本或MSE是3.72,对于beta=0.04,得到的成本=3.29。让快速可视化这个:

plt.plot(Cost_table.Beta, Cost_table.Cost, color = 'blue', label = '成本函数曲线') plt.xlabel('Beta值') plt.ylabel('成本') plt.legend()

这是得到的图表。所以如所见,成本在0时大约是3.72,这是起始值。之后,随着Beta值的增加,误差降低,达到最小值,然后开始增加。

现在的问题是,知道这种关系,如何找到β和b的值,以便可以找到成本最小化的具体位置。

现在,当有两个参数时,意思是,现在假设b是0.1,但实际上想要做的是随着b和β的变化而变化,在这种特定情况下,得到的曲线是:

所以再次,这只是3D图表,所以有两个维度,但它将再次有一个最小值,想法是找到这个最小值。但不能像以前那样迭代地做。所以需要找到一种更聪明的方式来找到这个最小值,这就是梯度下降技术发挥作用的地方。

在本文中,学习了如何计算不同直线的误差以及如何找到最优直线。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485