python实现线性回归之最小二乘法,最小二乘法详解

线性回归是确定两种及两种以上变量的相互依赖关系。在数据分析中,线性回归是最简单且最有效的分析方法。举个简单的例子,某商品的利润在售价为2元、5元、10元时分别为4元、10元、20元,我们很容易得出商品的利润与售价的关系符合直线:y=2x.在上面这个简单的一元线性回归方程中,我们称“2”为回归系数,即斜率为其回归系数,回归系数表示商品的售价(x)每变动一个单位,其利润(y)与之对应的变动关系。

1.线性回归

                                                    

如上图所示,上图为一个简单的一元线性回归示意图,线性回归表示这些离散的点总体上“最逼近”哪条直线。同理,在二元线性回归中,离散的点在空间中最逼近哪个平面。其它多元线性回归亦是如此。线性回归在数据量化分析,数据预测方面有着重要应用。

2.最小二乘法

同样是上图,那这些离散的点总体上“最逼近”哪条直线呢,这需要一个量化。对于同一x,实际数据为y,回归方程的推断数据为ax,则误差d=y-ax。最小二乘法定义为,当D=\sum_{i=1}^{n}(y_{i}-ax_{i})^2,D最小时,回归方程的拟合度最高,根据min(D)求出a即可,对最小二乘法的定义方程进行微分求极值即可得出a。

对于多元变量,设

                                        X=\begin{bmatrix} x_{11}&x_{12}&...&x_{1n}\\ x_{21}&x_{22}&...&x_{2n}\\ ...&...&...&...\\ x_{n1}&x_{n2}&...&x_{nn} \end{bmatrix},    Y=\begin{bmatrix} y_{1}\\ y_{2}\\ ...\\ y_{n} \end{bmatrix},    a=\begin{bmatrix} a_{1}\\ a_{2}\\ ...\\ a_{n} \end{bmatrix}

其回归方程为Y=Xa。同理,现在我们要求矩阵a的值,使得

                                                               S=\sum _{i=1}^{n}[y_{i}-\sum_{j=1}^{n}(a_{i}x_{ij})]^2

取最小值即可。对上式进行微分求解(具体求解步骤可参考线性代数相关知识),可得

                                                                              X^{T}Xa=X^{T}Y

如果该矩阵满秩,则

                                                                           a=(X^{T}X)^{-1}X^{T}Y

上述便为最小二乘法的基本思想。

3.python实现

一元线性回归测试:

from numpy.linalg import inv  # 矩阵求逆
from numpy import dot  # 矩阵点乘
from numpy import mat  # 二维矩阵

X = mat([1, 2, 3]).reshape(3, 1)  # x为1,2,3
Y = mat([5, 10, 15]).reshape(3, 1)  # y为5,10,15
a = dot(dot(inv(dot(X.T, X)), X.T), Y)  # 最小二乘法公式
print(a)

首先,这里推荐一个公式的代码实现技巧,代码从内向外写,即X的转置与X点乘,再求逆, 再与X的转置点乘,再与Y点乘,一层层加括号即可。

由上述代码不难看出,y与x的关系为y=5x,下面我们看测试结果是否为5:

测试结果正确。

实战:

这里准备了一组数据,数据示例截图如下:

 

上述数据为某一商品的销售量与售价、服务投资和其它投资的对应关系,即我们要求出:

                                                     X=\begin{bmatrix} 3.5 & 1.4 & 0.2 \\ 3.0 & 1.4 & 0.2 \\ 3.2 & 1.3 & 0.2\\ ... & ... & ... \end{bmatrix},    Y=\begin{bmatrix} 5.1\\ 4.9\\ 4.7\\ ... \end{bmatrix},      a=\begin{bmatrix} a_{1}\\ a_{2}\\ a_{3}\\ ... \end{bmatrix}

Y=Xa中,矩阵a。

代码如下:

import numpy as np
import pandas as pd
from numpy.linalg import inv  # 矩阵求逆
from numpy import dot  # 矩阵点乘


dataset = pd.read_csv('C:\\Users\\57105\\Desktop\\data.csv')  # 读入数据
X = dataset.iloc[:, 2: 5]  # x为所有行,2到4列
Y = dataset.iloc[:, 1]  # y为所有行,第1列
a = dot(dot(inv(np.dot(X.T, X)), X.T), Y)  # 最小二乘法求解公式
print(a)

测试结果:

a=\begin{bmatrix} 1.157\\ 0.782\\ -0.591 \end{bmatrix},对于单条数据,即y=1.157x_{1}+0.782x_{2}-0.591x_{3},该回归方程反应了商品销售量与售价、服务投资和其它投资的关系。

上述便为线性回归的最小二乘法求解方式,关于线性回归的另一种求解方式—梯度下降法可见笔者相关文章。

  • 32
    点赞
  • 287
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
好的,下面是普通最小二乘法实现线性回归算法的Python代码演示: ```python import numpy as np # 构造数据 x_data = np.array([338., 333., 328., 207., 226., 25., 179., 60., 208., 606.]) y_data = np.array([640., 633., 619., 393., 428., 27., 193., 66., 226., 1591.]) # 定义超参数 lr = 0.000001 # 学习率 theta0 = 0. # 初始化theta0 theta1 = 0. # 初始化theta1 epochs = 100000 # 迭代次数 # 定义损失函数 def compute_cost(theta0, theta1, x_data, y_data): total_cost = np.sum((y_data - theta1 * x_data - theta0) ** 2) / len(y_data) return total_cost # 定义梯度下降函数 def gradient_descent(theta0, theta1, x_data, y_data, lr, epochs): m = len(y_data) for i in range(epochs): theta0_grad = 0. theta1_grad = 0. for j in range(m): theta0_grad += (1.0 / m) * ((theta1 * x_data[j] + theta0) - y_data[j]) theta1_grad += (1.0 / m) * ((theta1 * x_data[j] + theta0) - y_data[j]) * x_data[j] theta0 -= lr * theta0_grad theta1 -= lr * theta1_grad if i % 10000 == 0: print("Epochs: ", i) print("Cost: ", compute_cost(theta0, theta1, x_data, y_data)) return theta0, theta1 # 运行梯度下降函数 theta0, theta1 = gradient_descent(theta0, theta1, x_data, y_data, lr, epochs) # 打印训练后的模型参数 print("theta0: ", theta0) print("theta1: ", theta1) ``` 这段代码实现线性回归算法的普通最小二乘法。首先构造了一组数据(x_data和y_data),然后定义了学习率lr、初始化的theta0和theta1、迭代次数epochs等超参数。接着定义了计算损失函数和梯度下降的函数,最后运行梯度下降函数,输出训练后的模型参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超级战斗王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值