使用Python从头开始的线性回归

可以说,任何Python项目的第一部分都是导入一堆有用的包。这里最重要的包是:

·NumPy - 用于科学计算的软件包

·Pandas - 一个为数据存储和检索提供便捷方法的软件包

·matplotlib&seaborn - 绘图库

%matplotlib inline
import scipy.stats as stats
import numpy as np
import pandas as pd
import math
import seaborn as sns
import matplotlib.pyplot as plt
plt.style.use('ggplot')

接下来,为了构建线性回归,我们需要一些数据。因此,我们将生成一些虚拟数据:

data = pd.DataFrame({'x': [1, 2, 4, 3, 5], 'y': [1, 3, 3, 2, 5]})

我们现在可以看看这些数据:

机器学习:线性回归_经验分享

 

此数据框提供了所有必要的信息,但通常最好的是绘制我们的数据图以更直观地理解变量x和y之间的关系:

机器学习:线性回归_经验分享_02

 

x和y之间似乎存在线性关系。来自seaborn的这个lmplot甚至适合回归线。

线性回归构件块

在数学生涯的某些阶段,您很可能会遇到以下公式:

机器学习:线性回归_经验分享_03

 

具有截距α和斜率β的线。

我们引入残差残差描述了使用上述函数对数据点的估计值是多少。

机器学习:线性回归_经验分享_04

 

为了使我们的回归尽可能接近我们的数据,我们自然希望在所有数据点上最小化这些残差。这可以使用以下公式表示:

机器学习:线性回归_经验分享_05

 

所有这些都表明我们希望最小化我们预测的平方误差之和。通过扩展此公式,我们可以找到我们对alpha和beta的最佳估计。让我们从beta开始,最后进入一些Python代码:

机器学习:线性回归_经验分享_06

 

首先让我们计算公式的x和y的平均值:

mean_x = np.mean(data.x)
mean_y = np.mean(data.y)
print('The mean of x is {} and the mean of y is {}'.format(mean_x, mean_y))
#The mean of x is 3.0 and the mean of y is 2.8

借助我们的手段,我们可以开始构建分子

机器学习:线性回归_经验分享_07

 

在下面的代码片段中,numerator1指的是分子的左边部分,numerator2指的是右边的部分。

numerator1 = data.x - mean_x
numerator2 = data.y - mean_y
print('x values: 
', numerator1, '

', 'y values: 
', numerator2)
#x values: 
# 0 -2.0
#1 -1.0
#2 1.0
#3 0.0
#4 2.0
#Name: x, dtype: float64 
#
# y values: 
#0 -1.8
#1 0.2
#2 0.2
#3 -0.8
#4 2.2
Name: y, dtype: float64
numerator = np.sum(numerator1 * numerator2)
numerator
#8.0

我们完成了分子!现在剩下的就是计算分母。

机器学习:线性回归_经验分享_08

 

但是,我们甚至不需要重新开始。分母只是分子numerator1的平方!

denominator = np.sum(numerator1 **2)
denominator
#10.0

我们到了那里。现在,要获得我们的beta估计,我们所要做的就是将分子和分母组合在一起:

beta1 = numerator/denominator
print('beta1 is: {}'.format(beta1))
#beta1 is: 0.8

请注意,虽然公式将截距称为alpha,但我将其称为beta零。

完成测试后,我们可以将结果与手段一起插入以下公式中以获得拦截:

机器学习:线性回归_经验分享_09

 

在Python中:

beta0 = mean_y - beta1 * mean_x
print('beta0 is: {}'.format(beta0))
#beta0 is: 0.39999999999999947

我们现在有了回归线的等式:y = 0.4 + 0.8x。Beta和alpha也称为“最小平方系数”,因为我们只是将平方误差最小化并达到beta和alpha。因此,这种推导它们的方法被称为“普通最小二乘法”或简称OLS。我们将使用这个等式来预测我们的数据。

做出预测

现在到了有趣的部分:使用我们的回归方程来根据x值预测数据的y值。所要做的就是用数据中x的一列代替我们的衍生回归方程中的x:

predicted_y = beta0 + beta1 * data.x
after_pred = pd.concat([data.x, data.y, predicted_y.rename('prediction')], axis=1)
after_pred

机器学习:线性回归_经验分享_10

原始X和Y值与我们的预测相对应

让我们绘制我们的预测,看看他们如何与本文开头中的回归线进行比较。

plt.figure(figsize=(8,6))
original_y = plt.scatter(data.x, data.y, marker ='^', s=70)
predicted_y = plt.scatter(data.x, after_pred.prediction, s=70)
plt.title('Y vs. Predicted Y')
plt.legend((original_y, predicted_y), ('y', 'Predicted y')) 

机器学习:线性回归_经验分享_11

 

蓝点,我们的预测,形成一条直线,非常类似于我们之前在图中看到的线!我们的回归似乎有效!在调用它之前我们应该先看一下的是回归模型的表现。

估计错误

虽然有几种方法可以测量误差并因此模拟性能,但为了简单起见,我将坚持使用RMSE(均方根误差)。

机器学习:线性回归_经验分享_12

 

Python实现:

rmse = math.sqrt(np.mean((after_pred.prediction-data.y)**2))
print('Our RMSE is {}'.format(rmse))
#Our RMSE is 0.692820323027551

这意味着,我们的每个预测都偏差约0.69。