27、数据分析部署与异常检测实践

数据分析部署与异常检测实践

1. 数据分析部署类型

1.1 交互式分析

交互式分析结合了查询、用户界面和分析核心。目前没有最佳的实现方法或技术,建议将分析核心放在共享库中,使用通用框架(如 Power BI)或基于 Python 的库(如 Dash、Streamlit、Bokeh)开发用户界面,也可使用更高级的工具(如 Jupyter)。

1.2 云分析

云分析具有部署和管理容易、可快速扩展、能处理大量数据等优点,但也存在不能处理高频数据(每小时超过 100 GB 且采样间隔小于 1 毫秒)和网络延迟问题,在这些特殊情况下,建议在边缘运行。

1.3 边缘分析

边缘分析是物联网中较新的分析类型,也是工业领域较老的分析类型。有三种情况适合部署边缘分析:
- 有高采样数据,如涡轮机的振动。
- 有数据发送到区域外的政策限制。
- 需要低延迟。

1.4 控制器分析

在工业领域,基于云或边缘的分析很少被允许在控制器上执行操作,更倾向于使用在控制器上优化的分析来执行可能影响生产的操作,因为涉及安全和鲁棒性问题,且相关操作在物联网革命前就已存在,有广泛测试的技术。

1.5 实时操作系统(RTOS)

通常分析在实时操作系统(RTOS)上运行,与云的高延迟不同。AWS、OEM 的云以及 Google 正在开发与边缘设备紧密配合的 RTOS,如 AWS Greengrass 和 FreeRTOS。

1.6 高级分析

AI 的发展对计算能力提出了更高要求,NVIDIA 和 Apple 分别开发了图形处理单元(GPU)和神经处理单元(NPU),AWS、Azure 和 GCP 在云端支持这些新处理器,目前 NVIDIA 的 CUDA 驱动和 HFX GPU 在该领域处于领先地位。

1.7 开放系统架构(OSA)

开放系统架构(OSA)将之前讨论的概念总结在一张图中。以 CBM 为例,其 OSA 由数据采集、信号处理、状态监测、健康评估、预测和决策支持六层组成,这些步骤可在基于云的架构和部分本地环境中实现。信号处理和状态监测可使用流分析或基于规则的引擎,健康评估和预测阶段需要基于机器学习或物理模型的高级分析,最后一步可以是按需分析或大数据查询。

graph LR
    A[数据采集] --> B[信号处理]
    B --> C[状态监测]
    C --> D[健康评估]
    D --> E[预测]
    E --> F[决策支持]

2. 异常检测实践

2.1 问题陈述与数据集

使用免费的预测性维护数据集,可从官方仓库(https://ti.arc.nasa.gov/opensource/projects/)下载。数据为 CSV 格式,包含日期时间、旋转、电压、机器压力和预期异常(1 表示异常,0 表示正常)四个列。目标是计算时间序列中的异常,以了解标准操作期间可能出现的潜在问题。

2.2 环境准备

  1. 从命令控制台启动 Jupyter Notebook。
  2. 从官方仓库下载数据集到当前文件夹。
  3. 打开浏览器访问 http://localhost:8888/,启动新的 Python 笔记本。
  4. 打开新单元格,安装所需包:
%pip install pandas numpy matplotlib scikit-learn catboost
  1. 导入数据集:
import pandas as pd
df = pd.read_csv('data_PdM_errors.csv')
df['datetime'] = pd.to_datetime(df['datetime'])

2.3 探索性数据分析(EDA)

  1. 显示数据:
import matplotlib.pyplot as plt
# showing dataset
df.plot(x='datetime', kind='line', subplots=True)
plt.show()
  1. 分析标准差:
# analysis of variance
df_std = df.std()
print(df_std)
  1. 移除无用变量:
#removing un-usefull vars
df=df.drop(['vibration'], axis=1)
  1. 分析传感器之间的相关性:
from seaborn import heatmap
heatmap(df.corr(),annot=True,cmap='Blues', fmt='.2f')
  1. 拆分数据集:
# separate into input and output variables
X = df[['volt', 'rotate', 'pressure']].values
y = df[['anomaly']].values
idx_split=6500
X_train, y_train = X[0:idx_split,:], y[0:idx_split]
X_test, y_test = X[idx_split:,:], y[idx_split:]

2.4 构建模型(基于移动平均滤波器的无监督方法)

import numpy as np
def moving_average(data, window_size):
    window = np.ones(int(window_size))/float(window_size)
    return np.convolve(data, window, 'same')
def search_anomalies(x, window_size, sigma=1.0):
    avg = moving_average(x, window_size).tolist()
    residual = x - avg
    # Calculate the variation in the distribution of the residual
    std = np.std(residual)
    anomalies=[]
    i=int(window_size)
    for y_i, avg_i in zip(x, avg):
        if (y_i > avg_i + (sigma*std)) | (y_i < avg_i - (sigma*std)):
            anomalies.append(1)
        else:
            anomalies.append(0)
    return np.array(anomalies)
volt = df['volt'].values
pressure = df['pressure'].values
anomalies_volt = search_anomalies(volt, window_size=60, sigma=2)
anomalies_pressure = search_anomalies(pressure, window_size=60, sigma=2)

2.5 显示异常样本

from sklearn.metrics import confusion_matrix, accuracy_score
import matplotlib.pyplot as plt
def show_anomalies(X_test, y_test, y_predicted, anomalous=1, title=''):
    t = np.array([i for i in range(len(y_test))])
    idx_predicted = y_predicted==anomalous
    idx_real = y_test==anomalous
    plt.figure(figsize=(10,5))
    plt.xlabel('samples')
    plt.ylabel(title)
    plt.plot(t,X_test,'tab:gray')
    plt.plot(t[idx_predicted], X_test[idx_predicted],'rD', label="predicted anomaly")
    plt.plot(t[idx_real],X_test[idx_real],'gX', label="real anomaly")
    plt.legend()
    plt.show()
    print('accuracy:',accuracy_score(idx_real,idx_predicted))
    print('confusion matrix:\n',confusion_matrix(idx_real,idx_predicted))
show_anomalies(volt[idx_split:], y[idx_split:], anomalies_volt[idx_split:], title='volt (V)')
模型预测非异常样本 模型预测异常样本
实际非异常样本 461 34(假阳性)
实际异常样本 3(假阴性) 2

该算法虽然准确率较高(92.6%),但存在大量假阳性和三个假阴性。假阴性可能会造成严重损害,因此异常检测算法应更关注不遗漏异常。后续将尝试使用更复杂的无监督机器学习模型。

2.6 打包和部署

开发单元测试和回归测试来检查分析的质量,以下是一个简单的单元测试:

import numpy as np
def test_search_anomalies():
    data=np.array([10, 10, 10, 10, 30, 20, 10, 10])
    predicted=search_anomalies(data, 2)
    assert predicted[1]==0
    assert predicted[4]==1
    assert predicted[5]==1

部署到云端时,可使用流基础设施将算法直接部署到数据流上。

2.7 监控

建议每季度审查算法的性能,使用新获取的数据集计算假阳性和假阴性。

3. 更复杂的异常检测方法

3.1 使用 ARIMA 和单类支持向量机构建模型

在之前基于移动平均滤波器的异常检测算法中,存在缺乏数据集信息的问题,不知道飞机的正常运行状态。因此,可使用无监督机器学习算法来改进。单类支持向量机(OCSVM)是一种不错的选择,它将数据点分为好或坏两类,需要训练数据集来构建边界。同时,为了去除数据集中的趋势或季节性,可构建自回归积分滑动平均(ARIMA)模型并分析残差。

以下是提取残差并应用 OCSVM 的代码:

from statsmodels.tsa.arima.model import ARIMA
from matplotlib import pyplot
import numpy as np
from sklearn.svm import OneClassSVM
import pandas as pd

def ARIMA_residuals(series):
    # fit model
    model = ARIMA(series, order=(5,1,3))
    model_fit = model.fit()
    print(model_fit.summary())
    # plot residual errors
    residuals = pd.DataFrame(model_fit.resid)
    return residuals.T

def search_anomalies_OCSVM(X_train, X_test):
    clf = OneClassSVM(kernel="rbf", tol=0.0001, nu=0.1).fit(X_train)
    y_pred = clf.predict(X_test)
    anomalies=[ 0 if _x > 0 else 1 for _x in y_pred]
    return np.array(anomalies)

X_residual=np.vstack(( ARIMA_residuals(volt),
                      ARIMA_residuals(rotate),
                      ARIMA_residuals(pressure))).T
anomalies=search_anomalies_OCSVM(X_residual, X_residual)

使用该方法后,检测到的异常数量从两个增加到三个,准确率达到 90%。对应的混淆矩阵如下:
| | 模型预测非异常样本 | 模型预测异常样本 |
| — | — | — |
| 实际非异常样本 | 450 | 45(假阳性) |
| 实际异常样本 | 2(假阴性) | 3 |

3.2 使用隔离森林构建模型

隔离森林是一种基于树的更强大的算法。构建基于隔离森林的异常检测模型,首先需要在训练集上训练模型,然后在测试集上进行预测。

from sklearn.ensemble import IsolationForest
import numpy as np

# 训练模型
clf = IsolationForest(contamination=float(0.05))
clf.fit(X_train)

# 预测结果
anomalies = clf.predict(X_test)
anomalies = np.array([1 if _x < 0 else 0 for _x in anomalies])

此方法获得了 96% 的准确率,检测到四个异常(实际有五个)。混淆矩阵如下:
| | 模型预测非异常样本 | 模型预测异常样本 |
| — | — | — |
| 实际非异常样本 | 481 | 14(假阳性) |
| 实际异常样本 | 1(假阴性) | 4 |

最后,显示检测到的异常:

show_anomalies(X_test[:,0], y_test, anomalies)

3.3 超参数调优的考虑

在上述练习中,使用了机器学习模型的默认参数。通常,会从训练集中保留一个小的子集来调整模型的超参数。

4. 有监督机器学习的异常检测

4.1 问题陈述与数据集

使用包含多个异常的数据集,输入变量包括产品 ID、类型、空气温度 [K]、转速 [rpm] 和刀具磨损 [min] 等;输出变量是需要预测的五种异常,分别编码在五列中,从 0(非异常)到 1(异常),包括刀具磨损故障(TWF)、散热故障(HDF)、电源故障(PWF)、过度应变故障(OSF)和随机故障(RNF)。

数据集可通过以下代码加载:

import pandas as pd
df = pd.read_csv('ai4i2020.csv')

定义输入变量(X)和输出变量(y):

cat_features=['Product ID', 'Type']
X_features= cat_features + ['Air temperature [K]',
                          'Process temperature [K]', 'Rotational speed [rpm]', 'Torque [Nm]',
                          'Tool wear [min]']
y_features=[ 'TWF', 'HDF', 'PWF', 'OSF', 'RNF']
X=df[X_features]
y=df[y_features]

4.2 探索性数据分析(EDA)

在构建模型之前,需要了解目标变量。可通过以下代码查看目标变量的分布:

y.value_counts()

输出结果显示大部分数据是非异常的,异常占比约 3.4%。将数据集分为训练集(80%)和测试集(20%):

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

4.3 构建模型

针对每种异常类型构建模型,以 HDF 异常为例:

from catboost import CatBoostClassifier
from sklearn import metrics
import numpy as np

# set the current type of anomaly
on="HDF"
_y_train = y_train[on].values.flatten()
clf = CatBoostClassifier(
    iterations=300,
    loss_function='Logloss',
    cat_features=cat_features,
    auto_class_weights='Balanced').fit(X_train, _y_train)

# 评估模型
_y_val = y_test[on].values.flatten()
y_pred = clf.predict(X_test)
print(metrics.accuracy_score(_y_val, y_pred))
print(metrics.balanced_accuracy_score(_y_val, y_pred))
print(metrics.confusion_matrix(_y_val, y_pred))

输出结果如下:

0.995
0.9974
[[1968  10]
 [  0  22]]

该模型成功检测到所有 22 个异常,捕获了 10 个假异常,标准和平衡准确率约为 99%。

重复上述步骤,对其他四种异常类型(TWF、PWF、OSF、RNF)进行分析,除 RNF 异常外,其他结果大致相似。这表明当异常已知时,有监督方法是最佳选择;当异常罕见或未知时,应采用无监督方法。

4.4 指标选择

在分类算法中,准确率可能是一个不充分的指标,尤其是在数据严重不平衡的情况下。这里使用了平衡准确率,它是两类准确率的平均值。此外,还有更合适的指标,如精确率、召回率和 AUC 等。

4.5 解释异常

检测到异常后,可使用 CatBoost 的功能研究导致这些异常的最重要因素。以下代码可突出异常的主要贡献因素:

feature_importance = clf.feature_importances_
sorted_idx = np.argsort(-1*feature_importance)
for col,imp in zip(X_train.columns[sorted_idx], feature_importance[sorted_idx]):
    print(f"{col} is {int(imp)}% important on {on}")

综上所述,不同的异常检测方法适用于不同的场景。无监督方法适用于对异常情况了解较少的情况,而有监督方法在有足够的已分类异常样本时更为有效。在实际应用中,需要根据具体情况选择合适的方法,并对模型进行适当的评估和调优。

graph LR
    A[选择异常检测方法] --> B{异常是否已知}
    B -- 是 --> C[有监督机器学习方法]
    B -- 否 --> D[无监督机器学习方法]
    C --> E[数据准备]
    D --> E
    E --> F[模型构建]
    F --> G[模型评估]
    G --> H{是否满足需求}
    H -- 是 --> I[部署与监控]
    H -- 否 --> J[调整参数或更换方法]
    J --> F
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值