pycaret 和 H2O 异常检测的不同结果
Different results on anomaly detection bettween pycaret and H2O
我正在研究从以下数据中检测异常:
它来自经过处理的液压系统信号,从那里我知道红框中的点是系统出现故障时发生的异常。
我正在使用前 3k 条记录在 pycaret 和 H20 中训练模型。这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得到的结果还不错:
经过一些 post 处理,我可以得到以下结果,这非常接近理想情况:
另一方面,使用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 中使用隔离森林更接近
Pycaret 使用库 PyOD 进行异常检测。然后是 PyOD vs H2O。也许有不同的默认参数。在 Pycaret (PyOD) 中可以修改参数 fraction - default = 0.05,数据集中异常值的百分比/比例。
你应该尝试使用这个参数,也许你从两个库中得到相同的结果。
首先,您需要提供每个库的特定版本作为隔离林的实现,因此结果可能因 PyOD 版本而异。
除此之外,首先尝试查看 PyOD 和 H2O 中单独的 运行 隔离林的结果是否始终相同 - 也许它更多的是随机数生成器/状态问题而不是实现差异。
除了验证参数外,我建议您查看这些库的代码 - 可能是默认参数值之间的差异:https://pyod.readthedocs.io/en/latest/_modules/pyod/models/iforest.html
TLDR:通过将检测异常的实例更改为循环而不是来自传感器的单个数据样本,您的问题将得到极大简化。现有应用方法之间的差异可能是由于超参数的差异,以及由于不太理想的问题规范而对超参数的敏感性。
这是一个时间序列,您的异常似乎是有状态的 - 即异常开始发生,然后影响许多时间步长,然后再次恢复。但是,您似乎试图检测单个时间步长/样本中的异常,这不会很好地工作,因为在异常情况下,最高值仍然在正常情况下单个数据点的正常范围内。此外,对于正常情况,您的数据中存在强烈的时间模式,并且无法使用这种方法对这些模式进行建模。不同的软件给出不同的不太好的结果是预料之中的,因为必须做出权衡,不同的超参数会影响这一点。
你应该做的是转换你的原始时间序列以获得比单个点样本更有意义的实例。对于这种周期之间相似性很强的循环过程,最好的办法就是将每个周期转化为一个时间序列。这需要知道(或可靠地检测)一个周期何时开始。
如果循环开始不可用,可以改为使用滑动 window 方法,其中 window 足够长以涵盖一个或多个循环。
有了这样一套windows,就可以考虑对它做异常检测了。从计算汇总 window(平均值、标准值、最小值、最大值、最大值-最小值等)的基本统计数据开始。您作为示例显示的异常将可以通过周期的平均值(或最大值或最小值)轻松分离。甚至不需要隔离森林,高斯混合模型就可以了,并且可以得到更多可解释的结果。这应该适用于广泛的模型和超参数。
一旦捕获如此大的差异的基本解决方案到位,就可以考虑更进一步。例如,如果有足够的数据,添加一个序列模型自动编码器将能够获得更小的偏差。
我正在研究从以下数据中检测异常:
它来自经过处理的液压系统信号,从那里我知道红框中的点是系统出现故障时发生的异常。
我正在使用前 3k 条记录在 pycaret 和 H20 中训练模型。这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得到的结果还不错:
经过一些 post 处理,我可以得到以下结果,这非常接近理想情况:
另一方面,使用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 中使用隔离森林更接近
Pycaret 使用库 PyOD 进行异常检测。然后是 PyOD vs H2O。也许有不同的默认参数。在 Pycaret (PyOD) 中可以修改参数 fraction - default = 0.05,数据集中异常值的百分比/比例。
你应该尝试使用这个参数,也许你从两个库中得到相同的结果。
首先,您需要提供每个库的特定版本作为隔离林的实现,因此结果可能因 PyOD 版本而异。
除此之外,首先尝试查看 PyOD 和 H2O 中单独的 运行 隔离林的结果是否始终相同 - 也许它更多的是随机数生成器/状态问题而不是实现差异。
除了验证参数外,我建议您查看这些库的代码 - 可能是默认参数值之间的差异:https://pyod.readthedocs.io/en/latest/_modules/pyod/models/iforest.html
TLDR:通过将检测异常的实例更改为循环而不是来自传感器的单个数据样本,您的问题将得到极大简化。现有应用方法之间的差异可能是由于超参数的差异,以及由于不太理想的问题规范而对超参数的敏感性。
这是一个时间序列,您的异常似乎是有状态的 - 即异常开始发生,然后影响许多时间步长,然后再次恢复。但是,您似乎试图检测单个时间步长/样本中的异常,这不会很好地工作,因为在异常情况下,最高值仍然在正常情况下单个数据点的正常范围内。此外,对于正常情况,您的数据中存在强烈的时间模式,并且无法使用这种方法对这些模式进行建模。不同的软件给出不同的不太好的结果是预料之中的,因为必须做出权衡,不同的超参数会影响这一点。
你应该做的是转换你的原始时间序列以获得比单个点样本更有意义的实例。对于这种周期之间相似性很强的循环过程,最好的办法就是将每个周期转化为一个时间序列。这需要知道(或可靠地检测)一个周期何时开始。
如果循环开始不可用,可以改为使用滑动 window 方法,其中 window 足够长以涵盖一个或多个循环。
有了这样一套windows,就可以考虑对它做异常检测了。从计算汇总 window(平均值、标准值、最小值、最大值、最大值-最小值等)的基本统计数据开始。您作为示例显示的异常将可以通过周期的平均值(或最大值或最小值)轻松分离。甚至不需要隔离森林,高斯混合模型就可以了,并且可以得到更多可解释的结果。这应该适用于广泛的模型和超参数。
一旦捕获如此大的差异的基本解决方案到位,就可以考虑更进一步。例如,如果有足够的数据,添加一个序列模型自动编码器将能够获得更小的偏差。