前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >线性回归

线性回归

原创
作者头像
AlanWalker
发布2022-03-17 14:36:39
8070
发布2022-03-17 14:36:39
举报
文章被收录于专栏:jinyu's Blog

理论

回归问题通常用于连续值的预测,可以总结为给定x, 想办法得到f(x),使得f(x)的值尽可能逼近对应x的真实值y。

假设,输入变量x与输出值y成线性关系,比如随着年龄(x)增大, 患癌症的概率(y)也会逐渐增大。

则有,

f(x) = w * x + b

其中:x为输入值,f(x)为预测值,w为权重,b为修正的常量

我们给定w,b一个初始值。最终的目标是得到一个w, b的确定值,使得f(x)与真实值y的误差尽可能小。

于是,定义一个用来评价预测值与真实值之间的误差的函数loss:

loss = ∑_i (w * x_i + b - y_i)

我们认为当这个损失函数最小的时候能够得到不错的w和b,从而获得不错的估计值。因此,问题就转换成了找到loss的最小值。

为了找到最小值,这里使用梯度下降法(Gradient Descent)

image.png
image.png

梯度下降算法的核心就是一个函数的导数是指向函数值的增长方向的。因此当导数值变化的时候,我们就可以得到函数的极小值。为了找到最小值,这个计算导数的最小值得方向应该是朝着导数变小的方向来前进。

为了避免单次变化太大,一步跨过最小点,我们需要使用学习率(leaning rate)乘以导数,这个就是步长,这样就可以防止跨过最小点。

总结,目标是得到w’和b’,为了得到这两个值我们使用了一个损失函数,损失函数最小的时候的可以得到最优的w’和b’,为了得到最小的损失函数我们使用梯度下降方法。

  1. 构造损失函数
  2. 梯度下降找到最小的损失函数

就这么简单。

代码演示

这里单纯使用数学方式,借助python numpy来实现。(过程仅供参考,不一定写的标准)

原始数据为csv文件。

image.png
image.png
代码语言:python
代码运行次数:0
复制
import numpy as np
from matplotlib import pyplot as plt


def loss_function(b: float, w: float, points: np.ndarray):
    totalError = 0
    loss_b = 0
    loss_w = 0
    for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1]
        totalError += (y - (x*w + b))**2
        loss_b += 2 * (1 / len(points)) * ((x*w + b) - y)
        loss_w += 2 * (1 / len(points)) * ((x*w + b) - y) * x
    totalError = totalError / len(points)
    return loss_b, loss_w, totalError


def gradient_descent_iterator(num_iterations: int, initial_b: float, initial_w: float, points: np.ndarray, leaning_rate: float):
    b = initial_b
    w = initial_w
    totalError = 0
    for i in range(num_iterations):
        [b, w, totalError] = gradient_descent_step(b, w, points, leaning_rate)
        print("step{0}====b:{1}, w:{2}, loss: {3}".format(str(i), str(b), str(w), str(totalError)))
    return [b, w, totalError]


def gradient_descent_step(b: float, w: float, points: np.ndarray, leaning_rate: float):
    loss_b, loss_w, totalError = loss_function(b, w, points)
    new_b = b - leaning_rate * loss_b
    new_w = w - leaning_rate * loss_w
    return [new_b, new_w, totalError]


def draw_figure(points: np.ndarray, b: float, w: float):
    xPoints = points.transpose()[0]
    yPoints = points.transpose()[1]
    yPredict = xPoints * w + b
    plt.scatter(xPoints, yPoints)
    plt.plot(xPoints, yPredict)
    plt.legend(['yPoints', 'yPredict'])
    plt.show()


def run():
    # 将csv文件内的数据读入并转成shape为(100, 2)的ndarray
    points = np.genfromtxt('data.csv', delimiter=',')
    # 学习率
    leaning_rate = 0.0001
    # 修正常量初始值
    initial_b = 0
    # 权重初始值
    initial_w = 0
    # 迭代次数
    num_iterations = 1000
    draw_figure(points, initial_b, initial_w)
    [b, w, totalError] = gradient_descent_iterator(num_iterations, initial_b, initial_w, points, leaning_rate)
    draw_figure(points, b, w)


if '__main__' == __name__:
    run()

结果打印如下:

image.png
image.png

可以看到,虽然我们设置迭代1000次,但由于过于简单,在迭代第8次的时候,损失就已经由5565降到了112,并趋于平缓。

训练前和训练后的图像绘制如下:

image.png
image.png
image.png
image.png

拟合的结果还是比较符合预期的。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 理论
  • 代码演示
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档