机器学习之回归模型-梯度下降法求解线性回归

机器学习之回归模型-梯度下降法求解线性回归

线性回归是一种线性模型,它假设输入变量x与单个输出变量y之间存在线性关系。具体的说,就是利用线性回归模型,从一组输入变量的线性组合中,计算出输出变量y。

如果有两个或者两个以上的自变量,这样的线性回归分析,就是多元线性回归。其实,在实际生活中,一个现象往往受多个因素的影响,所以多元线性回归比一元线性回归的应用更广。

假如说:我想买西瓜,此时,我应该挑选自己满意的西瓜,那么怎么挑选呢,我们应该从从色泽,根蒂,敲打的声音等多个维度考察西瓜的质量,假如每个影响西瓜的因素和瓜的质量是线性关系,就可以写成入下线性的关系:

在这里插入图片描述
使用梯度下降法求解多元线性回归:
其中J为损失函数,对损失函数中的参数求偏导得到梯度,带到梯度下降公式中,使得梯度不断下降,即沿着负梯度方向,使得损失函数越来越小,即误差最小,模型越来越好。
在这里插入图片描述
负梯度方向:函数变化减少最快的方向,即变量沿此方向变化时,函数减少最快。

损失函数是系数的函数,如果系数沿着损失函数的负梯度变化,此时损失函数减少最快,能够以最快速度下降到最小值。

其中,梯度下降公式入下:
其中α叫做步长,也叫做学习率,这意味着我们可以通过控制及步长来控制每一步走的距离,保证不要走太快,防止错过了最低点,同时也要保证尽快收敛,故α在梯度下降中还是比较重要的,既不能太大,也不能太小。
在这里插入图片描述
如果觉得多元线性回归的梯度下降不好理解,我们可以退回到一元线性回归的梯度下降进行观察,如下所示,其实就是不停的更新参数值,使得损失函数越来越小
在这里插入图片描述
线性回归求解可以使用最小二乘法和梯度下降法,下面我们针对两种方法进行对比:
1-相同点:本质和目标相同,两种都是经典的学习算法,在给定已知数据的情况下,利用求导算出一个模型(函数),使得损失函数最小,然后对给定的新数据进行估算预测。

2-不同点:损失函数的选择:最小二乘法必须使用平方损失函数,而梯度下降可以选取其它函数;实现方法不同,最小二乘法是实现全局最小,而梯度下降是一种迭代法;一般最小二乘法一定可以得到全局最小,但对于多元计算繁琐,且复杂情况下未必有解,而梯度下降的迭代比较简单,但找到的一般是局部最小,即极小值,仅在目标函数是下凸函数是才是全局最小,到最小点的收敛速度会变慢,且对初始点的选择极为敏感,而且步长的选择对损失函数也有影响。

使用梯度下降求解线性回归代码如下所示,
demo同步已经能上传至github,包含源代码和数据集,链接如下:https://github.com/wgdwg/-1

#梯度下降求解线性回归
import numpy as np #导入计算包
import matplotlib.pyplot as plt #导入绘图包
#1.加载数据源,并画出散点图
points = np.genfromtxt('data.csv', delimiter=',')

#提取points的两列数据,分别作为x,y
x = points[:,0] #第一列数据
y = points[:,1] #第2列数据

#用plt画出散点图
plt.scatter(x,y)
plt.show()

#2.定义损失函数,损失函数是系数的函数
def cost_function(w, b, points):
    total_const = 0 #初始化损失函数
    m = len(points) #数据个数
    #逐点计算平方误差,然后求平均数
    for i in range(m):
        x = points[i,0] #第i行,第1列
        y = points[i,1] #第i行,第2列
        total_const += (y - w * x - b) ** 2
    return total_const / m

#3.定义模型的超参数
alpha = 0.0001 #学习速率
init_w = 0 #初始参数
init_b = 0 #初始参数
num_iter = 10 #迭代次数

#4.定义核心梯度下降算法函数
def grad_desc(points, init_w, init_b, num_iter):
    w = init_w
    b = init_b
    #定义一个列表cost_list保存所有损失函数值
    cost_list = []
    for i in  range(num_iter):
        cost_list.append(cost_function(w,b,points)) #存入损失函数
        w, b = step_grad_desc(w,b,alpha,points) #不挺的更新参数w,b
    return [w, b, cost_list]

def step_grad_desc(current_w, current_b, alpha, points):
    sum_grad_b = 0
    sum_grad_w = 0
    m = len(points)
    #对每个点,带入公式求和
    for i in range(m):
        x = points[i, 0]  # 第i行,第1列
        y = points[i, 1]  # 第i行,第2列
        sum_grad_w += (current_w * x + current_b - y) * x
        sum_grad_b += (current_w * x + current_b - y) ;
    #求当前的偏导
    grad_w = 2 / m * sum_grad_w
    grad_b = 2 / m * sum_grad_b
    #梯度下降,沿负梯度方向,更新当前的w和b
    update_w = current_w - alpha * grad_w
    update_b = current_b - alpha * grad_b

    return update_w, update_b

#5.测试,运行梯度下降,计算最优的w和b
w, b, cost_list = grad_desc(points, init_w, init_b, num_iter)
cost = cost_function(w,b,points) #得到损失函数

print("参数w = ", w)
print("参数b = ", b)
print("损失函数 = ", cost)
plt.plot(cost_list)
plt.show()

#6.画出拟合曲线
plt.scatter(x,y) #原始的散点图
pred_y = (w * x) + b #预测的y
plt.plot(x,pred_y,c='r') #红色的拟合直线
plt.show() #显示绘图


梯度下降,迭代数次后,损失函数趋于最小,110左右。
在这里插入图片描述
散点图的拟合直线如下所示:
在这里插入图片描述
控制台输出的损失函数相对于最小二乘法稍大,即误差稍大。
在这里插入图片描述

  • 5
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

nuist__NJUPT

给个鼓励吧,谢谢你

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

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

打赏作者

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

抵扣说明:

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

余额充值