本来想发在知乎专栏的,但是文章死活提交不了,我也是醉了,于是乎我就干脆提交到CNBLOGS了。

前言

前段时间我们介绍了Logistic的数学原理和C语言实现,而我呢?其实还是习惯使用Matlab进行计算的,而且是不带C的Matlab。(主要我们都用Windows)

那为什么要用SQL实现呢?(准确的说是PL/SQL)

因为我发现数据一次性加载进内存里面太大了,直接在SELECT的时候OutOfMemory了(其实数据是勉强能装进内存的,只是SELECT的时候产生的对象太多)

更主要的原因是因为我的电脑另有它用,留下的内存也不多了。

卧槽,为什么不用服务器算呢?

最近在重装系统,等我的小服务器安装好了,次回我会可能带来使用Hadoop/Spark的Logistic回归。

关于为什么我对Logistic回归这么着迷,并不是不会其它的模型,第一它简单,第二可解释性好,易于并行或者处理数据流。

为什么使用SQL呢?性能并不是其优势,反而是其软肋,但是可以把压力转嫁到服务器上,对于我残破不堪的工作电脑也是一个解脱,其次,对于特别大量的数据要做到随机梯度下降防止陷入局部极小,用SQL也算是一个解决方案。

诚然这个方案是不合适的,但是那又怎么样,我和SQL只是玩玩而已

最近本人在找工作,希望找一个能让我做机器学习的岗位,我希望这家公司是一个脚踏实地的公司,有可持续的盈利模式,不会随便的喊出深度学习、人工智能和大数据之类的词汇,能从业务的角度来选择技术,那么我不会让你们失望。

准备数据

首先你有一张表,这张表列数不多,但是行数挺多的,其中一列是y,其余的是x,当然还可以有ID之类的一些其他信息。

我们这次的表结构是这样的:

CREATE TABLE public.jfeatures_cntf
(
---y
cbuy integer,
---X
cview integer,
cadd integer,
cdel integer,
cstar integer,
cclick integer
)

计算

首先你需要新建一个函数,该函数能做到从数据中随机取N行数据给你,因为数据量比较大,我们可能只有在Fine Tune的时候才会使用全部数据,平时的计算主要还是使用Radom Batch Gradient Descend/Ascend。

而Logistic的核心是:求偏导,我们也不需要什么都让SQL做,只要让SQL完成数据量最大的计算就行了。

随机取数据的函数

那我们首先构建一个PLSQL的函数:

CREATE OR REPLACE FUNCTION public.get_rand_x_record(x integer)
RETURNS SETOF jfeatures_cntf AS
$BODY$
DECLARE
N INTEGER;
BEGIN
--- N<-Length-x
SELECT count(*)-x INTO N FROM public.jfeatures_cntf;
--- Random select
RETURN QUERY SELECT * FROM public.jfeatures_cntf
OFFSET floor(random()*N) LIMIT x;
END;
$BODY$
LANGUAGE plpgsql VOLATILE

这个函数可以每次从数据库中取出N条数据,比ORDER BY random()快不少。

由于在运算的时候我们也不会增删记录,所以可以预先获取数据大小N,随后使用这个函数:

CREATE OR REPLACE FUNCTION public.get_rand_x_record(
x integer,
n bigint)
RETURNS SETOF jfeatures_cntf AS
$BODY$
DECLARE
BEGIN
--- Random select
RETURN QUERY SELECT * FROM public.jfeatures_cntf
OFFSET floor(random()*N) LIMIT x;
END;
$BODY$
LANGUAGE plpgsql VOLATILE

Logistic回归求偏导的函数

得到数据以后,我们首先会求y,也就是1/(1+exp(1+b^Tx)),随后将(y-t)广播的乘到X上,最后求和就得到了结果。

CREATE OR REPLACE FUNCTION public.log_model_lr_random(
batch_size integer,
pview double precision,
padd double precision,
pdel double precision,
pstar double precision,
pclick double precision)
RETURNS double precision[] AS
$BODY$
DECLARE
OUT_VALUE RECORD;
BEGIN
SELECT ---grad<-sum((y-t)*X)
sum(log(cview+1)*D)/batch_size as pdview,
sum(log(cadd+1)*D)/batch_size as pdadd,
sum(log(cdel+1)*D)/batch_size as pddel,
sum(log(cstar+1)*D)/batch_size as pdstar,
sum(log(cclick+1)*D)/batch_size as pdclick
INTO OUT_VALUE
FROM
( ---get y-t from data
SELECT *,
(1.0/(exp(
pview*log(cview+1) +
padd*log(cadd+1) +
pdel*log(cdel+1) +
pstar*log(cstar+1) +
pclick*log(cclick+1) + 1.0
)+1.0)
) - (case when cbuy>0 then 1.0 else 0.0 end)
AS D
FROM get_rand_x_record(batch_size)
) AS SUBS;
return ARRAY[
OUT_VALUE.pdview,
OUT_VALUE.pdadd,
OUT_VALUE.pddel,
OUT_VALUE.pdstar,
OUT_VALUE.pdclick];
END;$BODY$
LANGUAGE plpgsql VOLATILE

当然,这个函数也可以由N确定的版本(也就是如果你在计算过程中保证行数不变化的话可以使用的版本),我最终使用的也就是这个版本。

这个就由大家自己写吧!

性能

关于性能方面,对3,000,000条数据求偏导需要1min!要知道,这在Matlab上(使用bsxfun做了并发)只需要0.5秒,这个性能差了100多倍(当然PostgreSQL在单次任务上不支持并行计算也是一个软肋),但是这个是有限定的,一个是内存计算,一个是外存计算,当数据量大到一定程度的时候,往往就需要外存算法。

Logistic是支持并行的,用SQL明显委屈他了,下次咱用Spark发挥出他最大的优势。

[瞎玩儿系列] 使用SQL实现Logistic回归的更多相关文章

  1. Spark2.0机器学习系列之4:Logistic回归及Binary分类(二分问题)结果评估

    参数设置 α: 梯度上升算法迭代时候权重更新公式中包含 α :  http://blog.csdn.net/lu597203933/article/details/38468303 为了更好理解 α和 ...

  2. 《Machine Learning in Action》—— Taoye给你讲讲Logistic回归是咋回事

    在手撕机器学习系列文章的上一篇,我们详细讲解了线性回归的问题,并且最后通过梯度下降算法拟合了一条直线,从而使得这条直线尽可能的切合数据样本集,已到达模型损失值最小的目的. 在本篇文章中,我们主要是手撕 ...

  3. 神经网络、logistic回归等分类算法简单实现

    最近在github上看到一个很有趣的项目,通过文本训练可以让计算机写出特定风格的文章,有人就专门写了一个小项目生成汪峰风格的歌词.看完后有一些自己的小想法,也想做一个玩儿一玩儿.用到的原理是深度学习里 ...

  4. 机器学习笔记—Logistic回归

    本文申明:本系列笔记全部为原创内容,如有转载请申明原地址出处.谢谢 序言:what is logistic regression? Logistics 一词表示adj.逻辑的;[军]后勤学的n.[逻] ...

  5. 机器学习 —— 基础整理(五)线性回归;二项Logistic回归;Softmax回归及其梯度推导;广义线性模型

    本文简单整理了以下内容: (一)线性回归 (二)二分类:二项Logistic回归 (三)多分类:Softmax回归 (四)广义线性模型 闲话:二项Logistic回归是我去年入门机器学习时学的第一个模 ...

  6. 机器学习——Logistic回归

    1.基于Logistic回归和Sigmoid函数的分类 2.基于最优化方法的最佳回归系数确定 2.1 梯度上升法 参考:机器学习--梯度下降算法 2.2 训练算法:使用梯度上升找到最佳参数 Logis ...

  7. logistic回归

    logistic回归 回归就是对已知公式的未知参数进行估计.比如已知公式是$y = a*x + b$,未知参数是a和b,利用多真实的(x,y)训练数据对a和b的取值去自动估计.估计的方法是在给定训练样 ...

  8. Logistic回归 python实现

    Logistic回归 算法优缺点: 1.计算代价不高,易于理解和实现2.容易欠拟合,分类精度可能不高3.适用数据类型:数值型和标称型 算法思想: 其实就我的理解来说,logistic回归实际上就是加了 ...

  9. Logistic回归的使用

    Logistic回归的使用和缺失值的处理 从疝气病预测病马的死亡率 数据集: UCI上的数据,368个样本,28个特征 测试方法: 交叉测试 实现细节: 1.数据中因为存在缺失值所以要进行预处理,这点 ...

随机推荐

  1. 《用Python做HTTP接口测试》学习感悟

    机缘巧合之下,报名参加了阿奎老师发布在"好班长"的课程<用Python做HTTP接口测试>,报名费:15rmb,不到一杯咖啡钱,目前为止的状态:坚定不移的跟下去,自学+ ...

  2. 模拟jquery链式访问

    一直写代码写代码,博客都快荒废了,眼看一月要过完,不能不留下点记忆,嘿嘿,刚研究了下jquery的链式访问,这么好用的技能我赶紧get了下,研究后略微修改,模拟一个简单的链式访问,下面这段代码支持修改 ...

  3. VM安装centos

    1,centOS下载地址:http://mirrors.163.com/centos/7/isos/x86_64/ 2,VM下载地址:http://rj.baidu.com/soft/detail/1 ...

  4. golang的http分析

    首先,要认识一个贯穿始终的接口http.Handler type Handler interface { ServeHTTP(ResponseWriter, *Request) }   其中,两个参数 ...

  5. 02 nodejs命令参数(NodeJS基础入门)

    声明:本文章可供有一定js基础的朋友参考nodejs入门,本文未讲解nodejs的安装,如有需要的同学可以加QQ3382260752找我,进行交流学习. 建议使用开发软件:webstorm或hbuil ...

  6. ng自定义服务(利用factory)

    ng中我们可以自己定义自己的服务,服务中是一些使用重复率较高的方法.因此有效的使用服务可以提高开发速度. ng中定义服务的方法有多种,service,factory,provide,在此我只介绍最长用 ...

  7. 测试开发Python培训:抓取新浪微博抓取数据-技术篇

    测试开发Python培训:抓取新浪微博抓取数据-技术篇   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.在poptest的se ...

  8. 震荡信号Simulink仿真

    1. simulink仿真设计 震荡信号本质是调制信号,可以表示为: u(t)=A*(1+m*cos(Ωt+θ))*cos(ωt+φ)=A*cos (ωt+φ)+ A*m*cos(Ωt+θ)*cos( ...

  9. 读书笔记 effective c++ Item 46 如果想进行类型转换,在模板内部定义非成员函数

    1. 问题的引入——将operator*模板化 Item 24中解释了为什么对于所有参数的隐式类型转换,只有非成员函数是合格的,并且使用了一个为Rational 类创建的operator*函数作为实例 ...

  10. c# 逆波兰式实现计算器

    语文不好,不太会组织语言,希望不要太在意. 如题,先简要介绍一下什么是逆波兰式  通常我们在写数学公式的时候  就是a+b+c这样,这种表达式称为中缀表达式,逆波兰式又称为后缀表达式,例如a+b 后缀 ...