为什么我们使用搜索引擎时,不同的用户搜索同样的关键词看到的广告却不同?为什么我们到电子商务网站购物时,每次浏览同样的商品时都可以得到不同的商品推荐?作为网站服务的开发者,你有没有想过,你所拥有的数据蕴含着怎样的价值?当你准备对自己的网站数据进行深入分析时,是否曾面对着成百上千的数据不知如何下手?

  如果上面的问题会让你连连点头,那么请跟随我们,展开一段数据分析之旅。希望沿途的见闻,会让你在下次进行数据挖掘操作时,更加得心应手。

  借用一下本刊前面的一篇文章——《借助OTS快速构建LBS服务》中的故事。假设你利用OTS构建了一个很不错的LBS网站,公司业务蒸蒸日上,积累了大量的活跃用户,还拥有了北京地区大部分餐馆的物理信息和用户评价信息;如果你的广告业务也发展得很好,说不定你的公司已经收支平衡,并且小有盈余。可以说,这时的你已不满足于仅仅为用户提供餐馆信息,而且希望能够利用你拥有的数据为客户创造更大的价值。

  对了,在开始前,我们也要介绍一下本次旅行的交通工具:阿里云开放数据处理服务(Open Data Processing Service,简称ODPS)。ODPS是构建在大规模分布式计算系统上的海量数据处理服务,以REST API的形式支持描述性查询语言SQL的数据处理,适用于海量数据统计、数据模型、数据挖掘、数据商业智能等诸多互联网应用。

  一个简单的数据分析示例

  你拥有的数据可以支持很多复杂精彩的分析任务,我们从最简单的一个开始:希望利用所有用户的点评数据计算餐馆的综合评分,进而统计“北京最受欢迎的十大餐馆”。由于这个榜单相对固定,我们可以每天重新计算一次,看是否有黑马杀入。

  如果你的业务发展得比上文描述的还要好,那么你此刻可能会有点烦恼了:假设你已有8000万用户,按10%的活跃用户平均每人30条点评,其他90%的用户平均每人2条点评计算,用户点评数据约有4亿条;如果每条点评信息平均0.5KB,那么点评数据总计有200GB。利用传统数据库来完成数据分析会显得力不从心;而大数据处理的商业解决方案极为昂贵,开源的解决方案又需要非常专业的开发和运维知识。在这种场景下,就要靠ODPS大显身手了。

  第一个数据分析的SQL


▲表1 RestaurantInfo表存储餐馆的数据

  让我们回顾一下你的原始数据,它们都已经存储在OTS的表格中了(为了ODPS的计算需要,表的schema略有修改),如表1和表2所示。


▲表2 RestaurantComment表存储用户对餐馆的评价数据

  为了使用ODPS服务,你还需要到ODPS的管理中心申请数据存储所需的存储空间、数据分析所需的计算资源、用于确保数据和计算安全的AccessID和AccessKey【注:ODPS使用这一加密对来保证开发者的数据、作业和工作流不能被别人访问,因此开发者需要小心保管AccessId和AccessKey,不要对任何人泄露】的安全加密对,以及开发所需的SDK安装包(什么,你还没有注册?别担心,阿里云支持统一用户登录,你在使用OTS时已经注册过,此时仅仅需要开通ODPS服务就可以了)。

  在ODPS的SDK安装包中,提供了一个命令行工具odpscmd【注:随ODPS SDK一同发布的命令行操作工具,其安装过程参见http://odps.aliyun.com】。odpscmd封装了ODPS的REST API,支持ODPS服务的绝大部分功能,可以帮助你尽快了解并熟悉ODPS的常用操作。SQL的构造流程分为以下五步。

  用odpscmd来配置一下你的安全加密对(odpscmd要求所有命令以“;”结尾):

  $ odpscmd SET ACCESSID=AccessID ACCEESSKEY=AccessKey;
  将OTS中的两张表的schema和数据复制到ODPS中(以下以大写字母表示关键字,斜体字母表示用户自定义标识符;odpscmd对所有关键词和标识符不区分大小写):

  $ odpscmd CREATE TABLE RestaurantInfo AS SELECT * FROM OTS.RestaurantInfo;

  $ odpscmd CREATE TABLE RestaurantComment AS SELECT * FROM OTS.RestaurantComment;
  在HangMode【注:odpscmd处理SQL命令的一种模式,与NoneHangMode相对】模式下,odpscmd会同步串行处理提交的一系列SQL命令,直到最后一个SQL命令结束,结果表数据生成后才会返回。根据表中的数据量多少和运算的复杂性,等待时间可能会是几秒钟到几个小时不等。当OTS中的源表数据量很大、数据被分片保存时,ODPS服务会启动多个任务并发读取OTS中的数据,以缩短数据复制时间。存储在ODPS中的数据也会分片保存,以便后续的数据分析操作可以快速地读取数据。

  你还需要在ODPS中创建一张新表TopTenRestaurants,存储十大餐馆的统计信息,如表3所示。


▲表3 TopTenRestaurants表存储十大餐馆的统计数据

  建表命令为:

  $ odpscmd CREATE TABLE IF NOT EXISTS TopTenRestauransts (DistrictID INT, RestaurantID INT, Name STRING, Address STRING, PhonenNmber STRING, Location STRING, Category STRING, ScoreStat INT, CostStat INT);
  我们将用户对每个餐馆评分的平均值定义为该餐馆的口碑,取评分最高的前十名餐馆作为“北京最受欢迎的十大餐馆”。构造相应的SQL语句后,在odpscmd中提交:

  $ odpscmd INSERT OVERWRITE TABLE TopTenRestaurants SELECT a.DistrictID, a.RestaurantID, a.Name, a.Address, a.PhoneNumber, a.Location, a.Category, b.ScoreStat, b.CostStat FROM RestaurantInfo a JOIN (SELECT DistrictID, RestaurantID, AVG(Score) AS ScoreStat, AVG(Cost) AS CostStat FROM RestaurantComment GROUP BY DistrictID, RestaurantID) b ON a.DistrictID = b. DistrictID AND a.RestaurantID = b.RestaurantID ORDER BY b.ScoreStat DESC LIMIT 10;
  SQL语句运算完成后,我们可以查阅表中的结果数据:

  $ odpscmd READ TABLE TopTenRestaurants;
  在ODPS中计算的结果数据需要被外部应用访问,我们可以借助于OTS的实时查询功能。假设在OTS中利用相同的schema也创建了TopTenRestaurants表,你可以通过下面的命令将ODPS的数据推送到OTS中:

  $ odpscmd EXPORT DATA TO OTS TopTenRestaurants FROM TABLE TopTenRestaurants;