【论文阅读】Machine Learning, Linear Algebra, and More: Is SQL All You Need?

文章目录

  • 摘要
  • 一、介绍
  • 二、SQL算法原语
    • 2.1、Variables
    • 2.2、Functions
    • 2.3、Conditions
    • 2.4、Loops
    • 2.5、Errors
  • 三、案例研究
    • 3.1、对数据库友好的SQL映射
    • 3.2、性能结果
  • 四、结论以及未来工作


摘要

  尽管SQL在简单的分析查询中无处不在,但它很少用于更复杂的计算,如机器学习、线性代数和其他计算密集型算法。这些算法通常以过程方式编程,看起来与声明性SQL查询非常不同。然而,SQL实际上提供了执行各种计算的构造。在本文中,我们展示了如何将过程结构转换为SQL-启用复杂的SQL-only算法。在算法中使用SQL可以使计算更接近数据,只需要最小的用户权限,并增加软件的可移植性。生成的SQL算法的性能在很大程度上取决于底层DBMS和SQL代码。令人惊讶的是,我们发现像HyPer这样的查询引擎可以实现非常高的性能——在某些情况下甚至胜过像NumPy这样的最先进的线性代数包。

一、介绍

  理论上,任意计算都可以用SQL来表示。然而,这通常被认为是一种理论观察,而不是一种实际方法。在SQL中直接表示复杂算法的一个障碍是,算法通常是用过程语言表示的。SQL的声明性使得编写统计学习或优化算法的查询变得非常重要。

  目前,复杂的算法是在数据库系统之外实现的,使用用户定义函数(udf),或者依赖于系统特定的dbms内操作符。直接在SQL中表达算法有四个主要好处:

  • 近数据计算
      使用SQL算法,使得数据保留在数据库中,SQL查询引擎可以立即开始计算。并且只显示计算结果,而不显示底层数据,则可以确保更高的数据隐私。
  • 灵活性
      使用SQL可以自由定制修改,且只需要最小的用户权限就可以执行各种计算。
  • 高度抽象
      SQL算法的向量化、并行甚至分布式执行由底层DBMS自动完成
  • 可移植性
      如果SQL算法使用由多个DBMS供应商支持的通用SQL子集,那么该算法无需修改即可在其他DBMS上运行。

二、SQL算法原语

  在本节中,我们将过程语言的算法原语映射到SQL的声明性语法。为了演示这种转换,我们将展示Python和PostgreSQL的SQL方言中的代码片段。

2.1、Variables

  在SQL中,Variables可以表示为关系或关系中的值。这里的关系指的是一些数据结构,如标量、向量、矩阵、张量、集合、哈希表,甚至树和图。在SQL计算期间,可以使用WITH子句创建新变量。WITH子句允许命名子查询。然后可以在主查询中的几个位置引用这些命名的子查询。然而,与过程语言中的变量不同,SQL中使用with子句创建的变量是不可变的。要更新SQL变量,必须创建一个新变量。对于这类原语的python与SQL转换的例子如下:

在这里插入图片描述

2.2、Functions

  函数在大多数编程语言中都是必不可少的。SQL标准允许创建SQL函数,但并不是所有系统都支持。所以有一种替代方法是用WITH构造,从而允许将本地函数嵌入到SQL查询中。
在这里插入图片描述

2.3、Conditions

  标准SQL不提供分支结构,例如if-else来控制程序流。在SQL中,最接近if-else语句的结构是CASE语句。但是,CASE语句决定表达式的结果,因此类似于三元操作符而不是控制结构
  要在SQL中模拟条件控制流,UNION ALL构造是合适的。UNION ALL构造将两个或多个SELECT语句的结果组合在一起。通过只组合那些满足SELECT语句WHERE子句条件的结果,就可以模拟条件控制流(见清单3)。UNION ALL的唯一限制是各个SELECT语句中列的数量和列的数据类型必须匹配。
在这里插入图片描述

2.4、Loops

  在SQL中,循环有两种变体,它们是通过递归查询实现的,符合SQL标准[11]。大多数dbms都支持第一种变体,它是一个简单的循环,在子查询中没有递归引用(参见清单4),如下
在这里插入图片描述
  第二种变体包含子查询中的递归引用,据我们所知,它只在PostgreSQL、DuckDB和HyPer中得到完全支持,如下
在这里插入图片描述
  第二个循环变体允许在FROM子句的子查询中使用清单5中的递归工作表x。这些子查询也可以是递归的。如果对工作表的递归引用在FROM子句中出现超过一次,PostgreSQL将产生一个错误。可以通过在FROM子句中创建一个新变量并在以后的计算中引用它来避免这个错误(参见清单5中针对PostgreSQL的变通方法)我们大量利用子查询中的递归引用在SQL中实现各种算法。通过在子查询中支持递归引用,DBMS供应商可以在其产品中启用仅sql算法。

  递归查询的限制因素是缺乏拥有多个工作表的可能性。在递归中只允许有一个工作表。如果算法需要在每次迭代中更新多个变量,则必须立即将它们全部打包到工作表中。在迭代期间,这些变量必须从工作表中解包,然后再为下一次迭代重新打包。

2.5、Errors

  具有实用价值的SQL程序应该对错误的输入数据提供反馈。为了在SQL中实现输入验证,我们使用UNION ALL构造。在清单6中,计算了三种状态下概率分布的熵。概率的一个性质是它们大于等于零并且它们对所有状态的和是1。在创建错误关系时,在WHERE子句中检查这些前提条件。如果检测到错误输入,则Errors应该包含相应的错误消息。

在这里插入图片描述


三、案例研究

  这里使用基于梯度下降的逻辑回归作为案例研究,以证明以数据库友好风格编写的SQL算法是实用的。逻辑回归是一种流行的二元分类机器学习方法,它会导致以下凸优化问题:
在这里插入图片描述
  下面是一个用python写的基于梯度下降的逻辑回归
在这里插入图片描述

3.1、对数据库友好的SQL映射

  计算梯度是算法中最耗时的操作。如果性能很重要,那么用于计算梯度的SQL代码必须是数据库友好的。在这里,梯度计算主要由线性代数运算组成。SQL中的线性代数计算通常映射为一种格式,该格式显式存储向量或矩阵的每个值的索引。向量和矩阵的这种表示类似于用于稀疏线性代数的坐标格式(COO)。下面显示了如何在SQL中使用COO样式计算清单7中的梯度。
在这里插入图片描述
  在SQL中使用COO风格进行线性代数的一个优点是它的通用性,也就是说,SQL代码不依赖于矩阵中的列数。在使用COO风格时,默认情况下也支持稀疏线性代数。此外,正在进行积极的研究,以开发查询引擎,以减少类coo线性代数查询的执行时间[16]。然而,coo风格的SQL代码的性能可能不足,因为显式索引、糟糕的局部性和将数据转换为正确格式的昂贵转换会增加内存消耗。此外,SQL中co风格的线性代数严重依赖于连接。在清单8中,连接在WHERE子句中指定。

  SQL中coo风格线性代数的另一种方法是将关系本身视为向量或矩阵。关系的行和列对应于线性代数的行和列向量。向量和矩阵的这种表示类似于它们在密集线性代数中的表示。清单9显示了清单7中使用SQL中的密集线性代数样式的梯度计算。
在这里插入图片描述
  这里的梯度计算避免了连接,并且不需要为向量和矩阵提供显式索引。因此,我们称这种计算是数据库友好的。特性f1、f2和标签y存储在单个关系x中。在梯度计算过程中,特征和标签被传播以避免不必要的连接。例如,请查看在创建关系cse和v时如何选择特征f1和f2。例如在创建关系u时,当再次需要f1和f2时,这些“不必要的”选择避免了连接。

3.2、性能结果

  我们比较了NumPy、HyPer和PostgreSQL之间基于梯度下降的逻辑回归的性能。

  • NumPy是一个用于高性能科学计算的Python包。我们将NumPy链接到数学内核库(MKL)版本2020.0.2。英特尔的MKL库广泛使用矢量指令和多核处理。
  • HyPer是一个面向列的内存DBMS,在OLTP和OLAP工作负载下都能实现高性能[17]。我们使用Tableau公开的Hyper API版本0.0.13287。
  • PostgreSQL是一个广泛使用的、开源的、面向rowwororiented的DBMS。我们使用PostgreSQL 12.8版本。

  在我们的测量中,我们使用一台带有Intel i910980XE 18核处理器(36个超线程)的机器,运行Ubuntu 20.04.1 LTS,内存为128 GB。每个内核的基频为3.0 GHz,最大turbo频率为4.6 GHz,支持AVX-512矢量指令集。对于HyPer和PostgreSQL,我们测量了两种不同逻辑回归实现的性能。一种是基于coo风格的线性代数,另一种是数据库友好型的,使用无连接的密集风格进行线性代数(详细信息请参阅前一小节)。对于数据库测量,我们使用临时表。我们不使用数据库索引。在运行逻辑回归求解器时,我们以每秒迭代次数来报告性能。一次迭代计算梯度并更新前一次迭代的权重。我们验证所有实现计算相同的权重,从而获得相同的模型精度。

  下图显示了具有32个特征和100万个样本的数据集的基于梯度下降的逻辑回归的性能。虽然HyPer上的数据库友好实现实现了每秒100多次迭代,但PostgreSQL上的性能与它的COO实现没有什么不同。与HyPer相比,PostgreSQL的性能非常低,因为HyPer是一个使用查询编译的高效并行DBMS。因此,我们在进一步的测量中忽略了PostgreSQL。然而,令人惊讶的是,HyPer的速度几乎是NumPy的三倍。下面的测量探讨了HyPer优于NumPy的条件

在这里插入图片描述
  图2显示了性能取决于用于计算的线程数。当使用两个线程时,HyPer和NumPy的执行情况大致相同。当使用两个以上的线程时,HyPer上的数据库友好实现比NumPy快。随着可用内核数量的增加(线程数≤18),HyPer的性能会稳步提高。通过超线程的额外并行化,HyPer获得了更高的性能。与HyPer相比,NumPy中梯度计算的并行化很差。尽管MKL在并行化线性代数操作方面通常非常有效,但对于图2中包含32个特征的示例来说,它就失败了。

在这里插入图片描述
  在图3中,我们将特征的数量在4到128之间变化。我们把它留给实现来决定使用多少线程。NumPy利用数据集中所有18个核心和4个特征,但如图3所示,这种情况的效率相当低。图3显示,当数据集中少于128个特征时,HyPer是最快的替代方案。然而,HyPer和NumPy之间的性能差距随着数据集中特征数量的增加而缩小。在128个功能下,NumPy甚至比HyPer还要快一点
在这里插入图片描述

  图4显示了性能作为数据集中示例数量的函数。测量结果以对数标度表示。对于数据集中少于或等于105个示例,NumPy是最快的选择。NumPy将矩阵和向量连续地存储在内存中,因此当数据集适合缓存时,它将受益于良好的局部性。此外,由于权重更新依赖于先前计算的权重,因此对于小数据集,有效的并行化无法发挥作用。同样,为了进行基准测试,我们重复运行算法100次迭代。在HyPer中,这些时间包括缓存SQL查询的运行时。对于较小的数据量,查询的设置成本不会摊销。因此,对于小问题,NumPy要快得多。在HyPer中,测量中存在不规则性。对于数据集中的106个示例,HyPer每秒执行的迭代次数多于105个示例。这种不规律的原因是HyPer只通过一个线程执行少于或等于105个示例的所有查询。

在这里插入图片描述


四、结论以及未来工作

  纯sql算法不是一个理论噱头,但可以具有很高的实用价值。它们提供了诸如近数据计算、代码更改的灵活性、对底层DBMS体系结构的高度抽象以及可移植性等优点。我们展示了如何用SQL表示算法原语。通过使用这些原语,可以在SQL中实现计算密集型算法。在案例研究中,我们提供了数据库友好的SQL代码,它避免了线性代数操作的连接。事实证明在HyPer上的数据库友好型SQL实现甚至可以在更大的数据集上优于NumPy。

  算法中的循环通常包含对先前迭代数据的复杂计算。我们演示了如何在SQL中通过在WITH recursive的FROM子句中使用对工作表的递归引用来实现这种循环。像PostgreSQL、DuckDB或HyPer这样支持递归引用的dbms,已经可以使用SQL进行各种计算。扩展DBMS以支持子查询中的递归引用将是很简单的,我们希望本文能够促使DBMS开发人员实现这一特性。

  在未来的工作中,我们计划使用编译将命令式结构自动转换为SQL。编译器方法也可以将线性代数操作转换为SQL。为了使线性代数操作的转换尽可能高效,需要进一步探索SQL中无连接线性代数的局限性。深度学习似乎也是我们计划探索的一个有趣的用例。通过使用外部工具(如我们的矩阵演算[13-15])计算导数并将其转换为SQL,剩下要做的唯一事情就是在SQL中实现优化算法,这是可能的,正如我们在案例研究中所展示的那样。因此,我们相信SQL机器学习和其他形式的SQL计算密集分析非常有前途。

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

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

相关文章

文件流-ASCII文件(中北大学-程序设计基础(2))

目录 题目 源码 结果示例 题目 编写程序实现以下功能:【要求处理ASCII文件】 (1)按职工号由小到大的顺序将5个员工的数据(包括号码、姓名、年龄和工资)输出到磁盘文件中保存; (2&#xff…

自动驾驶决策规划——坐标转换

以下内容来自b站up主忠厚老实的老王,视频链接:自动驾驶决策规划算法序章 总纲与大致目录_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1hP4y1p7es/?spm_id_from333.999.0.0&vd_sourced36e625f376908cfa88ef5ecf2fb0ed8侵删。 决策规划算法…

自动故障转移

这里询问,你的插槽是从哪里移动过来的? all:代表全部,也就是三个节点各转移一部分具体的id:目标节点的iddone:没有了 这里我们要从7001获取,因此填写7001的id: 填完后,…

力扣75. 颜色分类

Problem: 75. 颜色分类 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 由于题目只提供0,1,2分别代表颜色红、白、蓝,并按此排序,那么我们可以遍历两次数组,第一次将0,全部放到数组前面一部分…

移动 App 入侵与逆向破解技术-iOS 篇

如果您有耐心看完这篇文章,您将懂得如何着手进行app的分析、追踪、注入等实用的破解技术,另外,通过“入侵”,将帮助您理解如何规避常见的安全漏洞,文章大纲: 简单介绍ios二进制文件结构与入侵的原理介绍入…

软考考试需要达到多少分才能及格?

当然是45分!45分!45分!而且是各科45! 初级和中级考两科 综合知识考试时长为150分钟,笔试,选择题(上午9:00-11:30) 案例分析考试时长为90分钟,笔试,问答题&…

计算机毕业设计 | vue+springboot图书借阅 书籍管理系统(附源码)

1. 开发目的 实现图书的智能化、信息化和简单化;实现图书信息的增加、删除、修改、查找、借阅、还书、收藏的显示操作及实时数据库的提交和更改和对普通用户的增、删、改、查;提高图书管理员工作信息报送及反馈的工作效率,减轻管理员的劳动负…

设计模式Java实现-迭代器模式

✨这里是第七人格的博客✨小七,欢迎您的到来~✨ 🍅系列专栏:设计模式🍅 ✈️本篇内容: 迭代器模式✈️ 🍱 本篇收录完整代码地址:https://gitee.com/diqirenge/design-pattern 🍱 楔子 很久…

苍穹外卖Day06笔记(复习了jwt的加密解密和传递)

疯玩了一个月,效率好低,今天开始捡起来苍穹外卖~ 1. 为什么不需要单独引入HttpClient的dependency? 因为我们在sky-common的pom.xml中已经引入了aliyun-sdk-oss的依赖,而这个依赖低层就引入了httpclinet的依赖,根据依…

JavaEE技术之SpringCloud(Nacos注册中心、Nacos配置中心、Sentinel实现熔断与限流)

文章目录 SpringCloud Alibaba1、简介1.1 背景1.2 Nacos主要功能1.3 Nacos和SpringBoot、SpringCloud版本选择 2、Nacos注册中心2.1 案例准备2.2 Nacos注册中心下载启动2.2.1 下载2.2.2 解压启动2.2.3 nacos-server访问测试 2.3 nacos注册中心客户端整合2.3.1 订单服务整合naco…

【UE】仿原神实现无限道路延伸的开场效果

目录 效果 步骤 一、无限生成砖块 二、制作门 三、停止移动并生成门 四、进入门 效果 步骤 一、无限生成砖块 1. 新建一个Basic关卡,再新建一个Pawn类,这里命名为“BP_MyPawn” 打开“BP_MyPawn”,添加一个胶囊体碰撞组件和一个摄像…

工器具管理(基于若依)

文章目录 前言一、工器具管理项目总览 二、入库功能1. 前端1.1 界面展示1.2 具体操作实现1.3 js文件 2. 后端2.1 工器具信息回显2.2 工器具入库 三、领用功能1. 前端1.1 界面展示1.2 具体实现操作1.3 js文件 2. 后端2.1 工器具信息回显2.2 工器具领用 遇到的问题1. 同一页面展示…

基于springboot+vue的自习室管理和预约系统(全套)

一、系统架构 前端:vue | element-ui | html 后端:springboot | mybatis-plus 环境:jdk1.8 | mysql | maven | nodejs 二、代码及数据库 三、功能介绍 01. web端-首页1 02. web端-首页2 03. web端-注册 04. web端-登录 05. w…

Apollo9.0 Control模块算法源码学习

参考资料 Apollo控制算法_哔哩哔哩_bilibili

Python自动化测试 | 如何使用Robot Framework进行自动化测试?

你还在手动测试?不妨了解一下更高效、准确且简单的测试方法——使用Python的Robot Framework进行自动化测试。 什么是Robot Framework? Robot Framework是一款开源的Python自动化测试框架,它基于关键字驱动的思想,具有易读、易扩…

每日一题 城市群的数量

题目解析 城市群数量_牛客题霸_牛客网 当解决这个问题时,首先需要理解题目要求。题目中给出了一个城市之间的邻接矩阵,矩阵中的元素表示城市之间是否直接相连。如果两个城市直接相连,或者通过其他城市间接相连,它们就属于同一个城…

深入理解Python的类,实例和type函数

问题起源: class t():pass s1 t() s2 type("Student2",(),{}) isinstance(s1, type), isinstance(s2, type)为什么第一个是false,第二个是true呢 根因定位: 在Python中,一切皆对象,类是对象&#xff0c…

nacos在没有指定数据源的情况下默认使用什么数据库?

在没有特别指定数据源的情况下,Nacos 默认使用内嵌的数据库 Derby 来存储其数据。Derby 是一个轻量级的、基于 Java 的数据库管理系统,适合于开发和测试环境,因为它简单易部署且无需额外的数据库服务器。然而,对于生产环境&#x…

Stability AI 推出 Stable Artisan,终于可以在Discord上使用Stable Diffusion了!

Stable Diffusion 社区最常见的要求之一是能够直接在 Discord 上使用他们的模型。近期,Stability AI 推出 Stable Artisan,这个需求终于被实现了。 Stable Artisan 支持在 Discord 上生成媒体,由 Stability AI 的尖端图像和视频模型 Stable D…

基于Springboot的实习生管理系统(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的实习生管理系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构&a…