webdancer's Blog

python科学计算——numpy

numpy是python进行科学计算的一个基础包,它的核心功能是提供ndarray对象,一个实现了n维数组的对象,与python自带的list相比,数组大小初始化时候确定,而且是单一类型(当然也可以使用 对象,这样也能包含多种对象),速度更快,大多数科学计算的程序可能都是基于numpy的。

1.基本的思想有两个:vectorization和broadcasting.

  • vectorization:说的是可以不适用for,而像线性代数里面提供的操作一样进行计算;
  • broadcasting:指的是对于element-by-element的计算,可以自动进行;

2.数据类型:支持丰富的数值类型,如下:

Data type Description
bool_ Boolean (True or False) stored as a byte
int_ Default integer type (same as C long; normally either int64 or int32)
intc Identical to C int (normally int32 or int64)
intp Integer used for indexing (same as C ssize_t; normally either int32 or int64)
int8 Byte (-128 to 127)
int16 Integer (-32768 to 32767)
int32 Integer (-2147483648 to 2147483647)
int64 Integer (-9223372036854775808 to 9223372036854775807)
uint8 Unsigned integer (0 to 255)
uint16 Unsigned integer (0 to 65535)
uint32 Unsigned integer (0 to 4294967295)
uint64 Unsigned integer (0 to 18446744073709551615)
float_ Shorthand for float64.
float16 Half precision float: sign bit, 5 bits exponent, 10 bits mantissa
float32 Single precision float: sign bit, 8 bits exponent, 23 bits mantissa
float64 Double precision float: sign bit, 11 bits exponent, 52 bits mantissa
complex_ Shorthand for complex128.
complex64 Complex number, represented by two 32-bit floats (real and imaginary components)
complex128 Complex number, represented by two 64-bit floats (real and imaginary components)

3.创建数组:有5中基本的方式:

  1. Conversion from other Python structures (e.g., lists, tuples)
  2. Intrinsic numpy array array creation objects (e.g., arange, ones, zeros, etc.)
  3. Reading arrays from disk, either from standard or custom formats: genfromtxt
  4. Creating arrays from raw bytes through the use of strings or buffers
  5. Use of special library functions (e.g., random)

4.索引:

import numpy as np

x = np.arange(10)

x[0]  ##从零开始索引,返回0

x.shape = (2,5)

x[1,2] ##这是与python的list,tuple不同的地方,支持多维的索引,返回7

x[0]等价于x[0,:]

x.shape=(10)

x[2:5] #与python的list一样,支持切片操作;

5.broadcasting:描述的是在进行算术操作时,Array的大小不一致的情况,numpy如何处理;将短的进行扩展,然后进行处理。

>>> a = np.array([1.0, 2.0, 3.0])
>>> b = 2.0
>>> a * b
array([ 2.,  4.,  6.])

When operating on two arrays, NumPy compares their shapes element-wise. It starts with the trailing dimensions, and works its way forward. Two dimensions are compatible when

  1. they are equal, or
  2. one of them is 1

 

[转]大数据:“人工特征工程+线性模型”的尽头

作者是CMU的博士,主页:http://www.cs.cmu.edu/~muli/

11年的时候我加入百度,在凤巢使用机器学习来做广告点击预测。当时非常惊讶于过去两年内训练数据如此疯狂的增长。大家都在热情的谈特征,每次新特征的加入都能立即得到AUC的提升和收入的增长。大家坚信特征才是王道,相信还会有源源不断的特征加入,数据规模还会成倍的增长。我也深受感染,坚定的相信未来两年数据至少还会长十倍,因此一切的工作都围绕这个假设进行。现在两年过去了,回过头来看,当时的预测是正确的吗?

 
  数据的飞速增长,给模型训练带来极大压力。事实上,11年的时候模型训练已经是新特征上线的主要障碍了。凭着年轻的冲动,和对分布式系统和数值算法优化的一点点知识,我头脑一热就开始设计下一代模型训练系统了。目标是在同样的资源下,能容纳当前十倍的数据。项目是在情人节立项,取了一个好玩的名字,叫darlin【吐槽1】,这个系统应该是百度使用率最高的机器学习训练系统之一了。一个重要问题是,它会像前任一样在两年后成为性能瓶颈吗?
 
  目前看来,以上两个问题的答案都是否定的。
 
  【吐槽1】意思是distributed algorithm for linear problems。更好玩的是,计算核心模块叫heart,络通讯模块叫telesthesia。数据是用类似bigtable的格式,叫cake,因为切起来很像蛋糕。开发的时候开玩笑说,以后上线了就会时不时听人说“darlin”,是 不是会很有意思?可惜全流量上线后我就直奔CMU了,没享受到这个乐趣:)
  
  我们首先讨论特征。特征是机器学习系统的原材料,对最终模型的影响是毋庸置疑的。如果数据被很好的表达成了特征,通常线性模型就能达到满意的精度。一个使用机器学习的典型过程是:提出问题并收集数据,理解问题和分析数据继而提出抽取特征方案,使用机器学习建模得到预测模型。第二步是特征工程,如果主要是人来完成的话,我们称之为人工特征工程(human feature engineering)。举个例子,假设要做一个垃圾邮件的过滤系统,我们先收集大量用户邮件和对应的标记,通过观察数据我们合理认为,标题和正文含有“交友“、”发票“、”免费促销“等关键词的很可能是垃圾邮件。于是我们构造bag-of-word特征。继而使用线性logisitic regression来训练得到模型,最终把模型判断成是垃圾邮件的概率大于某个值的邮件过滤掉。
 
  就这样搞定啦?没有。特征工程是一个长期的过程。为了提升特征质量,需要不断的提出新特征。例如,通过分析bad case,不久我们便发现,如果邮件样式杂乱含有大量颜色文字和图片,大概率是垃圾邮件。于是我们加入一个样式特征。又通过头脑风暴,我们认为如果一个长期使用中文的人收到俄语的邮件,那估计收到的不是正常邮件,可以直接过滤掉。于是又加入字符编码这一新特征。再通过苦苦搜寻或买或央求,我们得到一个数据库包含了大量不安全ip和发信地址,于是可以加入不安全来源这一新特征。通过不断的优化特征,系统的准确性和覆盖性不断的提高,这又驱使我们继续追求新特征。
 
  由此可以看出,特征工程建立在不断的深入理解问题和获取额外的数据源上。但问题是,通常根据数据人能抽象出来的特征总类很有限。例如,广告点击预测,这个被广告投放公司做得最透彻的问题,目前能抽象出来的特征完全可以写在一张幻灯片里。好理解的、方便拿来用的、干净的数据源也不会很多,对于广告无外乎是广告本身信息(标题、正文、样式),广告主信息(行业、地理位置、声望),和用户信息(性别、年龄、收入等个人信息,cookie、session等点击信息)。KDD CUP2013腾讯提供了广告点击预测的数据,就包含了其中很多。所以最终能得到的特征类数上限也就是数百。另外一个例子是,google使用的数据集里每个样本含有的特征数平均不超过100,可以推断他们的特征类数最多也只是数百。
  
 
大数据:“人工特征工程+线性模型”的尽头
  
  因此,新数据源和新特征的获得会越来越难。然而,模型的精度并不是随着特征的增长而线性提高。很多情况是指数。随着人工特征工程的深入,投入的人力和时间越来越长,得到的新特征对系统的提升却越来越少。最终,系统性能看上去似乎是停止增长了。Robin曾问过我老大一个问题:“机器学习还能持续为百度带来收益吗?” 但时候我的第一反应是,这个商人!现在想一想,Robin其实挺高瞻远瞩。
 
  另外一个例子是IBM的Watson。从下图中可以看出,虽然每次性能的提升基本都是靠引入了新数据和新特征,但提升幅度是越来越小,也越来越艰难。
 
  
大数据:“人工特征工程+线性模型”的尽头
 
  这解释了第一个问题,为什么特征数量的涨幅比当初预计的要少很多。一个特征团队,5个经验丰富的大哥加上10个动手强的小弟,几个月就能把可能的特征发掘得差不多,然后再用1、2年把特征全部做进系统。再然后呢?就会被发现有点后续无力了,进入中年稳定期了。
 
  接下来讨论模型训练,因为不想被跨国追捕所以主要用google sibyl​来举例子。Sibyl是一个线性分类器,支持多种常见loss,例如logistc loss,square loss,hingle loss。还可以使用l2罚,或者l1罚来得到稀疏模型。Sibyl每天要被运行数百次,被广泛应用在google的搜索,gmail,youtube等应用上。由于这些应用直接关系到用户体验和收入,通常需要得到收敛精度很高而且收敛点稳定的模型。因为一个有着数百亿项的模型,如果收敛不够,即使只是少数特征上权重计算误差过大,也很容易引起bad case。同时,应用也希望模型的输出在一段时间是稳定的。
 
  Sibyl使用parallel boosting,而darin用了一个更生僻的算法。后来听说了linkedin,yahoo,facebook的算法之后,狠下心survey了一些古老的优化论文,发现虽然大家名字各不相同,但其实都等价的【吐槽2】。在合适算法下,收敛到所要求的精度通常只需要数十论迭代。而且随着数据量的增大迭代数还会进一步降低。更多的,在online/incremental的情况下,还能更进一步大幅减少。
 
  【吐槽2】在尝试过ml人最近一些年做的一系列算法后发现,它们真心只是研究目的:(
 
  然后是工程实现。google有强大的底层支持,例如GFS,Mapreduce,BigTable,最近几年更是全部更新了这一套。所以sibyl的实现应该是相当轻松。但即使是从0开始,甚至不借助hadoop和mpi,也不是特别复杂。纯C开发,只是用GCC的情况下,代码量也只是数万行。主要需要考虑的是数据格式,计算,和网络通讯。数据格式首先考虑压缩率,可以大量节省I/O时间,其次是空间连续性(space locality)。但通常数据都远超last level cache,也不需要顾虑太多。计算可以用一些常见小技巧,例如少用锁,线程分配的计算量要尽量均匀(稀疏数据下并不容易),double转float,甚至是int来计算,buffer要管理好不要不断的new和delete,也不要太浪费内存。网络稍微复杂一点,要大致了解集群的拓扑结构,注意不要所有机器同时大量收发打爆了交换机,从而引起大量重传(这个经常发生),尽量少的做集群同步。
 
  考察了几个公司的系统性能后,可以认为现在state-of-the-art的性能标准是,100T数据,通常包含几千亿样本,几百亿特征,200台机器,收敛精度要求大致等于L-BFGS 150轮迭代后的精度,可以在2小时内训练完成。如果用online/incremental模式,时间还可以大幅压缩。例如,使用67T数据和1000核,Sibyl在不到一个小时可以完成训练。
 
  
  这回答了前面的第二个问题。假设特征不会突增,那么数据的主要增长点就是样本的累积。这只是一个线性的增长过程,而硬件的性能和规模同时也在线性增长。目前来看效率已经很让人满意。所以一个有着适当优化算法和良好工程实现的系统会胜任接下来一两年的工作。
 
  在人工特征工程下,随着可用的新数据源和新特征的获取越来越困难,数据的增长会进入慢速期。而硬件的发展使得现有系统能完全胜任未来几年内的工作量,因此人工特征工程加线性模型的发展模式进入了后期:它会随着数据和计算成本的降低越来越普及,但却无法满足已经获得收益而希求更多的人的期望。
 
  所以,然后呢?我来抛砖引玉:)
  
  还是先从特征开始。正如任何技术一样,机器学习在过去20年里成功的把很多人从机械劳动里解救了出来,是时候再来解救特征专家们了。因为线性分类系统有足够的性能来支撑更多的数据,所以我们可以用它来做更加复杂的事情。一个简单的想法是自动组合特征,通过目标函数值的降低或者精度的提升来启发式的搜索特征的组合。此外,Google最近的deep learning项目【吐槽3】展现另外一种可能,就是从原始数据中构造大量的冗余特征。这些特征虽然质量不如精心构造的特征来得好,但如果数量足够多,极有可能得到比以前更好的模型。他们使用的算法结合了ICA和sparse coding的优点,从100x100图片的原始pixel信息中抽取上十亿的特征。虽然他们算法现在有严重的scalability的问题,但却可以启发出很多新的想法。
 
  【吐槽3】中文介绍请见余老师的文章​。我个人觉得这个项目更多是关于提取特征。引用Quoc来CMU演讲时说的两点。一、为了减少数据通讯量和提升并行效率,每一层只与下层部分节点相连。因此需要多层来使得局部信息扩散到高层。如果计算能力足够,单层也可能是可以的。二、如果只使用DL来得到的特征,但用线性分类器来训练,还可以提升训练精度。
  
  模型方面,线性模型虽然简单,但实际上是效果最差的模型。鉴于计算能力的大量冗余,所以是时候奔向更广阔的天空了。在广告点击预测那个例子里,数据至少可以表示成一个四纬的张量:展现 x广告 x 广告主 x 用户。线性模型简单粗暴把它压成了一个2维矩阵,明显丢掉了很多信息。一个可能的想法是用张量分解(现在已经有了很高效的算法)来找出这些内在的联系。另一方面,点击预测的最终目的是来对广告做排序,所以这个本质是一个learning to rank的问题,而不是一个简单的分类问题。例如可以尝试boosted decision tree。
 
  再有,最近大家都在谈神经网络。多层神经网络理论上可以逼近任何一个函数,但由于计算复杂、参数过多、容易过拟合等特点被更加简单的kernel svm取代了。但现在的数据规模和计算能力完全不同当年,神经网络又再一次显示它的威力,hinton又再一次走向了职业生涯的巅峰。微软的语音实时翻译是一个很好的样例。反过来说,有多少人真正试过百亿样本级别kernel svm?至少,据小道消息说,多项式核在语音数据上效果很好。
  
  我的结论是,大数据时代,虽然人工特征工程和线性模型将会被更广泛的事情,但它只是大数据应用的起点。而且,我们应该要迈过这个起点了。

 

[转] Computer science: The learning machines

文章链接:http://www.nature.com/news/computer-science-the-learning-machines-1.14481

Using massive amounts of data to recognize photos and speech, deep-learning computers are taking a big step towards true artificial intelligence.

Three years ago, researchers at the secretive Google X lab in Mountain View, California, extracted some 10 million still images from YouTube videos and fed them into Google Brain — a network of 1,000 computers programmed to soak up the world much as a human toddler does. After three days looking for recurring patterns, Google Brain decided, all on its own, that there were certain repeating categories it could identify: human faces, human bodies and … cats1.

介绍了 Deep  learning的最新 的一些 进展,简单的总结一下:

  • Google  Brain Project(10^6神经元,10^9连接)代表的Deep learning技术让神经网络复兴;
  • Neural Networks(神经网络)模仿人脑的神经元连接,通过经验来更改连接的强度,模拟人类的学习;
  • 神经网络可以用来识别图像,处理自然语言,语音识别,翻译语言等;
  • AI的历史:
    • 50s:手工提取特征,费事耗力;
    • 80-90s:浅层网络“Neural nets were always a delicate art to manage. There is some black magic involved,”
    • 2000s:计算能力的增强和数据的爆炸式增长;“For about US$100,000 in hardware, we can build an 11-billion-connection network, with 64 GPUs,” 
  • 现在 Deep  Learning在 语音识别(25%), 图像 识别(ImageNet, 15%),下一步在NLP

 

Scala基础--控制结构

1.if,while,do while与Java相同;

2.for:

  • 遍历集合对象中的每一个元素;
for(i <- 1 to 4)
	println(i)
  • 遍历集合对象中的部分元素:
for(i <- 1 to 4 if i > 2)
	println(i)

 

Scala--基本类型和操作

1.类型:Scala的基本类型与Java中的Primitive type对应起来,不过都是首字母大写的类,例如Byte,Short,Int,Long,Char,Float,Double,String,Boolean

2.字面值(literal):在代码中直接写常数值的一种方式。这个Scala与Java基本相同。但是Scala提供Symbol字面值。

val s='type

3.操作:对于大部分操作符来说,与Java相同,但是“==”不同。在Scala中,"=="首先判断“==”左边是否是null,如果不是null然后条用equals方法。

4.Scala给基本类型提供了Rich Wrapper,可以有更加丰富的方法。

[转]机器学习是什么--周志华

机器学习现在是一大热门,研究的人特多,越来越多的新人涌进来。
不少人其实并没有真正想过,这是不是自己喜欢搞的东西,只不过看见别人都在搞,觉着跟大伙儿走总不会吃亏吧。
问题是,真有个“大伙儿”吗?就不会是“两伙儿”、“三伙儿”?如果有“几伙儿”,那到底该跟着“哪伙儿”走呢?
很多人可能没有意识到,所谓的machine learning community,现在至少包含了两个有着完全不同的文化、完全不同的价值观的群体,称为machine learning "communities"也许更合适一些。
第一个community,是把机器学习看作人工智能分支的一个群体,这群人的主体是计算机科学家。
现在的“机器学习研究者”可能很少有人读过1983年出的“Machine Learning: An Artificial Intelligence Approach”这本书。这本书的出版标志着机器学习成为人工智能中一个独立的领域。它其实是一部集早期机器学习研究之大成的文集,收罗了若干先贤(例 如Herbert Simon,那位把诺贝尔奖、图灵奖以及各种各样和他相关的奖几乎拿遍了的科学天才)的大作,主编是Ryszard S. Michalski(此君已去世多年了,他可算是机器学习的奠基人之一)、Jaime G. Carbonell(此君曾是Springer的LNAI的总编)、Tom Mitchell(此君是CMU机器学习系首任系主任、著名教材的作者,机器学习界没人不知道他吧)。Machine Learning杂志的创刊,正是这群人努力的结果。这本书值得一读。虽然技术手段早就日新月异了,但有一些深刻的思想现在并没有过时。各个学科领域总有 不少东西,换了新装之后又粉墨登场,现在热火朝天的transfer learning,其实就是learning by analogy的升级版。
人工智能的研究从以“推理”为重点到以“知识”为重点,再到以“学习”为重点,是有一条自然、清晰的脉络。人工智能出身的机器学习研究者,绝大部分 是把机器学习作为实现人工智能的一个途径,正如1983年的书名那样。他们关注的是人工智能中的问题,希望以机器学习为手段,但具体采用什么样的学习手 段,是基于统计的、代数的、还是逻辑的、几何的,他们并不care。
这群人可能对统计学习目前dominating的地位未必满意。靠统计学习是不可能解决人工智能中大部分问题的,如果统计学习压制了对其他手段的研 究,可能不是好事。这群人往往也不care在文章里show自己的数学水平,甚至可能是以简化表达自己的思想为荣。人工智能问题不是数学问题,甚至未必是 依靠数学能够解决的问题。人工智能中许多事情的难处,往往在于我们不知道困难的本质在哪里,不知道“问题”在哪里。一旦“问题”清楚了,解决起来可能并不 困难。
第二个community,是把机器学习看作“应用统计学”的一个群体,这群人的主体是统计学家。
和纯数学相比,统计学不太“干净”,不少数学家甚至拒绝承认统计学是数学。但如果和人工智能相比,统计学就太干净了,统计学研究的问题是清楚的,不象人工智能那样,连问题到底在哪里都不知道。在相当长时间里,统计学家和机器学习一直保持着距离。
慢慢地,不少统计学家逐渐意识到,统计学本来就该面向应用,而机器学习天生就是一个很好的切入点。因为机器学习虽然用到各种各样的数学,但要分析大 量数据中蕴涵的规律,统计学是必不可少的。统计学出身的机器学习研究者,绝大部分是把机器学习当作应用统计学。他们关注的是如何把统计学中的理论和方法变 成可以在计算机上有效实现的算法,至于这样的算法对人工智能中的什么问题有用,他们并不care。
这群人可能对人工智能毫无兴趣,在他们眼中,机器学习就是统计学习,是统计学比较偏向应用的一个分支,充其量是统计学与计算机科学的交叉。这群人对统计学习之外的学习手段往往是排斥的,这很自然,基于代数的、逻辑的、几何的学习,很难纳入统计学的范畴。
两个群体的文化和价值观完全不同。第一个群体认为好的工作,第二个群体可能觉得没有技术含量,但第一个群体可能恰恰认为,简单的才好,正因为很好地 抓住了问题本质,所以问题变得容易解决。第二个群体欣赏的工作,第一个群体可能觉得是故弄玄虚,看不出他想解决什么人工智能问题,根本就不是在搞人工智 能、搞计算机,但别人本来也没说自己是在“搞人工智能”、“搞计算机”,本来就不是在为人工智能做研究。
两个群体各有其存在的意义,应该宽容一点,不需要去互较什么短长。但是既然顶着Machine Learning这个帽子的不是“一伙儿”,而是“两伙儿”,那么要“跟进”的新人就要谨慎了,先搞清楚自己更喜欢“哪伙儿”。
引两位著名学者的话结尾,一位是人工智能大奖得主、一位是统计学习大家,名字我不说了,省得惹麻烦:
“I do not come to AI to do statistics”
“I do not have interest in AI”

Scala学习-类,对象

1.类:类是对象的蓝图,根据类,使用new关键字,就可以创建对象了。和Java一样,Scala的对象也包含:属性和方法。这部分和Java基本上相同。

  • 属性:默认是public的,使用private可以改变作用域;
  • 方法:定义类的方法与定义普通的相同;Scala没有静态方法。
    class ChecksumAccumulator {
      private var sum = 0
      def add(b: Byte) { sum += b }
      def checksum(): Int = ~ (sum & 0xFF) + 1
    }

在Scala的代码中,一个语句如果单独一行的话,可以不加分号,自动进行分号的推断;

  • class可以带参数,class Rational(a:Int,b:Int)
  • 使用override进行函数重载:
  • class Rational(a:Int,b:Int){
        overrride def toString = a + "/" + b
    }
  • preconditions:可以使用require()。
class Rational(a:Int, b:Int){
	require(b != 0)
	val  numer:Int = a
	val  demon:Int = b
	override def toString = a + "/" + b
	def add(that: Rational) = new Rational(
		a * that.demon + b * that.numer,
		b * that.demon
		)
}

2.使用object定义singleton 对象。

import scala.collection.mutable.Map

object ChecksumAccumulator {
  private val cache = Map[String, Int]()
  def calculate(s: String): Int =
    if (cache.contains(s))
      cache(s)
    else {
      val acc = new ChecksumAccumulator
      for (c <- s)
        acc.add(c.toByte)
      val cs = acc.checksum()
        cache += (s -> cs)
        cs
}
}

Singleton与class的名字相同,他们得放在同一源文件中,称为companion class 与companion object。不会创建新的类型;与class的名字不同,称为standalone对象,这种对象可以作为一个Scala程序的启动点。

 

3.Scala程序的启动类似Java,使用含有main方法的Singleton对象。

运行程序的话,首先使用scalac或是fsc进行编译,然后使用scala运行(不含后缀),终于Java的命令行是类似的。

也可是使用Application traits来启动程序,不过这种方法仅仅用在一些简单的,单线程程序中。

 

Scala-数组,列表,元组和文件读写

已经对Scala的变量,函数了解以后,看一下比较高级的数据结构以及IO。

1.数组:

val language = new Array[String](2)
language(0)="Java"
language(1)="Scala"

在scala中提供一种更加简洁的方式,

val language = Array("java","Scala")

可以看到,与Java明显不同的是:Scala中数组使用()来索引,而不是使用[]。得到数组里面的每个元素,可以使用:

for(i <- 0 to 2)
    println(language(i))

需要注意的是:0 to 2 相当于0.to(2),这个和1+3是一样的道理,所有的操作符都是函数调用的方式进行的。这也是Scala中索引使用(),而不使用[]的原因。language(1)相当于language.apply(1)。

 

2.Scala的数组长度不可变,但是数组还是可以变化的,比如:

langage(0) = "C"

如果想让数组中元素也不可变,可以使用List。

val l1 = List(1,2)
val l2 = List(3,4)
val l3 = l1:::l2
val l4 = 2::l2

List是不可变的,符合函数式编程的性质,它有很多操作。

  • 构造:List()
  • 连接:l1 ::: l2
  • 数数:l1.count(e => e>0)
  • Map:l1.map(e => e* 2)
  • filter: l1.filter(e => e>1)
  • foreach: l1.foreach(println)
  • 长度:l1.length
  • reverse:l1.reverse()
  • 排序:l1.sortWith((a,b) => a<b)
  • head,last,init,tail

3.Tuple:与List基本一样,但是可以放不同类型的元素;最多可以放22个;索引从1开始,使用._进行索引,比如:t._1

4.set,Map

5.读写文件:

import scala.io.Source

for(line <- Source.fromFile(filename).readlines())
    println(line)

 




Host by is-Programmer.com | Power by Chito 1.3.3 beta | © 2007 LinuxGem | Design by Matthew "Agent Spork" McGee