Page 35 - MSDN Magazine, November 2017
P. 35

Figure 2 Anomaly Detection Tab of the RemoteCamera App
Anomaly Detection
As explained in a recent article by James McCaffrey (msdn.com/ magazine/mt826350), one common way of detecting abnormalities is through time-series regression. By fitting a model to your data, you can predict trends and then see if all sequence values follow them by calculating the difference between actual and predicted values. A large divergence from expected values indicates outliers or anomalous values. Here, I’ll first demonstrate how to detect such outliers by analyzing the so-called z-scores. The larger the z-score, the higher the probability that the actual value is an outlier. So, to find abnormalities, you specify the range of z-scores, which are treated as “normal.” All z-scores outside that range indicate abnormalities. However, this approach uses a fixed threshold, thus it might lead to a large number of false positives. To solve such an issue, more-complex algorithms are employed. Specifically, the Azure Time Series Anomaly Detection module is based on exchangeability martingales (bit.ly/2wjBYUU), which analyze if a
Figure 3 Acquiring Training Dataset
sequence of values can be arbitrarily reordered without changing the probability of finding a given value in that sequence (or, in other words, that each value is equally likely to be found in a dataset). This exchangeability property of the dataset leads to small anomaly scores. When exchangeability is broken, large anomaly scores will be generated, indicating abnormal values.
In this article I’ll demonstrate how to create such machine learn- ing (ML) algorithms. I’ll use the Microsoft Azure Machine Learning Studio (studio.azureml.net), which was also described by McCaffrey in the September 2014 issue (msdn.com/magazine/dn781358). Here, I’ll go beyond that article and, as well as creating ML experiments, I’ll show how to deploy the resulting solution as a Web service, then how to use such a service in the RemoteCamera app.
Training the Data Set
The first step is to extend the RemoteCamera app by adding another tab, which lets you acquire the training dataset and enable or disable anomaly detection using a checkbox (Figure 2).
The button, Acquire training dataset, becomes enabled after you start the camera preview (using controls from the first tab). When you tap this button, an app starts acquiring the training dataset. This works in the background and is indicated with a progress ring. The resulting training dataset comprises 100 data points, each of which is represented by an instance of the BrightnessDataPoint structure:
public struct BrightnessDataPoint {
public DateTime Time { get; private set; } public byte Brightness { get; private set; }
public BrightnessDataPoint(byte brightness) {
Time = DateTime.Now; Brightness = brightness;
}
The BrightnessDataPoint struct stores a brightness value along with the time the brightness was determined. A collection of such values is then exported to the BrightnessData.csv file, which looks like the following:
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
The particular location of the training dataset is then displayed in the textbox. I use a comma-separated (CSV) file so it can be easily uploaded to the Machine Learning Studio.
To implement this functionality, I wrote two classes: Brightness- FileStorage and AnomalyDetector. The first class, Brightness- FileStorage, is defined in the BrightnessFileStorage.cs file in the AnomalyDetection subfolder of the companion code. Brightness- FileStorage saves a collection of BrightnessDataPoint objects to the CSV file using the DataWriter class (bit.ly/2wS31dq).
The second class, AnomalyDetector, handles the logic related to anomaly detection. In particular, it has a public method, AddTraining- Value, shown in Figure 3, which is invoked right after the image brightness is calculated (see the ImageProcessor_ProcessingDone
}
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)); }
}
msdnmagazine.com
November 2017 31































































   33   34   35   36   37