这篇文章是继之前的文章:
的续篇。在之前的文章中,我重点讲述了什么是机器学习。Elastic ML 在机器学习领域里意味着上面。同时我也展示了如何使用 Elastic ML 来创建机器学习任务。在上面文章中展示的机器学习任务 single-metric,multi-metric 及 population 中,使用的是 unsupervised 机器学习。
在今天的文章中,我将展示 Elastic ML 的一些新的技术:
- Transforms
- Outlier Detection
在下面的展示中,我将使用 Elastic Stack 7.6.2 来进行演示。
准备
我们需要按照 “Elastic:开发者上手指南” 中的文章:
- 如何在 Linux,MacOS 及 Windows 上进行安装 Elasticsearch
- Kibana:如何在 Linux,MacOS 及 Windows上安装 Elastic 栈中的 Kibana
来安装好自己的 Elasticsearch 及 Kibana。在本演示中,我们将使用机器学习功能,所以,我们同时也需要启动白金版试用功能:
这样白金版的试用功能就启动了。更多关于 Elasticsearch 的订阅请参考官方链接 订阅 | Elastic Stack 产品和支持 | Elastic 。
Transforms
Transform 使n 能够将现有的 Elasticsearch 索引转换为汇总索引,从而为新的见解和分析提供机会。 例如,你可以使用转换将数据转换为以实体(entity)为中心的索引,这些索引总结了数据中用户或会话或其他实体的行为。 或者你可以使用转换在所有具有某个唯一键的文档中查找最新的文档。
在我们大多数的数据中,它通常是以时序来表示的一个流数据:
通常这样的时序数据包含一个叫做 @timestamp 的字段。这个是 Elastic 最早创建机器学习的基础。 Elastic 机器学习基于时序数据进行学习,并检测时序数据中的异常。这个在我之前的文章 “Elastic:机器学习的原理及实践 - single metric job” 有看到。
当我们分析更为高级的机器学习案例时,以时序为基础的数据集或索引,并不是很容易来进行分析。针对一些案例,我们可以使用以 entity (实体)来进行分析会变得更加容易。我们首先来看一个示例:
如上所示,假如有一个 eCommerce 商店,我们把如上商品的文档写入到 Elasticsearch 中。左上的文档代表一个时间系列的文档(它含有一个叫做 Date 的字段)。我们可以通过正常的机器学习来分析这个时序的异常。这个是没有任何问题的,但是假如我们想分析这些数据的 entity(针对上面的例子,就是客户的名字 name),比如每个客户的行为,她或他是否表现的和别人不一样。比如在上面,我们经过 transform,可以清楚地看到 Anna 购买的数量比 Simon 要多,而且平均价格也较贵。我们可以针对这个 transform 过后的表格进行 outlier 分析。当然针对我们上面的情况,它仅有两个文档而已,而在实际的使用中,我们可能面对的是千万,甚至是 PB 级的数据。我们可以轻松地借助 Elastic ML 来分析我们的数据。
Transforms 展示
为了让大家对 Transform 有一个比较清楚的认识,我们现在使用一个 Kibana 自带的例子来进行演示。首先打开 Kibana:
这样我们就为 Elasticsearch 创建了一个叫做 kibana_sample_data_ecommerce 的索引。这是一个时序的索引:
在上面,我们选择合适的时间范围,我们可以看到这个 eCommerce 的订单。我们仔细研究一下这些文档:
这些文档里含有一个叫做 customer_full_name 的字段。显示可以用作这个数据集的 entity,如果我们想针对每个客户进行研究的话。当然,在实际的使用中,entity 甚至可以是上面的 category 字段,假如我们想分析每个 category 的情况。
我们接下来使用 Elastic 的 Transforms 来提炼出以客户名为实体(entity)的表格。我们进行如下的操作:
在上面,我们选择 Pivot。在 Group by 里选择 customer_full_name,也就是选择 customer_full_name 为 entity。
接下来,我们选择感兴趣的 aggregations:
一旦我们选择好自己感兴趣的 aggregation,Wizard 会自动帮我们生产一个如下的 preview:
从上面的 Preview 中,我们可以看出来这是一个以 customer_full_name 为 entity 的表格。这里的数据是从时序数据里把每个客户的数据进行聚合。从这个表格里,我们可以看出来哪些用户花钱最多,哪些客户买商品的平均价格较高。
点击上面的 Next 按钮:
从上面,我们可以看出来一个叫做 webinar-demo-ecommerce-dest 的索引已经被生成。这个索引不再是一个时序的索引,而是一个基于 customer_full_name 为 entity 的一个索引。每个文档含有客户的名字,花费的总价钱及平均价格。
机器学习分类
Elastic 机器学习可以分为如下的两类:
如上所示,Elastic ML 分为有监督的机器学习和没有监督的机器学习两大类。Unsupervised 机器学习通常不需要一个数据集进行学习,而 Supervised 机器学习需要一定的数据来进行训练,然后我们可以运用训练的模型来对未来的数据进行分类或预测。
Outlier Detection
Outlier Detection,也称作为异常值检测。它是属于 Unsupervised 机器学习的一个部分。它是用于发现以 entity 为基础的数据集中的异常。在上面的练习中,我们已经了解了如何把一个时序的数据集转为以 entity 为基础的数据集。如果你的原始数据集本身就是一个以 entity 为基础的数据集,我们就不需要做任何的转换了。我们就可以直接对数据进行 Outlier Dection。
在进行 Outlier Detection 展示之前,我们先来简单地了解一下 Outlier Detection 是如何工作的。 我们先拿一个南瓜作为例子来进行描述。我们知道一个南瓜含有重量(weight)及 周长(circumference)。
假如我们我们有如下的一个统计图:
如图所示,在通常的情况下周长越长,那么南瓜的重量就越大。按照这个说法,我们很容易解释左下角及右上角的一些数据。我们用肉眼很容易发现 A 及 B 是两个异类。Elastic 里的机器学习 Outlier Detection 其实按原理就是基于这种理解来进行计算的,只不过它使用了算术的方法来进行计算的。
在 Elastic Stack 的 Outlier Detection 中,它由四种互补的技术来实现的:
回顾之前的例子,A 及 B 被视为异常是因为它们远离大多数正常南瓜所在的区域。这让我们创建一个公式来计算任何一个数据和其它数据之间的距离。当这些数据的距离相比较其它的要大很多,那么就可以视为异常。我们可以通过计算一个数据到它的 kth-nearest 附近数据的距离及平均距离来算出异常值。这个值将计入总的异常分数。尽管这种方法在大多数情况下非常有效,但是针对一些数据比较分散的数据集来说,所有的数据和其它的数据的距离都几乎相当,或者说都很远。我们在这种情况下需要测量这个点周围的数据密度来确定这个点是否异常。
如上所示,我们使用了另外的两个技术来测量一个点和周围的点的密度。通过这个技术我们能了解任何一个点的周围的点到底离它有多近,从而测出这个点的密度。通过这两个技术,我们可以得出另外一个分数。通过上面四种互补技术的运用,我们可以得出一个介于 0 到 1 的分数。这个分数越接近于 1,那么代表该数据越异常。
Outlier Detection 展示
在今天的展示中,我将使用一个真实的例子来进行演示。我们可以到地址 House Sales in King County, USA | Kaggle 下载。这是一个在美国 King County 地区的房屋销售真实数据。一旦下载完数据,我们可以使用 Kibana 来把数据导入:
我们选择解压缩文件中的 kc_house_data.csv 文件:
我们把索引的名字取为 king-county-house-prices。我们在摄入时,会发现 ingest pipeline 会自动帮我们把数值进行转换,并创建一个叫做 location 的字段。它里面包含有文档中的经纬度。点击上面的 Import 按钮:
这样,我们就成功地创建了一个叫做 king-county-house-prices 的索引。我们点击上面的按钮,这样我们可以在 Discover 的页面中进行查看:
很显然这不是一个时序的数据。在这个页面,我们可以查看这个数据集的各个字段,比如面积,多少个 bed rooms,多少个 bath rooms 地理位置信息等。
在进行下面的操作之前,我们先来创建一个运行时字段 bedrooms_per_bath,它表示一个 bathoom 对于于多少个 bedrooms。这对于有些客户来说,也是一个比较感兴趣的参数。打开 Kibana:
我们把如下的脚本填入到 Define script 框中:
emit((double)doc['bedrooms'].value/(double)doc['bathrooms'].value)
点击 Save 按钮。这样我们就生成了一个叫做 bedrooms_per_bath 的动态字段。
我们接下来的兴趣点是找到在 King County 这个地方哪些 zipcode 是比较异常的地方。这个即便是在中国的房地产中,也是非常有意思的一个兴趣点,比如我们可以发现北京的那个区域的房价比较突出:价钱比较高,或者价钱比较低。
我们接下来对数据进行 Transform。我们按照之前的方法来进行操作。显然针对我们的情况,我们选择 zipcode 作为 entity。
我们选择 zipcode 为 entity,然后按照上面的显示分别计算出来它们的 aggregation。
我们可以看到类似如上文档的索引 king-country-real-estate-dest。
接下来我们使用 Elastic 机器学习提供的 Outlier Detection 来判定哪些 zipcode 是异常的。
在实际的使用中,我们可以选择我们想要的字段来进行异常分析。在我们的实例中,我们除去 zipcode。
好了。我们通过这个练习了解了如何使用 Elastic 的机器学习对 data frame 数据进行异常检测。希望这个对你的实际工作有所帮助。