2017-03-03 41 views
1

我試圖通過在Accord.Net中使用OneclassSupportVectorLearning實現異常檢測。我在訓練過程中遇到了NullReference錯誤。以下是我在測試中的示例代碼。 欣賞有人能幫助我解決這個問題。In Accord.Net如何使用One-Class SVM進行異常檢測?

double[][] inputs = 
{ 
    new double[] { 0, 1, 1, 0 }, // 0 
    new double[] { 0, 1, 0, 0 }, // 0 
    new double[] { 0, 0, 1, 0 }, // 0 
    new double[] { 0, 1, 1, 0 }, // 0 
    new double[] { 0, 1, 0, 0 }, // 0 
}; 
var oteacher = new OneclassSupportVectorLearning<ChiSquare,double[]>(); 
var k = oteacher.Learn(inputs); //NullReference error occur here. 

編輯------------------------------------------ ---------------------------

基於Jstreet的評論,嘗試下面的代碼,但它在2-dim上工作,但在更高的失敗尺寸。

static void Main(string[] args) 
{ 
Random r = new Random(DateTime.Now.Millisecond); 

int size = 1000; 
int min = 45; 
int max = 55; 

double[][] inputs = new double[size][]; 

for (int i = 0; i < size; i++) 
{ 
    double[] d = new double[] { r.Next(min,max), r.Next(min,max), r.Next(min,max), r.Next(min,max) }; 
    inputs[i] = d; 
} 

var oteacher = new OneclassSupportVectorLearning<ChiSquare>(); 
var k = oteacher.Learn(inputs); 

double[][] test = 
{ 
    // normal 
    new double[] { 50, 53 , 50, 50}, 
    new double[] { 49, 52 , 50, 50}, 
    new double[] { 48, 51 , 50, 50}, 
    new double[] { 47, 52 , 50, 50}, 
    new double[] { 46, 53 , 50, 50}, 
    // anomalies 
    new double[] { 50, 70, 70, 70 }, 
    new double[] { 51, 69, 70, 70 }, 
    new double[] { 52, 68, 70, 70 }, 
    new double[] { 53, 67, 70, 70 }, 
    new double[] { 54, 66, 70, 70 }, 
}; 

foreach (double[] d in test) 
{ 
    if (k.Decide(d) == true) 
     Console.WriteLine(" OK = {0}, {1}, {2}, {3}", d[0], d[1], d[2], d[3]); 
    else Console.WriteLine(" Anomaly = {0}, {1}, {2}, {3}", d[0], d[1], d[2], d[3]); 
} 

Console.ReadLine(); 

}

+0

更新到版本3.4.2 **-α**。 – jsanalytics

+0

謝謝jstress!我嘗試最新的預版本,現在它可以運行。當它完成學習時,我通過傳回訓練集來運行「k.Decide(輸入)」方法。但是對於整個訓練集來說它只是返回所有「假」(它假設全部是「真」)。我在這裏檢查了代碼,根據在線文檔它應該是有效的。感謝您能分享我更多關於此的提示。 – alinm

回答

0

我建議你用一個2維數據集可讓您看到的結果,並得到一點感覺實驗:

static void Main(string[] args) 
    { 
     Random r = new Random(DateTime.Now.Millisecond); 

     int size = 100; 
     int min = 45; 
     int max = 55; 

     double[][] inputs = new double[size][]; 

     for (int i = 0; i < size; i++) 
     { 
      double[] d = new double[] { r.Next(min,max), r.Next(min,max) }; 
      inputs[i] = d; 
     } 

     var oteacher = new OneclassSupportVectorLearning<ChiSquare>(); 
     var k = oteacher.Learn(inputs); 

     double[][] test = 
     { 
      // normal 
      new double[] { 50, 53 }, 
      new double[] { 49, 52 }, 
      new double[] { 48, 51 }, 
      new double[] { 47, 52 }, 
      new double[] { 46, 53 }, 
      // anomalies 
      new double[] { 50, 70 }, 
      new double[] { 51, 69 }, 
      new double[] { 52, 68 }, 
      new double[] { 53, 67 }, 
      new double[] { 54, 66 }, 
     }; 

     foreach (double[] d in test) 
     { 
      if (k.Decide(d) == true) 
       Console.WriteLine(" OK = {0}, {1}", d[0], d[1]); 
      else Console.WriteLine(" Anomaly = {0}, {1}", d[0], d[1]); 
     } 

     Console.ReadLine(); 
    } 

此示例代碼生成以下輸出:

OK = 50, 53 
OK = 49, 52 
OK = 48, 51 
OK = 47, 52 
OK = 46, 53 
Anomaly = 50, 70 
Anomaly = 51, 69 
Anomaly = 52, 68 
Anomaly = 53, 67 
Anomaly = 54, 66 

這是相同結果的圖形視圖:

enter image description here


編輯:就像我說的,它需要一些試驗。這是我對四維輸入數據集的結果。注意,我降低每個維度如何變量,並保持相同的輸入尺寸,100

static void Main(string[] args) 
    { 
     Random r = new Random(DateTime.Now.Millisecond); 

     int size = 100; 
     int min = 45; 
     int max = 50; 
     int min2 = 60; 
     int max2 = 65; 

     double[][] inputs = new double[size][]; 

     for (int i = 0; i < size; i++) 
     { 
      double[] d = new double[] { r.Next(min, max), r.Next(min, max), r.Next(min, max), r.Next(min, max) }; 
      inputs[i] = d; 
     } 

     var oteacher = new OneclassSupportVectorLearning<ChiSquare>(); 
     var k = oteacher.Learn(inputs); 

     double[][] test = 
     { 
      // normal 
      new double[] { r.Next(min, max), r.Next(min, max), r.Next(min, max), r.Next(min, max) }, 
      new double[] { r.Next(min, max), r.Next(min, max), r.Next(min, max), r.Next(min, max) }, 
      new double[] { r.Next(min, max), r.Next(min, max), r.Next(min, max), r.Next(min, max) }, 
      new double[] { r.Next(min, max), r.Next(min, max), r.Next(min, max), r.Next(min, max) }, 
      new double[] { r.Next(min, max), r.Next(min, max), r.Next(min, max), r.Next(min, max) }, 
      // anomalies 
      new double[] { r.Next(min2, max2), r.Next(min2, max2), r.Next(min2, max2), r.Next(min2, max2) }, 
      new double[] { r.Next(min2, max2), r.Next(min2, max2), r.Next(min2, max2), r.Next(min2, max2) }, 
      new double[] { r.Next(min2, max2), r.Next(min2, max2), r.Next(min2, max2), r.Next(min2, max2) }, 
      new double[] { r.Next(min2, max2), r.Next(min2, max2), r.Next(min2, max2), r.Next(min2, max2) }, 
      new double[] { r.Next(min2, max2), r.Next(min2, max2), r.Next(min2, max2), r.Next(min2, max2) }, 
     }; 

     foreach (double[] d in test) 
     { 
      if (k.Decide(d) == true) 
       Console.WriteLine("OK = {0}, {1}, {2}, {3}", d[0], d[1], d[2], d[3]); 
      else Console.WriteLine("Anomaly = {0}, {1}, {2}, {3}", d[0], d[1], d[2], d[3]); 
     } 

     Console.ReadLine(); 
    } 

而結果:

OK = 49, 46, 47, 49 
OK = 49, 45, 45, 47 
OK = 45, 45, 46, 47 
OK = 47, 49, 47, 48 
OK = 45, 45, 47, 48 
Anomaly = 62, 60, 61, 63 
Anomaly = 61, 63, 63, 64 
Anomaly = 64, 60, 60, 64 
Anomaly = 61, 64, 63, 63 
Anomaly = 62, 60, 62, 62 
+0

再次感謝Jstreet。但是當我嘗試增加數據維度時,它似乎無法正確預測真/假。 – alinm

+0

嘗試在輸入中增加點數(**大小**)。 – jsanalytics

+0

已經嘗試了5000個輸入樣本,但它仍然給出了所有錯誤,通過下面的示例代碼我發佈。可能是OneclassSupportVectorLearning還不成熟嗎? – alinm