机器学习笔记——线性回归与梯度下降代码初体验

机器学习笔记——线性回归与梯度下降代码初体验

一、引言

  • 之前的几篇博文我们学习了线性回归、梯度下降的基础思想与操作方法,但也只限于纸上谈兵。机器学习是一门更看重应用与问题解决的学科,因此动手实操尤为重要。
  • 本篇博文我们会详细叙述线性回归与梯度下降初步用python语言实现的过程,为日后研究学习大型项目打下基础。本次实验的目的是复习掌握线性回归与梯度下降的思想,并且熟悉使用python语言实现机器学习。

二、简单模拟线性回归

  • 首先生成x列向量,设定好真实线性函数方程ytrue。由于我们没有相关的离散训练数据集,因此我们使用一定方法去制作一个训练集。我们通过ytrue+noise来产生所有的训练数据集,并用此数据集来训练线性模型。
  • 我们使用sklearn中内置的线性回归相关函数,生成一个线性回归对象,再由该对象训练数据集得到训练后的模型。我们最后通过在图中画出训练集中所有散点与训练得到的线性函数来评估拟合程度。
  • 具体python代码如下:
import numpy as np
from sklearn import linear_model#sklearn是机器学习常用的第三方模块
import matplotlib.pyplot as plt#数据可视化画图
# 获取一个线性回归对象reg
reg = linear_model.LinearRegression()
# 生成列向量x
x = np.arange(-3, 5, step=1)
x = x.reshape(-1, 1)
# 定义ytrue,并由ytrue与noise生成训练集
ytrue = 2 * x - 1
noise = np.random.normal(0, 0.2, len(x)).reshape(-1, 1)
y = ytrue + noise
# reg对象调用fit函数拟合x与y返回函数模型
lmodel = reg.fit(x, y)
coef = lmodel.coef_#获取线性函数斜率
intercept = lmodel.intercept_#获取线性函数截距
R2 = lmodel.score(x, y)#获取线性函数R^2
# 根据fit得出的参数构造训练后的线性函数
ytrain = coef * x + intercept
# 画图表示训练后的函数与训练集散点之间关系
#输出训练集的离散点
plt.plot(x, y, 'b+')#输出训练集散点
#plt.plot(x, ytrue)#输出真实模型
plt.plot(x,ytrain)#输出训练得到的函数模型
plt.xlabel('x')
plt.ylabel('y')
plt.show()
  • 最后得出的图像为:
    在这里插入图片描述
  • 不需要分析,得出的图像一定十分拟合。因为我们这次实验只是一次模拟而已,训练数据集是我们根据真实函数加入一定偏差得到的并不具有分散的代表性。

三、简单梯度下降实现

import numpy as np
from sklearn import linear_model
##sklearn是机器学习常用的第三方模块
import matplotlib.pyplot as plt

reg = linear_model.LinearRegression()#获得线性回归对象
x = np.array([1, 3, 5]).reshape(-1, 1)#获得x列向量
ytrue = 3 * x - 1
noise = np.array([1, -2, 2]).reshape(-1, 1)
y = ytrue + noise#获得三个散点的训练数据集
plt.plot(x, y, 'b+')#散点图展示训练数据集

在这里插入图片描述

lmodel = reg.fit(x, y)#调用fit函数拟合x\y
coef = lmodel.coef_
intercept = lmodel.intercept_
R2 = lmodel.score(x, y)
ytrain1 = coef * x + intercept#获得拟合后的线性函数
plt.plot(x,ytrain1)
plt.plot(x,y,'b+')

在这里插入图片描述

# methods to optimize the square loss function
# define functions: y = ax+b
# x - [1 , 3, 5]
# y = [3,6,16]
# loss = (y1pred-y1)**2 + (y2pred-y2)**2 + (y3pred-y3)**2
# 以下函数根据当前参数值计算两个参数的梯度,返回一个列表
def cal_minus_gradient(a, b):
    gradient_a = 70 * a + 18 * b - 202
    gradient_b = 18 * a + 6 * b - 50
    return ([-gradient_a, -gradient_b])#梯度反方向因此返回值要加个负号
  • 大家可能会对以上函数中梯度计算的公式感到疑惑,其实本次实验也只是简单模拟梯度下降。仅仅设计了三个散点作为训练数据集,根据损失函数LOSS我们可以直接表示出梯度的计算公式,推导过程如下:
    在这里插入图片描述
# main主函数部分
alpha = 0.01#学习率
a = 100#初始a参数值
b = -11#初始b参数值
epslon = 0.00001#精度要求
diff = 1#初始精度设置
model = np.array([[a, b]])#初始化保存参数的列表

# 具体迭代过程,注意循环结束条件
while diff > epslon:
    #根据当前参数计算当前梯度
    G = cal_minus_gradient(a, b)
    a = a + alpha * G[0]#参数更新
    b = b + alpha * G[1]#参数更新
    #下面函数进行列表连接,保存参数修改的历史记录
    model = np.concatenate((model, np.array([[a, b]])), axis=0)
    #下面函数求增长幅度的平方和再开根,当平均增长幅度足够小时才停止迭代
    diffvec = np.array([alpha * G[0], alpha * G[1]])
    diff = np.linalg.norm(diffvec)#平方和再开根
ypred = x * a + b#由梯度下降方法得到相关线性函数

# 画图表示梯度下降得到函数与训练集间的拟合关系
fig, axs = plt.subplots(2)#设置两个子图
#子图1来显示两个参数的梯度下降变化过程
axs[0].plot(model)
axs[1].plot(x, ypred, 'red')
axs[1].plot(x, y, 'bo')

#用R2来衡量线性模型的拟合程度
error = ypred - y  # prediction error
SST = sum((y - y.mean()) ** 2)  #
SSR = sum(error ** 2)
R2 = 1 - SSR / SST
print(R2)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值