使用 Spark 进行聚类的异常检测程序

Gui*_*era 1 cluster-analysis data-mining apache-spark

我正在使用 Apache Spark 开展多个项目,并且一直停留在异常/离群值检测部分。

我使用聚类技术来查找异常,其想法是异常/离群值将形成自己的聚类,这意味着被视为异常的数据点实际上是聚类中心。如果与数据量相关的异常值很少,则此方法有效,但如果有很多异常值,则此方法不起作用。到目前为止,这是我的代码:https: //github.com/Guillermo19/MyTest/blob/3511d33f5c7336adef04f2f93a69f1af7865e066/anomalyDetection.java

我确信我的离群点成为聚类中心的想法是正确的,但这取决于生成的聚类数量,并且到目前为止数据本身和聚类数量之间没有任何关系,所以我找不到一个根据可能的异常值的数量来增加聚类的方法。

我可以在程序中修复/修改哪些内容才能使用聚类正确显示异常值?

或者如果我可以使用不同的方法解决这个问题请告诉我。我个人认为聚类是查找异常值最可行、最好的方法之一......

编辑:这是我迄今为止一直在工作的数据,以及预期的异常结果:

第一个文件:

Name    Size    Records
File1   1000    104370
File2   997     103121
File3   1500    109123
File4   2170    113888
File5   2000    111974
File6   1820    110666
File7   1200    106771
File8   1500    108991
File9   1000    104007
File10  1300    107037
File11  1900    111109
File12  1430    108051
File13  1780    110006
File14  2010    114449
File15  2017    114889
File16  800     88812 //possible outlier. My program does indeed show this
File17  1307    107098
File18  1519    109321
File19  1641    110777
File20  1056    104888
Run Code Online (Sandbox Code Playgroud)

第二个文件:

Name    Size    Records
File1   1013    105727
File2   980     104230
File3   1520    110542
File4   2198    115369
File5   2026    113430
File6   1844    112105
File7   1216    108159
File8   1520    110408
File9   1013    105359
File10  1317    108428
File11  1925    112553
File12  1449    109456
File13  1803    111436
File14  2036    115937
File15  2043    116383
File16  1002    105177
File17  1324    108490
File18  1539    110742
File19  1662    112630
File20  1070    106589
Run Code Online (Sandbox Code Playgroud)

//no outliers, and my program does show that

第三个文件:

Name    Size    Records
File1   1100    50 //anomalous
File2   1003    106712
File3   1556    113174
File4   2250    500000 //anomalous
File5   2074    116131
File6   1888    114774
File7   1245    110734
File8   1556    113037
File9   1037    229999 //anomalous
File10  1348    111569
File11  1971    115233
File12  1484    112062
File13  1846    114089
File14  2084    118698
File15  2092    118564
File16  1026    107681
File17  1356    111073
File18  1576    113379
File19  1702    114889
File20  1325    70000 //anomalous
Run Code Online (Sandbox Code Playgroud)

我在第三个文件中的程序仅将 File4 和 File9 识别为异常,并且不显示 File1 和 File20。我确信他们都在一起,这就是为什么他们不会出现。我想避免异常数据被分组在一起,但我不知道该怎么做。

Ano*_*sse 5

人们尝试过 k-means 进行异常检测,但效果不佳。

想象一下您有两个非常相似的异常值。它们将成为一簇。即使不相似,您也经常会在这样的集群中看到多个异常值。

如果您有不同密度的簇,此方法通常不会检测到靠近密集簇的异常值。簇之间也没有异常值。

由于随机种子和选择 k 的问题,该方法很脆弱且难以使用。另外,通常需要选择较大的 k,这样运行时间就会增加很多。

相反,人们主要使用最近邻异常值检测和 LOF(局部异常值因子)。由于您在 JVM 上,请尝试将数据加载到 ELKI 中并尝试其一些异常值检测方法。ELKI的k-means聚类也比Spark快很多,如果我没记错的话,它已经包含了一个用k-means检测异常值进行比较的方法。