php求线性回归函数,一篇文章完全弄懂线性回归(Linear Regression)(含详细推导以及代码)...

个人的原创笔记,欢迎dalao们指正错误!

线性回归(Linear Regression)

什么是回归分析?

回归分析是确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。下图是两个变量之间的关系图:

30739020605dc17d50fc275fd21bbcd8.png

也就是用数学语言表达变量之间的关系。举个例子:

30ec7a73a79942f51d61776a7eecedd0.png

什么是线性回归?

线性回归就是变量之间的相互依赖关系可以通过一个线性方程表达。

这里借用吴恩达老师经典的例子。在房价预测中,假设房价仅由房子的面积大小决定,也就是房价“依赖”与房子的面积。此时我们可以设房价为因变量,记为

1de8c3ce1c077889c28a7464d49931c0.png ,房子的面积为自变量,记为 

c8cd358564567df87f3498ab0fb9e46e.png ,建立一个单变量线性方程来表述这个依赖关系,记为 

4bd4716a93509ad8a1c295b44647e625.png。列出方程如下:

8f07d89485773212321ac70a45138ac0.png

我们根据已有的样本对模型训练,就可以得到对应

9e8a9beb2e402454b5e932349c389781.png 和 

bd6cd799e059e3335238aaba2abc823a.png 的取值。当我们完成训练时,我们就已经得到一个房价关于房子面积的准确的表达式,通过此式,我们可以使用一个房子的面积来估计其价格(估计而不是确定,因为存在误差)。

整个过程就是单变量线性回归的完整过程。

我们通常把

9e8a9beb2e402454b5e932349c389781.png 和 

bd6cd799e059e3335238aaba2abc823a.png 成为模型的参数,对模型的训练过程就是对模型参数的求解过程。一旦确定了 

9e8a9beb2e402454b5e932349c389781.png 和 

bd6cd799e059e3335238aaba2abc823a.png ,模型就确定下来了。

如何确定

9e8a9beb2e402454b5e932349c389781.png 和 

bd6cd799e059e3335238aaba2abc823a.png

9e8a9beb2e402454b5e932349c389781.png 和 

bd6cd799e059e3335238aaba2abc823a.png 是模型的参数,反映 

c8cd358564567df87f3498ab0fb9e46e.png 与 

1de8c3ce1c077889c28a7464d49931c0.png 之间的关系。由于样本分布不总是规律的(总有一些点是无法被 

4bd4716a93509ad8a1c295b44647e625.png 覆盖),因此,我们希望模型尽可能地贴近训练样本。这个贴近样本分布的过程,我们称之为拟合。

31f95203b9b762f7f88ff14758d8bbe9.png

那么下面要解决的问题就是,我们如何保证计算出来的

4bd4716a93509ad8a1c295b44647e625.png 足够拟合样本?很简单,使用他们之间的距离来表达差异程度即可。

9dbd31407e34e5bb2de6123f328fefbd.png

这个式子又称为代价函数(cost function)。解释一下:

求和:因为是考虑所有样本的距离,因此需要对所有的距离求和。

除以

6e914e2326c8a71a262b84a99e6a918b.png

6e914e2326c8a71a262b84a99e6a918b.png 在这里是样本容量。除以 

6e914e2326c8a71a262b84a99e6a918b.png 也就是对其求平均值。(整体的视角)

平方:为了消除正负号(有的样本在直线上侧,有的在直线的下测)。

除以 2:在后面推导

2c301a150e9cab4e3780fbe4d74b3af2.png 时就会发现,平方求导出来的2正好能抵消。

距离

ee0065cdd266579d80a02802134f269c.png描述:真实值与预测值的差的平方和。我们希望这距离越小,越能拟合样本,使模型更好地表达,因此我们可以顺理成章地得出线性回归的目标:

536c09fae62e5fb5486770304378de56.png ,也就是最小化代价函数。

那么下面要解决的问题就是,怎么最小化代价函数?

我们根据

69a1b47740e013cf511cf7f4469cbf1d.png 表达式可以画出如下的图:

b08d6dbcef2f52ab79277a10f5f6a4d8.png

将其三维图像映射到二维,使用等高线图表示如下:

566e56afbe288dc1ba9db17f7abba891.png

很显然,我们发现,求

536c09fae62e5fb5486770304378de56.png,也就是求 

69a1b47740e013cf511cf7f4469cbf1d.png 取全局最小值时的 

9e8a9beb2e402454b5e932349c389781.png 和 

bd6cd799e059e3335238aaba2abc823a.png 。

计算全局最小值,我们采用梯度下降法。

怎么使用梯度下降法?

何为梯度下降?我们可以将下降理解为“从山顶上下山的过程”,如何下山能最快到达山底呢?沿着最陡峭的坡滚下去!这里最陡的坡的方向就是我们的梯度的方向。方向我们已经选取好了,就是我们的梯度下降的方向。那么在梯度方向上我们每一步走多远呢?这就是通过步长来决定,也称学习率,记作

fa47eb2c6c60871b3a2a2e47b05df5e0.png

那么综合了方向和步长,我们可以列出

9e8a9beb2e402454b5e932349c389781.png 和 

bd6cd799e059e3335238aaba2abc823a.png 的更新公式如下:

5b8b09a695627bbbd70232e03847a3b6.png

8c3a68201342dae613d36d79c820e8e6.png

于是,我们可以随机设置初始

9e8a9beb2e402454b5e932349c389781.png 和 

bd6cd799e059e3335238aaba2abc823a.png ,然后根据上述公式开始迭代,当 

9e8a9beb2e402454b5e932349c389781.png 和 

bd6cd799e059e3335238aaba2abc823a.png 的值不再更新为迭代停止的标志。

这里的

fa47eb2c6c60871b3a2a2e47b05df5e0.png 的选择对结果以及训练时间是有很大影响,过小的步长会导致学习速度较慢,增加迭代次数或者有可能导致陷入局部最优解;而过大的步长可能会出现难以收敛的情况。这方面我会在别的笔记中补充。因此,选择一个适当的 

fa47eb2c6c60871b3a2a2e47b05df5e0.png 是很重要的。

那么这里我将详细地对线性回归的梯度下降进行推算:

65795ccf0953b36b65971a0cfd1aae54.png

ed8a011f1f97694318b3a465b4f49bef.png

注意:

443ec8a01f1eced7cb8d52300bd633f6.png  是因为平方项求导出来会产生一个2,相互抵销了。 

bd6cd799e059e3335238aaba2abc823a.png 的求导由于前面有系数 

b70c483ad2c9fef901f2088b6a0d7eff.png ,因此在表达式后面乘了 

b70c483ad2c9fef901f2088b6a0d7eff.png 。如果还是不懂的话,建议百度一下复合函数求导。

代码实现

主要就是跟着公式般下来。

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

from sklearn.linear_model import LinearRegression

train = pd.read_csv('Salary_Data.csv')

train.size

输出:60

x = train.iloc[:,0].values

y = train.iloc[:,-1].values

x_ = train.iloc[:,0].values

y_ = train.iloc[:,-1].values

theta_0 = 1

theta_1 = 1

alpha = 0.01

plt.scatter(x, y)

plt.show()

输出:

4cf3ceb9ca06749dcc71a64f7bafa028.png

自己实现线性回归

## H函数

def hF(x, theta0, theta1):

return theta0 + theta1 * x;

##梯度下降过程

def GD_step1(theta_0, theta_1):

sum = 0

for index in range(x.size):

sum += hF(x[index], theta_0, theta_1) - y[index]

return sum

def GD_step2(theta_0, theta_1):

sum = 0

for index in range(x.size):

sum += (hF(x[index], theta_0, theta_1) - y[index]) * x[index]

return sum

## 梯度下降

def GD_0(theta_0, theta_1):

for a in range(1000):

for index in range(x.size):

sum1 = GD_step1(theta_0, theta_1);

sum2 = GD_step2(theta_0, theta_1);

theta_0 = theta_0 - alpha * sum1 / x.size

theta_1 = theta_1 - alpha * sum2 / x.size

return theta_0, theta_1

theta_0, theta_1 = GD_0(theta_0, theta_1)

hF(x[0], theta_0, theta_1)

plt.scatter(x, y)

plt.plot(x, hF(x, theta_0, theta_1), c='red')

输出:

a018067c83a851efb7697190a4f72f66.png

调用sklearn

model = LinearRegression()

x_0 = x_.reshape(-1, 1)

y_0 = y_.reshape(-1, 1)

model.fit(x_0, y_0)

predict = model.predict(x_0)

plt.scatter(x, y)

plt.plot(x, predict, c='red')

plt.show()

158216a9187244e9c6942631cd2746e3.png

数据集百度云链接:链接:https://pan.baidu.com/s/1337VuvKHizv8juNMvlWb3Q 提取码:jgb0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用梯度下降法实现线性回归模型的Python代码: ```python import numpy as np import pandas as pd import matplotlib.pyplot as plt # 加载数据集 data = pd.read_csv('linearRegression_data.txt', header=None, names=['x', 'y']) # 特征缩放 data['x'] = (data['x'] - data['x'].mean()) / data['x'].std() # 添加一列全为1的向量作为截距 data.insert(0, 'Ones', 1) # 将数据集分为特征和目标变量 X = np.matrix(data.iloc[:, :-1].values) y = np.matrix(data.iloc[:, -1:].values) # 初始化theta theta = np.matrix(np.zeros((1, X.shape[1]))) # 定义代价函数 def computeCost(X, y, theta): inner = np.power(((X * theta.T) - y), 2) return np.sum(inner) / (2 * len(X)) # 定义梯度下降函数 def gradientDescent(X, y, theta, alpha, iters): temp = np.matrix(np.zeros(theta.shape)) parameters = int(theta.ravel().shape[1]) cost = np.zeros(iters) for i in range(iters): error = (X * theta.T) - y for j in range(parameters): term = np.multiply(error, X[:, j]) temp[0, j] = theta[0, j] - ((alpha / len(X)) * np.sum(term)) theta = temp cost[i] = computeCost(X, y, theta) return theta, cost # 设置学习率和迭代次数 alpha = 0.01 iters = 1000 # 运行梯度下降算法 theta, cost = gradientDescent(X, y, theta, alpha, iters) # 输出最终的theta值 print(theta) # 绘制代价函数随迭代次数的变化图 fig, ax = plt.subplots() ax.plot(np.arange(iters), cost, 'r') ax.set_xlabel('Iterations') ax.set_ylabel('Cost') ax.set_title('Error vs. Training Epoch') plt.show() ``` 上述代码中,我们首先加载数据集,并进行特征缩放,然后添加一列全为1的向量作为截距。接着,我们将数据集分为特征和目标变量,并初始化theta。然后,我们定义代价函数和梯度下降函数。在梯度下降函数中,我们迭代地更新theta,并计算代价函数的值。最后,我们设置学习率和迭代次数,并运行梯度下降算法。最终,输出得到的theta值,并绘制代价函数随迭代次数的变化图。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值