我尝试使用Accord.Net中的OneclassSupportVectorLearning来实现异常检测。在训练过程中遇到了NullReference错误。下面是我的测试代码示例。如果有人能帮我解决这个问题,我将不胜感激。
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错误发生在这里。
编辑——————————————————————–
根据Jstreet的评论,尝试以下代码,但在二维数据上有效,但在更高维度上失败。
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 = { // 正常 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}, // 异常 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(" 异常 = {0}, {1}, {2}, {3}", d[0], d[1], d[2], d[3]);}Console.ReadLine();
}
回答:
我建议你使用二维数据集进行实验,这样你可以可视化结果并更好地理解它:
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 = { // 正常 new double[] { 50, 53 }, new double[] { 49, 52 }, new double[] { 48, 51 }, new double[] { 47, 52 }, new double[] { 46, 53 }, // 异常 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(" 异常 = {0}, {1}", d[0], d[1]); } Console.ReadLine(); }
这个示例代码生成了以下输出:
OK = 50, 53 OK = 49, 52 OK = 48, 51 OK = 47, 52 OK = 46, 53 异常 = 50, 70 异常 = 51, 69 异常 = 52, 68 异常 = 53, 67 异常 = 54, 66
以下是相同结果的图形视图:
编辑: 正如我所说,这需要一些实验。以下是我对四维输入数据集的结果。注意,我减少了每个维度的变化性,并保持了相同的输入大小,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 = { // 正常 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) }, // 异常 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("异常 = {0}, {1}, {2}, {3}", d[0], d[1], d[2], d[3]); } Console.ReadLine(); }
结果如下:
OK = 49, 46, 47, 49OK = 49, 45, 45, 47OK = 45, 45, 46, 47OK = 47, 49, 47, 48OK = 45, 45, 47, 48异常 = 62, 60, 61, 63异常 = 61, 63, 63, 64异常 = 64, 60, 60, 64异常 = 61, 64, 63, 63异常 = 62, 60, 62, 62