2017 年 11 月

第 33 卷,第 11 期

此文章由机器翻译

机器学习 - 用于异常情况检测的 Azure 机器学习时序分析

通过 Dawid Borycki

异常检测是最重要的物联网 (IoT) 解决方案的收集和分析的数据从各种传感器 tem 门户更改的功能之一。在许多情况下,传感器数据不会随着时间的推移显著更改。但是,当执行,则通常意味着在你的系统遇到异常,并且此异常会导致特定故障。这篇文章中我将向你演示如何使用 Azure 机器学习时间系列异常检测来标识异常传感器读数。将与此 end 扩展我在我以前的文章中开发 RemoteCamera 通用 Windows 平台 (UWP) 应用 (msdn.com/magazine/mt809116) 通过添加显示异常值的列表 (请参阅图 1).RemoteCamera 应用获取从网络摄像头的图像,并计算其亮度,除非相机图像发生了重大变化解决某些特定的值将根据不断变化。由于 (通过涵盖相机,例如),您可以轻松地引发严重亮度更改,从而导致的异常,此应用程序为提供正确的输入时间序列异常检测。

检测异常亮度值与 Azure 机器学习

图 1 检测异常亮度值与 Azure 机器学习

异常检测

中所述的新文章通过 James McCaffrey (msdn.com/magazine/mt826350),检测异常情况的一种常用方式是通过时间序列回归。通过将模型拟合到你的数据,你可以预测趋势,,然后查看是否所有序列值都遵循它们通过计算实际和预测值之间的差异。离群值或异常值,该值指示与预期值大分歧。在这里,我将首先演示如何通过分析所谓的 z 评分检测此类离群值。越大 z 评分,越高的实际值为离群值的概率。因此,若要查找异常情况,你指定的范围的 z 的评分,会为"正常"。 此范围外的所有 z 评分都指示异常情况。但是,此方法使用固定的阈值,因此,可能会导致大量的误报。若要解决此类问题,请使用更复杂算法。具体而言,Azure 时间系列异常检测模块基于 exchangeability martingales (bit.ly/2wjBYUU),该分析如果值的序列可任意重新排序而无需更改的概率该序列中 (或以其他字,相当于每个值都同样可能存在数据集中),请查找给定的值。数据集此 exchangeability 属性会导致对小异常评分。当 exchangeability 已损坏时,将会生成大型异常评分,异常值,该值指示。

这篇文章中,我将演示如何创建此类机器学习 (ML) 算法。我将使用 Microsoft Azure Machine Learning Studio (studio.azureml.net),这将在 2014 年 9 月问题也已由 McCaffrey (msdn.com/magazine/dn781358)。在这里,我将超出该文章,并作为也为创建 ML 试验中,我将演示如何部署生成的解决方案作为 Web 服务,然后如何 RemoteCamera 应用中使用此类服务。

定型数据集

第一步是通过添加另一个选项卡上,允许您获取训练数据集以及启用或禁用异常检测使用一个复选框来扩展 RemoteCamera 应用 (图 2)。

异常检测 RemoteCamera 应用选项卡

图 2 异常检测选项卡上的 RemoteCamera 应用

此按钮时,获取训练数据集,将成为启用后,启动相机预览 (使用从第一个选项卡控件)。点击此按钮后,应用程序启动获取训练数据集。这将在后台工作,并采用进度环指示。生成的训练数据集包含 100 个数据点,其中每个由 BrightnessDataPoint 结构的一个实例:

public struct BrightnessDataPoint
{
  public DateTime Time { get; private set; }
  public byte Brightness { get; private set; }

  public BrightnessDataPoint(byte brightness)
  {
    Time = DateTime.Now;
    Brightness = brightness;
  }
}

BrightnessDataPoint 结构存储亮度已确定的时间以及一个亮度值。此类值的集合然后导出到 BrightnessData.csv 文件,如以下所示:

Time,Brightness
9/8/2017 11:30:00,103
9/8/2017 11:30:01,103
9/8/2017 11:30:02,102
9/8/2017 11:30:03,42
9/8/2017 11:30:04,46
9/8/2017 11:30:05,149
9/8/2017 11:30:06,99
9/8/2017 11:30:07,101
9/8/2017 11:30:08,104

然后在文本框中显示的训练数据集的特定位置。何时使用以逗号分隔 (CSV) 文件,以便它可以轻松地上载到 Machine Learning Studio。

若要实现此功能,我已编写两个类:BrightnessFileStorage 和 AnomalyDetector。第一个类,亮度文件存储,是在随附的代码的 AnomalyDetection 子文件夹 BrightnessFileStorage.cs 文件中定义的。亮度文件存储将 BrightnessDataPoint 对象的集合保存到 CSV 文件使用 DataWriter 类 (bit.ly/2wS31dq)。

第二个类,AnomalyDetector,处理相关的异常检测的逻辑。具体而言,它有一个公共方法,添加 TrainingValue 中, 所示图 3,即调用右计算图像亮度后 (请参阅在 MainPage.xaml.cs 中的 ImageProcessor_ProcessingDone 事件处理程序随附的代码)。AddTrainingValue 过程如下所示:首先,我创建 BrightnessDataPoint,然后添加到集合的实例。当此集合具有 100 个项目时,我可以将其保存到 CSV 文件。我然后激发 TrainingDataReady 事件,这在 MainPage 中断训练数据集获取并在 UI 中显示的文件位置中处理:

private async void AnomalyDetector_TrainingDataReady(
  object sender, TrainingDataReadyEventArgs e)
{
  await ThreadHelper.InvokeOnMainThread(() =>
  {
    remoteCameraViewModel.IsTrainingActive = false;
    remoteCameraViewModel.TrainingDataSetFilePath = e.FilePath;
  });
}

图 3 获取训练数据集

private const int trainingDataSetLength = 100;
private List<BrightnessDataPoint> trainingDataSet = 
  new List<BrightnessDataPoint>();

public event EventHandler<TrainingDataReadyEventArgs> TrainingDataReady;

public async Task AddTrainingValue(byte brightness)
{
  trainingDataSet.Add(new BrightnessDataPoint(brightness));

  // Check if all data points were acquired
  if (trainingDataSet.Count == trainingDataSetLength)
  {
    // If so, save them to csv file
    var brightnessFileStorage = 
      await BrightnessFileStorage.CreateAsync();
    await brightnessFileStorage.WriteData(trainingDataSet);

    // ... and inform listeners that the training data set is ready
    TrainingDataReady?.Invoke(this,
      new TrainingDataReadyEventArgs(
      brightnessFileStorage.FilePath));
  }
}

训练数据集的位置被显示在文本框中,以便你可以轻松地将其复制并将其粘贴在 Windows 资源管理器以查看生成的数据。

Z 评分分析

准备定型数据集,我将准备 Machine Learning Studio,McCaffrey 的 2014年文章中的说明中的第一个试验。我首次上载 BrightnessData.csv 文件,和中所示然后设计使用可视化设计器中,试验图 4。简言之,所有组件都都在菜单中,位于 Machine Learning Studio 的左侧。若要在试验中放置一个元素,你只需将其试验窗格 (中心 Machine Learning Studio 部分) 上。每个组件有特定的输入和输出。你连接兼容的节点,以控制模块之间的数据流。组件可以具有其他配置,使用属性窗口 (显示在 Machine Learning Studio 右侧) 设置。

异常检测使用 z 评分分析

图 4 异常检测使用 z 评分分析

ML 算法图中所示图 4在两个模式工作: 试验和 Web 服务。它们的区别仅在于输入。在 experi 管理模式下,输入组成上载的训练数据集 (BrightnessData),它将替换输入 Web 服务中的 Web 服务模式。独立于模式下,输入转换为数据集,然后从亮度列的值被规范化使用 z 评分转换 (bit.ly/2eWwHAa)。转换将亮度值转换为 z 的评分,告诉你的当前值摘自平均值的程度。此距离的单位为标准偏差。更大的距离,更高版本的当前值为离群值的概率。由于一般情况下,将基表或正常亮度级别而异哪些相机看到应用 z 评分规范化。因此,z 评分转换可确保正确的亮度级别后 normaliza 一种接近于 0。原始亮度值会不同于大约 40 到 150。标准化后,所有亮度值将都在大约-4.0 和之间 +4.0 中, 所示图 5。因此,若要查找异常值我需要做是应用阈值筛选器。在这里,我使用 Azure 机器学习阈值筛选器的类型 OutOfRange 与下限和上限边界设置为-2 和 1.5。选择这些值基于在 z 评分绘图图 5并对其使用的阈值过滤器属性板在 Machine Learning Studio 中设置。

训练数据集后规范化

图 5 标准化后的训练数据集

完成故障排除后数据集包含一个布尔值列,指定给定的时间点是否超出指定范围。为补充此信息与实际亮度值标识为离群值,我可以将此列与原始数据集结合起来,然后将生成的数据集拆分为两个子集: 一个包含异常值仅和另一种具有正常值 (请参阅的底部图 4)。在拆分因为拆分数据模块不接受布尔值前更改列数据类型。然后,试验返回第一个的子集。在 Web 服务视图中,此结果将传输到客户端。请注意,若要查看从任何数据集的值你使用结果数据集 |可视化 Machine Learning Studio 中的数据集上下文菜单中的选项。此选项效果提供以前已运行此试验。图 6描述了从试验中所示的此类的最后一个数据集的可视化示例图 4

异常值检测到与 z 评分分析

图 6 异常值检测到与 z 评分分析

机器学习时间时序分析

让我们现在将了解如何使用 Azure 时间系列异常检测 (ATSAD) 模块来识别离群值。中所示图 7,试验的流,则非常类似于前一个。初始数据集进行了规范化用 z 评分转换和 trans-ferred 到 ATSAD 模块 (可以在 Machine Learning Studio 的时序节点下找到它)。这要求你提供多个输入,你配置了属性窗口 (bit.ly/2xUGTg2)。首先,指定数据和时间列中,然后配置鞅类型。在这里,我使用 Power 鞅。这将激活另一个文本框中,Epsilon,可以在其中键入任何从 0 到 1 指定检测器的敏感度的值。然后,你选择 strangeness 函数,请使用三个选项之一:

  • RangePercentile:使用此选项以确定一些明显超出了范围,如峰值或 dip 的值。因此它将工作类似地到以前的试验中,但需要满足的更全面分析我实验中使用此选项。
  • SlowPos-和 SlowNegTrend:使用这些选项来标识你的数据集的正值和负值趋势变化。你的解决方案查找增加或减少中观测的值,这很有用。

利用 Azure 时间系列异常检测模块试验

图 7 试验利用 Azure 时间系列异常检测模块

接下来,你指定的鞅和 strangeness 值历史记录的长度。你可以选择介于 10 到 1000年之间的任何整数。经过一定的试用版错误试验,我决定采用以下参数为我检测器:

  • Epsilon = 0.4
  • 长度鞅以及 strangeness 值历史记录 = 50

检测程序的最后一个参数是警报的阈值,它指定将标记为属于离群的给定的值的异常分数的最小值。默认情况下,警报阈值设置为 3.5。我在我的试验,更改此为 2。

如果你可视化 ATSAD 模块的输出,你将看到它补充输入数据集包含两个列: 异常分数,测量异常情况和警报的指标,其中包含一个二进制值 (0 或 1),该值指示如果值为异常。我使用后者来将数据集拆分为两个子集: 正常和异常。试验返回仅异常的子集。试验的其他元素是之前相同,因此我不会再次讨论它们。我将仅请注意,Web 服务所需的试验非常重要的方面的输入和输出的名称。我将这些值设置为数据 (Web 服务输入) 和 AnomalyDetectionResult (Web 服务输出)。

Web 服务客户端

与设置试验我现在可以将发布它们作为 Web 服务以便它们可以访问由 RemoteCamera 应用来标识任何映像亮度异常情况。若要设置 Web 服务,你需要运行此试验,然后按 Machine Learning Studio 的底部窗格上的部署 Web 服务图标 (请参阅中的突出显示的项图 8)。如果不添加 Web 服务输入和输出到试验的模块,此窗格将显示设置 Web 服务。如果你单击它,Web 服务输入和输出模块将添加到试验中,而且按钮标签将更改为部署 Web 服务。

Azure 机器学习 Studio 操作窗格

图 8 Azure 机器学习 Studio 操作窗格

Web 服务部署完成后,你将重定向到 Web 服务仪表板中, 所示图 9。仪表板中显示已发布的 Web 服务,以及 API 密钥和如何将请求发送和处理响应 (API 帮助页) 的说明的摘要。具体而言,单击后请求/响应超链接,Web 服务 URL 的详细的请求和响应结构,以 JSON 格式将显示。

Web 服务仪表板

图 9 Web 服务仪表板

若要继续进一步,我存储的 API 密钥,并创建 JSON-到-C# 使用 JSONUtils 服务 (jsonutils.com) 的映射。然后保存所产生的类中的相应文件,AnomalyDetectionRequest.cs 和 AnomalyDetectionResponse.cs,AnomalyDetection 子文件夹。其结构是类似 — 这两个文件包含照常组成主要自动实现的属性的类。AnomalyDetectionRequest 和 AnomalyDetectionResponse 表示相应客户端和 Web 服务之间正在传输的 JSON 对象。例如,AnomalyDetectionRequest 类和依赖对象的定义中给定图 10。请注意,若要将的亮度数据点的集合转换为接受 Machine Learning Studio Web 服务 (的二维数组的字符串) 的输入,我使用的帮助程序类,ConversionHelper。后者中随附的代码, 的完整定义,则有两个公共方法。它们也将转换的亮度数据点的集合为字符串 [、] (BrightnessDataToStringTable) 或 vice 外部样式表 (AnomalyDetectionResponseToBrignthessData)。

图 10 先决条件的 AnomalyDetectionRequest 类和依赖对象的定义

public class AnomalyDetectionRequest
{
  public Inputs Inputs { get; set; }
  public GlobalParameters GlobalParameters { get; set; }

  public AnomalyDetectionRequest(
    IList<BrightnessDataPoint> brightnessData)
  {
    Inputs = new Inputs()
    {
      Data = new Data()
      {
        ColumnNames = new string[]
        {
          "Time",
          "Brightness"
        },

          Values = ConversionHelper.
            BrightnessDataToStringTable(brightnessData)
      }
    };
  }
}

public class Inputs
{ 
  public Data Data { get; set; }
}

public class Data
{
  public string[] ColumnNames { get; set; }
  public string[,] Values { get; set; }
}

public class GlobalParameters { }

一次的 JSON-到-建立 C# 对象映射,可以编写实际的 Web 服务客户端。为此第一次安装 Microsoft.AspNet.WebApi.Client NuGet 包并使用它来定义 AnomalyDetectionClient 类 (请参阅随附的代码中的相应文件)。此类有三个私有字段: baseAddress,apiKey 和 httpClient。第一个字段存储 Machine Learning Studio Web 服务的 URL,而第二个包含的 API 密钥。这两个值用于实例化 HttpClient 类 (从已安装的 NuGet 程序包):

public AnomalyDetectionClient()
{
  httpClient = new HttpClient()
  {
    BaseAddress = new Uri(baseAddress),
  };

  httpClient.DefaultRequestHeaders.Authorization = 
    new AuthenticationHeaderValue("Bearer", apiKey);
}

在创建后客户端,我可以开始使用 AnomalyDetectionClient.DetectAnomalyAsync 方法从将请求发送到 Machine Learning Studio Web 服务图 11。此方法接受表示测试数据的亮度数据点的集合。此测试数据将替换我以前用于试验和用来实例化 AnomalyDetectionRequest 的 CSV 文件。PostAsJsonAsync 扩展方法与此类的实例更高版本发布到 Web 服务以供分析。生成的 JSON 响应转换为最后 DetectAnomalyAsync 函数返回对 AnomalyDetectionResponse 类实例。我还查找任何错误,并最终在适当时引发异常。

图 11 将请求发送到 Azure 机器学习 Studio Web 服务

public async Task<IList<BrightnessDataPoint>> 
  DetectAnomalyAsync(IList<BrightnessDataPoint> brightnessData)
{
  var request = new AnomalyDetectionRequest(brightnessData);

  var response = await httpClient.PostAsJsonAsync(string.Empty, request);

  IList<BrightnessDataPoint> result; 

  if (response.IsSuccessStatusCode)
  {
    var anomalyDetectionResponse = await 
      response.Content.ReadAsAsync<AnomalyDetectionResponse>();

    result = ConversionHelper.
      AnomalyDetectionResponseToBrightnessData(anomalyDetectionResponse);
  }
  else
  {
    throw new Exception(response.ReasonPhrase);
  }

  return result;
}

在 AnomalyDetector 类的 AddTestValue 方法中使用 AnomalyDetectionClient (图 12)。如 AddTrain ingValue,AddTestValue 也会调用在 ImageProcessor_ProcessingDone 事件处理程序中 (请参阅 compan 离子代码中的 MainPage.xaml.cs)。但是,AddTestValue 继续比 AddTrainingValue 方法略有不同的方式。在 AddTestValue 我将亮度数据点添加到内部使用泛型 List 类实现滚动窗口 BrightnessDataset 类的实例。此窗口中的,James McCaffrey 年 10 月文章中所示用于存储测试值。默认情况下,滚动窗口的大小设置为 30 的元素,但你可以控制使用构造函数的 BrightnessDataset 此值。中所示图 12,我不发送数据以进行分析之前窗口已满,则检查 Web 服务返回的异常值的集合是否包含任何元素。如果是,我将调用 AnomalyDetected 事件,还用于将异常传递到侦听器。

图 12 检测异常

public event EventHandler<AnomalyDetectedEventArgs> AnomalyDetected;
private BrightnessDataset dataSet = new BrightnessDataset();

public async Task AddTestValue(byte brightness)
{
  dataSet.Add(new BrightnessDataPoint(brightness));

  if (dataSet.IsFull)
  {
    try
    {
      var anomalousValues = await anomalyDetectionClient.
        DetectAnomalyAsync(dataSet.Data);

      if (anomalousValues.Count > 0)
      {
        AnomalyDetected?.Invoke(this,
          new AnomalyDetectedEventArgs(anomalousValues));
      }
    }
    catch (Exception ex)
    {
      Debug.WriteLine(ex);
    }
  }
}

若要在 UI 中显示异常值,我 AnomalyDetected 在中处理事件的 MainPage 类,如下所示:

Private async void AnomalyDetector_AnomalyDetected(
  object sender, AnomalyDetectedEventArgs e)
{
  await ThreadHelper.InvokeOnMainThread(() =>
  {
    foreach (var anomalousValue in e.AnomalousValues)
    {
      if (!remoteCameraViewModel.AnomalousValues.Contains(anomalousValue))
      {
        remoteCameraViewModel.AnomalousValues.Add(anomalousValue);
      }
    }
  });
}

具体而言,我循环访问获取的值来检查是否已添加到本地数据存储 (AnomalousValues 视图模型属性) 的集合。如果没有,我将它们添加到可查看的集合。因此,仅新的异常值将出现在列表中的以前所示图 1。由于滚动的窗口中,在其中只有一个元素到 Web 服务的连续调用之间更改,我做此其他检查。

若要测试我的解决方案,你将需要运行 RemoteCamera 应用程序、 启动相机预览并启用异常检测使用异常检测选项卡上的复选框。完成此操作后你可以通过涵盖相机生成异常的值。这些值应快速识别的远程 ML 检测器作为异常并显示在列表框 (如图 1)。

总结

我此处演示如何设计 Azure Machine Learning Studio 中的两个不同的异常检测试验。这两个 exper iments 已作为 Web 服务部署,而且与客户端应用程序,RemoteCamera,它将发送机器学习分析,以确定其中存在异常的本地获取的时间序列数据结合使用。在这里,我在 UWP 应用中使用 Web 服务。但是,你可以使用相同的代码来访问 Web 服务从 ASP.NET Web 应用程序,当你从处理在后端而不是在终结点上的 ML 逻辑-,对于 IoT 可以是简单传感器。


Dawid Borycki是软件工程师、生物医学研究员、作家和会议演讲者。他喜欢学习有关软件实验和原型设计的新技术。

衷心感谢以下 Microsoft 技术专家对本文的审阅:ScriptoJames McCaffrey


在 MSDN 杂志论坛讨论这篇文章