2017 年 11 月

第 33 卷,第 11 期

本文章是由機器翻譯。

機器學習服務 - 利用 Azure Machine Learning 時間序列分析進行異常偵測

Dawid Borycki

異常偵測是其中一個最重要的物聯網 (IoT) 解決方案的收集和分析項目 poral 變更從各種感應器資料的功能。在許多情況下,感應器資料不會大幅經過一段時間變更。不過,當的話,通常表示您的系統發生異常狀況,而且這個異常可能會造成特定的功能有問題。在本文中,我將示範如何使用來識別異常感應器讀數的 Azure 機器學習時間數列異常偵測。為此,我將會延長我我先前的文件中開發 RemoteCamera 通用 Windows 平台 (UWP) 應用程式 (msdn.com/magazine/mt809116) 加上顯示異常值的清單 (請參閱圖 1).RemoteCamera 應用程式取得映像從網路攝影機,並計算其亮度,除非大幅變更相機映像,有一些特定的值。因為您可以輕鬆地引發嚴重的亮度變更,(依覆蓋相機,例如),導致審查,此應用程式提供良好的輸入時間序列異常偵測。

偵測異常的亮度與 Azure Machine Learning 中的值

圖 1 偵測異常的亮度與 Azure Machine Learning 中的值

異常偵測

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),這也 McCaffrey 所描述在 2014 年 9 月問題 (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。第一個類別,而亮度 FileStorage,BrightnessFileStorage.cs 檔案 AnomalyDetection 的子資料夾中隨附的程式碼中定義。亮度 FileStorage 將 BrightnessDataPoint 物件的集合儲存至 CSV 檔案使用 DataWriter 類別 (bit.ly/2wS31dq)。

第二個類別,AnomalyDetector,處理相關的異常偵測邏輯。特別是,它具有公用的方法,新增-TrainingValue 所示圖 3,計算映像亮度之後即叫用權限 (請參閱 ImageProcessor_ProcessingDone 事件處理常式,在 MainPage.xaml.cs 中的隨附的程式碼)。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 分數分析

準備好的定型資料集,以準備工作第一個試驗,在機器學習 Studio 中,McCaffrey 的 2014年文件中的指示。我先上傳 BrightnessData.csv 檔案,並如中所示,然後設計使用視覺化設計工具中,實驗圖 4。簡言之,所有元件都是在功能表中,位於 Machine Learning Studio 左側。若要將項目放在您實驗中,您只要將它拖曳 [實驗] 窗格 (Machine Learning Studio 的中心部分)。每個元件會有特定的輸入和輸出。您連接相容的節點,以控制模組之間的資料流程。元件可以有額外的設定,您使用 [屬性] 視窗 (顯示在 Machine Learning Studio 右側) 來設定。

異常偵測使用 z 分數分析

圖 4 異常偵測使用 Z-score 分析

ML 演算法述圖 4適用於兩種模式: 實驗和 Web 服務。只有輸入的不同。在 experi 會模式中,輸入是由已上傳的定型資料集 (BrightnessData),這會取代 Web 服務模式中,輸入 Web 服務所組成。獨立的模式,輸入會轉換成資料集,然後使用 z 分數轉換正規化亮度資料行的值 (bit.ly/2eWwHAa)。轉換會將亮度的值轉換成 z 分數-,可以讓您知道伸展多遠的目前值是平均數。這個距離被以標準差。較大的距離,目前的值為極端值的機率愈高。因為基底或一般的亮度一般情況下,而異數位相機會看到,我會套用 z-score 正規化。因此,z 分數轉換可確保正確的亮度,趨近 0 normaliza tion 之後。未經處理的亮度值大約是 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-score 分析的異常值偵測

圖 6 異常值偵測到使用 Z-score 分析

機器學習時間序列分析

我們現在來看看如何使用 Azure 時間數列異常偵測 (ATSAD) 模組,來識別極端值。中所示圖 7,實驗的流量會與上一個相當類似。初始資料集都被正規化使用 z 分數轉換與 trans-ferred ATSAD 模組 (您可以找到它 Machine Learning Studio 中的時間序列節點下)。這需要您提供數種輸入,您使用 [屬性] 視窗來設定 (bit.ly/2xUGTg2)。首先,您指定的日期和時間資料行,然後設定 martingale 型別。在此,我使用電源 martingale。這會啟動另一個文字方塊中,Epsilon,您可以在其中輸入任何介於 0 到 1 來指定的偵測器敏感度的值。然後,您選擇 strangeness 函式,使用其中一個選項:

  • RangePercentile:使用此選項來識別是很清楚的範圍,如果看到爆增情形等 dip 以外的值。好讓它能夠類似地先前的實驗,但更全面的分析,我實驗中使用此選項。
  • SlowPos-以及 SlowNegTrend:使用這些選項來識別您的資料集的正面和負面趨勢變更。當您的方案看起來會增加或減少中觀察到的值時,這非常有用。

利用 Azure 時間數列異常偵測模組實驗

圖 7 實驗利用 Azure 時間數列異常偵測模組

接下來,您可以指定 martingale 和 strangeness 值歷程記錄的長度。您可以選擇任何介於 10 到 1000年之間的整數。試用錯誤試驗的位元之後, 我決定採用下列參數的 [我的偵測器:

  • Epsilon = 0.4
  • 長度 martingale 以及 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 代表對應的 JSON 物件,用戶端和 Web 服務之間傳輸。舉例來說,AnomalyDetectionRequest 類別和相依物件的定義已列在圖 10。請注意,若要接受的機器學習 Studio Web 服務 (的二維陣列的字串) 的輸入轉換亮度資料點的集合,我使用協助程式類別,ConversionHelper。後者,哪一個完整的定義是隨附的程式碼,有兩個公用方法。它們可以將集合轉換亮度資料點的字串 [、] (BrightnessDataToStringTable),或反過來反之亦然 (AnomalyDetectionResponseToBrignthessData)。

圖 10 A 定義 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。第一個欄位儲存機器學習 Studio Web 服務的 URL,而第二個則包含的 API 金鑰。這兩個值可用來具現化 HttpClient 類別 (從已安裝的 NuGet 封裝):

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

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

建立用戶端之後,我可以開始到機器學習 Studio Web 服務傳送要求,以從 AnomalyDetectionClient.DetectAnomalyAsync 方法圖 11。這個方法會接受亮度資料點,表示測試資料的集合。此測試資料會取代我先前用於實驗,並用來具現化 AnomalyDetectionRequest CSV 檔案。稍後張貼至 Web 服務以進行分析 PostAsJsonAsync 擴充方法與這個類別的執行個體。JSON 回應的結果會轉換成 AnomalyDetectionResponse 類別執行個體,最後由 DetectAnomalyAsync 函式。我也尋找有任何錯誤,並最終會視擲回例外狀況。

圖 11 將要求傳送至 Azure Machine Learning 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;
}

AddTestValue AnomalyDetector 類別方法中利用 AnomalyDetectionClient (圖 12)。AddTrain ingValue,像是 AddTestValue 也會叫用 ImageProcessor_ProcessingDone 的事件處理常式 (請參閱 < MainPage.xaml.cs compan ionic 程式碼中)。不過,AddTestValue 會繼續比 AddTrainingValue 方法稍有不同的方式。在 AddTestValue 我加入亮度資料點在內部使用的泛型清單類別實作輪流視窗 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* 軟體工程和 biomedical 研究者、 作者和會議的喇叭。他喜歡的休閒活動學習新技術的軟體進行實驗以及建立原型。*

非常感謝下列 Microsoft 技術專家檢閱這篇文章:Dr。James McCaffrey


MSDN Magazine 論壇中的這篇文章的討論