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 右侧) 设置。
图 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。
图 6 异常值检测到与 z 评分分析
机器学习时间时序分析
让我们现在将了解如何使用 Azure 时间系列异常检测 (ATSAD) 模块来识别离群值。中所示图 7,试验的流,则非常类似于前一个。初始数据集进行了规范化用 z 评分转换和 trans-ferred 到 ATSAD 模块 (可以在 Machine Learning Studio 的时序节点下找到它)。这要求你提供多个输入,你配置了属性窗口 (bit.ly/2xUGTg2)。首先,指定数据和时间列中,然后配置鞅类型。在这里,我使用 Power 鞅。这将激活另一个文本框中,Epsilon,可以在其中键入任何从 0 到 1 指定检测器的敏感度的值。然后,你选择 strangeness 函数,请使用三个选项之一:
RangePercentile:使用此选项以确定一些明显超出了范围,如峰值或 dip 的值。因此它将工作类似地到以前的试验中,但需要满足的更全面分析我实验中使用此选项。
SlowPos-和 SlowNegTrend:使用这些选项来标识你的数据集的正值和负值趋势变化。你的解决方案查找增加或减少中观测的值,这很有用。
图 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 服务。
图 8 Azure 机器学习 Studio 操作窗格
Web 服务部署完成后,你将重定向到 Web 服务仪表板中, 所示图 9。仪表板中显示已发布的 Web 服务,以及 API 密钥和如何将请求发送和处理响应 (API 帮助页) 的说明的摘要。具体而言,单击后请求/响应超链接,Web 服务 URL 的详细的请求和响应结构,以 JSON 格式将显示。
图 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);
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)
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 杂志论坛讨论这篇文章