机器学习__线性回归

问题引入

现有一组训练数据train_xtrain_y:

train_x = [1, 2, 3, 5, 6]
train_y = [2, 4, 5, 7, 9]

执行下述代码后

mp.scatter(train_x, train_y)
mp.show()

得到散点图:
在这里插入图片描述
通过观察我们可以发现, 训练集中的5个点近似分布在一条直线上, 我们将这条直线用y = w0 + w1*x表示. 线性回归的目的, 就是求出一组合适的w0w1

损失函数

我们如何判断求得的w0w1是否合适呢? 显然, 我们求得的直线应该尽可能地靠近训练集中的5个点.
我们用损失函数loss_function来描述数据"靠近"回归直线的程度.
假设对于某一个x, x对应的值为y, 我们将’x’带入直线方程中得到为y', 则损失定义为0.5*(y'-y)^2, 即0.5*(w0+w1*x-y)^2. 损失函数即为全部数据损失的和.
此时, 问题转化成了: 如何求得一组w0w1, 使得损失函数取得极小值.

梯度下降法

梯度下降法能够帮助我们高效地找到损失函数的极小值(或近似极小值), 思路如下:

  1. 规定梯度下降次数times和学习率lrate
times = 1000
lrate = 0.01
  1. 随机选择一组w0w1的取值
w0, w1 = 1, 1
  1. w0w1分别求偏导数d0d1
d0 = (w0 + w1 * train_x - train_y).sum()
d1 = (train_x * (w0 + w1*train_x - train_y)).sum()
  1. 更新w0w1的值
w0 = w0 - lrate*d0
w1 = w1 - lrate*d1
  1. 重复步骤3,4, 次数为times
完整代码
times = 1000
lrate = 0.01
w0, w1 = 1, 1
for i in range(0, times):
    d0 = (w0 + w1 * train_x - train_y).sum()
    d1 = (train_x * (w0 + w1*train_x - train_y)).sum()
    w0 = w0 - lrate * d0
    w1 = w1 - lrate * d1
print("w0=", w0)
print("w1=", w1)
# w0= 1.0116288204591268
# w1= 1.2906974643094398

得到的回归直线如下图所示:
在这里插入图片描述

调参

在上述训练过程中, timeslrate的取值会对结果产生比较大的影响, 为此我们需要调整二者的取值, 以达到更好的训练效果.

我们适当调整一下训练代码, 将每一次梯度下降后的w0,w1loss都保存下来, 最后以图像的形式展示出来.

times = 1000
lrate = 0.001
w0, w1, losses, cnt = [3], [3], [], []
for i in range(1, times+1):
    cnt.append(i)
    loss = ((w0[-1] + w1[-1] * train_x - train_y) ** 2).sum() / 2
    losses.append(loss)
    d0 = (w0[-1] + w1[-1] * train_x - train_y).sum()
    d1 = (train_x * (w0[-1] + w1[-1] * train_x - train_y)).sum()
    w0.append(w0[-1] - lrate * d0)
    w1.append(w1[-1] - lrate * d1)


line_x = np.linspace(train_x.min(), train_x.max(), 100)
line_y = w0[-1] + w1[-1] * line_x
print(w0[-1], w1[-1])

mp.figure('result')
mp.scatter(train_x, train_y)
mp.plot(line_x, line_y, color="orange")

mp.figure('process')
mp.subplot(311)
mp.ylabel(r'$w_0$')
mp.plot(cnt, w0[1:], color="blue")
mp.subplot(312)
mp.ylabel(r'$w_1$')
mp.plot(cnt, w1[1:], color="green")
mp.subplot(313)
mp.ylabel(r'$loss$')
mp.plot(cnt, losses, color="blue")

mp.show()

得到下图:
在这里插入图片描述
在这里插入图片描述

我们观察到, 虽然loss已经基本不变, 但w0仍然在变化, 所以我们应当适当增加times的取值, 不妨令times = 5000, 得到下图:
在这里插入图片描述
在这里插入图片描述

调用API

import numpy as np
import matplotlib.pyplot as mp
import sklearn.linear_model as lm

train_x = np.array([1, 2, 3, 5, 6])
train_y = np.array([2, 4, 5, 7, 9])

# 创建模型
model = lm.LinearRegression()
# 训练模型
# 输入为一个二维数组(一行一样本,一列一特征)
# 输出为一个一维数组
train_x = train_x.reshape(-1, 1)  # 将train_x转化为一个n行1列的二维数组
model.fit(train_x, train_y)
# 模型预测
# 输入为一个二维数组(一行一样本,一列一特征)
# 输出为一个一维数组
pre_y = model.predict(train_x)

# 绘制回归线
mp.figure('result')
mp.scatter(train_x, train_y)
mp.plot(train_x, pre_y, color="orange")

mp.show()

得到下图:
在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值