梯度下降法求解线性预测问题(Python+matlab实现)

问题描述

一阶线性函数可表示为如下形式(其中x为横坐标,y为纵坐标):

给定数据如下图所示,共有10个样本点。

其中左边一列(1, 2, 3, ..., 10)为X坐标,右边一列(3.64, 4.35, 4.74, ..., 7.50)为Y坐标。

将数据表示在坐标轴上,如下图所示:

要求根据给出的数据,使用梯度下降法求出k和b的值。

Python实现


import numpy as np

def grad_descent(points, k_start, b_start, learning_rate, num_iter):
    k = k_start
    b = b_start
    for i in range(num_iter):
        # 根据k和b的初始值,计算新一轮迭代后k和b的值
        # 该部分每运行一次,意味着k和b更新一次

        # k和b梯度初始值设为0
        grad_k = 0
        grad_b = 0

        # 依次代入每个样本点
        for i in range(len(points)):
            # 读取样本点中的X和Y坐标
            x = points[i][0]
            y = points[i][1]

            # 将每个样本点代入损失函数的偏导数,累加计算梯度值
            # 损失函数:E = 0.5 * ((k * x) + b - y) ** 2
            # 所以损失函数对于k和b的偏导数分别为:dE/dk、dE/db
            grad_k += x * ((k * x) + b - y)  # grad_k = dE/dk
            grad_b += (k * x) + b - y  # grad_b = dE/db

        # 更新k和b的值
        k = k - (learning_rate * grad_k)
        b = b - (learning_rate * grad_b)

    return [k, b]


if __name__ == "__main__":
    # 训练集数据点坐标
    points = [[1,3.64],[2,4.35],[3,4.74],[4,4.4],[5,4.3],[6,5.5],[7,7.42],[8,6.69],[9,8.52],[10,7.5]]
    
    # 设置参数
    learning_rate = 0.001  # 学习率
    num_iter = 100  # 迭代次数

    # 设定k和b的初始值
    k_start = 1
    b_start = 1

    # 计算k和b的值
    [k, b] = grad_descent(points, k_start, b_start, learning_rate, num_iter)
    print("k = ", k)
    print("b = ", b)

输出结果如下:


k =  0.7343955949672608
b =  1.3369372262480115

将k和b的值代入,然后画图(程序略),结果如下:

图中蓝色的散点即为训练集样本点,红色的直线即为由k和b值得到的图像。

matlab实现

构造函数grad_descent如下:

function [k, b] = grad_descent(points, k_start, b_start, learning_rate, num_iter)

% function [k, b] = grad_descent(points, k_start, b_start, learning_rate, num_iter)
% 梯度下降法求解线性回归问题
% 输入:point——训练集样本点坐标集合,每行表示一个样本点,第1列表示X坐标,第2列表示Y坐标
% 输入:k_start、b_start——k和b的初始值
% 输入:learning_rate——学习率
% 输入:num_iter——迭代次数
% 输出:k、b——计算后得到的k和b值

k = k_start;
b = b_start;

% 进行num_iter次迭代
for i = 1 : num_iter
    grad_k = 0;
    grad_b = 0;
    
    % 对于每个样本点
    for j = 1 : size(points, 1)
        % X、Y坐标
        x = points(j, 1);
        y = points(j, 2);
        
        % 偏导数(梯度)
        grad_k = grad_k + x * ((k * x) + b - y);
        grad_b = grad_b + (k * x) + b - y;
        
        % 更新k和b的值
        k = k - (learning_rate * grad_k);
        b = b - (learning_rate * grad_b);
    end
end

代入数据计算:

clear all;
close all;

% 样本点
points = [1,3.64; 2,4.35; 3,4.74; 4,4.4; 5,4.3;
    6,5.5; 7,7.42; 8,6.69; 9,8.52; 10,7.5];

% 参数设置
learning_rate = 0.001;  % 学习率
num_iter = 100;  % 迭代次数

% k、b的初始值
k_start = 1;
b_start = 1;

% 计算k、b的值
[k, b] = grad_descent(points, k_start, b_start, learning_rate, num_iter);
fprintf("k = %d\n", k);
fprintf("b = %d\n", b);

输出结果如下:


k = 5.571244e-01
b = 2.585857e+00

根据求出的k和b的值,画图如下:

图中蓝色的散点即为训练集样本点,红色的直线即为由k和b值得到的图像。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值