线性回归(梯度下降)

news2024/9/25 17:18:03

首先说案例:

房子的价格和所占面积有着很大的关系,假如现在有一些关于房子面积和价格的数据,我要如何根据已经有的数据来判断未知的数据呢?

假如x(房屋面积),y(房屋价格)

x=[ 56 72 69 88 102 86 76 79 94 74]

y=[92, 102, 86, 110, 130, 99, 96, 102, 105, 92]

单变量梯度下降

我们可以看到x和y有一定的关系。假如,我们令

$y=\omega x + b$

这里有两个未知数(\omega,b),我们要如何求得这两个未知数?

我们现在知道的是什么?是所有的x、y的真实值。我们想干什么?想要用公式来预测。预测什么?根据x预测y。我们可以不断尝试改变w和b的值,来判断其预测的准确性。因此这里的w和b是变量。我们要如何衡量这个变量取值后预测的准确性呢?我们可以看下面的图:红线是预测直线,点是真实的面积和价格。可以看到其中不乏存在误差,我们的目标就是使误差达到最小值。那么我们如何来衡量误差呢?我们加下来引进以下术语:

模型函数:y= \omega x + b,也可写成:h_{\omega,b}(x)=\omega x + b

规定:

x^{(i)}第i条记录(样本)
m总样本数

损失函数:

我们要定义一个函数来衡量误差的大小,这个函数称为损失函数

那么如何定义损失函数才能够准确衡量呢?

首先要体现预测值与真实值的误差,那就需要有预测值与真实值的差。

J(\omega,b)=\frac{\sum_{i=1}^{m}(h_{w,b}(x^{(i)})-y^{(i)})^{2}}{2m}

这里用到平方使值都为正数,以便不会相加的时候正负抵消,这里除以m是为了使随着m的增大让损失函数不会递增,这里分母上的2是为了后续计算简便。

我们现在的任务就是求解损失函数J的最小值时对应的w和b。

这里我们引入梯度下降法。网上有很多讲解,这里就不展开。

这里展示对J求导的具体过程:

\frac{\partial J(\omega,b)}{\partial \omega} =\frac{1}{2m}\frac{\partial (\sum_{i=1}^{m}(\omega x^{(i)}+b-y^{(i)})^{2})}{\partial \omega} =\frac{\sum_{i=1}^{m}2 (\omega x^{(i)}+b-y^{(i)})x^{(i)}}{2m} =\frac{\sum_{i=1}^{m}(h_{\omega,b}(x^{(i)})-y^{(i)})x^{(i)}}{m}

梯度下降:

\omega=w-\alpha \frac{\partial J(\omega,b)}{\partial w}

b=b-\alpha \frac{\partial J(\omega,b)}{\partial b}

多变量梯度下降

下面看向量化的内容:

上面的参数只有一个,但是现实生活中影响因子可不止一个,假如有10000个我们肯定不能像上面那样写成一个乘一个。

 波士顿房价数据集 是机器学习中非常知名的数据集,它被用于多篇回归算法研究的学术论文中。该数据集共计 506 条,其中包含有 13 个与房价相关的特征以及 1 个目标值(房价)。

数据在这里:https://labfile.oss.aliyuncs.com/courses/1081/course-5-boston.csv

该数据集统计了波士顿地区各城镇的住房价格中位数,以及与之相关的特征。每列数据的列名解释如下:

  • CRIM: 城镇犯罪率。
  • ZN: 占地面积超过 2.5 万平方英尺的住宅用地比例。
  • INDUS: 城镇非零售业务地区的比例。
  • CHAS: 查尔斯河是否经过 (=1 经过,=0 不经过)。
  • NOX: 一氧化氮浓度(每 1000 万份)。
  • RM: 住宅平均房间数。
  • AGE: 所有者年龄。
  • DIS: 与就业中心的距离。
  • RAD: 公路可达性指数。
  • TAX: 物业税率。
  • PTRATIO: 城镇师生比例。
  • BLACK: 城镇的黑人指数。
  • LSTAT: 人口中地位较低人群的百分数。
  • MEDV: 城镇住房价格中位数。(需要预测的)

我们现在有n个参数\omega_{1}\omega_{2}\omega_{3} \cdots \omega_{n-1}\omega_{n},写成向量的形式就是\vec{\omega}=[\omega_{1}\cdots \omega_{n}]

现在模型就是:f_{\vec{\omega},b}=\vec{\omega}\cdot \vec{x}+b

损失函数是:J(\vec{\omega},b)

梯度下降重复操作是:

repeat:

\omega_{j}=w_{j}-\alpha \frac{\partial J(\vec{\omega},b)}{\partial \omega_{j}}

b=b-\alpha \frac{\partial J(\vec{\omega},b)}{\partial b}

接下来我们具体对损失函数求导:

接下来介绍一些线性回归的一些API:

import sklearn.linear_model as lm
#创建模型
model = lm.LinearRegression()
#训练模型
#输入为一个二维数组表示的样本矩阵
#输出为每个样本最终结果
model.fit(输入,输出)#
#预测输出
#输入array是一个二维数组,每行是一个样本,每一列是一个特性
result = model.perdict(array)

假如下面是总体数据:

x1x2x3y

那么这个就是输入:

这就是输出:

这里使用上面的数据进行测试:

我们的思路如下:

import pandas as pd
import numpy as np
import matplotlib

matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

features = pd.read_csv("https://labfile.oss.aliyuncs.com/courses/1081/course-5-boston.csv")
target = features['medv']
split_num = int(features.shape[0] * 0.7)  # 得到 70% 位置  # 目标值数据
X_train = features[:split_num]  # 训练集特征
y_train = target[:split_num]  # 训练集目标

X_test = features[split_num:]  # 测试集特征
y_test = target[split_num:]  # 测试集目标

model = LinearRegression()  # 建立模型
model.fit(X_train, y_train)
print("系数为", model.coef_)
print("截距为", model.intercept_)

pre = model.predict(X_test)


# 计算平均绝对误差(MAE):
def mae_value(y_true, y_pred):
    n = y_true.shape[0]
    mae = sum(np.abs(y_true - y_pred)) / n
    return mae


# 计算均方误差(MSE)
def mse_value(y_true, y_pred):
    n = y_true.shape[0]
    mse = sum(np.square(y_true - y_pred)) / n
    return mse


mae = mae_value(y_test.values, pre)
mse = mse_value(y_test.values, pre)

print("MAE: ", mae)
print("MSE: ", mse)
plt.figure(figsize=(10, 6))
plt.scatter(y_test.index,y_test.values, color='blue', label='真实值', marker='o')
plt.scatter(y_test.index,pre, color='red', label='预测值', marker='x')
plt.title("预测值与真实值比较")
plt.xlabel('样本编号')
plt.ylabel('房价')
plt.legend(loc='best')
plt.grid(True)
plt.show()

结果:
系数为 [-3.89487871e-15 -5.03069808e-15  3.26128013e-16  9.53456200e-15
  1.23485884e-14 -1.95123865e-15 -4.26741975e-15  6.41414005e-16
  2.91894330e-16  2.81025203e-16  1.00033913e-15 -5.89805982e-17
 -1.12323345e-16  1.00000000e+00]
截距为 2.4513724383723456e-13
MAE:  6.197381789039163e-14
MSE:  7.683577875093926e-27

因为数据给的有点刻意,所以预测结果非常匹配。

注意:这里使用的学习率和最大迭代次数都是固定的,如果想要修改可以通过如下:
 

model = SGDRegressor(learning_rate='constant', eta0=0.01, max_iter=1000, tol=1e-3)

其中:
 

  1. learning_rate

    • 这个参数决定了学习率的调度方法(schedule)。它可以取以下值之一:
      • 'constant':使用恒定的学习率,即 eta0
      • 'optimal':使用一个自适应的学习率,这个学习率取决于初始学习率、当前步数和正则化项。
      • 'invscaling':使用逆比例调度的学习率,学习率会随时间步数的增加而减少。
      • 'adaptive':如果一次训练中的损失未减少,学习率会逐步减少。
  2. eta0

    • 初始学习率。当 learning_rate 设为 'constant''invscaling' 或 'adaptive' 时,这个值就决定了模型的初始学习率。对于 SGDRegressoreta0 是模型学习参数更新的步长。
  3. max_iter

    • 最大迭代次数。它决定了训练模型时允许的最大迭代次数。对于大型数据集,可能需要更多的迭代次数才能使模型收敛。
  4. tol

    • 容差(tolerance)。训练过程会在损失函数的变化小于这个容差值时提前停止,意味着模型已基本收敛。如果设置得过小,模型可能会运行更多的迭代次数才能收敛。

下面看一个纯手敲的版本:
添加一个截距项,方便矩阵相乘得出,偏移项b

# 增加一个截距项
X_train = np.c_[np.ones(X_train.shape[0]), X_train]
X_test = np.c_[np.ones(X_test.shape[0]), X_test]

这个代码:X_train.shape得到的是一个元组(行数,列数),再[0]取出行数。然后用np.ones创建一个这么多行的全为1的矩阵。np.c_是将两个矩阵连接(水平连接)

接下来是梯度下降的过程:
 

def gradient_descent(X, y, learning_rate=0.01, max_iter=1000, tol=1e-3):
    m, n = X.shape
    theta = np.zeros(n)
    for iteration in range(max_iter):
        gradient = X.T.dot(X.dot(theta) - y) / m
        new_theta = theta - learning_rate * gradient
        if np.linalg.norm(new_theta - theta, ord=1) < tol:
            break
        theta = new_theta
    return theta
  1. 输入参数:

    • X: 特征矩阵,其中每行代表一个样本,每列代表一个特征。
    • y: 目标变量的向量。
    • learning_rate: 学习率,控制每次更新的步长,默认为0.01。
    • max_iter: 最大迭代次数,用于控制梯度下降的迭代次数,默认为1000。
    • tol: 容忍度,用于控制算法收敛的阈值,默认为1e-3。
  2. 初始化参数:

    • m, n = X.shape: 获取特征矩阵 X 的行数(样本数)和列数(特征数)。
    • theta = np.zeros(n): 初始化参数向量 theta,全部设为零,长度与特征数相同。
  3. 梯度下降迭代:

    • for iteration in range(max_iter)::循环执行梯度下降迭代。
    • gradient = X.T.dot(X.dot(theta) - y) / m: 计算梯度,这里使用了线性回归模型的损失函数的梯度公式。
    • new_theta = theta - learning_rate * gradient: 更新参数向量 theta,向梯度的负方向移动一定步长。
    • if np.linalg.norm(new_theta - theta, ord=1) < tol::检查参数更新的变化是否小于阈值 tol,如果满足要求则停止迭代。
    • theta = new_theta: 将更新后的参数向量赋值给 theta 继续下一次迭代。
  4. 返回结果:

    • 返回最终收敛的参数向量 theta,该向量能够使得线性回归模型拟合样本数据最佳。

看一下矩阵推导的梯度下降:
 

这里面有一些关于矩阵求导的课程:

【机器学习中的矩阵求导方法】 https://www.bilibili.com/video/BV1ZU4y1g7Zj/?share_source=copy_web&vd_source=4d2276692373e2a32789e2a8319e4a50

【【手推机器学习】矩阵求导--合集】 https://www.bilibili.com/video/BV1xk4y1B7RQ/?p=5&share_source=copy_web&vd_source=4d2276692373e2a32789e2a8319e4a50

矩阵求导(四)常见矩阵求导公式证明 - 知乎 (zhihu.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1923975.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

struts2如何防止XSS脚本攻击(XSS防跨站脚本攻击过滤器)

只需要配置一个拦截器即可解决参数内容替换 一、配置web.xml <filter><filter-name>struts-xssFilter</filter-name><filter-class>*.*.filters.XssFilter</filter-class></filter><filter-mapping><filter-name>struts-xss…

1.5.1抽象java入门

前言&#xff1a; 1.5.0版本中&#xff0c;我们熟练使用Git三个可视化操作&#xff08;签出&#xff0c;提交&#xff0c;对比&#xff09;&#xff0c;再加上1.4.0版本的新建&#xff0c;总计使用四个Git可视化操作&#xff1b;对java编程的学习&#xff0c;总结&#xff0c;…

vector 介绍

1.简述vector 首先我们要大致弄明白vector是一个什么东西,其实vector就是之前我们学过的顺序表,这里直接使用就行了. 定义vector-------->vector<typename> arr 此时的这种定义vector可以理解成为一个数组,而typename可以是各种数据类型,比如string,int,double....…

react启用mobx @decorators装饰器语法

react如果没有经过配置&#xff0c;直接使用decorators装饰器语法会报错&#xff1a; Support for the experimental syntax ‘decorators’ isn’t currently enabled 因为react默认是不支持装饰器语法&#xff0c;需要做一些配置来启用装饰器语法。 step1: 在 tsconfig.js…

宪法学学习笔记(个人向) Part.6

宪法学学习笔记(个人向) Part.6 5. 国家机构 概述 国家机构是国家为了实现其管理社会、维护社会秩序职能而建立起来的国家机关的总和&#xff1b;它包括&#xff1a; 立法机关&#xff08;全国人大及其常委会&#xff09;;行政机关&#xff08;国务院和地方人民政府&#xff09…

文心一言:如何备考软考架构师

提问&#xff1a;软考高级:架构师指导&#xff0c;有哪些考点、重点考点有哪些&#xff1f;需要如何备考&#xff1f;案例分析题如何做&#xff1f;论文如何写&#xff1f; 文心一言回答1700字如下&#xff1a; 针对软考高级架构师的考试&#xff0c;以下是对考点、重点考点、备…

33. 322.零钱兑换,279.完全平方数,139.单词拆分,关于多重背包,你该了解这些!,背包问题总结篇!

class Solution { public:int coinChange(vector<int>& coins, int amount) {if(amount 0) return 0;// dp[j]&#xff1a;凑足总额为j所需钱币的最少个数为dp[j]vector<int> dp(amount 1, INT_MAX); //注意初始化方式&#xff01;&#xff01;&#xff01;&…

包管理器冲突-jupyter安装配置

当你使用不同的包管理器安装相同的包&#xff0c;可能存在冲突&#xff0c;比如安装jupyter notebook在本地运行&#xff0c;你可能会遇到这种错误&#xff1a; TypeError: create.<locals>.Validator.__init__() got an unexpected keyword argument registry 甚至你可…

客家菜餐馆点菜小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;菜系管理&#xff0c;菜品信息管理&#xff0c;我的订单管理&#xff0c;桌号管理&#xff0c;退款信息管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;菜品信息&#…

vue + element ui 实现侧边栏导航栏折叠收起

首页布局如下 要求点击按钮,将侧边栏收缩, 通过 row 和 col 组件&#xff0c;并通过 col 组件的 span 属性我们就可以自由地组合布局。 折叠前 折叠后 <template><div class"app-layout" :class"{ collapse: app.isFold }"><div class&…

医疗级微型导轨:保障医疗行业手术安全!

微型直线导轨能成为一种专为医疗行业设备运用的高精度线性运动设备&#xff0c;在现代医疗领域&#xff0c;精准的位置控制和平稳的运动对于确保医疗设备的高效性能至关重要。那么&#xff0c;医疗行业对微型导轨有哪些要求呢&#xff1f; 1、精度&#xff1a;在手术过程中&…

蔡仲杨摄影入门到高手

描述 蔡仲杨&#xff0c;一个富有才华的老师&#xff01; 对于大家的学习有不可多得的帮助。 内容 目前主要的内容以摄影为主&#xff0c;对于学习摄影有比较大的帮助&#xff01; 但是网络上面错综复杂&#xff0c;很多老旧的版本影响学习&#xff01; 而这里我整理了相关…

小白学python(第七天)

哈哈&#xff0c;这个系列的文章也有一段时间没更新&#xff0c;主要是最近在忙c嘎嘎&#xff0c;不过没事接下来会优先更python啦&#xff0c;那么我们先进入正题吧 函数的定义及调用 函数定义 格式&#xff1a;def 函数名&#xff08;形参列表&#xff09;&#xff1a; 语…

函数(实参以及形参)

实际参数&#xff08;实参&#xff09; 实际参数就是在调用函数时传递给函数的具体值。这些值可以是常量、变量、表达式或更复杂的数据结构。实参的值在函数被调用时传递给对应的形参&#xff0c;然后函数内部就可以使用这些值来执行相应的操作。 int main() {int a 0;int b …

【Flowable | 第一篇】Flowable介绍以及数据库表说明

文章目录 1.前言1.1Flowable是什么&#xff1f;1.2重要概念1.3使用步骤 2.全局配置说明2.1数据库表说明2.2BPMN文件说明&#xff08;了解&#xff09;2.2.1BPMN定义2.2.2BPMN基础元素 1.前言 1.1Flowable是什么&#xff1f; Flowable是WorkFlow的一种工作流WorkFlow&#xff…

zabbix 7.0 SNMP Hex数据预处理新功能

一、简介 zabbix7.0新特性是监控项新增支持SNMP Hex数据预处理。其中内置了对snmp请求结果Hex转换处理&#xff0c;不再需要使用繁琐的方式&#xff0c;如javascript脚本、替换、修整等方式处理将监控项取值做可视化处理&#xff0c;大福提升SNMP采集获取到Hex数据的处理效率。…

day05-matplotlit设置图形各种参数

matplotlib网格 1. 显示网格:plt.grid() plt.grid(True, linestyle "--",color "gray", linewidth "0.5",axis x)显示网格linestyle&#xff1a;线型&#xff0c;“–”:表示网格是虚线&#xff0c;默认为实线color&#xff1a;网格颜色li…

MongoDB7出现:Windows下使用mongo命令提示不是内部或外部命令

确保环境变量添加正确的情况&#xff0c;仍然出现这种问题。如果安装的是新版本&#xff0c;则大概率是新版本mongodb的bin里面没有mongo命令 解决方案&#xff1a; 下载mongodb shell 下载链接 把shell的命令放进来 启用命令&#xff1a;mongosh

记录些Redis题集(3)

分布式锁 分布式锁是一种用于在分布式系统中实现互斥访问的机制&#xff0c;它可以确保在多个节点、或进程同时访问共享资源。如果没有适当的锁机制&#xff0c;就可能导致数据不一致或并发冲突的问题。 分布式锁需要的介质 需要一个多个微服务节点都能访问的存储介质&#…

【操作系统】进程管理——死锁(个人笔记)

学习日期&#xff1a;2024.7.13 内容摘要&#xff1a;死锁的概念和三大处理策略 目录 死锁 死锁的概念 死锁、饥饿和死循环的区别 死锁产生的必要条件 死锁的处理策略&#xff1a;预防、避免和解除 预防死锁 破坏互斥条件 破坏不剥夺条件 破坏请求和保持条件 破坏循…