我必须识别服务器的不同运行状态。我有与服务器的不同传感器相关的读数(如温度传感器、风扇速度传感器、工作负载传感器等)。我有关于一些操作状态(正常、高温、高温和高风扇速度)等的信息。我应该使用什么 ML 算法来识别是否出现了任何其他操作状态,即训练数据没有看到的状态?
我使用了几种聚类算法。我希望高斯混合模型能够很好地工作,但它们未能表明它出现了新的操作状态。
我使用 LSTM 并查看了残差,但必须查看每个参数的残差以识别差异状态。
我必须识别服务器的不同运行状态。我有与服务器的不同传感器相关的读数(如温度传感器、风扇速度传感器、工作负载传感器等)。我有关于一些操作状态(正常、高温、高温和高风扇速度)等的信息。我应该使用什么 ML 算法来识别是否出现了任何其他操作状态,即训练数据没有看到的状态?
我使用了几种聚类算法。我希望高斯混合模型能够很好地工作,但它们未能表明它出现了新的操作状态。
我使用 LSTM 并查看了残差,但必须查看每个参数的残差以识别差异状态。
一种可能的方法是学习一些训练数据的压缩潜在表示,并检查新数据与该表示的匹配程度。
在实践中,您可以尝试通过最小化其输入(您的原始特征)和其输出(重建)之间的重建误差来在训练数据上训练自动编码器。
训练后,您可以通过检查重建误差是否大于阈值来检查是否出现新的操作状态。这背后的直觉是,如果新数据属于模型从训练数据中学习到的已知或正常操作状态,那么模型将能够正确地对其进行重构,并且误差会很低。
可能有很多方法可以解决您的问题。您想要的解决方案将建立在这两种现有方法之上:(1)异常值检测;(2)罕见事件检测。异常值检测源于您对 GMM 的提及,而罕见事件检测源于您对 LSTM 的提及。
我将专注于异常值检测。您可以将异常值检测本身用作中间步骤。新数据可以说是在检测到的异常值附近。
在众多异常值检测方法中,我将重点关注隔离森林。这也是 scikit-learn 的一部分,因此您应该能够相对轻松地尝试一下。
异常值检测和隔离森林
与其他流行的异常值检测方法不同的主要思想是隔离森林显式识别异常而不是分析正常数据点。与任何树集成方法一样,隔离森林是建立在决策树的基础上的。在这些树中,首先随机选择一个特征,然后在所选特征的最小值和最大值之间选择一个随机分割值来创建分区。
离群值比常规观测值少,并且在值方面与它们不同(它们离特征空间中的常规观测值更远)。这就是为什么通过使用这种随机分区,它们应该被识别为更接近树的根(更短的平均路径长度,即观察必须在树中从根到终端节点的边数),更少必要的分裂。
可以在图 1 中观察到正常与异常数据点的识别。正态分布中的点(左侧)比异常点(右侧)需要识别更多的分区。
使用 Scikit-Learn 的示例
我们将生成具有正态分布的集群数据进行训练。然后我们将数据两种类型的数据点:正态分布点;和异常点。
# importing libaries ----
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pylab import savefig
from sklearn.ensemble import IsolationForest
# Generating data ----
rng = np.random.RandomState(42)
# Generating training data
X_train = 0.2 * rng.randn(1000, 2)
X_train = np.r_[X_train + 3, X_train]
X_train = pd.DataFrame(X_train, columns = ['x1', 'x2'])
# Generating new, 'normal' observation
X_test = 0.2 * rng.randn(200, 2)
X_test = np.r_[X_test + 3, X_test]
X_test = pd.DataFrame(X_test, columns = ['x1', 'x2'])
# Generating outliers
X_outliers = rng.uniform(low=-1, high=5, size=(50, 2))
X_outliers = pd.DataFrame(X_outliers, columns = ['x1', 'x2'])
接下来,让我们使用 scikit-learn 中的 Isolation Forest 来学习和预测正常和异常数据点。
# Isolation Forest ----
# training the model
clf = IsolationForest(max_samples=100, random_state=rng)
clf.fit(X_train)
# predictions
y_pred_train = clf.predict(X_train)
y_pred_test = clf.predict(X_test)
y_pred_outliers = clf.predict(X_outliers)
# new, 'normal' observations ----
print("Accuracy:", list(y_pred_test).count(1)/y_pred_test.shape[0])
# outliers ----
print("Accuracy:", list(y_pred_outliers).count(-1)/y_pred_outliers.shape[0])
用于绘制此处使用的数据点的实用程序代码。# 绘制生成的数据 ---- plt.title("Data") p1 = plt.scatter(X_train.x1, X_train.x2, c='white', s=20 4, edgecolor='k') p2 = plt .scatter(X_test.x1, X_test.x2, c='green', s=20 4, edgecolor='k') p3 = plt.scatter(X_outliers.x1, X_outliers.x2, c='red', s= 20*4, edgecolor='k') plt.axis('tight') plt.xlim((-2, 5)) plt.ylim((-2, 5)) plt.legend([p1, p2, p3 ], ["训练观察", "new regular obs.", "new 异常 obs."], loc="lower right") # 保存图形 plt.savefig('generated_data.png', dpi=300) plt.显示()
生成新的训练数据点(又名数据增强)
现在您已经确定了异常值的纠正;您可以使用随机扰动的统计噪声来生成新的训练数据。我指的是用于数据增强的变分自动编码器
GAN
当然,您以后可能想使用 GAN 进行数据增强。
我已经尝试让您对使用 Isolation Forests 的问题有一个基本的动手体验;但是,如果您有更多时间进行投资,那么 VAE 或 GAN 将是您最有希望的方法。