大数据

上一节说到,大多的AI问题,会有很多个变量,这里深入的解释一下这个问题。

比如说某个网站要做用户行为分析,从而指导网站建设的改进。通常而言如果没有行为分析,并不需要采集用户太多的数据。

比如用户注册,最少只需要用户名、用户密码就够了。随后比如为了当用户过生日的时候,自动给用户发送一封贺卡(潜台词,我们可能需要给用户推送广告),我们再增加两项生日日期和邮箱地址。再下来国家规定网站注册必须实名制,我们可能又增加了用户姓名和身份证号码,可能还需要增加用户手机号码,用于同移动通信部门打通,验证用户实名制的真实性。这样一共是七个数据字段(仅为示例,事实比本例肯定要复杂很多倍)。

随后通过网站的运营,用户数不断增加,到了某一天,网站的技术人员发现,数据量太大了,并发也太高了,一组服务器已经无法负担网站的运营。最重要其中的基础数据库也变得太大,系统无法容纳,需要分库、集群的新技术,才能保证网站的运营。

从网站的运维来讲,这的确是一项重要的技术改进。但从“机器学习”的角度看,这些数据量的变化,并没有什么不同,可能在算法上,也不需要有太大的改变。所以严格上讲,这样的数据管理,还不能叫大数据。

我们继续向下看,为了进行用户行为的分析。我们还要增加很多用户数据的采集点。比如用户每次访问网页的IP地址、用户的点击习惯、每个页面停留的时间、在页面上习惯点哪些位置的链接、操作上有什么习惯、用户的设备是什么型号、用户每次上网在什么时间段,这样需要关注的数据,我们还能列出很多。甚至可能会付费去第三方的公司购买很多其它的信息,比如我的用户还喜欢在什么网站停留,停留在其它网站的时候关注了什么内容,最近购买了什么东西等等信息。

这些信息有下面几个特点:

  • 并不是简单的信息表长度增长了,而是每行信息关注的维度大大的增加了,也就是信息表变宽了。
  • 随着维度的增加,总体的数据量可能会激增,很少的用户数,就需要利用到集群、并发等多种处理方式来解决压力问题。
  • 这些增加的维度,由于数量的增加,基本只能考虑用机器学习的方式,由计算机自动完成处理,分析其中的规律。

还有一些数据,天生就是多维的,比如图片识别。每幅图片,数字化保存到电脑之后,很可能是一大笔数据,比如某副照片320x240分辨率,那就相当于320x240x(RGB 3色)=230400维的一个数据集。这个在后面讲到具体案例的时候还会说到。

梯度下降法解线性回归方程

在数据维度非常多的时候,也就是我们的方程可能有n个变量(n值很大)的时候,原有的公式、解法都已经失效了。可能是计算量过大导致速度无法接受,也可能是空间需求太大导致我们的计算机无法做到,所以我们需要有新的办法来完成解方程----也就是机器学习的过程。

梯度下降法是我们常用的一种方式,实际上这种算法包括其针对性或者改进型算法有很多种,应当称为梯度下降法家族。比如批量梯度下降法(BGD)、随机梯度下降法(SGD)、小批量梯度下降法(MBGD)等。

这是统计学家和经济学家在大量数据分析过程中常用的手段,所以其实早期的机器学习专家往往也是来自于统计专业。

在大多机器学习的课程中,对梯度下降法及相关算法的讲解是最重要的一部分,但现在情况有所改变。TensorFlow以及其它一些流行框架,已经内置了函数用于运行梯度下降法及其它常用算法,技术人员即便不了解这些知识,也能够上手机器学习项目。所以原本我计划略去这部分算法的细节。但发现实际上还是不能,因为我看到了很多在TensorFlow官方样例运行很好,但到了具体项目中就失败的例子,归根结底还是对算法本身了解太少,碰到问题不知道如何下手解决。

所以几经修改,我决定既不略去,也不再作为重点。这里用伪代码的方式来简略描述一下这个算法的工作流程:

  1. 首先定义好我们的公式,比如前面提到的房价公式是y = Θ0 * x + Θ1,方便起见,我们这里称这个公式为:y'=fj(x)
  2. 我们定义一个代价函数(Cost function),用于表示真实房价与我们计算房价差的绝对值,这里记为:abs(y-y’)。这里我们省去梯度下降法的公式推导过程,最终的推导结果我们记为J(Θ0,Θ1),你只需要知道,这个跟上面说的预测房价合真实房价之差是等价的。这个代价函数的值越小,表示我们要求的方程越接近真实解。注意x/y都是我们手中资料库中已有的数据集,我们想用这些已有的数据集,来得出原来公式中Θ0/Θ1两个常量的值,从而完成方程求解,也就是“机器学习”的过程。
  3. 我们随机为Θ0/Θ1取一个初始值。
  4. 利用Θ0/Θ1的当前值,带入一组当前已有的数据x,利用公式fj(x)求得一个房价值,记为y',同时跟样本中的真实y值一起计算代价函数的值。
  5. 通过梯度下降步长alpha,带入梯度下降公式,得到一组新的Θ0/Θ1,并以此带入fj(x)计算新的y',然后计算新的代价函数值。(梯度下降公式有兴趣请查看链接资料)
  6. 重复步骤5,直到得到一个最小的代价函数值,此时的Θ0/Θ1取值就是我们要求解的值。
  7. 这里的讲解,把先前的常量a/b替换成了Θ0/Θ1,原因是,我们将来的参数集可不会只有两个这么少,可能是n个,希望你明白这里只是在降维模拟一个过程。



    这张图描述了梯度下降法解方程的过程。需要说明的是图中手绘的部分,就是我们一开始随机取了初始值,也就是初始点,然后逐步的梯度下降,直到代价函数值最小的时候,得到两个未知数的解。

    同时从图中可以看出来,因为初始值的不同及步长的不同,梯度下降法很可能会陷入某个局部最小值,这时候梯度下降法因为已经最小,向周围任何一点继续都无法得到更小的代价函数值,从而终止了继续求解。但实际上离最优解还有很大差距.下面这张图是降维到2维的一张示意图,可以看的更清楚:



    图中的G点是最优解,A/B/C/D点都是局部最优解。当我们的变量很多的时候,很高的维度使得获取全局最优解往往是很不容易的。

    陷入局部最优解的时候实际上只有这样几个选择:1.随机产生另外一组初始值,同时增加尝试求解过程的次数,从而得到不同的解,取其中最好的值;2.变更梯度下降步长;3.变更或者优化算法。

局部最优解是《机器学习》算法调优重点之一

具体的算法本身是纯粹的数学问题,有网友收集、撰写的参考资料在最下面的参考链接里面,写的很不错。我建议有志于算法研究的朋友一定仔细阅读。刚才说了,实际上在很多《机器学习》课程中,这部分占了相当的篇幅,可见其重要性。从这个角度上说,现代机器学习的框架一方面降低了学习的门槛,不需要懂梯度下降法也能使用机器学习,另外一方面,是不是也就此屏蔽了很多人真正上升的空间呢?

第一个练习,我们先深入一下

行文这么长了,终于要进入TensorFlow的世界。估计你读的很辛苦,我尽力用非专业的语言来解释很多基础的概念和来龙去脉,忍得也很辛苦。

在正式例子之前,再补充一个“机器学习”的重要概念,数据“规范化”。

我们注意到了,为了进行“机器学习”,我们从很多维度获取相关数据,建立复杂的数学模型,以求得到比较好的结果。

但这些方方面面的数据,差别非常大,比如有价格因素,取值范围很可能是几千到上亿;也很可能是面积因素,取值几十到几百。将来还可能有朝向因素,如果把方向数字化,可能不过是1-4;类似的还很多,比如楼层数。

总的来说,这些数字如此大的量级差距,在一个试图建立较为通用(注:后面还会对“较为通用”这个词再详细解释)的数学化公式的算法中,会对结果产生不可估量的影响。比如面积多1平米或者少1平米,本来应当对最终房价有很大的影响。但对于同样的数字,计算机并不理解这个数量级跟另外一个参数数量级之间的差别,它看起来增加1平米跟增加1块钱是一样的。最后的结果,不可避免的会倾向数字大的参数所导致的影响,从而让计算结果完全不可用。

因此,所有采集到的数据在真正进入运算之前,首先要规范化,比较通用的规范化方式,是计算某个具体值在该参量取值范围中的比例值,让最终的结果是0-1之间的浮点小数,这样可以保证所有的参量,最终是工作在同一个量级维度上,从而保证结果的正确性。

数据的“规范化”,是影响“机器学习”精度的重要因素,绝对不可省略。

终于可以进入源代码部分了,我习惯于在代码中加入详细的注释让你做到每一行都看懂,我认为这是重要的学习手段之一。

源码中随机生成了100套住房面积和对应价格的数据集,然后通过TensorFlow使用内置的梯度下降法解出每平米价格及基础费用两个系数。在这里要求读者已经有python的基础知识,因为至少当前,机器学习的首选语言还是python。

#!/usr/bin/env python
# -*- coding=UTF-8 -*- #本代码在mac电脑,python2.7环境测试通过
#第一行是mac/Linux系统脚本程序的标志,表示从环境参量中寻找python程序解释器来执行本脚本
#省去了每次在命令行使用 python <脚本名> 这样的执行方式
#第二行表示本脚本文本文件存盘使用的代码是utf-8,并且字符串使用的编码也是utf-8,
#在本源码中,这一点其实没有什么区别,但如果需要中文输出的时候,这一行就必须要加了。 #引入TensorFlow库
import tensorflow as tf
#引入数值计算库
import numpy as np #使用 NumPy 生成假数据集x,代表房间的平米数,这里的取值范围是0-1的浮点数,
#原因请看正文中的说明,属于是“规范化”之后的数据
# 生成的数据共100个,式样是100行,每行1个数据
x = np.float32(np.random.rand(100,1))
#我们假设每平米0.5万元,基础费用0.7万,这个数值也是规范化之后的,仅供示例
#最终运行的结果,应当求出来0.5/0.7这两个值代表计算成功
#计算最终房价y,x和y一同当做我们的样本数据
# np.dot的意思就是向量x * 0.5
y = np.dot(x,0.5) + 0.7
#---------------------------------数据集准备完成
#以下使用TensorFlow构建数学模型,在这个过程中,
#直到调用.run之前,实际上都是构造模型,而没有真正的运行。
#这跟上面的numpy库每一次都是真正执行是截然不同的区别
# 请参考正文,我们假定房价的公式为:y=a*x+b #tf.Variable是在TensorFlow中定义一个变量的意思
#我们这里简单起见,人为给a/b两个初始值,都是0.3,注意这也是相当于规范化之后的数值
b = tf.Variable(np.float32(0.3))
a = tf.Variable(np.float32(0.3)) #这是定义主要的数学模型,模型来自于上面的公式
#注意这里必须使用tf的公式,这样的公式才是模型
#上面使用np的是直接计算,而不是定义模型
# TensorFlow的函数名基本就是完整英文,你应当能读懂
y_value = tf.multiply(x,a) + b # 这里是代价函数,同我们文中所讲的唯一区别是用平方来取代求绝对值,
#目标都是为了得到一个正数值,功能完全相同,
#平方计算起来会更快更容易,这种方式也称为“方差“
loss = tf.reduce_mean(tf.square(y_value - y))
# TensorFlow内置的梯度下降算法,每步长0.5
optimizer = tf.train.GradientDescentOptimizer(0.5)
# 代价函数值最小化的时候,代表求得解
train = optimizer.minimize(loss) # 初始化所有变量,也就是上面定义的a/b两个变量
init = tf.global_variables_initializer() #启动图
sess = tf.Session()
#真正的执行初始化变量,还是老话,上面只是定义模型,并没有真正开始执行
sess.run(init) #重复梯度下降200次,每隔5次打印一次结果
for step in xrange(0, 200):
sess.run(train)
if step % 5 == 0:
print step, sess.run(loss),sess.run(a), sess.run(b)

随后我们看看上面脚本运行的结果:

0 0.017659416 0.56524247 0.7991155
5 4.084394e-06 0.50660795 0.6963032
10 1.9465895e-06 0.5046281 0.697532
15 9.344591e-07 0.50320655 0.69828993
20 4.4858396e-07 0.5022217 0.69881517
25 2.1534281e-07 0.5015393 0.69917905
30 1.0337125e-07 0.5010665 0.6994312
35 4.9617547e-08 0.5007389 0.69960594
40 2.3823773e-08 0.500512 0.69972694
45 1.1437169e-08 0.50035477 0.6998108
50 5.4911653e-09 0.5002458 0.6998689
55 2.6369513e-09 0.50017035 0.69990915
60 1.2654721e-09 0.500118 0.69993705
65 6.075896e-10 0.5000818 0.69995636
70 2.9137154e-10 0.5000566 0.69996977
75 1.4008027e-10 0.5000393 0.69997907
80 6.7331245e-11 0.50002724 0.69998544
85 3.2336054e-11 0.5000189 0.6999899
90 1.5535804e-11 0.5000131 0.699993
95 7.4518525e-12 0.50000906 0.69999516
100 3.5502267e-12 0.50000626 0.69999665
105 1.648246e-12 0.5000043 0.6999977
110 8.017054e-13 0.500003 0.6999984
115 3.877787e-13 0.5000021 0.6999989
120 1.8626878e-13 0.50000143 0.6999992
125 8.9173115e-14 0.500001 0.69999945
130 4.515499e-14 0.5000007 0.69999963
135 2.1138646e-14 0.5000005 0.69999975
140 1.20437e-14 0.50000036 0.6999998
145 1.20437e-14 0.50000036 0.6999998
150 1.20437e-14 0.50000036 0.6999998
155 1.20437e-14 0.50000036 0.6999998
160 1.20437e-14 0.50000036 0.6999998
165 1.20437e-14 0.50000036 0.6999998
170 1.20437e-14 0.50000036 0.6999998
175 1.20437e-14 0.50000036 0.6999998
180 1.20437e-14 0.50000036 0.6999998
185 1.20437e-14 0.50000036 0.6999998
190 1.20437e-14 0.50000036 0.6999998
195 1.20437e-14 0.50000036 0.6999998

因为数据集是随机产生的,所以上面结果每次运行都会不同,但基本上在150步以内都能有效收敛,请看打印出来的两个结果值,也是很令人满意的。

(待续...)

引文及参考

大数据与多维度

多元线性回归模型公式

梯度下降法

(原创博文,谢绝一切商业转载,个人转载请注明出处。)

从锅炉工到AI专家(2)的更多相关文章

  1. TensorFlow从1到2(一)续讲从锅炉工到AI专家

    引言 原来引用过一个段子,这里还要再引用一次.是关于苹果的.大意是,苹果发布了新的开发语言Swift,有非常多优秀的特征,于是很多时髦的程序员入坑学习.不料,经过一段头脑体操一般的勤学苦练,发现使用S ...

  2. 从锅炉工到AI专家 ---- 系列教程

    TensorFlow从1到2(十二)生成对抗网络GAN和图片自动生成 那些令人惊艳的TensorFlow扩展包和社区贡献模型  从锅炉工到AI专家(11)(END) 从锅炉工到AI专家(10)  从锅 ...

  3. 从锅炉工到AI专家(1)

    序言 标题来自一个很著名的梗,起因是知乎上一个问题:<锅炉设计转行 AI,可行吗?>,后来就延展出了很多类似的问句,什么"快递转行AI可行吗?"."xxx转行 ...

  4. 从锅炉工到AI专家(7)

    说说计划 不知不觉写到了第七篇,理一下思路: 学会基本的概念,了解什么是什么不是,当前的位置在哪,要去哪.这是第一篇希望做到的.同时第一篇和第二篇的开始部分,非常谨慎的考虑了非IT专业的读者.希望借此 ...

  5. 从锅炉工到AI专家(5)

    图像识别基本原理 从上一篇开始,我们终于进入到了TensorFlow机器学习的世界.采用第一个分类算法进行手写数字识别得到了一个91%左右的识别率结果,进展可喜,但成绩尚不能令人满意. 结果不满意的原 ...

  6. 从锅炉工到AI专家(4)

    手写数字识别问题 图像识别是深度学习众多主流应用之一,手写数字识别则是图像识别范畴简化版的入门学习经典案例.在TensorFlow的官方文档中,把手写数字识别"MNIST"案例称为 ...

  7. TensorFlow从1到2(二)续讲从锅炉工到AI专家

    图片样本可视化 原文第四篇中,我们介绍了官方的入门案例MNIST,功能是识别手写的数字0-9.这是一个非常基础的TensorFlow应用,地位相当于通常语言学习的"Hello World!& ...

  8. 从锅炉工到AI专家(11)(END)

    语音识别 TensorFlow 1.x中提供了一个语音识别的例子speech_commands,用于识别常用的命令词汇,实现对设备的语音控制.speech_commands是一个很成熟的语音识别原型, ...

  9. 从锅炉工到AI专家(10)

    RNN循环神经网络(Recurrent Neural Network) 如同word2vec中提到的,很多数据的原型,前后之间是存在关联性的.关联性的打破必然造成关键指征的丢失,从而在后续的训练和预测 ...

随机推荐

  1. 关于二进制枚举-计蒜客-得到整数X

    某君有 n个互不相同的正整数,现在他要从这 n 个正整数之中无重复地选取任意个数,并仅通过加法凑出整数 X.求某君有多少种不同的方案来凑出整数 X. 输入格式 第一行,输入两个整数 n,X(1≤n≤2 ...

  2. Analysis of Web.xml in Hello1 project

    一.web.xml文件介绍 The web.xml file contains several elements that are required for a Facelets applicatio ...

  3. Redis数据库概述

    Redis数据库概述 Redis是什么 redis是一个高性能的key-value存储系统.支持的value类型相对更多,包括string,list,set,zset(sorted set --有序集 ...

  4. [CF1093G]Multidimensional Queries

    [CF1093G]Multidimensional Queries 题目大意: \(k(k\le5)\)维空间中有\(n(n\le2\times10^5)\)个点.\(m\)次操作,操作包含一下两种: ...

  5. 浏览器url地址殊字符转义编码

    网址URL中特殊字符转义编码字符    -    URL编码值 空格    -    %20"          -    %22#         -    %23%        -   ...

  6. js数组基础

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. JS中[object object]怎么取值

    错误信息:本来是要显示JSON对象的  结果控制台打印了[object object] 需要做一个简单的转换,如下: var jsonData = JSON.stringify(data);// 转成 ...

  8. Elasticsearch 滚动重启 必读

    关键词:elasticsearch , es , 滚动重启 , 禁止分片 由于之前es GC没有怎么调优,结果今天被大量scroll查询查挂了,GC 卡死了.然后为了先恢复给业务使用,也没什么其他办法 ...

  9. 详解node + mongoDb(mongoDb安装、运行,在node中连接、增删改查)

    一.序言 好久没写博客了,这次主要聊聊 node 和 mongoDb . 先说明一下技术栈  node + express + mongoose + mongoDb.这篇博客,主要讲述 mongoDb ...

  10. Python入门(青铜篇)

    一.定义变量 print('hello world \n') 定义变量name='单宝梁' #定义字符串一定加‘’age=28 引号使用words="i'm 单宝梁" #字符串里有 ...