pycaret 和 H2O 的异常检测结果不同
Posted
技术标签:
【中文标题】pycaret 和 H2O 的异常检测结果不同【英文标题】:Different results on anomaly detection bettween pycaret and H2O 【发布时间】:2021-09-28 08:04:58 【问题描述】:我正在从以下数据中检测异常情况:
它来自液压系统的处理信号,从那里我知道红框中的点是系统发生故障时发生的异常情况。
我在 pycaret 和 H20 中都使用前 3k 条记录来训练模型。这 3k 条记录涵盖了 5 个数据周期,如下图所示:
要在 pycaret 中训练模型,我使用以下代码:
from pycaret.anomaly import *
from pycaret.datasets import get_data
import pandas as pd
exp_ano101 = setup(df[["Pressure_median_mw_2500_ac"]][0:3000], normalize = True,
session_id = 123)
iforest = create_model('iforest')
unseen_predictions = predict_model(iforest, data=df[["Pressure_median_mw_2500_ac"]])
unseen_predictions = unseen_predictions.reset_index()
我从pycaret得到的结果还不错:
通过一些后期处理,我可以得到以下结果,非常接近理想:
另一方面,使用 H20,代码如下:
import pandas as pd
from h2o.estimators import H2OIsolationForestEstimator, H2OGenericEstimator
import tempfile
ifr = H2OIsolationForestEstimator()
ifr.train(x="Pressure_median_mw_2500_ac",training_frame=hf)
th = df["mean_length"][0:3000].quantile(0.05)
df["anomaly"] = df["mean_length"].apply(lambda x: "1" if x> th else "0")
我明白了:
这是一个巨大的差异,因为它没有将此块检测为异常:
我的疑问是,鉴于我使用的是相同的算法,即隔离森林,我如何才能获得与从 pycaret 获得的结果相似的结果。即使在 Pycaret 中使用 SVM,我得到的结果也比在 H2O 中使用隔离森林更接近
【问题讨论】:
这是时间序列数据,还是这些独立样本中的每一个? @JonNordby 它是时间序列,它来自一个周期性的工业过程 可能一些小的参数调整可能会让模型收敛。也只是检查一下,数据是否针对 H20 方法进行了标准化? 【参考方案1】:Pycaret 使用 PyOD 库进行异常检测。然后是 PyOD 与 H2O。也许有不同的默认参数。在 Pycaret (PyOD) 中可以修改参数 fraction - default = 0.05,即数据集中异常值的百分比/比例。
你应该尝试使用这个参数,也许你从两个库中得到相同的结果。
【讨论】:
【参考方案2】:首先,您需要提供每个库的特定版本作为隔离林的实现,因此 PyOD 版本之间的结果可能会有所不同。
除此之外,首先尝试查看在 PyOD 和 H2O 中单独运行隔离林的结果是否始终如一 - 可能更多的是随机数生成器/状态问题,而不是实现差异。
除了验证参数,我建议您查看这些库的代码 - 可能是默认参数值之间的差异:https://pyod.readthedocs.io/en/latest/_modules/pyod/models/iforest.html
【讨论】:
【参考方案3】:TLDR:通过将检测异常的实例更改为循环,而不是来自传感器的单个数据样本,您的问题将大大简化。现有应用方法之间的差异可能是由于超参数的差异,以及由于不太理想的问题规范对超参数的敏感性。
这是一个时间序列,您的异常似乎是有状态的——即异常开始发生,然后影响许多时间步长,然后再次恢复。但是,您似乎正在尝试检测单个时间步长/样本中的异常,这将无法正常工作,因为在异常条件下,最高值仍然在正常条件下单个数据点的正常范围内。此外,在正常情况下,您的数据中存在很强的时间模式,并且无法使用这种方法进行建模。预计不同的软件会给出不同的不太好的结果,因为必须进行权衡,并且不同的超参数会影响这一点。
您应该做的是转换原始时间序列以获得比单个点样本更有意义的实例。对于这种循环之间具有很强相似性的循环过程,最好的方法是转换为每个循环的时间序列。这需要知道(或可靠地检测)循环何时开始。
如果循环开始不可用,则可以使用滑动窗口方法,其中窗口足够长以覆盖一个或多个循环。
一旦有了这样的一组窗口,就可以考虑对其进行异常检测。从计算总结窗口的基本统计数据开始(平均值、标准差、最小值、最大值、最大值-最小值等)。您作为示例显示的异常将可以通过循环的平均值(或最大值或最小值)轻松分离。甚至不需要隔离森林,高斯混合模型就可以了,并允许更多可解释的结果。这应该适用于各种模型和超参数。
一旦有了能够捕捉到如此大差异的基本解决方案,就可以考虑更进一步。例如,如果有足够的数据,添加序列模型自动编码器将能够拾取更小的偏差。
【讨论】:
以上是关于pycaret 和 H2O 的异常检测结果不同的主要内容,如果未能解决你的问题,请参考以下文章