大数据工具大全–大数据开源处理工具汇总

大数据工具大全–大数据开源处理工具汇总

查询引擎

一、Phoenix
贡献者::Salesforce
简介:这是一个Java中间层,可以让开发者在Apache HBase上执行SQL查询。Phoenix完全使用Java编写,代码位于GitHub上,并且提供了一个客户端可嵌入的JDBC驱动。
Phoenix查询引擎会将SQL查询转换为一个或多个HBase scan,并编排执行以生成标准的JDBC结果集。直接使用HBase API、协同处理器与自定义过滤器,对于简单查询来说,其性能量级是毫秒,对于百万级别的行数来说,其性能量级是秒。
Phoenix最值得关注的一些特性有:
❶嵌入式的JDBC驱动,实现了大部分的java.sql接口,包括元数据API
❷可以通过多部行键或是键/值单元对列进行建模
❸完善的查询支持,可以使用多个谓词以及优化的扫描键
❹DDL支持:通过CREATE TABLE、DROP TABLE及ALTER TABLE来添加/删除列
❺版本化的模式仓库:当写入数据时,快照查询会使用恰当的模式
❻DML支持:用于逐行插入的UPSERT VALUES、用于相同或不同表之间大量数据传输的UPSERT ❼SELECT、用于删除行的DELETE
❽通过客户端的批处理实现的有限的事务支持
❾单表——还没有连接,同时二级索引也在开发当中
➓紧跟ANSI SQL标准
二、Stinger
贡献者::Hortonworks
简介:原叫Tez,下一代Hive,Hortonworks主导开发,运行在YARN上的DAG计算框架。
某些测试下,Stinger能提升10倍左右的性能,同时会让Hive支持更多的SQL,其主要优点包括:
❶让用户在Hadoop获得更多的查询匹配。其中包括类似OVER的字句分析功能,支持WHERE查询,让Hive的样式系统更符合SQL模型。
❷优化了Hive请求执行计划,优化后请求时间减少90%。改动了Hive执行引擎,增加单Hive任务的被秒处理记录数。
❸在Hive社区中引入了新的列式文件格式(如ORC文件),提供一种更现代、高效和高性能的方式来储存Hive数据。
❹引入了新的运行时框架——Tez,旨在消除Hive的延时和吞吐量限制。Tez通过消除不必要的task、障碍同步和对HDFS的读写作业来优化Hive job。这将优化Hadoop内部的执行链,彻底加速Hive负载处理。
三、Presto
贡献者::Facebook
简 介:Facebook开源的数据查询引擎Presto ,可对250PB以上的数据进行快速地交互式分析。该项目始于 2012 年秋季开始开发,目前该项目已经在超过 1000 名 Facebook 雇员中使用,运行超过 30000 个查询,每日数据在 1PB 级别。Facebook 称 Presto 的性能比诸如 Hive 和 Map*Reduce 要好上 10 倍有多。
Presto 当前支持 ANSI SQL 的大多数特效,包括联合查询、左右联接、子查询以及一些聚合和计算函数;支持近似截然不同的计数(DISTINCT COUNT)等。
四、Shark
简 介:Shark即Hive on Spark,本质上是通过Hive的HQL解析,把HQL翻译成Spark上的RDD操作,然后通过Hive的metadata获取数据库里的表信息,实 际HDFS上的数据和文件,会由Shark获取并放到Spark上运算。Shark的特点就是快,完全兼容Hive,且可以在shell模式下使用 rdd2sql()这样的API,把HQL得到的结果集,继续在scala环境下运算,支持自己编写简单的机器学习或简单分析处理函数,对HQL结果进一 步分析计算。
❶Shark速度快的原因除了Spark平台提供的基于内存迭代计算外,在设计上还存在对Spark上进行了一定的改造,主要有
❷partial DAG execution:对join优化,调节并行粒度,因为Spark本身的宽依赖和窄依赖会影响并行计算和速度
基于列的压缩和存储:把HQL表数据按列存,每列是一个array,存在JVM上,避免了JVM GC低效,而压缩和解压相关的技术是Yahoo!提供的。
结 来说,Shark是一个插件式的东西,在我现有的Spark和Hive及hadoop-client之间,在这两套都可用的情况下,Shark只要获取 Hive的配置(还有metastore和exec等关键包),Spark的路径,Shark就能利用Hive和Spark,把HQL解析成RDD的转 换,把数据取到Spark上运算和分析。在SQL on Hadoop这块,Shark有别于Impala,Stringer,而这些系统各有自己的设计思路,相对于对MR进行优化和改进的思路,Shark的思 路更加简单明了些。
五、Pig
简介:Pig是一种编程语言,它简化了Hadoop常见的工作任务。Pig可加载数据、表达转换数据以及存储最终结果。Pig内置的操作使得半结构化数据变得有意义(如日志文件)。同时Pig可扩展使用Java中添加的自定义数据类型并支持数据转换。
Pig最大的作用就是对mapreduce算法(框架)实现了一套shell脚本 ,类似我们通常熟悉的SQL语句,在Pig中称之为Pig Latin,在这套脚本中我们可以对加载出来的数据进行排序、过滤、求和、分组(group by)、关联(Joining),Pig也可以由用户自定义一些函数对数据集进行操作,也就是传说中的UDF(user-defined functions)。
六、Cloudera Impala
贡献者::Cloudera
简 介:Cloudera Impala 可以直接为存储在HDFS或HBase中的Hadoop数据提供快速,交互式的SQL查询。除了使用相同的存储平台外, Impala和Apache Hive一样也使用了相同的元数据,SQL语法(Hive SQL),ODBC驱动和用户接口(Hue Beeswax),这就很方便的为用户提供了一个相似并且统一的平台来进行批量或实时查询。
Cloudera Impala 是用来进行大数据查询的补充工具。 Impala 并没有取代像Hive这样基于MapReduce的分布式处理框架。Hive和其它基于MapReduce的计算框架非常适合长时间运行的批处理作业,例 如那些涉及到批量 Extract、Transform、Load ,即需要进行ETL作业。
Impala 提供了:
❶数据科学家或数据分析师已经熟知的SQL接口
❷能够在Apache Hadoop 的大数据中进行交互式数据查询
❸ Single system for big data processing and analytics so customers can avoid costly modeling and ETL just for analytics
七、Apache Drill
贡献者::MapR
简 介:Apache Drill是是一个能够对大数据进行交互分析、开源的分布式系统,且基于Google Dremel实现,它能够运行在上千个节点的服务器集群上,且能在几秒内处理PB级或者万亿条的数据记录。Drill能够帮助企业用户快速、高效地进行 Hadoop数据查询和企业级大数据分析。Drill于2012年8月份由Apache推出。
从Drill官方对其架构的介绍中得知,其具有适于实时的分析和快速的应用开发、适于半结构化/嵌套数据的分析、兼 容现有的SQL环境和Apache Hive等特征。另外,Drill的核心模块是Drillbit服务,该服务模块包括远程访问子模块、SQL解析器、查询优化器、任务计划执行引擎、存储 插件接口(DFS、HBase、Hive等的接口)、分布式缓存模块等几部分,如下图所示:
八、Apache Tajo
简 介:Apache Tajo项目的目的是在HDFS之上构建一个先进的数据仓库系统。Tajo将自己标榜为一个“大数据仓库”,但是它好像和之前介绍的那些低延迟查询引擎类 似。虽然它支持外部表和Hive数据集(通过HCatalog),但是它的重点是数据管理,提供低延迟的数据访问,以及为更传统的ETL提供工具。它也需 要在数据节点上部署Tajo特定的工作进程。
Tajo的功能包括:
❶ANSI SQL兼容
❷JDBC 驱动
❸集成Hive metastore能够访问Hive数据集
❹一个命令行客户端
❺一个自定义函数API
九、Hive
简介:hive 是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供简单的sql查询功能,可以将sql语句转换为 MapReduce任务进行运行。 其优点是学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。

流式计算

一、Facebook Puma
贡献者:Facebook
简介:实时数据流分析
二、Twitter Rainbird
贡献者:Twitter
简介:Rainbird一款基于Zookeeper, Cassandra, Scribe, Thrift的分布式实时统计系统,这些基础组件的基本功能如下:
❶ Zookeeper,Hadoop子项目中的一款分布式协调系统,用于控制分布式系统中各个组件中的一致性。
❷Cassandra,NoSQL中一款非常出色的产品,集合了Dynamo和Bigtable特性的分布式存储系统,用于存储需要进行统计的数据,统计数据,并且提供客户端进行统计数据的查询。(需要使用分布式Counter补丁CASSANDRA-1072)
❸ Scribe,Facebook开源的一款分布式日志收集系统,用于在系统中将各个需要统计的数据源收集到Cassandra中。
❹ Thrift,Facebook开源的一款跨语言C/S网络通信框架,开发人员基于这个框架可以轻易地开发C/S应用。
用处
Rainbird可以用于实时数据的统计:
❶统计网站中每一个页面,域名的点击次数
❷内部系统的运行监控(统计被监控服务器的运行状态)
❸记录最大值和最小值
三、Yahoo S4
贡献者:Yahoo
简 介:S4(Simple Scalable Streaming System)最初是Yahoo!为提高搜索广告有效点击率的问题而开发的一个平台,通过统计分析用户对广告的点击率,排除相关度低的广告,提升点击率。 目前该项目刚启动不久,所以也可以理解为是他们提出的一个分布式流计算(Distributed Stream Computing)的模型。
S4的设计目标是:
·提供一种简单的编程接口来处理数据流
·设计一个可以在普通硬件之上可扩展的高可用集群。
·通过在每个处理节点使用本地内存,避免磁盘I/O瓶颈达到最小化延迟
·使用一个去中心的,对等架构;所有节点提供相同的功能和职责。没有担负特殊责任的中心节点。这大大简化了部署和维护。
·使用可插拔的架构,使设计尽可能的即通用又可定制化。
·友好的设计理念,易于编程,具有灵活的弹性
四、Twitter Storm
贡献者:Twitter
简介:Storm是Twitter开源的一个类似于Hadoop的实时数据处理框架,它原来是由BackType开发,后BackType被Twitter收购,将Storm作为Twitter的实时数据分析系统。
实时数据处理的应用场景很广泛,例如商品推荐,广告投放,它能根据当前情景上下文(用户偏好,地理位置,已发生的查询和点击等)来估计用户点击的可能性并实时做出调整。
storm的三大作用领域:
1.信息流处理(Stream Processing)
Storm可以用来实时处理新数据和更新数据库,兼具容错性和可扩展性,它 可以用来处理源源不断的消息,并将处理之后的结果保存到持久化介质中。
2.连续计算(Continuous Computation)
Storm可以进行连续查询并把结果即时反馈给客户,比如将Twitter上的热门话题发送到客户端。
3.分布式远程过程调用(Distributed RPC)
除此之外,Storm也被广泛用于以下方面:
  • 精确的广告推送
  • 实时日志的处理

迭代计算

一、Apache Hama
简介:Apache Hama是一个纯BSP(Bulk Synchronous Parallel)计算框架,模仿了Google的Pregel。用来处理大规模的科学计算,特别是矩阵和图计算。
❶建立在Hadoop上的分布式并行计算模型。
❷基于 Map/Reduce 和 Bulk Synchronous 的实现框架。
❸运行环境需要关联 Zookeeper、HBase、HDFS 组件。
Hama中有2个主要的模型:
– 矩阵计算(Matrix package)
– 面向图计算(Graph package)
二、Apache Giraph
代码托管地址: GitHub
简介:Apache Giraph是一个可伸缩的分布式迭代图处理系统,灵感来自BSP(bulk synchronous parallel)和Google的Pregel,与它们 区别于则是是开源、基于 Hadoop 的架构等。
Giraph处理平台适用于运行大规模的逻辑计算,比如页面排行、共享链接、基于个性化排行等。Giraph专注于社交图计算,被Facebook作为其Open Graph工具的核心,几分钟内处理数万亿次用户及其行为之间的连接。
三、HaLoop
简介:迭代的MapReduce,HaLoop——适用于迭代计算的Hadoop 。
Hadoop与HaLoop的不同
与Hadoop比较的四点改变:
1.提供了一套新的编程接口,更加适用于迭代计算;
HaLoop给迭代计算一个抽象的递归公式:

2.HaLoop的master进行job内的循环控制,直到迭代计算结束;
3.Task Scheduler也进行了修改,使得任务能够尽量满足data locality
4.slave nodes对数据进行cache并index索引,索引也以文件的形式保存在本地磁盘。
四、Twister
简介:Twister, 迭代式MapReduce框架,Twister是由一个印度人开发的,其架构如下:
在Twister中,大文件不会自动被切割成一个一个block,因而用户需提前把文件分成一个一个小 文件,以供每个task处理。在map阶段,经过map()处理完的结果被放在分布式内存中,然后通过一个broker network(NaradaBroking系统)将数据push给各个reduce task(Twister假设内存足够大,中间数据可以全部放在内存中);在reduce阶段,所有reduce task产生的结果通过一个combine操作进行归并,此时,用户可以进行条件判定, 确定迭代是否结束。combine后的数据直接被送给map task,开始新一轮的迭代。为了提高容错性,Twister每隔一段时间会将map task和reduce task产生的结果写到磁盘上,这样,一旦某个task失败,它可以从最近的备份中获取输入,重新计算。
为了避免每次迭代重新创建task,Twister维护了一个task pool,每次需要task时直接从pool中取。在Twister中,所有消息和数据都是通过broker network传递的,该broker network是一个独立的模块,目前支持NaradaBroking和ActiveMQ。

离线计算

一、Hadoop MapReduce
简 介:MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。概念”Map(映射)”和”Reduce(归约)”,和它们的主要思 想,都是从函数式编程语言里借来的,还有从矢量编程语言里借来的特性。它极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系 统上。 当前的软件实现是指定一个Map(映射)函数,用来把一组键值对映射成一组新的键值对,指定并发的Reduce(归约)函数,用来保证所有映射的键值对中 的每一个共享相同的键组。
二、Berkeley Spark
简 介:Spark是UC Berkeley AMP lab所开源的类Hadoop MapReduce的通用的并行,Spark,拥有Hadoop MapReduce所具有的优点;但不同于MapReduce的是Job中间输出结果可以保存在内存中,从而不再需要读写HDFS,因此Spark能更好 地适用于数据挖掘与机器学习等需要迭代的map reduce的算法。
三、DataTorrent
简介:DataTorrent基于Hadoop 2.x构建,是一个实时的、有容错能力的数据流式处理和分析平台,它使用本地Hadoop应用程序,而这些应用程序可以与执行其它任务,如批处理,的应用程序共存。该平台的架构如下图所示:

键值存储

一、LevelDB
贡献者:Google
简介:Leveldb是一个google实现的非常高效的kv数据库,目前的版本1.2能够支持billion级别的数据量了。 在这个数量级别下还有着非常高的性能,主要归功于它的良好的设计。特别是LMS算法。
LevelDB 是单进程的服务,性能非常之高,在一台4核Q6600的CPU机器上,每秒钟写数据超过40w,而随机读的性能每秒钟超过10w。
此处随机读是完全命中内存的速度,如果是不命中 速度大大下降。
二、RocksDB
贡献者:facebook
简 介:RocksDB虽然在代码层面上是在LevelDB原有的代码上进行开发的,但却借鉴了Apache HBase的一些好的idea。在云计算横行的年代,开口不离Hadoop,RocksDB也开始支持HDFS,允许从HDFS读取数据。RocksDB 支持一次获取多个K-V,还支持Key范围查找。LevelDB只能获取单个Key。
RocksDB除了简单的Put、Delete操作,还提供了一个Merge操作,说是为了对多个Put操作进行合并。
RocksDB提供一些方便的工具,这些工具包含解析sst文件中的K-V记录、解析MANIFEST文件的内容等。RocksDB支持多线程合并,而LevelDB是单线程合并的。
三、HyperDex
贡献者:Facebook
HyperDex是一个分布式、可搜索的键值存储系统,特性如下:
  • 分布式KV存储,系统性能能够随节点数目线性扩展
  • 吞吐和延时都能秒杀现在风头正劲的MonogDB,吞吐甚至强于Redis
  • 使用了hyperspace hashing技术,使得对存储的K-V的任意属性进行查询成为可能
四、TokyoCabinet

日本人Mikio Hirabayashi(平林干雄)开发的一款DBM数据库。Tokyo Cabinet 是一个DBM的实现。这里的数据库由一系列key-value对的记录构成。key和value都可以是任意长度的字节序列,既可以是二进制也可以是字符 串。这里没有数据类型和数据表的概念。

当 做为Hash表数据库使用时,每个key必须是不同的,因此无法存储两个key相同的值。提供了以下访问方法:提供key,value参数来存储,按 key删除记录,按key来读取记录,另外,遍历key也被支持,虽然顺序是任意的不能被保证。这些方法跟Unix标准的DBM,例如GDBM,NDBM 等等是相同的,但是比它们的性能要好得多(因此可以替代它们) 。下一代KV存储系统,支持strings、integers、floats、lists、maps和sets等丰富的数据类型。

TokyoCabinet官方网站>>>

五、Voldemort

Voldemort是一个分布式键值存储系统,是Amazon’s Dynamo的一个开源克隆。特性如下:

  • 支持自动复制数据到多个服务器上。
  • 支持数据自动分割所以每个服务器只包含总数据的一个子集。
  • 提供服务器故障透明处理功能。
  • 支持可拨插的序化支持,以实现复杂的键-值存储,它能够很好的5.集成常用的序化框架如:Protocol Buffers、Thrift、Avro和Java Serialization。
  • 数据项都被标识版本能够在发生故障时尽量保持数据的完整性而不会影响系统的可用性。
  • 每个节点相互独立,互不影响。
  • 支持可插拔的数据放置策略

六、Amazon Dynamo

贡献者:亚马逊

简介:Amazon Dynamo 是一个经典的分布式Key-Value 存储系统,具备去中心化,高可用性,高扩展性的特点,但是为了达到这个目标在很多场景中牺牲了一致性。Dynamo在Amazon中得到了成功的应用,能 够跨数据中心部署于上万个结点上提供服务,它的设计思想也被后续的许多分布式系统借鉴。如近来火热的Cassandra,实际上就是基本照搬了 Dynamo的P2P架构,同时融合了BigTable的数据模型及存储算法。

Amazon Dynamo官方网站>>>

七、Tair

贡献者:淘宝

简介:tair 是淘宝自己开发的一个分布式 key/value 存储引擎. tair 分为持久化和非持久化两种使用方式. 非持久化的 tair 可以看成是一个分布式缓存. 持久化的 tair 将数据存放于磁盘中. 为了解决磁盘损坏导致数据丢失, tair 可以配置数据的备份数目, tair 自动将一份数据的不同备份放到不同的主机上, 当有主机发生异常, 无法正常提供服务的时候, 其于的备份会继续提供服务.tair 的总体结构

tair 作为一个分布式系统, 是由一个中心控制节点和一系列的服务节点组成. 我们称中心控制节点为config server. 服务节点是data server. config server 负责管理所有的data server, 维护data server的状态信息. data server 对外提供各种数据服务, 并以心跳的形式将自身状况汇报给config server. config server是控制点, 而且是单点, 目前采用一主一备的形式来保证其可靠性. 所有的 data server 地位都是等价的.

八、Apache Accumulo

Apache Accumulo 是一个可靠的、可伸缩的、高性能的排序分布式的 Key-Value 存储解决方案,基于单元访问控制以及可定制的服务器端处理。Accumulo使用 Google BigTable 设计思路,基于 Apache Hadoop、Zookeeper 和 Thrift 构建。

官网:http://accumulo.apache.org/

九、Redis
Redis是一个高性能的key-value存储系统,和Memcached类似,它支持存储的 value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。与memcached一样,为了保证效 率,数据都是缓存在内存中,区别的是Redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步。
Redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Python、Ruby、Erlang、PHP客户端,使用很方便。

表格存储

一、OceanBase
贡献者:阿里巴巴
简 介:OceanBase是一个支持海量数据的高性能分布式数据库系统,实现了数千亿条记录、数百TB数据上的跨行跨表事务,由淘宝核心系统研发部、运维、 DBA、广告、应用研发等部门共同完成。在设计和实现OceanBase的时候暂时摒弃了不紧急的DBMS的功能,例如临时表,视图(view),研发团 队把有限的资源集中到关键点上,当前 OceanBase主要解决数据更新一致性、高性能的跨表读事务、范围查询、join、数据全量及增量dump、批量数据导入。
目前OceanBase已经应用于淘宝收藏夹,用于存储淘宝用户收藏条目和具体的商品、店铺信息,每天支持4~5千万的更新操作。等待上线的应用还包括CTU、SNS等,每天更新超过20亿,更新数据量超过2.5TB,并会逐步在淘宝内部推广。
OceanBase 0.3.1在Github开源,开源版本为Revision:12336。
二、Amazon SimpleDB
贡献者:亚马逊
Amazon SimpleDB是一个分散式数据库,以Erlang撰写。同与Amazon EC2和亚马逊的S3一样作为一项Web 服务,属于亚马逊网络服务的一部分。
正如EC2和S3,SimpleDB的按照存储量,在互联网上的传输量和吞吐量收取费用。 在2008年12月1日,亚马逊推出了新的定价策略,提供了免费1 GB的数据和25机器小时的自由层(Free Tire)。 将其中的数据转移到其他亚马逊网络服务是免费的。
它是一个可大规模伸缩、用 Erlang 编写的高可用数据存储。
三、Vertica
贡献者:惠普
简 介:惠普2011年2月份起始3月21号完成收购Vertica。Vertica基于列存储。基于列存储的设计相比传统面向行存储的数据库具有巨大的优 势。同时Vertica支持MPP(massively parallel processing)等技术,查询数据时Vertica只需取得需要的列,而不是被选择行的所有数据,其平均性能可提高50x-1000x倍。(查询性 能高速度快)
Vertica的设计者多次表示他们的产品围绕着高性能和高可用性设计。由于对MPP技术的支持,可提供对粒度,可伸缩性和可用性的优势。每个节点完全独立运作,完全无共享架构,降低对共享资源的系统竞争。
Vertica的数据库使用标准的SQL查询,同时Vertica的架构非常适合云计算,包括虚拟化,分布式多节点运行等,并且可以和Hadoop/MapReduce进行集成。
Vertica官网:http://www.vertica.com/
四、Cassandra
贡献者:facebook
简 介:Cassandra是一套开源分布式NoSQL数据库系统。它最初由Facebook开发,用于储存收件箱等简单格式数据,集 GoogleBigTable的数据模型与Amazon Dynamo的完全分布式的架构于一身Facebook于2008将 Cassandra 开源,此后,由于Cassandra良好的可扩放性,被Digg、Twitter等知名Web 2.0网站所采纳,成为了一种流行的分布式结构化数据存储方案。
Cassandra是一个混合型的非关系的数据库,类似于Google的BigTable。其主要功能比 Dynamo (分布式的Key-Value存储系统)更丰富,但支持度却不如文档存储MongoDB(介于关系数据库和非关系数据库之间的开源产品,是非关系数据库当 中功能最丰富,最像关系数据库的。支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型)。Cassandra最初 由Facebook开发,后转变成了开源项目。它是一个网络社交云计算方面理想的数据库。以Amazon专有的完全分布式的Dynamo为基础,结合了 Google BigTable基于列族(Column Family)的数据模型。P2P去中心化的存储。很多方面都可以称之为Dynamo 2.0。
五、HyperTable
简介:Hypertable是一个开源、高性能、可伸缩的数据库,它采用与Google的Bigtable相似的模型。在过去数年中,Google为在PC集群 上运行的可伸缩计算基础设施设计建造了三个关键部分。
第一个关键的基础设施是Google File System(GFS),这是一个高可用的文件系统,提供了一个全局的命名空间。它通过跨机器(和跨机架)的文件数据复制来达到高可用性,并因此免受传统 文件存储系统无法避免的许多失败的影响,比如电源、内存和网络端口等失败。第二个基础设施是名为Map-Reduce的计算框架,它与GFS紧密协作,帮 助处理收集到的海量数据。第三个基础设施是Bigtable,它是传统数据库的替代。Bigtable让你可以通过一些主键来组织海量数据,并实现高效的 查询。Hypertable是Bigtable的一个开源实现,并且根据我们的想法进行了一些改进。
HyperTable官网:http://hypertable.org/
六、FoundationDB
简介:支持ACID事务处理的NoSQL数据库,提供非常好的性能、数据一致性和操作弹性。
2015 年1月2日,FoundationDB已经发布了其key-value数据库的3.0版本,主要专注于可伸缩性和性能上的改善。FoundationDB 的CEO David Rosenthal在一篇博客上宣布了新的版本,其中展示了FoundationDB 3.0在可伸缩性方面的数据,它可以在一个32位的c3.8xlarge EC2实例上每秒写入1440万次;这在性能上是之前版本的36倍。
除了性能和可伸缩性的改善之外,FoundationDB 3.0还包含了对监控支持的改善。这种监控机制不仅仅是简单的机器检查,它添加了对多种潜在的硬件瓶颈的诊断,并且把那些高层级的信息整合到现有监控基础架构中。
七:HBase
贡献者: Fay Chang 所撰写的“Bigtable
简介:HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。HBase是Apache的Hadoop 项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式。

文件存储

一、CouchDB
简 介:CouchDB是用Erlang开发的面向文档的数据库系统,最近刚刚发布了1.0版本(2010年7月14日)。CouchDB不是一个传统的关系 数据库,而是面向文档的数据库,其数据存储方式有点类似lucene的index文件格式,CouchDB最大的意义在于它是一个面向web应用的新一代 存储系统,事实上,CouchDB的口号就是:下一代的Web应用存储系统。
特点:
一、CouchDB是分布式的数据库,他可以把存储系统分 布到n台物理的节点上面,并且很好的协调和同步节点之间的数据读写一致性。这当然也得靠Erlang无与伦比的并发特性才能做到。对于基于web的大规模 应用文档应用,分布式可以让它不必像传统的关系数据库那样分库拆表,在应用代码层进行大量的改动。
二、CouchDB是面向文档的数据库,存储半结构化的数据,比较类似lucene的index结构,特别适合存储文档,因此很适合CMS,电话本,地址本等应用,在这些应用场合,文档数据库要比关系数据库更加方便,性能更好。
三、CouchDB支持REST API,可以让用户使用JavaScript来操作CouchDB数据库,也可以用JavaScript编写查询语句,我们可以想像一下,用AJAX技术结合CouchDB开发出来的CMS系统会是多么的简单和方便。
其实CouchDB只是Erlang应用的冰山一角,在最近几年,基于Erlang的应用也得到的蓬勃的发展,特别是在基于web的大规模,分布式应用领域,几乎都是Erlang的优势项目。
二、MongoDB
简介:MongoDB 是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson 格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数 据库单表查询的绝大部分功能,而且还支持对数据建立索引。
特点
它的特点是高性能、易部署、易使用,存储数据非常方便。主要功能特性有:
*面向集合存储,易存储对象类型的数据。
mongodb集群参考
mongodb集群参考
*模式自由。
*支持动态查询。
*支持完全索引,包含内部对象。
*支持查询。
*支持复制和故障恢复。
*使用高效的二进制数据存储,包括大型对象(如视频等)。
*自动处理碎片,以支持云计算层次的扩展性。
*支持RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。
*文件存储格式为BSON(一种JSON的扩展)。
*可通过网络访问。
三、Tachyon
贡献者:Haoyuan Li(李浩源)
简介:Tachyon是一个分布式内存文件系统,可以在集群里以访问内存的速度来访问存在tachyon里的文件。 把Tachyon是架构在最底层的分布式文件存储和上层的各种计算框架之间的一种中间件。主要职责是将那些不需要落地到DFS里的文件,落地到分布式内存 文件系统中,来达到共享内存,从而提高效率。同时可以减少内存冗余,GC时间等。
Tachyon架构
Tachyon的架构是传统的Master— slave架构,这里和Hadoop类似,TachyonMaster里WorkflowManager是 Master进程,因为是为了防止单点问题,通过Zookeeper做了HA,可以部署多台Standby Master。Slave是由Worker Daemon和Ramdisk构成。这里个人理解只有Worker Daemon是基于JVM的,Ramdisk是一个off heap memory。Master和Worker直接的通讯协议是Thrift。
下图来自Tachyon的作者Haoyuan Li:
四、KFS
简介:GFS的 C++开源版本,Kosmos distributed file system (KFS)是一个专门为数据密集型应用(搜索引擎,数据挖掘等)而设计的存储系统,类似于Google的GFS和Hadoop的HDFS分布式文件系统。 KFS使用C++实现,支持的客户端包括C++,Java和Python。KFS系统由三部分组成,分别是metaserver、chunkserver 和client library。
五、HDFS
简介:Hadoop分布式文件系统(HDFS)被设计成适合运行在通用硬件(commodity hardware)上的分布式文件系统。它和现有的分布式文件系统有很多共同点。但同时,它和其他的分布式文件系统的区别也是很明显的。HDFS是一个高 度容错性的系统,适合部署在廉价的机器上。HDFS能提供高吞吐量的数据访问,非常适合大规模数据集上的应用。HDFS放宽了一部分POSIX约束,来实 现流式读取文件系统数据的目的。HDFS在最开始是作为Apache Nutch搜索引擎项目的基础架构而开发的。HDFS是Apache Hadoop Core项目的一部分。

资源管理

一、Twitter Mesos
开发者:Twitter研发人员John Oskasson
简介:Apache Mesos是由加州大学伯克利分校的AMPLab首先开发的一款开源群集管理软件,支持Hadoop、ElasticSearch、Spark、 Storm 和Kafka等架构,由于其开源性质越来越受到一些大型云计算公司的青睐,例如Twitter、Facebook等。
二、Hadoop Yarn
Hadoop 新 MapReduce 框架 Yarn。为从根本上解决旧 MapReduce 框架的性能瓶颈,促进 Hadoop 框架的更长远发展,从 0.23.0 版本开始,Hadoop 的 MapReduce 框架完全重构,发生了根本的变化。新的 Hadoop MapReduce 框架命名为 MapReduceV2 或者叫 Yarn,其架构图如下图所示:
Yarn 框架相对于老的 MapReduce 框架什么优势呢?我们可以看到:
1、这个设计大大减小了 JobTracker(也就是现在的 ResourceManager)的资源消耗,并且让监测每一个 Job 子任务 (tasks) 状态的程序分布式化了,更安全、更优美。
2、 在新的 Yarn 中,ApplicationMaster 是一个可变更的部分,用户可以对不同的编程模型写自己的 AppMst,让更多类型的编程模型能够跑在 Hadoop 集群中,可以参考 hadoop Yarn 官方配置模板中的 mapred-site.xml 配置。
3、对于资源的表示以内存为单位 ( 在目前版本的 Yarn 中,没有考虑 cpu 的占用 ),比之前以剩余 slot 数目更合理。
4、 老的框架中,JobTracker 一个很大的负担就是监控 job 下的 tasks 的运行状况,现在,这个部分就扔给 ApplicationMaster 做了,而 ResourceManager 中有一个模块叫做 ApplicationsMasters( 注意不是 ApplicationMaster),它是监测 ApplicationMaster 的行状况,如果出问题,会将其在其他机器上重启。
5、 Container 是 Yarn 为了将来作资源隔离而提出的一个框架。这一点应该借鉴了 Mesos 的工作,目前是一个框架,仅仅提供 java 虚拟机内存的隔离 ,hadoop 团队的设计思路应该后续能支持更多的资源调度和控制 , 既然资源表示成内存量,那就没有了之前的 map slot/reduce slot 分开造成集群资源闲置的尴尬情况。

接上一部分:这部分主要收集整理的内容主要有日志收集系统、消息系统、分布式服务、集群管理、RPC、基础设施、搜索引擎、Iaas和监控管理等大数据开源工具。

日志收集系统

一、Facebook Scribe
贡献者:Facebook
简介:Scribe是 Facebook开源的日志收集系统,在Facebook内部已经得到大量的应用。它能够从各种日志源上收集日志,存储到一个中央存储系统(可以是 NFS,分布式文件系统等)上,以便于进行集中统计分析处理。它为日志的“分布式收集,统一处理”提供了一个可扩展的,高容错的方案。当中央存储系统的网 络或者机器出现故障时,scribe会将日志转存到本地或者另一个位置,当中央存储系统恢复后,scribe会将转存的日志重新传输给中央存储系统。其通 常与Hadoop结合使用,scribe用于向HDFS中push日志,而Hadoop通过MapReduce作业进行定期处理。
Scribe的系统架构
二、Cloudera Flume
贡献者:Cloudera
简介:Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力。
Flume提供了从console(控制台)、RPC(Thrift-RPC)、text(文件)、tail(UNIX tail)、syslog(syslog日志系统,支持TCP和UDP等2种模式),exec(命令执行)等数据源上收集数据的能力。
当前Flume有两个版本Flume 0.9X版本的统称Flume-og,Flume1.X版本的统称Flume-ng。由于Flume-ng经过重大重构,与Flume-og有很大不同,使用时请注意区分。
Cloudera Flume构架:
三、logstash
简介:logstash 是一个应用程序日志、事件的传输、处理、管理和搜索的平台。你可以用它来统一对应用程序日志进行收集管理,提供 Web 接口用于查询和统计。他可以对你的日志进行收集、分析,并将其存储供以后使用(如,搜索),您可以使用它。说到搜索,logstash带有一个web界 面,搜索和展示所有日志。
四、kibana
简 介:Kibana 是一个为 Logstash 和 ElasticSearch 提供的日志分析的 Web 接口。可使用它对日志进行高效的搜索、可视化、分析等各种操作。kibana 也是一个开源和免费的工具,他可以帮助您汇总、分析和搜索重要数据日志并提供友好的web界面。他可以为 Logstash 和 ElasticSearch 提供的日志分析的 Web 界面。

消息系统

一、StormMQ
简介:MQMessageQueue消息队列产品 StormMQ,是一种服务程序。
二、ZeroMQ
简介:这是 个类似于Socket的一系列接口,他跟Socket的区别是:普通的socket是端到端的(1:1的关系),而ZMQ却是可以N:M 的关系,人们对BSD套接字的了解较多的是点对点的连接,点对点连接需要显式地建立连接、销毁连接、选择协议(TCP/UDP)和处理错误等,而ZMQ屏 蔽了这些细节,让你的网络编程更为简单。ZMQ用于node与node间的通信,node可以是主机或者是进程。
引 用官方的说法: “ZMQ(以下ZeroMQ简称ZMQ)是一个简单好用的传输层,像框架一样的一个socket library,他使得Socket编程更加简单、简洁和性能更高。是一个消息处理队列库,可在多个线程、内核和主机盒之间弹性伸缩。ZMQ的明确目标是 “成为标准网络协议栈的一部分,之后进入Linux内核”。现在还未看到它们的成功。但是,它无疑是极具前景的、并且是人们更加需要的“传统”BSD套接 字之上的一 层封装。ZMQ让编写高性能网络应用程序极为简单和有趣。”
三、RabbitMQ
简介:RabbitMQ是一个受欢迎的消息代理,通常用于应用程序之间或者程序的不同组件之间通过消息来进行集成。本文简单介绍了如何使用 RabbitMQ,假定你已经配置好了rabbitmq服务器。
RabbitMQ是用Erlang,对于主要的编程语言都有驱动或者客户端。我们这里要用的是Java,所以先要获得Java客户端。
像RabbitMQ这样的消息代理可用来模拟不同的场景,例如点对点的消息分发或者订阅/推送。我们的程序足够简单,有两个基本的组件,一个生产者用于产生消息,还有一个消费者用来使用产生的消息。
四、Apache ActiveMQ
简 介:ActiveMQ 是Apache出品,最流行的,能力强劲的开源消息总线。ActiveMQ 是一个完全支持JMS1.1和J2EE 1.4规范的 JMS Provider实现,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着特殊的地位。
特性:
⒈ 多种语言和协议编写客户端。语言: Java,C,C++,C#,Ruby,Perl,Python,PHP。应用协议: OpenWire,Stomp REST,WS Notification,XMPP,AMQP
⒉ 完全支持JMS1.1和J2EE 1.4规范 (持久化,XA消息,事务)
⒊ 对Spring的支持,ActiveMQ可以很容易内嵌到使用Spring的系统里面去,而且也支持Spring2.0的特性
⒋ 通过了常见J2EE服务器(如 Geronimo,JBoss 4,GlassFish,WebLogic)的测试,其中通过JCA 1.5 resource adaptors的配置,可以让ActiveMQ可以自动的部署到任何兼容J2EE 1.4 商业服务器上
⒌ 支持多种传送协议:in-VM,TCP,SSL,NIO,UDP,JGroups,JXTA
⒍ 支持通过JDBC和journal提供高速的消息持久化
⒎ 从设计上保证了高性能的集群,客户端-服务器,点对点
⒏ 支持Ajax
⒐ 支持与Axis的整合
⒑ 可以很容易得调用内嵌JMS provider,进行测试
五、Jafka
贡献者:LinkedIn
简 介:Jafka 是一个开源的、高性能的、跨语言分布式消息系统,使用GitHub托管。Jafka 最早是由Apache孵化的Kafka(由LinkedIn捐助给Apache)克隆而来。由于是一个开放式的数据传输协议,因此除了Java开发语言受 到支持,Python、Ruby、C、C++等其他语言也能够很好的得到支持。
特性:
1、消息持久化非常快,服务端存储消息的开销为O(1),并且基于文件系统,能够持久化TB级的消息而不损失性能。
2、吞吐量取决于网络带宽。
3、完全的分布式系统,broker、producer、consumer都原生自动支持分布式。自动实现复杂均衡。
4、内核非常小,整个系统(包括服务端和客户端)只有一个272KB的jar包,内部机制也不复杂,适合进行内嵌或者二次开发 。整个服务端加上依赖组件共3.5MB。
5、消息格式以及通信机制非常简单,适合进行跨语言开发。目前自带的Python3.x的客户端支持发送消息和接收消息。
六、Apache Kafka
贡献者:LinkedIn
简 介:Apache Kafka是由Apache软件基金会开发的一个开源消息系统项目,由Scala写成。Kafka最初是由LinkedIn开发,并于2011年初开源。 2012年10月从Apache Incubator毕业。该项目的目标是为处理实时数据提供一个统一、高通量、低等待的平台。
Kafka是一个分布式的、分区的、多复本的日志提交服务。它通过一种独一无二的设计提供了一个消息系统的功能。
Kafka 集群可以在一个指定的时间内保持所有发布上来的消息,不管这些消息有没有被消费。打个比方,如果这个时间设置为两天,那么在消息发布的两天以内,这条消息 都是可以被消费的,但是在两天后,这条消息就会被系统丢弃以释放空间。Kafka的性能不会受数据量的大小影响,因此保持大量的数据不是一个问题。

分布式服务

一、ZooKeeper
贡献者:Google
简介:ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。
ZooKeeper 是以Fast Paxos算法为基础的,paxos算法存在活锁的问题,即当有多个proposer交错提交时,有可能互相排斥导致没有一个proposer能提交成 功,而Fast Paxos作了一些优化,通过选举产生一个leader,只有leader才能提交propose,具体算法可见Fast Paxos。因此,要想弄懂ZooKeeper首先得对Fast Paxos有所了解。
架构:

RPC

(Remote Procedure Call Protocol)——远程过程调用协议
一、Apache Avro
简介:Apache Avro是Hadoop下的一个子项目。它本身既是一个序列化框架,同时也实现了RPC的功能。Avro官网描述Avro的特性和功能如下:
  • 丰富的数据结构类型;
  • 快速可压缩的二进制数据形式;
  • 存储持久数据的文件容器;
  • 提供远程过程调用RPC;
  • 简单的动态语言结合功能。
相比于Apache Thrift 和Google的Protocol Buffers,Apache Avro具有以下特点:
  • 支持动态模式。Avro不需要生成代码,这有利于搭建通用的数据处理系统,同时避免了代码入侵。
  • 数据无须加标签。读取数据前,Avro能够获取模式定义,这使得Avro在数据编码时只需要保留更少的类型信息,有利于减少序列化后的数据大小。
二、Facebook Thrift
贡献者:Facebook
简 介:Thrift源于大名鼎鼎的facebook之手,在2007年facebook提交Apache基金会将Thrift作为一个开源项目,对于当时的 facebook来说创造thrift是为了解决facebook系统中各系统间大数据量的传输通信以及系统之间语言环境不同需要跨平台的特性。
thrift 可以支持多种程序语言,例如: C++, C#, Cocoa, Erlang, Haskell, Java, Ocami, Perl, PHP, Python, Ruby, Smalltalk. 在多种不同的语言之间通信thrift可以作为二进制的高性能的通讯中间件,支持数据(对象)序列化和多种类型的RPC服务。
Thrift 适用于程序对程 序静态的数据交换,需要先确定好他的数据结构,他是完全静态化的,当数据结构发生变化时,必须重新编辑IDL文件,代码生成,再编译载入的流程,跟其他 IDL工具相比较可以视为是Thrift的弱项,Thrift适用于搭建大型数据交换及存储的通用工具,对于大型系统中的内部数据传输相对于JSON和 xml无论在性能、传输大小上有明显的优势。
Thrift 主要由5个部分组成:
· 类型系统以及 IDL 编译器:负责由用户给定的 IDL 文件生成相应语言的接口代码
· TProtocol:实现 RPC 的协议层,可以选择多种不同的对象串行化方式,如 JSON, Binary。
· TTransport:实现 RPC 的传输层,同样可以选择不同的传输层实现,如socket, 非阻塞的 socket, MemoryBuffer 等。
· TProcessor:作为协议层和用户提供的服务实现之间的纽带,负责调用服务实现的接口。
· TServer:聚合 TProtocol, TTransport 和 TProcessor 几个对象。
上述的这5个部件都是在 Thrift 的源代码中通过为不同语言提供库来实现的,这些库的代码在 Thrift 源码目录的 lib 目录下面,在使用 Thrift 之前需要先熟悉与自己的语言对应的库提供的接口。
Facebook Thrift构架:

集群管理

一、Nagios
简介:Nagios是一款开源的免费网络监视工具,能有效监控Windows、Linux和Unix的主机状态,交换机路由器等网络设置,打印机等。在系统或服务状态异常时发出邮件或短信报警第一时间通知网站运维人员,在状态恢复后发出正常的邮件或短信通知。
Nagios可运行在Linux/Unix平台之上,同时提供一个可选的基于浏览器的WEB界面以方便系统管理人员查看网络状态,各种系统问题,以及日志等等。
二、Ganglia
简 介:Ganglia是UC Berkeley发起的一个开源集群监视项目,设计用于测量数以千计的节点。Ganglia的核心包含gmond、gmetad以及一个Web前端。主要 是用来监控系统性能,如:cpu 、mem、硬盘利用率, I/O负载、网络流量情况等,通过曲线很容易见到每个节点的工作状态,对合理调整、分配系统资源,提高系统整体性能起到重要作用。
三、Apache Ambari
简 介:Apache Ambari是一种基于Web的工具,支持Apache Hadoop集群的供应、管理和监控。Ambari目前已支持大多数Hadoop组件,包括HDFS、MapReduce、Hive、Pig、 Hbase、Zookeper、Sqoop和Hcatalog等。
Apache Ambari 支持HDFS、MapReduce、Hive、Pig、Hbase、Zookeper、Sqoop和Hcatalog等的集中管理。也是5个顶级hadoop管理工具之一。
Ambari主要取得了以下成绩:
  • 通过一步一步的安装向导简化了集群供应。
  • 预先配置好关键的运维指标(metrics),可以直接查看Hadoop Core(HDFS和MapReduce)及相关项目(如HBase、Hive和HCatalog)是否健康。
  • 支持作业与任务执行的可视化与分析,能够更好地查看依赖和性能。
  • 通过一个完整的RESTful API把监控信息暴露出来,集成了现有的运维工具。
  • 用户界面非常直观,用户可以轻松有效地查看信息并控制集群。
Ambari使用Ganglia收集度量指标,用Nagios支持系统报警,当需要引起管理员的关注时(比如,节点停机或磁盘剩余空间不足等问题),系统将向其发送邮件。
此外,Ambari能够安装安全的(基于Kerberos)Hadoop集群,以此实现了对Hadoop 安全的支持,提供了基于角色的用户认证、授权和审计功能,并为用户管理集成了LDAP和Active Directory。

基础设施

一、LevelDB
贡献者:Jeff Dean和Sanjay Ghemawat
简 介:Leveldb是一个google实现的非常高效的kv数据库,目前的版本1.2能够支持billion级别的数据量了。 在这个数量级别下还有着非常高的性能,主要归功于它的良好的设计。特别是LMS算法。LevelDB 是单进程的服务,性能非常之高,在一台4核Q6600的CPU机器上,每秒钟写数据超过40w,而随机读的性能每秒钟超过10w。
Leveldb框架:
二、SSTable
简介:如 果说Protocol Buffer是谷歌独立数据记录的通用语言 ,那么有序字符串表(SSTable,Sorted String Table)则是用于存储,处理和数据集交换的最流行​​的数据输出格式。正如它的名字本身,SSTable是有效存储大量键-值对的简单抽象,对高吞吐 量顺序读/写进行了优化。
SSTable是Bigtable中至关重要的一块,对于LevelDB来说也是如此。
三、RecordIO
贡献者:Google
简介:我们大家都在用文件来存储数据。文件是存储在磁盘上的。如果在一些不稳定的介质上,文件很容损坏。即时文件某个位置出现一点小小的问题,整个文件就废了。
下面我来介绍Google的一个做法,可以比较好的解决这个问题。那就是recordio文件格式。recoidio的存储单元是一个一个record。这个record可以根据业务的需要自行定义。但Google有一种建议的处理方式就是使用protobuf。
reocordio底层的格式其实很简单。一个record由四部分组成:
  • MagicNumber (32 bits)
  • Uncompressed data payload size (64 bits)
  • Compressed data payload size (64 bits), or 0 if the data is not compressed
  • Payload, possibly compressed.
详细格式如下图所示:
到这里,大家可能已经知道,recordio之所以能对付坏数据,其实就是在这个MagicNumber(校验值)。
四、Flat Buffers
贡献者:Google
简介:谷歌开源高效、跨平台的序列化库FlatBuffers。
该库的构建是专门为游戏开发人员的性能需求提供支持,它将序列化数据存储在缓存中,这些数据既可以存储在文件中,又可以通过网络原样传输,而不需要任何解析开销。
FlatBuffers有如下一些关键特性——
  • 访问序列化数据不需要打包/拆包
  • 节省内存而且访问速度快——缓存只占用访问数据所需要的内存;不需要任何额外的内存。
  • 灵活性——通过可选字段向前向后兼容
  • 代码规模小
  • 强类型——错误在编译时捕获,而不是在运行时
  • 便利性——生成的C++头文件代码简洁。如果需要,有一项可选功能可以用来在运行时高效解析Schema和JSON-like格式的文本。
  • 跨平台——使用C++编写,不依赖STL之外的库,因此可以用于任何有C++编辑器的平台。当前,该项目包含构建方法和在Android、Linux、Windows和OSX等操作系统上使用该库的示例。
与Protocol Buffers或JSON Parsing这样的可选方案相比,FlatBuffers的优势在于开销更小,这主要是由于它没有解析过程。
五、Protocol Buffers
贡献者:Google
简 介:Protocol Buffers是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。它不依赖于语言和平台 并且可扩展性极强。现阶段官方支持C++、JAVA、Python等三种编程语言,但可以找到大量的几乎涵盖所有语言的第三方拓展包。
通过它,你可以定义你的数据的结构,并生成基于各种语言的代码。这些你定义的数据流可以轻松地在传递并不破坏你已有的程序。并且你也可以更新这些数据而现有的程序也不会受到任何的影响。
Protocol Buffers经常被简称为protobuf。
六、Consistent Hashing(哈希算法)
简 介:一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法,设计目标是为了解决因特网中的热点(Hot spot)问题,初衷和CARP十分类似。一致性哈希修正了CARP使用的简 单哈希算法带来的问题,使得分布式哈希(DHT)可以在P2P环境中真正得到应用。
一致性hash算法提出了在动态变化的Cache环境中,判定哈希算法好坏的四个定义:
1、平衡性(Balance):平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。很多哈希算法都能够满足这一条件。
2、单调性(Monotonicity):单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲加入到系统中。哈希的结果应能够保证原有已分配的内容可以被映射到原有的或者新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。
3、 分散性(Spread):在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不 同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为 它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也 就是尽量降低分散性。
4、负载(Load):负载问题实际上是从另一个角度看待分散性问题。既然不同的 终端可能将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同 的内容。与分散性一样,这种情况也是应当避免的,因此好的哈希算法应能够尽量降低缓冲的负荷。
在分布式集群中,对机器的添加删除,或者机器故障后自动脱离集群这些操作是分布式集群管理最基本的功能。如果采用常用的hash(object)%N算法,那么在有机器添加或者删除后,很多原有的数据就无法找到了,这样严重的违反了单调性原则。
七、Netty
贡献者:JBOSS
简介:Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
也就是说,Netty 是一个基于NIO的客户,服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。
“快 速”和“简单”并不意味着会让你的最终应用产生维护性或性能上的问题。Netty 是一个吸收了多种协议的实现经验,这些协议包括FTP,SMTP,HTTP,各种二进制,文本协议,并经过相当精心设计的项目,最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。
八、BloomFilter
简 介:Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员。如果检测结果为是,该元素不一定在集合中;但如果 检测结果为否,该元素一定不在集合中。因此Bloom filter具有100%的召回率。这样每个检测请求返回有“在集合内(可能错误)”和“不在集合内(绝对不在集合内)”两种情况,可见 Bloom filter 是牺牲了正确率和时间以节省空间。
Bloom filter 优点就是它的插入和查询时间都是常数,另外它查询元素却不保存元素本身,具有良好的安全性。

搜索引擎

一、Nutch
简介:Nutch 是一个开源Java 实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。包括全文搜索和Web爬虫。
尽管Web搜索是漫游Internet的基本要求, 但是现有web搜索引擎的数目却在下降. 并且这很有可能进一步演变成为一个公司垄断了几乎所有的web搜索为其谋取商业利益.这显然 不利于广大Internet用户.
Nutch为我们提供了这样一个不同的选择. 相对于那些商用的搜索引擎, Nutch作为开放源代码 搜索引擎将会更加透明, 从而更值得大家信赖. 现在所有主要的搜索引擎都采用私有的排序算法, 而不会解释为什么一个网页会排在一个特定的位置. 除此之外, 有的搜索引擎依照网站所付的 费用, 而不是根据它们本身的价值进行排序. 与它们不同, Nucth没有什么需要隐瞒, 也没有 动机去扭曲搜索的结果. Nutch将尽自己最大的努力为用户提供最好的搜索结果.
Nutch目前最新的版本为version v2.2.1。
二、Lucene
开发者:Doug Cutting(Hadoop之父,你懂的)
简 介:Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的 查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中 实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。
三、SolrCloud
简介:SolrCloud是Solr4.0版本以后基于Solr和Zookeeper的分布式搜索方案。SolrCloud是Solr的基于Zookeeper一种部署方式。Solr可以以多种方式部署,例如单机方式,多机Master-Slaver方式。
原理图:
SolrCloud有几个特色功能:
集中式的配置信息使用ZK进行集中配置。启动时可以指定把Solr的相关配置文件上传
Zookeeper, 多机器共用。这些ZK中的配置不会再拿到本地缓存,Solr直接读取ZK中的配置信息。配置文件的变动,所有机器都可以感知到。另外,Solr的一些任务 也是通过ZK作为媒介发布的。目的是为了容错。接收到任务,但在执行任务时崩溃的机器,在重启后,或者集群选出候选者时,可以再次执行这个未完成的任务。
自 动容错SolrCloud对索引分片,并对每个分片创建多个Replication。每个Replication都可以对外提供服务。一个 Replication挂掉不会影响索引服务。更强大的是,它还能自动的在其它机器上帮你把失败机器上的索引Replication重建并投入使用。
近实时搜索立即推送式的replication(也支持慢推送)。可以在秒内检索到新加入索引。
查询时自动负载均衡SolrCloud索引的多个Replication可以分布在多台机器上,均衡查询压力。如果查询压力大,可以通过扩展机器,增加Replication来减缓。
自动分发的索引和索引分片发送文档到任何节点,它都会转发到正确节点。
事务日志事务日志确保更新无丢失,即使文档没有索引到磁盘。
四、Solr
简介:Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果。
Solr是一个高性能,采用Java5开发,基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。
五、ElasticSearch
简 介:ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是第二最流行的企业搜索引擎。设计用于云计算 中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
六、Sphinx
简 介:Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得 应用程序更容易实现专业化的全文检索。Sphinx特别为一些脚本语言设计搜索API接口,如PHP,Python,Perl,Ruby等,同时为 MySQL也设计了一个存储引擎插件。
Sphinx单一索引最大可包含1亿条记录,在1千万条记录情况 下的查询速度为0.x秒(毫秒级)。Sphinx创建索引的速度为:创建100万条记录的索引只需 3~4分钟,创建1000万条记录的索引可以在50分钟内完成,而只包含最新10万条记录的增量索引,重建一次只需几十秒。
七、SenseiDB
贡献者:linkedin
简 介:SenseiDB是一个NoSQL数据库,它专注于高更新率以及复杂半结构化搜索查询。熟悉Lucene和Solor的用户会发现,SenseiDB 背后有许多似曾相识的概念。SenseiDB部署在多节点集群中,其中每个节点可以包括N块数据片。Apache Zookeeper用于管理节点,它能够保持现有配置,并可以将任意改动(如拓扑修改)传输到整个节点群中。SenseiDB集群还需要一种模式用于定义 将要使用的数据模型。
从SenseiDB集群中获取数据的唯一方法是通过Gateways(它 没有“INSERT”方法)。每个集群都连接到一个单一gateway。你需要了解很重要的一点是,由于SenseiDB本身没法处理原子性 (Atomicity)和隔离性(Isolation),因此只能通过外部在gateway层进行限制。另外,gateway必须确保数据流按照预期的方 式运作。内置的gateway有以下几种形式:
  • 来自文件
  • 来自JMS队列
  • 通过JDBC
  • 来自Apache Kafka

数据挖掘

一、Mahout
简介:Apache Mahout 是 Apache Software Foundation (ASF) 开发的一个全新的开源项目,其主要目标是创建一些可伸缩的机器学习算法,供开发人员在 Apache 在许可下免费使用。该项目已经发展到了它的最二个年头,目前只有一个公共发行版。Mahout 包含许多实现,包括集群、分类、CP 和进化程序。此外,通过使用 Apache Hadoop 库,Mahout 可以有效地扩展到云中。
虽然在开源领域中相对较为年轻,但 Mahout 已经提供了大量功能,特别是在集群和 CF 方面。Mahout 的主要特性包括:
  • Taste CF。Taste 是 Sean Owen 在 SourceForge 上发起的一个针对 CF 的开源项目,并在 2008 年被赠予 Mahout。
  • 一些支持 Map-Reduce 的集群实现包括 k-Means、模糊 k-Means、Canopy、Dirichlet 和 Mean-Shift。
  • Distributed Naive Bayes 和 Complementary Naive Bayes 分类实现。
  • 针对进化编程的分布式适用性功能。
  • Matrix 和矢量库。
  • 上述算法的示例。

Iaas

IaaS(Infrastructure as a Service),即基础设施即服务。
一、OpenStack
简介:OpenStack是一个由NASA(美国国家航空航天局)和Rackspace合作研发并发起的,以Apache许可证授权的自由软件和开放源代码项目。
OpenStack 是一个开源的云计算管理平台项目,由几个主要的组件组合起来完成具体工作。OpenStack支持几乎所有类型的云环境,项目目标是提供实施简单、可大规 模扩展、丰富、标准统一的云计算管理平台。OpenStack通过各种互补的服务提供了基础设施即服务(IaaS)的解决方案,每个服务提供API以进行 集成。
6个核心项目:Nova(计算,Compute),Swift(对象存 储,Object),Glance(镜像,Image),Keystone(身份,Identity),Horizon(自助门 户,Dashboard),Quantum & Melange(网络&地址管理),另外还有若干社区项目,如Rackspace(负载均衡)、Rackspace(关系型数据库)。
相关阅读:
二、Docker
贡献者:dotCloud
简介:Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架或包括系统。
三、Kubernetes
贡献者:Google
简介:Kubernetes是Google开源的容器集群管理系统。它构建Ddocker技术之上,为容器化的应用提供资源调度、部署运行、服务发现、扩容缩容等整一套功能,本质上可看作是基于容器技术的mini-PaaS平台。
Kubernetes从另一个角度对资源进行抽象,它让开发人员和管理人员共同着眼于服务的行为和性能的提升,而不是仅仅关注对单一的组件或者是基础资源。
那 么Kubernetes集群到底提供了哪些单一容器所没有功能?它主要关注的是对服务级别的控制而并非仅仅是对容器级别的控制,Kubernetes提供 了一种“机智”的管理方式,它将服务看成一个整体。在Kubernete的解决方案中,一个服务甚至可以自我扩展,自我诊断,并且容易升级。例如,在 Google中,我们使用机器学习技术来保证每个运行的服务的当前状态都是最高效的。
四、Imctfy
贡献者:Google
简介:Google开源了自己所用Linux容器系统的开源版本lmctfy,读音为lem-kut-fee。包括一个C++库(使用了C++11,文档可以参考头文件)和命令行界面。目前的版本是0.1,只提供了CPU与内存隔离。项目还在密集开发中。
mctfy本身是针对某些特定使用场景设计和实现的,目前拥有一台机器上所有容器时运行情况最好,不推荐与LXC和其他容器系统一起使用(虽然也可行)。已在Ubuntu 12.04+和Ubuntu 3.3与3.8内核上测试。

监控管理

一、Dapper
贡献者:Google
简 介:Dapper是一个轻量的ORM(对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping)。并不单纯的是一个DBHelper.因为在Dapper中数据其实就是一个对象。Dapper扩展与IDbConnection上,所 以事实上它的倾入性很低。我用了StructureMap。如果不喜欢可以自己更换,或者自己实现下。
代码就一个SqlMapper.cs文件,主要是IDbConnection的扩展方法,编译后就40K的一个很小的dll。
特性:
  • Dapper很快。Dapper的速度接近与IDataReader。
  • Dapper支持主流数据库 Mysql,SqlLite,Mssql2000,Mssql2005,Oracle等一系列的数据库
  • 支持多表并联的对象。支持一对多 多对多的关系,并且没侵入性。
  • 原理通过Emit反射IDataReader的序列队列,来快速的得到和产生对象
  • Dapper语法十分简单。并且无须迁就数据库的设计
二、Zipkin
贡献者:Twitter
简 介:Zipkin (分布式跟踪系统)是 Twitter 的一个开源项目,允许开发者收集 Twitter 各个服务上的监控数据,并提供查询接口。该系统让开发者可通过一个 Web 前端轻松的收集和分析数据,例如用户每次请求服务的处理时间等,可方便的监测系统中存在的瓶颈。

阿里巴巴为什么要选择星际争霸作为AI算法研究环境?

 

《星际争霸》一直是游戏玩家心目中即时战略类的经典之作,历时十多年而不衰。而如今它更成为深度强化学习、人工智能算法研究的一个主要平台和工具。因为其蕴含了多智能体协作、多任务学习、宏观策略规划等复杂问题,一旦取得部分突破和进展,对商业和社会发展都会带来极大影响。如国外的 DeepMind、Facebook 等公司相继投入大量人力基于它进行通用人工智能的研究。在本次演讲中,我们将介绍阿里巴巴如何在《星际争霸》游戏环境中研究人工智能算法,并重点阐述多智能体协作在微观战斗场景中的应用。

演示视频

大家下午好!我是来自阿里巴巴认知计算实验室的龙海涛,今天主要跟大家聊一下“《星际争霸》与人工智能”的话题。首先我会介绍一下为什么我们会选择《星际争霸》这个游戏来做人工智能前沿性的研究,然后是我们在这方面初步的尝试和成果,最后我会跟大家探讨一下,未来我们在《星际争霸》这个游戏里面还可以继续去研究的一些课题。

为什么选择《星际争霸》作为人工智能算法研究的环境

首先可能大家有疑问,为什么选择《星际争霸》这个游戏来做我们AI研究的一个平台。我们这个认知计算实验室目前是挂靠在搜索事业部下面,我们团队的成员基本都是做搜索、广告、推荐、算法这样的背景,之前我们主要做的是CTR预估的优化,还有CVR转化率的一些优化,从去年“双11”之后,我们想在认知智能方面做一些前沿性的探索,我们一致认为游戏是一个研究AI算法的绝佳平台,首先它是非常干净的平台,可以源源不断的去产生数据,而且迭代非常快,就是说它的智能是可以观测到的。另外,它离真实的场景和应用是比较近的,并且《星际争霸》十多年来就是一个非常好的受大家欢迎的游戏,积累了非常非常多的数据,这样我们可以从之前的经验去学习,这也是我们考虑的一个方面。最重要的,它对AI来讲存在着非常大的挑战,非常复杂,主要有以下六点:

第一点,它是一个不完全信息下的环境

比起像围棋或者象棋这种大家都可能看得见的、完全信息下的博弈,《星际争霸》是有战争迷雾的,所以必须去探路、侦查、了解对手的信息,从而在不确定的情况下去做智能的决策,这个是相对其他游戏来讲非常不同或者挑战更大的一个方面。

第二点,它有非常巨大的搜索空间

围棋的搜索空间大概在10^170,《星际争霸》在128×128的地图上并且人口上限是400个unit的情况下,它的搜索空间大概在10^1685,比围棋高10个数量级,这还是在没有算上其他状态(比如说血量等等)的情况下。所以现有的任意一个单一的算法是根本不可能解决《星际争霸》里面所有的问题的。

第三点,它是一个即时对抗类的游戏

下围棋可以有一分钟或者两分钟的思考时间,但是在《星际争霸》里,如果说正常游戏大概是1秒钟24帧,那么你必须在42毫秒之内做出迅速的反应,而且这个反应不是一个action,而是一系列的action,每个unit都会采取行动,这对我们算法的性能、效率、工程上的考虑都是非常大的挑战。

第四点,它需要智能体有一个长期的规划

不是一个下意识的动作,是需要有记忆,需要考虑这场战争应该采取什么样的策略,中盘应该怎么考虑,发展到后期又应该采取什么样的策略,而且这个策略的计划是根据侦查到的所有的信息动态去调整,这对人工智能的挑战是非常非常大的。

第五点,时间、空间上的推理

在《星际争霸》里面要玩好的话,必须基于时序上、空间上去做推理,比如说地理位置的优势,坦克如果架在哪里可能会比较好,如果开分机在哪个位置去开会比较有利,甚至于军营造在什么地方,这些对于AI来说都需要进行一个空间上的推理。

第六点,多个智能体协作

《星际争霸》最高有400个unit,所以其实是需要多个智能体协作的,需要多个兵种去配合,这也是对AI来讲一个很大的挑战。

《星际争霸》里面AI的研究或者竞赛不是最近才出现的,其实在2010年的时候已经有大量的研究人员在研究《星际争霸》里面的AI,主要是以ALBERTA大学为主的研究力量,包括一些老师和学生,而且有三个固定的竞赛和一些循环赛,大家在上面PK。这一类AI的话是Classic AI,也就是没有学习能力、没有模型、也不需要训练,而是基于预编程的规则,所以不是非常灵活,这种算法下的AI其实离真正超过人类或者打败人类目标还是非常非常远的,它们可以打败内置的AI,但是还远远比不上人类的专业选手,甚至连普通选手基本上也打不过。

另外一类是Modern AI,也就是以智能体自主学习为主的算法,从去年开始这个领域火起来了,一方面就是,阿里巴巴还有伦敦大学学院,最近我们在合作的基于《星际争霸1》里面做一些新的AI的尝试。

另外就是Google Deep Mind,去年11月份他们和暴雪合作,会基于《星际争霸2》去开放一个API,让大家基于《星际争霸2》上开发自己的AI算法,另外像Facebook他们也有一些团队做这方面的研究。

深度强化学习

强化学习是非常接近人类学习的一个学习机制,通过这个Agent跟环境的交互,在交互当中学习。Agent会观察周围的环境,然后环境会给它一些反馈,Agent根据状态和反馈会做出一些动作,这些动作会或多或少的影响这个环境,环境会根据这个动作反馈一些Reward,Reward可能是奖励的也可能是惩罚的,Agent根据这样的试错,不断的去调整。Agent背后有两个概念非常重要,一个是不停的优化策略,什么样的状况下采用什么样的Action是合理的,另外一个是用价值函数评估当前的状态它的价值是怎么样的。

强化学习跟深度学习结合,就叫深度强化学习。因为深度学习或者神经网络是非常适合去做这种表示学习的,可以表示成一个复杂的函数。policy或者value用神经网络去逼近的话,在工程上或者效率上是非常好的提升。以AlphaGo的例子来讲,在训练的时候分成三个阶段,第一个阶段,从人类的棋谱里面学习人类的先验的知识,通过监督学习学习一个还好的、胜率比较高的policy network,第二个阶段,基于监督学习学习出来的policy network,然后自我对弈,通过policy gradient再去优化policy network,这就比之前学出来的policy network要更好。第三阶段,再用学出来的强化学习版的policy network自我对弈,得到一个最佳的。

多智能体协作

其实目前为止所有的AI的智能体比较成功的一些应用基本都是这种单个的Agent,其实对于人类来讲,协作智能是智能体的一个非常大的方面,我们的祖先智人为什么可以统治地球,其中一个很大的原因就是,他们学会了大规模的协作,而且是非常灵活的协作。可以想象一下,未来全部都是这种AI的智能体,它们能不能自我学习到人类水平协作的一个智能呢?

我们用了一个词Artificial Collective Intelligence,这对现实和未来都有非常大的意义。比如手机淘宝,现在绝大部分流量背后都是一个算法推荐出来的,不管广告还是搜索其背后都是AI的智能体在做,目前这些智能体都是各出各的优化,或者推出自己的商品。

其实我们在考虑的是,比如手机淘宝首页里边有爱逛街、猜你喜欢这种位置,那么他们能不能够协同地去推出一些这样的商品,从而可以让用户的体验最好,让平台的价值最大化。其实以后可能都是算法经济、AI经济,都是这种AI的Agent,比如满大街可能都是自动驾驶的无人车,他们之间是不是也需要一些协作,让交通出行效率能够达到最大化。

最近我们在《星际争霸》里的微观战斗场景下,提出来一个多智能体双向协作网络,关于这个网络的详细内容大家感兴趣可以下载我们的paper看一下,这个工作是我们跟UCL一起合作完成的,用来探索或者解决多智能体协作的问题。

这是我们提出来的BiCNet(Multiagent Bidirectionally-Coordinated Net)的网络结构,它其实也是比较经典的结构,分成两部分,左边这部分是一个policy的网络,就是说从下往上会把《星际争霸》的环境进行一些抽象,包括地图的信息、敌方单位的血量、攻击力,还有我方unit的信息,抽象出来形成一个共享的State,经过一个双向的RNN这样的网络,进行充分的双向的沟通,再往上每个Agent去得出自己的Action,比如我到某一个地方去攻击谁。左边这个policy network就是对于当前的状态应该采取什么行动,右边就是一个value的network,根据前面policy得出来的Action,还有抽象出来的State进行评估,Q值大概是多少,做出一个预判。当采取这些行动以后,这个环境就会给出相应的反馈,一些Reward来说明这步打的好还是不好,然后会通过一个Reword从右边这个网络下来,去反向传播更新里面的参数。

这个网络有几点比较好的设计:

第一,它的scalability比较好,《星际争霸》里面打仗的时候随时可能会有伤亡,这个Agent死掉以后这个网络不是还可以正常的工作,包括源源不断涌现的新的Agent进来,是不是也是可以工作。我们看到双向网络参数是共享的,所以是不会有影响的。

二,我们在中间用了这样一个双向网络以后,其实是在一个效率和性能之间做了比较好的平衡,如果用全连接网络的话,计算量会过大。但是我们用一个双向网络,前面告诉你大概要做什么样的Action,回来再告诉前面的人他们采取了什么样的Action,一结合,最后算出来应该追加的策略是什么样子,从实际来看效果也是非常好的。

其实我们认知计算实验室在设计一些算法或者模型的时候会参考神经科学里边目前的一些研究成果,我们认为研究认知心理学、大脑、类脑的研究或者神经科学,对于做人工智能应该有两个好处。

第一个好处就是,神经科学具有启发性,就是当你在一些具体的问题或者场景里面去思考的时候,会遇到一些问题,这些问题可能是从来没有人解过的,如果神经科学、交叉科学里有类似的这种结构或者算法,这些可能会很好的解决你的问题,带来算法上的一些启发。

反过来另外一点,神经科学也可以帮你做验证,你设计一个算法以后,如果神经科学里面有类似的结构,那么很大概率这个算法是可以工作的。

其实我们的Actor-Critic网络在人脑里面也是有相应的对应,左边就是Actor-Critic这个网络,右边是我们的大脑,大脑里边纹状体就是负责Actor、Critic两部分,这个纹状体腹部是负责Critic这部分,背部是负责Actor这部分,Reward下来以后我们大脑会计算,这与预期的Reward有什么差距,这个差距就会以多巴胺的形式影响到Actor,下一次你就要按照这个去调节,让下一次Action做的更好一点。

其实多巴胺体现在我们的算法里面就是TD error,也就是我们算的Reward的误差,这其实是一个很好的对应。

实验平台和实际效果

前面是网络架构的设计,为了实现这样一个算法模型,我们搭了一个实验平台,这个实验平台就是基于Facebook的TorchCraft,它是把《星际争霸1》和Torch封装在一起,但是我们比较习惯于TensorFlow和Python,所以在上面做了一个封装,再把这套架构放在这个OpenAI标准接口里边,大家有兴趣可以试一下。

这个架构主要分成两部分,对应刚才说的强化学习:

左边是Environment,其实就是《星际争霸》这个游戏,包括引擎,还有里面的DLL,DLL基于BWEnv,这是一个官方认可的DLL。基于这个BWEnv DLL把内部的状态、指令封装起来,其实这就是一个Server;

右边就是Agent,是一个Client,这样你可以连上很多的Agent玩这个游戏。中间是传递的信息,Environment会把它每一帧的数据吐给Agent,Agent会把每一帧的数据抽象成状态,然后再把这个State送到model里面去学习或者做预测,反过来会预测出来一些Action,这些Action会封装成指令,再发回给《星际争霸》的Environment,比如说开枪或者逃跑,这个是我们搭的这样一个《星际争霸》的实验平台。

下面是我们这个实验平台做到的一些效果,总结起来有五种可观测的智能。

第一种,可以配合走位。

这个例子就是三个枪兵打一个Super的小狗,这个小狗是我们编辑过的,血量非常大,一下子打不死。三个枪兵打一个小狗,a/b这两个图,在训练的早期其实是没有学会太多的配合意识,所以他们走位的时候经常会发生碰撞,经过可能几万轮的训练以后,他们慢慢学会了配合队友的走位,这样大家撞不到一起。

第二个场景,边打边撤

这个配合就是边打边撤,Hit and Run这样的技能,这个例子就是三个枪兵打一个狂徒,利用远程攻击的优势来消灭敌人。

第三种,掩护攻击

刚才三个枪兵打一个狂徒的时候是同时撤退,但是在这个场景下有些枪兵可能会去吸引这个小狗或者去阻挡一下,让另外两个枪兵抓住这个时间空隙来消灭这个小狗。非常有意思的一点就是,这种协作不是在任何情况下都会出现的,如果你的环境不是那么的有挑战性,可能它就是简单的Hit and Run就足够了,如果我们的环境更严苛一点,比如这个小狗血量调高,攻击力从3调到4,或者血量从210调到270,发现它又学会了另一种更高级的掩护攻击的协作,这就非常有意思了。

第四种,分组的集火攻击

这个例子是15个枪兵打16个枪兵,大家想想应该怎么取胜?策略可能3个枪兵或者4个枪兵自动组成一组,这3个枪兵先干掉一个、再干掉一个,就是把火力集中,但又不是15个枪兵打1个,而把火力分散一点,最后可能我们这方还剩6个枪兵,对方可能全部消灭掉了,这个都是通过很多轮次的学习之后他们自动去学到的这样一个配合。

第五种,不光是枪兵之间学会配合,还可以多兵种配合,异构的Agent的配合。

这个例子就是,两个运输机,每个运输机带一个坦克去打一头大象,正常来讲,两个坦克打一个大象肯定是打不过的,加上运输机的配合以后,大象攻击某一个坦克的时候,运输机会及时的把这个坦克收起来,让大象扑空,同时另外一个运输机赶紧把它的坦克放下去,去攻击大象,这样一来一回可能大象一点便宜占不到就被消灭了,这个是基于我们之前的做出BiCNet一个协作的展现。

关于未来的一些思考

但是《星际争霸》里其实不光是微观战斗,其实更难的是宏观的策略方面,怎么样“宏观+微观”打一整个游戏,这样其实我们也有一些思考,可能不是特别成熟,但是我们可以一起探讨一下。

每一个层级设定一个Goal

要玩一个full-game,如果是简单的单层次的强化学习,可能解决不了问题,因为action space实在太大了,一个比较自然的做法就是做层级式的方式,可能上层是策略规划,下面一层就是它的战斗、经济发展、探路、地图的分析等等,这样的话一层一层的,就是高层给下层设置一个goal,下层再给下面一层设计一个goal,其实这跟人的问题分解是比较类似的。

模仿学习(Imitation Learning)

我们觉得值得去研究和探讨的是模仿学习,Imitation Learning,刚刚讲的AlphaGo的例子也是Imitation Learning,第一步通过监督学习学习比较好的策略,再把监督学习学好的策略通过自我的对弈去提升,在《星际争霸》里面更需要这种模仿学习,比如说我们两个枪兵打一个小狗的时候,我们认为一个好的策略是一个枪兵吸引小狗在那儿绕圈,然后另外一个枪兵就站在中心附近开枪,把这个小狗消灭,两个枪兵一滴血可以不死。但是这种策略是比较难学习的,所以我们先给它人为的让这个枪兵在里面画圈,画上几步之后枪兵自己学会画圈了,带着小狗,然后另外一个枪兵在后面追着屁股打,这种探索就非常的有效。

持续学习(Continual Learning)

Continual Learning,如果要迈向通用智能,这是绕不过去的课题。

Continual Learning像人一样,我们学会了走路,下一次我们学会了说话,我们在学说话的时候可能就不会把走路这件事情这个本领忘掉,但是在《星际争霸》一些场景的时候,神经网络学到A的时候再去学B,这个时候可能会把A的事情忘掉。

举个例子,一开始我们训练一个枪兵打一个小狗,这个小狗是电脑里边自带的AI,比较弱,这个枪兵学会了边打边撤,肯定能把小狗打死。我们再反过来训练一个小狗,这个小狗去打电脑枪兵,这个小狗学会最佳策略就是说一直追着咬,永远不要犹豫,犹豫就会被消灭掉,所以它是一条恶狗,一直追着枪兵咬。然后我们把这枪兵和小狗同时训练,让他们同时对弈,这样发现一个平衡态,就是枪兵一直逃,狗一直追,《星际争霸》设计比较好的就是非常平衡。然后这个枪兵就学会了一直跑,我们再把这个枪兵放回到原来的环境,就是再打一个电脑带的小狗,发现它也会一直跑,它不会边打边撤。

你发现它学习的时候,学会了A再学会B,A忘了,这个其实是对通用人工智能是非常大的挑战,最近DeepMind也发了一个相关工作的paper,这也是一个promising的方向,大家有兴趣可以去看一下,他们的算法叫EWC。

引入Memory机制

最后一点,前面有说到几大挑战,其中有一大挑战就是长期的规划,长期规划里边我们认为一个比较好的做法就是,给这种强化学习里面去引入Memory的机制,这也是目前的一个比较火的方向,像Memory Networks、DNC,要解决的问题就是,我们在学习的过程当中应该记住什么东西,从而使得我们可以达到一个很好的最大的Reward。

所以今天跟大家交流的主要就是说,其实在《星际争霸》里面是蕴含了非常非常丰富的研究通用人工智能或者研究认知智能的场景,这个里面可以有很多非常有意思的课题。我只是列举了四个方向,其实还有很多很多方向可以去研究。

欢迎有兴趣的同学跟我们一起来认真的玩游戏。谢谢大家!

讲师介绍

龙海涛(花名德衡),2013 年加入阿里巴巴,现任认知计算实验室技术专家,目前主要关注深度学习、强化学习、神经科学等方面的科学和技术创新。在阿里巴巴任职期间,还负责过搜索直通车业务的架构设计,包括新一代的离线系统、在线引擎和索引内核。

文章转自搜狐网,原文地址:http://www.sohu.com/a/141708962_470008

2017,最受欢迎的 15 大 Python 库有哪些?

近年来,Python 在数据科学行业扮演着越来越重要的角色。因此,我根据近来的使用体验,在本文中列出了对数据科学家、工程师们最有用的那些库。

由于这些库都开源了,我们从Github上引入了提交数,贡献者数和其他指标,这可以作为库流行程度的参考指标。

核心库

1. NumPy (提交数: 15980, 贡献者数: 522)

当开始处理Python中的科学任务,Python的SciPy Stack肯定可以提供帮助,它是专门为Python中科学计算而设计的软件集合(不要混淆SciPy库,它是SciPy Stack的一部分,和SciPy Stack的社区)这样我们开始来看一下吧。然而,SciPy Stack相当庞大,其中有十几个库,我们把焦点放在核心包上(特别是最重要的)。

关于建立科学计算栈,最基本的包是Numpy(全称为Numerical Python)。它为Python中的n维数组和矩阵的操作提供了大量有用的功能。该库提供了NumPy数组类型的数学运算向量化,可以改善性能,从而加快执行速度。

2. SciPy (提交数: 17213, 贡献者数: 489)

SciPy是一个工程和科学软件库。雷锋网(公众号:雷锋网)再次提醒,你需要理解SciPy Stack和SciPy库之间的区别。

SciPy包含线性代数,优化,集成和统计的模块。SciPy库的主要功能是建立在NumPy上,从而它的数组大量的使用了NumPy的。它通过其特定子模块提供有效的数值例程,并作为数字积分、优化和其他例程。SciPy的所有子模块中的功能都有详细的说明 ——又是一个SciPy非常有帮助的点。

3. Pandas (提交数: 15089, 贡献者数:762)

Pandas是一个Python包,旨在通过“标记”和“关系”数据进行工作,简单直观。Pandas是数据整理的完美工具。它设计用于快速简单的数据操作,聚合和可视化。

库中有两个主要的数据结构:

  • “系列”(Series),一维

     2017,最受欢迎的 15 大 Python 库有哪些?

  • “数据帧”(Data Frames),二维

     2017,最受欢迎的 15 大 Python 库有哪些?

例如,当您要从这两种类型的结构中接收到一个新的Dataframe时,通过传递一个Series,您将收到一个单独的行到DataFrame的DF:

 2017,最受欢迎的 15 大 Python 库有哪些?

 这里稍微列出了你可以用Pandas做的事情:

  • 轻松删除并添加数据帧(DataFrame)中的列
  • 将数据结构转换为数据帧(DataFrame)对象
  • 处理丢失的数据,表示为NaN
  • 功能强大的分组

Google趋势记录

 2017,最受欢迎的 15 大 Python 库有哪些?

trends.google.com

GitHub请求历史记录

 2017,最受欢迎的 15 大 Python 库有哪些?

datascience.com/trends

可视化

4.Matplotlib (提交数: 21754, 贡献者数: 588)

又一个SciPy Stack核心软件包以及 Python库,Matplotlib为轻松生成简单而强大的可视化而量身定制。它是一个顶尖的软件(在NumPy,SciPy和Pandas的帮助下),它使Python成为像MatLab或Mathematica这样的科学工具的竞争对手。

然而,这个库是低层级的,这意味着你需要编写更多的代码才能达到高级的可视化效果,而且通常会比使用更多的高级工具付出更多的努力,但总体上这些努力是值得的。

只要付出一点你就可以做任何可视化:

  • 线图
  • 散点图
  • 条形图和直方图
  • 饼状图;
  • 茎图
  • 轮廓图
  • 场图
  • 频谱图

还有使用Matplotlib创建标签,网格,图例和许多其他格式化实体的功能。基本上,一切都是可定制的。

该库由不同的平台支持,并使用不同的GUI套件来描述所得到的可视化。不同的IDE(如IPython)都支持Matplotlib的功能。

还有一些额外的库可以使可视化变得更加容易。

 2017,最受欢迎的 15 大 Python 库有哪些?

5. Seaborn (提交数: 1699, 贡献者数: 71)

Seaborn主要关注统计模型的可视化;这种可视化包括热图,这些热图(heat map)总结数据但仍描绘整体分布。Seaborn基于Matplotlib,并高度依赖于此。

  2017,最受欢迎的 15 大 Python 库有哪些?

 6. Bokeh (提交数: 15724, 贡献者数: 223)

另一个很不错的可视化库是Bokeh,它针对交互式可视化。与以前的库相比,它独立于Matplotlib。正如我们提到的,Bokeh的主要焦点是交互性,它通过现代浏览器以数据驱动文档(d3.js)的风格呈现。

 2017,最受欢迎的 15 大 Python 库有哪些?

7. Plotly (提交数: 2486, 贡献者数: 33)

最后,关于Plotly的话。它是一个基于Web用于构建可视化的工具箱,提供API给一些编程语言(Python在内)。在plot.ly网站上有一些强大的、上手即用的图形。为了使用Plotly,你将需要设置API密钥。图形将在服务器端处理,并发布到互联网,但有一种方法可以避免。

 2017,最受欢迎的 15 大 Python 库有哪些?

Google趋势记录

 2017,最受欢迎的 15 大 Python 库有哪些?

trends.google.com

GitHub请求历史记录

 2017,最受欢迎的 15 大 Python 库有哪些?

datascience.com/trends

机器学习

8. SciKit-Learn (提交数:21793, 贡献者数:842)

Scikits是Scikits Stack额外的软件包,专为像图像处理和机器学习辅助等特定功能而设计。对于机器学习辅助,scikit-learn是所有软件包里最突出的一个。它建立在SciPy之上,并大量利用它的数学运算。

scikit-learn给常见的机器学习算法公开了一个简洁、一致的接口,可简单地将机器学习带入生产系统中。该库中集成了有质量的代码和良好的文档、简单易用并且十分高效,是使用Python进行机器学习的实际行业标准。

深度学习—— Keras / TensorFlow / Theano

在深度学习方面,Python中最着名和最便的库之一是Keras,它可以在TensorFlow或Theano框架上运行。让我们来看一下它们的一些细节。

9.Theano. (提交数:25870, 贡献者数:300)

首先让我们谈谈Theano。

Theano是一个Python软件包,它定义了与NumPy类似的多维数组,以及数学运算和表达式。此库是被编译的,可实现在所有架构上的高效运行。最初由蒙特利尔大学机器学习组开发,它主要用于满足机器学习的需求。

值得注意的是,Theano紧密结合了NumPy在低层次上的运算 。另外,该库还优化了GPU和CPU的使用,使数据密集型的计算平台性能更佳。

效率和稳定性微调保证了即使在数值很小的情况下,仍有更精确的结果,例如,即使只给出x的最小值,log(1 + x)仍能计算出合理的结果。

10. TensorFlow. (提交数: 16785,贡献者数: 795)

TensorFlow来自Google的开发人员,它是数据流图计算的开源库,为机器学习不断打磨。它旨在满足谷歌对训练神经网络的高需求,并且是基于神经网络的机器学习系统DistBelief的继任者。然而,TensorFlow并不限制于谷歌的科学应用范围 – 它可以通用于多种多样的现实应用中。

TensorFlow的关键特征是它的多层节点系统,可以在大型数据集上快速训练神经网络。这为谷歌的语音识别和图像对象识别提供了支持。

11. Keras. (提交数: 3519,贡献者数: 428)

最后我们来看看Keras。它是一个用Python编写的开源的库,用于在高层的接口上构建神经网络。它简单易懂,具有高级可扩展性。Keras使用Theano或TensorFlow作为后端,但微软现在正努力整合CNTK(微软的认知工具包)作为新的后端。

设计中的简约方法旨在通过建立紧凑型系统进行快速、简便的实验。

Keras真的容易上手,并在持续完善它的快速原型能力。它完全用Python编写,可被高度模块化和扩展。尽管它以易上手、简单和以高层次为导向,但是Keras足够有深度并且足够强大,去支持复杂的模型。

谷歌发展趋势历史

 2017,最受欢迎的 15 大 Python 库有哪些?

trends.google.com

GitHub请求历史记录

 2017,最受欢迎的 15 大 Python 库有哪些?

datascience.com/trends

自然语言处理

12. NLTK (提交数: 12449,贡献者数: 196)

这个库的名称“Natural Language Toolkit”,代表自然语言工具包,顾名思义,它用于符号学和统计学自然语言处理(NLP) 的常见任务。 NLTK旨在促进NLP及相关领域(语言学,认知科学人工智能等)的教学和研究,目前受到重点关注。

NLTK的功能允许很多操作,例如文本标记,分类和标记,实体名称识别,建立语料库,可以显示语言内部和各句子间的依赖性、词根、语义推理等。所有的构建模块都可以为不同的任务构建复杂的研究系统,例如情绪分析,自动总结。

13. Gensim (提交数: 2878,贡献者数: 179)

它是一个用于Python的开源库,为有向量空间模型和主题模型的工作提供了使用工具。这个库是为了高效处理大量文本而设计的,所以不仅可以进行内存处理,还可以通过广泛使用NumPy数据结构和SciPy操作来获得更高的效率。Gensim高效也易于使用。

Gensim旨在与原始和非结构化的数字文本一起使用。 它实现了诸如hierarchical Dirichlet processes(HDP),潜在语义分析(LSA)和潜在Dirichlet分配(LDA)之类的算法,以及tf-idf,随机预测,word2vec和document2vec,便于检查一组文档中有重复模式的文本 (通常称为语料库)。所有的算法均是无监督的,意味着不需要任何参数,唯一的输入只有语料库。

谷歌发展趋势历史

 2017,最受欢迎的 15 大 Python 库有哪些?

trends.google.com

GitHub请求历史记录

 2017,最受欢迎的 15 大 Python 库有哪些?

datascience.com/trends

数据挖掘,统计学

14. Scrapy (提交数: 6325,贡献者数: 243)

Scrapy库是用于从网络结构化检索数据(如联系人信息或URL),可以用来设计crawling程序(也称为蜘蛛bots)。

它是开源的,使用用Python编写的。最开始只是如它的名字暗示的一样,只用来做scraping,但是它现在已经在完整的框架中发展,能够从API采集数据并作为通用的crawlers了。

该库在界面设计中标榜着“不要重复自己”  它推荐用户们编写泛化得到、可被重复使用的通用代码,从而构建和扩展大型的crawlers。

Scrapy的架构围绕着Spider class构建,这其中包含了crawler追从的一套指令。

 15. Statsmodels (提交数: 8960,贡献者数: 119)

你可能从名字就猜出大概了,statsmodels使用户能够通过使用各种统计模型的估算方法进行数据挖掘,并执行统计判断和分析。

 许多有用的特征是可被描述的,并通过使用线性回归模型,广义线性模型,离散选择模型,鲁棒线性模型,时间序列分析模型,各种估计方法得出统计结果。

这个库还提供了广泛的标定功能,专门用于大数据统计中的性能优化工作。

总结

许多数据科学家和工程师认为这些库是顶级的,并值得关注,或者需要或多或少了解它们。 以下是每个库在Github上的详细统计资料:

当然,这不是完全详尽的列表,还有许多其他的库和框架也是值得关注。一个很好的例子是SciKit的不同软件包各自专注一个特定的领域,如SciKit-Image是用于处理图像的。

文章转自雷锋网,原文地址:https://www.leiphone.com/news/201706/SP8YmNMNi2kSbUcE.html

谷歌机器学习白皮书全解析 43条黄金法则

2017-01-26 09:09:01 来源: 雷锋网(深圳)

英文版:http://martin.zinkevich.org/rules_of_ml/rules_of_ml.pdf

编者按:此白皮书为谷歌总结的机器学习(ML)最优实践方法,浓缩了其多年技术积累与经验,尤其是YouTube、Google Play和Google+ 等平台背后的ML算法开发、维护经历。谷歌于白皮书中总结了四十三条ML黄金法则,旨在帮助已经掌握了基础知识的开发者少走弯路。鉴于其珍贵程度与技术性,雷锋网逐条做了严格尊重原文的翻译。若你已学习过机器学习课程,抑或有开发ML模型的经验,那么应当具备足够的背景知识理解这篇文章。

术语

以下是对文中反复出现的术语的解释。

实例( Instance):做预测的对象。比如说,实例可以是一个网页,你想要把它分类为“关于猫”或者“与猫不相关”。

标记(Label):预测任务的答案。它既可以是机器学习系统生成的答案,也可以是训练数据中提供的正确答案(雷锋网(公众号:雷锋网)注:比如监督学习中的人工标记)。举例来说,一个网页的标记可以是“关于猫”。

特征(Feature):预测任务中实例的属性。比如说,某网页可能有“包含关键词‘猫’”的特征

特征栏 (Feature Column):这是谷歌自创的术语,意为关联特征的集合。比如说,用户的所有可能居住国家的集合。一个样例的特征栏可以有一个或多个特征。特征栏可被看作是VW系统(微软、雅虎所用)中的命名空间,或者场( field)。

样例(Example):有标记的实例(具备特征)。

模型(Model):对预测任务的统计表达。你用样例训练模型,然后用模型做预测。

指标(Metric):你在意的数字。可被直接优化过,也可没有。

目标(Objective):你的算法试图优化的指标。

流水线(Pipeline):机器学习算法的基础设施;包括从前端收集数据,把它放入训练数据文档,训练一个或多个模型,以及把模型输出、产品化。

概览:

为了开发出好产品:

做机器学习这一行首先要摆正心态,你是一名(优秀的)工程师,不要拿专家的标准来要求自己。

事实上,你将要面对的大多数难题是工程问题(engineering problems)。即便是一个杰出的ML专家,坐拥该级别才有的资源,其大多数收获也来自于特征而不是 ML 算法。所以,ML 开发的基本路线是:

保证可靠的端到端流水线

从制定合理的目标着手

用简单的方式,加入符合常识的特征

确保流水线始终可靠

该方法能帮你赚钱养家,并且让很多人满意。只有当无路可走、简单的技巧无法再起作用时,你才需要偏离该路线。但注意,提高复杂度会拖慢将来的产品发布。另外,当你穷尽了简单技巧,或许就到了登堂入室、探索 ML 最前沿技术的时候了。具体请看本文机器学习第三阶。

本文分为四个部分:

第一部分“1.0做机器学习之前”,会帮你搞清楚,你创建机器学习系统的时机是否已经成熟。

第二部分“2.0机器学习第一阶”是关于设置你的第一个流水线。

第三部分“3.0机器学习第二阶”,关乎启动和重复,同时向流水线加入新特征。

最后一部分“4.0机器学习第三阶”是关于达到瓶颈后怎么办。

43条黄金法则列表:

对发布一个不含 ML 技术的产品,不要有顾虑

首先要设计和贯彻指标

在机器学习和复杂启发算法之间,选择前者

第一个模型要简单,把基础设施弄好

测试基础设施要与 ML 测试分开

复制流水线时当心数据遗落

把启发式(heuristics)变为特征,不然就对它们做外部处理

了解系统的时效性

在输出模型之前发现问题

于无声处听惊雷:注意没表现出来的故障

注意特征栏的维护者和文件

选择直接优化哪个目标时,不需要想太多

选择一个简单、可观察并且可归属(attributable)的指标来作为第一个目标

用可解释的模型开头,修补漏洞会更简单

用 policy layer(规则层)把垃圾信息过滤和质量排序分来

做好模型被推倒和重建的准备

直接以观察到的或报告的特征开始训练,而不是经过学习的特征

从不同的上下文环境中提取特征

尽量选择更具体的特征

以合理的方式组合、修改现有特征

通过线性模型学到的特征权重的数目,大致与数据量成正比

清理不需要的特征

你并不是一个典型的用户

版本之间存在对等差分(symmetric difference)

选择模型时,性能胜过预测能力

从误差中查找新模式、创建新特征

尝试量化观察到的异常行为

注意短期行为和长期行为的差别

确保训练和服务一样好的最直接办法是:保存服务时使用的特征,然后将这些特征导入日志,以便在训练中使用。

重视采样数据

注意表格中的数据可能改变

尽量在训练和服务流水线中复用代码

训练和测试的数据不能相同

在二进制分类过滤的应用场景中(例如垃圾邮件检测),不要为了纯净的数据做太大的性能牺牲

注意排序问题的固有偏差

避免具有位置特征的反馈回路

测量训练/服务偏差

如果目标之间不搭,并成为问题,就不要在新特征上浪费时间

模型发布决策是长期产品目标的代理

保证集成模型(ensemble)的简洁

当性能达到瓶颈,相比精炼现存信号,不如寻找新性质的信息源

不要期望多样性、个性化、相关性和受欢迎程度之间有紧密联系

不同产品中,你的朋友总是那一个,你的兴趣不会如此

1.0做机器学习之前

  1. 对发布一个不含 ML 技术的产品,不要有顾虑

机器学习很酷,但要有数据。理论上,你可以把另一个相近课题的数据拿来用,调整下模型变成一个新产品。但这么做的实际效果,通常比简单的启发式算法(heuristics)还差。如果你认为机器学习能完成任务的100%。那么启发式算法能帮你完成50%。

比如说,若你为应用商店进行 app 排名,不妨直接利用下载率和装机量写个简单算法;若你在检测垃圾邮件,可以先把发送过垃圾邮件的地址过滤掉。也不要在人工编辑上有顾虑。如果机器学习对于你的产品不是必需的,那么在获得数据之前不要用它。

  1. 首先要设计和贯彻指标

在定义你的 ML 系统要做什么之前,要尽可能多地追踪你当前的系统。这出于以下原因:

在早期,获得系统用户的许可相对容易。

如果你认为有些东西在将来需要考虑,最好从现在起就收集历史数据。

如果你设计系统时考虑了指标的工具化( metric instrumentation),会省下将来的许多力气。你绝对不想为了指标而查找日志字符串。

有些东西会改变,有些不会。比如说,假设你想要直接优化每日活跃用户。但是,在你对系统的早期操作中,你也许会发现用户体验的大幅变化并不会显著改变这个指标。

Google+ 团队会衡量每次阅读的扩展数(expands per read)、分享、点赞、评论,以及每用户评论数、分享等等。然后他们利用这些数据计算发布消息的质量。另外要注意,能通过试验把用户分组并整合数据的试验框架非常重要,参考第12 条。

通过更灵活地收集指标,你能用更大的视角观察系统。发现一个问题?添加一个指标来追踪它!对上一个发布版本的量化变动很兴奋?添加指标来追踪!

  1. 在机器学习和复杂启发算法之间,选择前者

一个简单的启发算法能帮助产品走向市场,而复杂启发算法难以维护。一旦你有了数据以及需要实现的目标的蓝图,就可以转去开发 ML。在大多数软件工程任务中,开发者需要不停更新开发方式,不管是启发式算法还是 ML 模型。你会发现后者更加容易更新维护(参考第16 条)。

2.0 机器学习第一阶

2.1 你的第一条流水线

对于第一条流水线,关注你的系统基础设施。虽然,设想你将要做的种种 ML 应用很有趣;但如果你无法信任自己的流水线,你会很难搞清楚状况。

  1. 第一个模型要简单,把基础设施弄好

第一个模型为你的产品提供了最大的助力,所以它不需要花哨。而且你会遇到许多想象之外的基础设施问题。在你的新 ML 系统诞生之前,你需要决定:

如何获取学习算法的样例

对于你的系统,“好”、“坏”的定义是什么

如何把模型整合入应用。你可以实时应用模型,也可以在线下预计算模型,并把结果保存好。比如对网页预分类,然后在表格里保存结果。但有的任务可能需要对实时聊天信息进行分类。

选择简单的特征更容易保证:

这些特征正确应用于学习算法

模型学会合理的权重。

这些特征正确应用于服务器模型。

当你有了能可靠做到上述三点的系统,大部分的工作就已完成。简单模型提供给你基础的指标和行为,然后你可以用它们来测试更复杂的模型。有些团队把目标定为“中性”的首发——故意在首次发布不那么重视机器学习成果,以避免分心。

  1. 测试基础设施要与 ML 测试分开

要确保基础设施可测试,而且系统的学习部分都被包含在内,使得你能够测试所有相关物。特别是:

测试把数据导入算法。检查可填充的特征栏是不是空的。若条件允许,手工检查训练算法的输入。若可能,把流水线数据与其他地方作比较,比如 RASTA。

测试把数据导出训练算法。确保训练环境的模型与服务环境(serving environment)的模型产生同样的得分(详见第37 条)。

ML 有不可预测的因素。所以一定要对生成训练、服务样例的代码进行测试;这样你可以在服务中载入、使用固定模型。另外,理解你的数据也十分重要。

  1. 复制流水线时当心数据遗落

我们经常复制现成的流水线来创建新流水线(例如 cargo cult 编程),但有时旧流水线遗落了新流水线需要的数据。举个例子, Google Plus What’s Hot(雷锋网按:社交软件 Google+ 的热门新闻版块) 的流水线会遗落旧帖子(因为它试图为新帖子排名)。我们复制该流水线,用于 Google Plus Stream(Google+ 流)。对于后者,旧帖子仍然有意义,但新流水线仍然会丢掉数据。

另一个常见的模式是只记录用户看过的数据。因此,当你需要对为什么用户没有看到某个信息进行建模,该数据完全没用——因为所有反例已经被丢掉了。Google Play 发生过一个类似的问题:当我们开发 Google Play 应用商城主页时,创建出的新流水线包含另外两个登录页面(Play Games Home and Play Home Home,游戏主页和家庭主页)的样例。但是,并没有能够对“样例来自于哪个主页”加以区分的特征。

  1. 把启发式(heuristics)变为特征,不然就对它们做外部处理

通常来讲,ML 试图解决的问题并不是什么新问题——一般有现成的排名、分类等各种系统。这意味着有一大堆规则和启发式算法可用。这些启发式能在你调整 ML 时起到帮助。你应该压榨出启发式算法的所有信息,这有两个原因:1. 到 ML 系统的过渡会更顺畅。2. 这些规则通常包含一大堆关于系统的直觉信息,你绝对不想把它们扔掉。有四种利用现成启发式算法的途径:

使用启发式算法预处理。如果该特征非常棒,那么这就是一个选择。举个垃圾邮件过滤器的例子,若发件人已经被加入黑名单,不要试图重新学习“加入黑名单”是啥意思。直接拦截该信息。该方法最适用于二分类任务。

创建特征。直接用启发式创建特征相当棒。比如说,如果你用启发式计算一个问题结果的相关度分值,你可以把该得分作为特征值。之后,你或许想用 ML 技术来操作数值(比如把数值转化为有限个独立值集合,或与其他特征合并),但却拿启发式生成的原始数值来开头。

挖掘启发式的原始输入。如果有面向 APP 的启发式把装机量、文字中字母数目和日期组合到一起,就得考虑把它们分开——把这些输入分开来学习。有些应用于整体的技巧可用在这里(详见第 40 条)。

修正标记。当你发现启发式抓取了标记中未包含的信息时,这是一个选择。举个例子,如果你试图最大化下载量,但却仍然想要高品质内容,那么或许最好的方案是把标记与 APP 的平均星星得分相乘。这里有很大的余地。请参考“2.3 你的第一个目标”部分。

请注意启发式为 ML 系统加入的复杂度。在新 ML 算法中加入旧启发式有助于平滑地过渡,但你需要考虑是否更简单的实现方式。

2.2 监测

总的来讲,养成处理警告(alerts)的好习惯,比如对每个提醒付诸行动,并且建立一个仪表页面(dashboard page)。

  1. 了解系统的时效性

当你的模型已经开发出来一天、一周、一季度了,它的效果分别会降低多少?该信息能帮助你理解维护任务的优先级。假设模型一天没更新,你就要损失 10% 的收入。那么你或许要考虑雇佣专人每天维护。许多广告服务系统每天都有需要处理的新广告,因此必须每日更新。再举一个例子,如果 Google Play 的搜索 ML 模型停止更新,一个月内就会造成很大的损失。Google+ What’s Hot(雷锋网注:热门推荐)的一些模型,并没有针对发布信息的身份确认机制,所以不需要频繁导出这些模型。但有身份确认机制的模型就需要非常频繁地更新。另外需注意,时效性会随时间而变化,尤其是为模型添加或移除特征栏的时候。

  1. 在输出模型之前发现问题

许多 ML 系统包含该步骤:输出模型到服务端。如果输出的模型有问题,会直接让用户们遇上。而这个环节之前的问题只是训练问题,不会影响用户体验。

在导出模型之前一定要检查,尤其要确保模型在给定数据上有合理的效果。另外,若你对数据有顾虑,不要输出该模型。许多开发团队会在模型输出前检查 ROC 曲线 (或 AUC) 下的区域。未输出的模型存在问题,可能只需要一封 email 提醒一下。但用户端模型出了问题,很可能需要你向上司、同事解释一整页。所以最好多花点时间,在影响到用户之前做到胸有成竹。

  1. 于无声处听惊雷:注意没表现出来的故障

这是一个多见于机器学习、而少见于其他系统的问题。设想一个不再更新的特定表格:机器学习系统会调整,其行为仍会有合理表现,但逐渐退化。有时候开发者会发现过期几个月的表格——这时,一个简单的更新所提高的性能,比该季度的所有发布新版本都要高。举个例子,对一个特征的取舍会因为执行情况的变化而变化:覆盖 90% 样例的特征栏可能突然降低到只覆盖 60%。Google Play 曾经就有一个过期了六个月的表格,单单更新那个表格就带来了 2% 的安装率提升。如果你对统计数据进行跟踪,并偶尔人工检查,就能减少这类失误。

  1. 注意特征栏的维护者和文件

如果系统很大、有许多特征栏,你需要知道谁创立、维护了每一个特征栏。如果你发现懂得特征栏的那个人要跳槽了,一定要确保团队里有还有人知道这些信息。虽然许多特征栏有描述名称,你仍然需要更详细的解释,知道它是什么、从哪里来、起什么作用。

2.3 你的第一个目标

你有许多关心的系统指标或度量,但 ML 算法通常只需要一个目标——算法试图优化的某个数字。这里,我要区别目标(objectives)和指标(metrics):指标是系统报告的任何数字,或许重要,或许不重要。详见第二条。

  1. 选择直接优化哪个目标时,不需要想太多

你想要赚钱,让用户满意,并且让地球更美好。有许多你关心的指标,你应该全部都去测量(见第二条)。但在 ML 初期,你会注意到它们全都有提升,即便是那些没有直接优化的也是如此。举个例子,假设你关注点击数、浏览时间和每日活跃用户。如果你优化点击数,你会看到浏览时间也在上升。

所以简简单单就好。当你能轻易地提高所有指标,不需要在不同指标之间的平衡上想太多。但也不要误解这条建议:别把目标与系统最终的健康混为一谈(详见第 39 条)。另外,如果你增加了直接优化的指标,但决定不予发布,或许有必要重新修订目标。

  1. 选择一个简单、可观察并且可归属(attributable)的指标来作为第一个目标

很多情况下你不知道真正的目标是什么——你以为你知道。但当你仔细观察数据,以及对旧系统和新 ML 系统进行分析,你意识到自己其实想要对原定目标进行修改。团队不同成员也经常无法在真正的目标上取得一致意见。ML 目标应当易于测量,并可作为“真正”目标的代理。所以最好采用简单的 ML 目标训练,然后考虑在这之上设一个 “policy layer”(规则层),允许你加入额外的逻辑(但愿是简单的逻辑)来做最终排名。

最容易建模的是,能被直接观察到、并且可归属于系统中某个行动的用户行为:

这个排名链接被点击了吗?

这个排名对象被下载了吗?

这个排名对象被 转发/回复/发 email 了吗?

这个排名对象被打分了吗?

这个显示的对象被标记为垃圾邮件/色情信息/侮辱性信息了吗?

一开始要避免对间接作用建模:

用户在第二天访问了吗?

用户的访问时间是多长?

每日活跃用户都是谁?

其实,间接作用是非常不错的指标,并且可在 A/B 测试和发布决定中使用。

最后,不要试图让 ML 搞懂:

用户对使用该产品满意吗?

用户对体验满意吗?

产品提升了用户的福祉了吗?

这如何影响公司的整体健康?

这些都很重要,但是极度困难。你应该用代理来替代:如果用户感到开心,他们会在页面停留更长时间。如果用户满意,他明天会再次访问。目前,当涉及到福祉和公司健康状态,把 ML 目标与产品本质和商业计划之间做关联需要人的判断。

  1. 用可解释的模型开头,修补漏洞会更简单

线性回归、逻辑回归、泊松回归(Poisson regression)直接被概率模型驱动,每个预测都可作为概率或期望值解释。这使得相比使用了目标、直接优化分类精度或排序效果的模型(zero?one 损失、各种 hinge 损失等等),它们修补漏洞更加简单。如果通过对比或检查产品系统,发现训练里的概率偏离了预测概率,就可能存在问题。

比如说,在线性回归、逻辑回归、泊松回归之中,有的数据子集里平均预期和平均标签相等(1-?moment 校准,或者普通校准 )。对于一个值要么是 0 要么是 1 的特征,三个特征值为 1 的样例集就会被校准。同样地,若某特征下所有样例的特征值都是 1,它们都会被校准。

对于简单的模型,处理反馈回路( feedback loops )更加容易。我们经常用这些概率预期来做决定:比如以期望值(点击概率/下载量等)为标准对发布消息进行降序排列。但要记住,当决定采用那个模型的时候,你的决定比给定模型数据的可能性( the likelihood of the data given the model )更加重要(参考第 21 条)。

  1. policy layer(规则层)把垃圾信息过滤和质量排序分来

质量排序是一门高雅的艺术,而垃圾信息过滤是一场战争。对于使用你系统的人,你用来判断高质量消息的信号十分显而易见。然后,他们会据此调整他们的发布信息来获得这些属性。因此,你的质量排序应当专注于有信誉的内容——不应该让质量排序学习器退化到给垃圾信息高排名。同样的,重口味内容应当与质量排序分开。而垃圾信息过滤是另一回事了。你需要创建的特征会不断变化,对此要有心理准备。通常,你加入系统里的规则有些很显而易见(比如,若一个发布信息得到超过三个“垃圾信息”票数,不要恢复它)。任何学习到的模型需要至少每天更新。内容生产者的名誉会起到相当大的作用。

在某个层级,这两个系统的输出需要整合在一起。需要注意的是,在搜索结果里过滤垃圾信息,比过滤垃圾邮件要更加强力。 为了高质量的分类器而去除训练数据中的垃圾,已是行业标准。

3.0 机器学习第二阶段

3.1 特征工程

在进行机器学习相关实践的第一阶段,你要关注的主要问题包括以下三个方面:一是将训练数据导入系统,二是确定系统的重点关注指标,三是保证底层基础设施的稳定可靠。当这三个问题都确认无误,即已经搭建了一个端到端的可稳定运行的系统,并且针对系统本身和其中的每个单元都经过了严格测试,这时就可以进入第二阶段了。

应该说,第二阶段将更容易取得成绩。这一阶段会有许多显著的特征(feature)被导入系统,因此,导入并以直观的方式组合这些特征,将是本阶段涉及的主要任务。另外,本阶段也更适合多位工程师协同工作,共同对此前导入的训练数据进行整合和处理,推动所有的指标(metric)在本阶段取得持续性的上升。

  1. 做好模型被推倒和重建的准备

不要指望从头到尾只使用一个模型,也不要指望着某一结点之后就不用重建模型了,模型的推倒和重建是机器学习过程中的必修课。另外,每加入一个新特性都必须考虑是否会拉低模型的运行效率。目前,许多团队每三个月或一年就会新建一个模型。这里我们总结了一般情况下引发模型重建的三大原因:

1) 增加新的特征

2) 打算重组旧的特征,或对旧模型正则化

3) 修订建模目标

无论如何,创建模型时多想想并没有什么坏处:例如检查训练数据是否有更合理的组织形式,考虑当前的建模方式是否便于特征的修改和重组,当前的机器学习流水线(pipeline)是否便于创建副本并检验其正确率,以及是否可以创建两到三个副本并行运行等等。最后需要指出的是,并不一定非要在一个机器学习流水线中覆盖所有特征,在下一个版本中实现也是可行的。

  1. 直接以观察到的或报告的特征开始训练,而不是经过学习的特征

这一点建议或许存在一些争议,但的确能避免许多潜在的问题。这里经过学习的特征(learned feature)是指由外部系统(例如无监督的聚类系统)或模型本身(例如通过深度学习和因子模型)产生的特征。这两种情况虽然的确可以使用,但并不适合系统的第一个模型。

首先,在使用外部系统创建特征时必须要格外小心。因为外部系统的目标可能与当前系统并不相符,而且从外部系统更新当前系统的特征,其特定的含义也可能改变。

另一方面,因子模型和深度模型的主要问题是它们是非凸的(non-convex),因此它们无法保证可以最终找到或近似找到最优解,它们在每次迭代中产生的局部最小值都可能变化,而且目前无法评估这种变化对系统的影响是有益的还是有害的。通过创建没有深度特征的模型,你就可以获得很好的基准性能。在实现这一基准性能之后,你可以尝试更高阶的方法。

  1. 从不同的上下文环境中提取特征

通常情况下,机器学习只占到一个大系统中的很小一部分,因此你必须要试着从不同角度审视一个用户行为。比如热门推荐这一场景,一般情况下论坛里“热门推荐”里的帖子都会有许多评论、分享和阅读量,如果利用这些统计数据对模型展开训练,然后对一个新帖子进行优化,就有可能使其成为热门帖子。另一方面,YouTube上自动播放的下一个视频也有许多选择,例如可以根据大部分用户的观看顺序推荐,或者根据用户评分推荐等。总之,如果你将一个用户行为用作模型的标记(label),那么在不同的上下文条件下审视这一行为,可能会得到更丰富的特征(feature),也就更利于模型的训练。需要注意的是这与个性化不同:个性化是确定用户是否在特定的上下文环境中喜欢某一内容,并发现哪些用户喜欢,喜欢的程度如何。

  1. 尽量选择更具体的特征

在海量数据的支持下,即使学习数百万个简单的特征也比仅仅学习几个复杂的特征要容易实现。由于被检索的文本标识与规范化的查询并不会提供太多的归一化信息,只会调整头部查询中的标记排序。因此你不必担心虽然整体的数据覆盖率高达90%以上,但针对每个特征组里的单一特征却没有多少训练数据可用的情况。另外,你也可以尝试正则化的方法来增加每个特征所对应的样例数。

  1. 以合理的方式组合、修改现有的特征

目前有多种方法组合、修改现有的特征,由于本文以Google工具为背景,因此在这里推荐两种TensorFlow框架已实现好的方法:“离散化”(discretizations)和“交叉”(crosses)。

离散化主要包含提取连续特征和从连续特征中创建离散特征两个部分。比如对于年龄这一连续的特征,你就可以创建这样的离散特征:当年龄小于18时结果为1,或者当年龄介于18-35之间时为1,等等。另外,不要过分考虑直方图中基本分位数的问题。

在TensorFlow的术语中,特征栏是一组相似的特征,比如{男性,女性},{美国,加拿大,墨西哥}等。这里的交叉是指将两个或多个特征栏合并,例如{男性,女性}×{美国,加拿大,墨西哥}的结果就是一个交叉(a cross),也就构成了一个新的特征栏。假设你利用TensorFlow框架创建了这样一个交叉,其中也就包含了{男性,加拿大}的特征,因此这一特征也就会出现在男性加拿大人的样例中。需要注意的是,交叉方法中合并的特征栏越多,所需要的训练数据量就越大。

如果通过交叉法生成的特征栏特别庞大,那么就可能引起过拟合。例如,假设你正在进行某种搜索,并且在查询请求和文档中都具有一个包含关键字的特征栏。那么假如你选择用交叉法组合这两个特征栏,这样得到的新特征栏就会非常庞大,它内部包含了许多特征。当这种情况发生在文本搜索场景时,有两种可行的应对方法。最常用的是点乘法(dot produc),点乘法最常见的处理方式就是统计查询请求和文档中共同的所有特征词,然后对特征离散化。另一个方法是交集(intersection),比如当且仅当关键词同时出现在文档和查询结果中时,我们才能获取所需的特征。

  1. 通过线性模型学到的特征权重的数目,大致与数据量成正比

许多人都认为从一千个样例中并不能得到什么可靠的训练结果,或者由于选择了某种特定的模型,就必须获取一百万个样例,否则就没法展开模型训练。这里需要指出的是,数据量的大小是和需要训练的特征数是正相关的:

1) 假如你在处理一个搜索排名问题,文档和查询请求中包含了数百万个不同的关键词,并且有一千个被标记的样例,那么你应该用上文提到的点乘法处理这些特征。这样就能得到一千个样例,对应了十几个特征。

2) 如你有一百万个样例,那么通过正则化和特征选择的方式就可以交叉处理文档和查询请求中的特征栏,这可能会产生数百万的特征数,但再次使用正则化可以大大减少冗余特征。这样就可能得到一千万个样例,对应了十万个特征。

3) 如果你有数十亿或数百亿个样例,那同样可以通过特征选择或正则化的方法交叉处理文档和查询请求中的特征栏。这样就可能得到十亿个样例,对应了一千万个特征。

对特征数和样例来说,这些统计学上的结论并不能给出一个具体的比例关系,但却可以从数量级上给出一些指导。另外,这里推荐用户依照第28条建议来选择具体使用哪些特征。

  1. 清理不需要的特征

如果你发现有些特征并没有在使用,而且将其与其他特征相结合之后也无法使用的话,就应该清理这些特征。应该保持系统的清洁,这样才能尽快尝试那些最有希望出结果的特征。而且,如果有必要,被删除的特征也可以随时找人加回来。

在考虑增删一个特征时,应该仔细排查其覆盖范围。例如你有一些个性化的特征,但只有大约8%的用户使用了该特征,那么删掉或添加这个特征就不会有太大影响。

另一方面,增删特征时也要考虑其对应的数据量。例如你有一个只覆盖了1%数据的特征,但有90%的包含这一特征的样例都通过了训练,那么这就是一个很好的特征,应该添加。

3.2 对系统的人工分析

在进入机器学习实践的第三阶段之前,关注一些课堂上不曾教授的问题也同样至关重要,比如如何检查一个模型并改进它。要说这一点是一门科学,反而不如说它是一种艺术,这里我们介绍几点反面模式(anti-patterns)。

  1. 你并不是一个典型的用户

这可能是让一个团队陷入困境的最简单的方法。虽然fishfooding(只在团队内部使用原型)和dogfooding(只在公司内部使用原型)都有许多优点,但无论哪一种,开发者都应该首先确认这种方式是否符合性能要求。另一方面,应该尽量避免不好的变化,但任何看起来合理的产品策略都应该被进一步验证,例如通过非专业人士在众包平台上的问卷调查,或者请目标用户来实测。

走外部验证渠道的原因来自两个方面:一是作为开发者,你太熟悉代码。例如你可能正在分析数据的某一方面而非全局,或者投入了太多的个人感情色彩,从而引发一些偏见。二是几位工程师开一个小时的讨论会议得到的评估结果,可能远比不上直接交给众包平台来得简单和有效。

如果你真的想要获取用户反馈,那么应该采用用户体验法(user experience methodologies)。 在流程早期创建用户角色(详情见Bill Buxton的《Designing User ExperienCES》一书),然后进行可用性测试(详情见Steve Krug的《Do not Make Me Think》一书)。这里的用户角色涉及创建假想用户。例如,假设你的团队成员都是男性,现在要针对35岁女性用户研发一款产品,那么基于目标群体创建一个假想角色,肯定比几位25-40岁的男性开发者闭门造车的效果要好。当然,让用户实测产品并观察他们的反应也是很不错的方法。

  1. 版本之间存在对等差分(symmetric difference

将产品交付至用户之前,有时候最简单有效的做法就是评估当前版本与交付版本的差异。例如面对排名问题,你可以在两个版本间利用同一组样例进行测试,然后对比其结果。如果差异很小,那么意味着这个版本没问题。如果差异很大,那么就需要确认进行了哪些修改,为什么进行这些修改。通过查看哪些测试样例造成了这一差异,也有助于定性了解修改具体是怎样的。总之,目标是确保不同版本的模型之间的对等差分做到最小。

  1. 选择模型时,性能胜过预测能力

你的模型可能会被用来预测点击率,但更关键问题是:这种预测是应用在什么场景的。如果你用它来排列文档,那么最终排名的质量显然比预测本身更重要。如果你用它来排查垃圾邮件,那么识别精度显然更重要。大多数情况下,这两类功能应该是一致的,如果他们存在不一致,则意味着系统可能存在某种小增益。因此,假如一个改进措施可以解决日志丢失的问题,但却造成了系统性能的下降,那就不要采用它。当这种情况频繁发生时,通常应该重新审视你的建模目标。

  1. 从误差中查找新模式、创建新特征

假设你的模型在某个样例中预测错误。在分类任务中,这可能是误报或漏报。在排名任务中,这可能是一个正向判断弱于逆向判断的组。但更重要的是,在这个样例中机器学习系统知道它错了,需要修正。如果你此时给模型一个允许它修复的特征,那么模型将尝试自行修复这个错误。

另一方面,如果你尝试基于未出错的样例创建特征,那么该特征将很可能被系统忽略。例如,假设在谷歌Play商店的应用搜索中,有人搜索“免费游戏”,但其中一个排名靠前的搜索结果却是一款其他App,所以你为其他App创建了一个特征。但如果你将其他App的安装数最大化,即人们在搜索免费游戏时安装了其他App,那么这个其他App的特征就不会产生其应有的效果。

所以,正确的做法是一旦出现样例错误,那么应该在当前的特征集之外寻找解决方案。例如,如果你的系统降低了内容较长的帖子的排名,那就应该普遍增加帖子的长度。而且也不要拘泥于太具体的细节。例如你要增加帖子的长度,就不要猜测长度的具体含义,而应该直接添加几个相关的特征,交给模型自行处理,这才是最简单有效的方法。

  1. 尝试量化观察到的异常行为

有时候团队成员会对一些没有被现有的损失函数覆盖的系统属性感到无能为力,但这时抱怨是没用的,而是应该尽一切努力将抱怨转换成实实在在的数字。例如,当有些开发者认为在谷歌Play商店的搜索结果中显示了过多的其他App,就可以选择人工识别的方法剔除这些App(这时是可以选择人工标记数据的,因为相对较小的App查询可能占了很大一部分流量)。首先要确认你的问题是可量化的,然后才可以根据这些问题创建新的特征(features)、目标(objectives)或者指标(metrics)。总之规则是:先量化,再优化

  1. 注意短期行为和长期行为的差别

假设你有一个新系统,它可以查看每个doc_id和exact_query,然后根据每个文档的每次查询行为计算其点击率。你发现它的行为几乎与当前系统的并行和A/B测试结果完全相同,而且它很简单,于是你启动了这个系统。但却没有新的应用显示,为什么?由于你的系统只基于自己的历史查询记录显示文档,所以不知道应该显示一个新的文档。

要了解一个系统在长期行为中如何工作的唯一办法,就是让它只基于当前的模型数据展开训练。这一点非常困难。

3.3 训练服务的偏差(Training?-Serving Skew

这里训练服务偏差是指系统在训练时的性能表现和服务中的性能表现出现差别。造成这种差别的原因可能有如下三个方面:

1) 在训练和服务中的数据处理流水线不同;

2) 在训练和服务中使用了不同的数据;

3) 模型和算法间的反馈回路引起。

我们注意到谷歌的机器学习系统也存在训练服务偏差,而且会对性能产生负面影响。这里需要说明的是:最好的解决办法就是明确地监视它,使系统和数据的改变不至于引发潜在的偏差。

  1. 确保训练和服务一样好的最直接办法是:保存服务时使用的特征,然后将这些特征导入日志,以便在训练中使用

即使你不能对每个样例都这样做,做一小部分也比什么也不做好,这样你就可以验证服务和训练之间的一致性(见规则37)。在谷歌采取了这项措施的团队有时候会对其效果感到惊讶。比如YouTube主页在服务时会切换到日志记录特征,这不仅大大提高了服务质量,而且减少了代码复杂度。目前有许多团队都已经在其基础设施上采用了这种策略。

  1. 重视采样数据

当数据太多时,有些团队可能会选择丢弃一部分以减轻负担。这是一个明显的错误:历史经验证明在训练过程中丢弃数据将引发一系列问题(详见规则6)。当然,有时候的确可以丢弃数据,比如那些从未向用户显示过的,但重要性加权却是更好的选择。重要性加权意味着,如果你决定以30%的概率对样例X进行抽样,则权重应该是3/10。值得一提的是,使用重要性加权并不影响规则14中讨论的校准属性。

  1. 注意表格中的数据可能改变

假设你通过包含文件特征的表格(表格中还可能包含评论或点击的次数)加入文件的ID信息,那么需要注意表格中的特征可能会在训练和服务的不同时间点发生一些变化,造成模型对同一文档的预测也跟着改变。避免此类问题的最简单方法是在服务时记录特征(请参阅规则32)。如果表格的变化足够缓慢的话,你可以每天或每小时都记录一次表格以获得非常接近的数据,但需要注意的是,这并不能完全解决问题。

  1. 尽量在训练和服务流水线中复用代码

首先需要明确的一点是:批处理与在线处理不同。在线处理中,你必须在每个请求到达时及时处理(例如必须为每个查询单独查找);而在批处理中,你可以组合任务(例如建立联结)。类似的,可以将服务视为在线处理过程,而训练视为批处理过程,而其中有许多代码是可以复用的。比如说,你可以创建特定于系统的对象,其中的所有联结和查询结果都以人类可读的方式存储,错误也可以被简单地测试。然后,一旦在服务或训练期间收集了所有信息,你就可以通过一种通用方法在这个特定对象和机器学习系统需要的格式之间形成互通,训练和服务的偏差也得以消除。另外,由此推知:最好不要在训练和服务期间使用不同的编程语言(因为不同的语言间几乎无法复用)。

  1. 训练和测试的数据不能相同

一般来说,最好用不同的数据对模型进行训练和测试,例如你用1月5日之前的数据训练了一个模型,那么最好用1月6日之后的数据对模型展开测试。可能模型对新数据的性能表现不如训练数据,但也不会太糟。由于可能会产生每日效应(daily effects),因此你可能无法预测平均点击率或转化率,但曲线下方的面积(表示正面样例的分数高于反面样例的可能性)应该是接近的。

  1. 在二进制分类过滤的应用场景中(例如垃圾邮件检测),不要为了纯净的数据做太大的性能牺牲

一般在过滤应用场景中,反面样例并不会对用户展示。不过假如你的过滤器在服务过程中阻止了75%的反面样例,那么你可能需要从向用户显示的实例中提取额外的训练数据并展开训练。比如说,用户将系统认可的邮件标记为垃圾邮件,那么你可能就需要从中学习。

但这种方法同时也引入了采样偏差。如果改为在服务期间将所有流量的1%标记为“暂停”,并将所有这样的样例发送给用户,那你就能收集更纯净的数据。现在你的过滤器阻止了至少74%的反面样例,这些样例可以成为训练数据。

需要注意的是,如果你的过滤器阻止了95%或更多的反面样例,那这种方法可能就不太适用。不过即使如此,如果你想衡量服务的性能,可以选择做出更细致的采样(例如0.1%或0.001%),一万个例子足以准确地估计性能。

  1. 注意排序问题的固有偏差

当你彻底改变排序算法时,一方面会引起完全不同的排序结果,另一方面也可能在很大程度上改变算法未来可能要处理的数据。这会引入一些固有偏差,因此你必须事先充分认识到这一点。以下这些方法可以有效帮你优化训练数据。

1) 对涵盖更多查询的特征进行更高的正则化,而不是那些只覆盖单一查询的特征。这样,模型将偏好于那些基于一个或几个特定查询的特征,而不是所有的特征。这种方式可以有效防止那些最常见的查询结果泄漏到不相关的查询中。需要注意的是,这与一条更传统的建议相左:更多地正则化一些具有单一值的特征栏。

2) 只允许特征具有正向权重,这样一来就能保证任何好特征都会比未知特征合适。

3) 不要选择那些只处理文档数据的特征。例如,不管搜索请求是什么,即使一个给定的应用程序是当前的热门下载,你也不会想在所有地方都显示它。没有文档特征的话,这一点会很容易做到。

  1. 避免具有位置特征的反馈回路

内容的位置会显著影响用户与它交互的可能性。很明显,如果你把一个App置顶,那它一定会更频繁地被点击。处理这类问题的一个有效方法是加入位置特征,即关于页面中的内容的位置特征。假如你用正向特征来训练模型,那模型就会更偏向“1st-position”这类的特征。因而模型对其他因素的权重就会相应地减小,例如对“1st-position = true”这种样例。在服务的时候,你可以选择不提供任何位置特征的实例,或者为所有位置特征设置相同的初始值,因为在决定以怎样的顺序显示它们之前,你具有决策权。

需要注意的是,因为训练和测试的不对称性,所以最好在一些位置特征和模型之间保持一定的分离性,这一点很重要。让模型成为位置特征函数和其他特征函数的和,是理想的状态。比如说,最好不要交叉任何文档特征和位置特征。

  1. 测量训练/服务偏差

许多情况都会引起偏差,但它们大多可以分为如下三类:

1) 训练数据和测试数据的性能之间的差异。一般来说,这总是存在的,但并不会太严重。

2) 测试数据的性能与“第二天数据”(next-day data)之间的差异。同样,这也会一直存在。你可以不同程度地正则化以最大限度地提高第二天的性能(next-day performance)。然而,如果在测试数据和第二天数据之间存在很大的性能下降,这有可能意味着某些特征是时间敏感的,而且整个模型的性能也会跟着下降。

3) “第二天数据”和实时数据的性能之间的差异。如果你将模型应用于训练数据的样例,也应用于相同的服务样例,则它们应该给出完全相同的结果(详见规则5)。因此,这里的差异可能是指工程误差。

4.0 机器学习第三阶

4.1 减慢的增速,精细优化和复杂模型

第二阶段将要结束的时候,一定会有些信号。首先,你每月的收益开始降低。你开始要在指标之间做牺牲:一些试验中有的上升有的下降。从此情况变得更有趣。由于更难产生效益,机器学习不得不变得更复杂。

警告:这部分有许多开放式的实践法则。我们亲眼看着很多团队走过第一阶段和第二阶段的幸福期——一旦到达第三阶段,开发团队就不得不找出他们自己的路。

  1. 如果目标之间不搭,并成为问题,就不要在新特征上浪费时间

当达到度量瓶颈,你的团队开始关注 ML 系统目标范围之外的问题。如同之前提到的,如果产品目标没有包括在算法目标之内,你就得修改其中一个。比如说,你也许优化的是点击数、点赞或者下载量,但发布决策部分依赖于人类评估者。

  1. 模型发布决策是长期产品目标的代理

(雷锋网注:谷歌工程师在这里举了个例子)Alice 有一个关于降低安装预测的逻辑损失的想法。她加入一个特征。逻辑损失下降。当她实时测试时,安装量上升了。但在公司的发布会议上,有人指出每日活跃用户数降低了 5%。团队决定不发布该模型。Alice 很失望,但意识到发布决策取决于多个标准,其中只有一部分能够被 ML 直接优化。

事实是,现实世界并不是网络游戏:没有“攻击值”和“血量”来衡量产品的健康。团队需要利用收集的数据,来试图预测将来系统的表现会怎样。他们需要操心用户黏性、每日活跃用户、每月活跃用户、收入和广告主的收益。这些 A/B 测试中的指标,实际上只是长期目标的代理:让用户满意、增加用户、让合作方满意还有利润;即便这时你还可以考虑高品质、有使用价值的产品的代理,以及五年后一个繁荣的企业的代理。

做出发布决策变得容易的唯一一种情况是:所有指标都变好了(起码没有变差的)。如果团队在复杂 ML 算法和简单启发式算法之间有的选择;如果简单的启发式算法在这些指标上做得更好;那么应当选择后者。另外,所有指标数值并没有明确的排序。更具体的,考虑以下两种情形:

如果现有系统是 A ,团队不会想要转移到 B。如果现有系统是 B,团队也不会想要转到 A。这看起来与理性决策相抵触:但是,对指标变化的预期情形或许会发生,或许不会。因此任意一种改变都有相当大的风险。每一个指标覆盖了一些团队所关注的风险。但没有指标能覆盖团队的首要关切——“我的产品在五年后会怎样?”

另一方面,个体倾向于选择能直接优化的目标。大多数 ML 工具喜欢这样的环境。这样的环境下,一个能快速创建新特征的工程师能稳定输出一系列产品发布。有一种叫“多目标学习”(multi?objective learning)的机器学习开始解决这一问题。比如说,可以制定一个在每个指标上有下限的约束满意度问题(constraint satisfaction problem),然后优化指标的一些线性组合。但即便那时,也不是所有指标都能轻易表达为 ML 目标:如果一个文件被点击,或者 APP 被安装,这是因为有内容被展示出来。但搞清楚用户为什么访问你的页面就更加难了。如何预测一个页面在将来是否成功,是一项 AI?-complete 问题(雷锋网注:意味着完成它的难度相当于解决 AI 问题),与计算机视觉和自然语言处理一样难。

  1. 保证集成模型(ensemble)的简洁

接收原始特征、直接对内容排序的统一模型,是最容易理解、最容易修补漏洞的模型。但是,一个集成模型(一个把其他模型得分组合在一起的“模型”)的效果会更好。为保持简洁,每个模型应该要么是一个只接收其他模型的输入的集成模型,要么是一个有多种特征的基础模型,但不能两者皆是。如果你有单独训练、基于其它模型的模型,把它们组合到一起会导致不好的行为。

只用简单模型来集成:那些只把基础模型的输入作为输出、进行接收的模型。你或许想要为这些集成模型强加上属性。比如,基础模型生成得分的提高,不应该降低集成模型的分数。另外,如果连入模型在语义上可解释(比如校准了的)会更好,这样其下层模型不会与集成模型混淆。再者,强行让下层分类器预测的概率升高,不会降低集成模型的预测概率。

  1. 当性能达到瓶颈,相比精炼现存信号,不如寻找新性质(qualitatively)的信息源

你已经加入了一些关于用户的人口统计信息,还有文件中的词语。你经历了模板探索,和正则化(regularization)调参。但连续几个季度的发布,你都没有看到核心指标有超过 1% 的提升。现在怎么办?

你已经到了为不同寻常(雷锋网(公众号:雷锋网)注:很不一样)的特征,创建基础设施的时候了。比如用户昨天、上周、去年检索的文档,或是另一种属性的数据。为你的公司使用维基数据(wikidata)实体或者一些内部的东西(比如谷歌的知识图,Google’s knowledge graph)。你或许需要使用深度学习。开始调整你对投资回报的期望,并作出相应努力。如同所有工程项目,你需要平衡新增加的特征与提高的复杂度。

  1. 不要期望多样性、个性化、相关性和受欢迎程度之间有紧密联系

一系列内容的多样性能意味着许多东西,内容来源的多样性最为普遍。个性化意味着每个用户得到属于他们自己的结果。相关性意味着一个特定检索的结果,对应它比对应其他检索更合适。因此,这三个属性的定义都有别于“标准”。

但标准更难被打败。

注意:如果你的系统在统计点击量、耗费时间、浏览数、点赞数、分享数等等,你事实上在衡量内容的受欢迎程度。有团队试图学习具备多样性的个性化模型。为个性化,他们加入允许系统进行个性化的特征(有的特征代表用户兴趣),或者加入多样性(表示该文档与其它返回文档有相同特征的特征,比如作者和内容),然后发现这些特征比他们预想的得到更低的权重(有时是不同的信号)。

这不意味着多样性、个性化和相关性就不重要。如同上个法则所指出的,你可以通过后处理来提高多样性或相关性。如果你看到长期目标的进步,那么你可以宣布在受欢迎程度之外,多样性和相关性是有价值的。你可以继续采用后处理,或者直接根据多样性或相关性修改目标。

  1. 不同产品中,你的朋友总是同一个,你的兴趣不会如此

谷歌的 ML 团队 常常把一个预测某产品联系紧密程度(the closeness of a connection in one product)的模型,应用在另一个产品上,然后发现效果很好。另一方面,我见过好几个在产品线的个性化特征上苦苦挣扎的团队。是的,之前看起来它应该能奏效。但现在看来它不会了。有时候起作用的是——用某属性的原始数据来预测另一个属性的行为。即便知道某用户存在另一个属性能凑效的历史,也要记住这一点。比如说,两个产品上用户活动的存在或许就自身说明了问题。

谷歌白皮书原文地址:http://martin.zinkevich.org/rules_of_ml/rules_of_ml.pdf

人工智能

人工智能(Artificial Intelligence),英文缩写为AI。它是研究开发用于模拟延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。 人工智能是计算机科学的一个分支,它企图了解智能的实质,并生产出一种新的能以人类智能相似的方式做出反应的智能机器,该领域的研究包括机器人、语言识别、图像识别、自然语言处理和专家系统等。人工智能从诞生以来,理论和技术日益成熟,应用领域也不断扩大,可以设想,未来人工智能带来的科技产品,将会是人类智慧的“容器”。
人工智能可以对人的意识、思维的信息过程的模拟。人工智能不是人的智能,但能像人那样思考、也可能超过人的智能。
人工智能是一门极富挑战性的科学,从事这项工作的人必须懂得计算机知识,心理学和哲学。人工智能是包括十分广泛的科学,它由不同的领域组成,如机器学习,计算机视觉等等,总的说来,人工智能研究的一个主要目标是使机器能够胜任一些通常需要人类智能才能完成的复杂工作。但不同的时代、不同的人对这种“复杂工作”的理解是不同的。[1]