在工业中将人工智能用于各种系统的
预测性维护在国外越来越受欢迎。 该方法的目的是在操作阶段确定系统运行中的故障,直到系统出现故障为止,以便及时做出响应。
这种方法在我国和西方有多重要? 例如,可以在有关《哈布雷》和《媒介》的文章中得出结论。 在Habré上几乎没有关于解决预测性维护问题的文章。 在Medium上有一整套。 在这里,
这里和
这里都很好地描述了这种方法的目标和优势。
通过本文,您将学到:
- 为什么需要这种技术
- 哪种机器学习方法更常用于预测性维护,
- 我如何通过一个简单的例子尝试其中的一些技巧。
来源预测服务提供哪些功能?
- 控制修理工作的过程,必要时进行,从而节省了金钱,而且不着急,从而改善了这些工作的质量
- 识别设备运行中的特定故障(在设备运行时购买特定零件进行更换的能力提供了巨大的优势);
- 优化设备操作,负荷等;
- 减少定期关闭设备的成本。
下一篇有关Medium的文章很好地描述了需要理解的问题,以了解如何在特定情况下解决此问题。
在收集数据或选择数据以构建模型时,重要的是要回答三组问题:
- 是否可以预测所有系统问题? 哪个预测特别重要?
- 什么是失败过程? 整个系统会停止工作还是仅更改工作模式? 它是一个快速的过程,是瞬时的还是逐渐的退化?
- 系统性能是否足以反映其性能? 它们与系统的各个部分或整个系统有关吗?
事先了解您要预测的内容,可以预测的内容和不能预测的内容也很重要。
关于Medium的文章还列出了有助于确定您的特定目标的问题:
- 需要预测什么? 剩余寿命,是否有异常行为,在接下来的N小时/天/周内发生故障的概率是多少?
- 是否有足够的历史数据?
- 是否知道系统何时给出异常读数,何时不给出。 是否可以标记此类指示?
- 模型应该看多远? 读数在一小时/天/周的间隔中反映系统运行的独立性如何
- 您需要优化什么? 该模型应该在发出错误警报的同时捕获尽可能多的违规,还是足以捕获无误报的多个事件。
希望将来情况会有所改善。 迄今为止,在预测性维护领域中存在困难:很少有系统故障或系统故障时刻的例子,但它们没有被标记; 故障过程是未知的。
解决预测维护困难的主要途径是使用
异常搜索方法 。 这样的算法不需要标记来进行训练。 对于测试和调试算法,必须以一种或另一种形式进行标记。 这种方法的局限性在于它们不能预测特定的故障,而只能指示指示器的异常。
但这已经不错。
来源方法
现在,我想谈谈异常检测方法的一些功能,然后我们将一起在实践中测试一些简单算法的功能。
尽管在特定情况下将需要测试几种算法以查找异常并选择最佳算法,但是有可能确定该领域中使用的主要技术的一些优点和缺点。
首先,重要的是要事先了解数据中异常的百分比。
如果我们谈论的是半监督方法的一种变体(我们仅研究“正常”数据,然后进行工作(测试),然后研究异常数据),那么最佳选择就是
一类支持向量方法( One-Class SVM ) 。 当使用径向基函数作为内核时,此算法在原点周围构造一个非线性曲面。 训练数据越干净,效果越好。
在其他情况下,仍然需要知道异常点与“正常”点的比率-确定截止阈值。
如果数据中异常的数量超过5%,并且可以与主样本很好地分离,则可以使用标准的异常搜索方法。
在这种情况下,就质量而言,
隔离林方法是最稳定的:
隔离林是随机数据。 更具特征性的指示更有可能更深入,而不寻常的指示则将在第一次迭代中与其余样本分离。
如果其他算法“适合”数据的具体情况,则效果更好。
当数据具有正态分布时,
椭圆包络法是合适的,以多维正态分布近似数据。 该点属于分布的可能性越小,则该点异常的可能性就越大。
如果以这样的方式显示数据:不同点的相对位置很好地反映了它们的差异,那么度量方法似乎是一个不错的选择:例如,
k个最近的邻居,第k个最近的邻居,ABOD(基于角度的离群值检测)或LOF(局部离群值因子) )所有这些方法表明,“正确”的指标集中在多维空间的一个区域。 如果在第k个(或第k个)最近的邻居中,所有事物都离目标较远,则该点就是一个异常。 对于ABOD,其推理类似:如果相对于所考虑的k个点,所有k个最近的点都在相同的空间扇区中,则该点是异常的。 对于LOF:如果局部密度(对于每个点,由k个最近的邻居确定)低于k个最近的邻居,则该点是异常的。
如果数据聚类良好,则
基于聚类分析的方法是一个不错的选择。 如果该点与几个群集的中心等距,则为异常。
如果在数据中很好地区分了最大方差变化的方向,那么
基于主成分法搜索异常似乎是一个不错的选择。 在这种情况下,将n1(最“主要”分量)和n2(最不“主要”分量)的平均值偏差视为异常度量。
例如,建议查看
The Prognostics and Health Management Society(PHM Society)的数据集。 这个非营利组织每年都会安排比赛。 例如,在2018年,
需要预测操作错误以及离子束蚀刻厂发生故障之前的时间 。 我们将采用
2015年的
数据集 。 它包含用于30个安装的多个传感器的读数(培训样本),并且需要预测何时以及将发生什么错误。
我没有在网络上找到测试样本的答案,因此我们只会训练一个。
通常,所有设置都是相似的,但在组件数量,异常数量等方面有所不同。 因此,在前20个学习,而在其他20个测试则没有太大意义。
因此,我们将选择一种安装方式,将其加载并查看这些数据。 本文将不涉及
功能工程 ,因此我们不会过多关注。
import pandas as pd import matplotlib.pyplot as plt %matplotlib inline import seaborn as sns from sklearn.covariance import EllipticEnvelope from sklearn.neighbors import LocalOutlierFactor from sklearn.ensemble import IsolationForest from sklearn.svm import OneClassSVM dfa=pd.read_csv('plant_12a.csv',names=['Component number','Time','S1','S2','S3','S4','S1ref','S2ref','S3ref','S4ref']) dfa.head(10)
如您所见,有七个组件,每个组件每15分钟读取四个传感器的读数。 比赛说明中的S1ref-S4ref作为参考值列出,但这些值与传感器的读数有很大不同。 为了不浪费时间思考它们的含义,我们将其删除。 如果查看每个要素(S1-S4)的值分布,结果发现S1,S2和S4的分布是连续的,而S3的分布是离散的。 此外,如果查看S2和S4的联合分布,结果发现它们成反比。
尽管偏离直接依赖关系可能表明存在错误,但我们将不检查此错误,而只是删除S4。
我们再次处理数据集。 离开S1,S2和S3。 我们使用StandardScaler缩放S1和S2(减去平均值并除以标准差),将S3转换为OHE(一次热编码)。 我们将所有安装组件的读数缝在一起。 共有89个功能。 2 * 7 = 14-7个组件的读数S1和S2和R3的75个唯一值。 只有5.6万条这样的线路。
上载有错误的文件。
dfc=pd.read_csv('plant_12c.csv',names=['Start Time', 'End Time','Type']) dfc.head()
在我们的数据集上尝试这些算法之前,我将允许自己再做一个小小的题外话。 您需要测试。 为此,建议采用错误的开始时间和结束时间。 并且在此间隔内的所有指示均被视为异常,而在外部-正常。 这种方法有许多缺点。 但是尤其是一种错误行为很可能发生在错误修复之前。 为了保真,让我们在半小时前及时转移异常窗口。 我们将评估F1量度,精度和召回率。
用于区分功能和确定模型质量的代码:
def load_and_preprocess(plant_num):
PHM 2015 Data Challenge数据集上简单异常搜索算法的测试结果回到算法。 让我们在数据上尝试一个Class SVM(OCSVM),IsolationForest(IF),EllipticEnvelope(EE)和LocalOutlierFactor(LOF)。 首先,我们将不设置任何参数。 我注意到LOF可以在两种模式下工作。 如果novellity = False只能在训练集中搜索异常(只有fit_predict),如果为True,则其目的是在训练集中搜索异常(可以单独拟合和预测)。 IF具有旧的和新的行为模式。 我们使用新的。 他给出了更好的结果。
OCSVM可以很好地检测到异常,但是假阳性过多。 对于其他方法,结果甚至更糟。
但是假设我们知道数据中异常的百分比。 在我们的案例中,为27%。 OCSVM具有nu-误差百分比的上限估计值,而支持向量的百分比下限值。 其他污染方法具有一定百分比的数据错误。 在IF和LOF方法中,它是自动确定的,而对于OCSVM和EE,默认情况下将其设置为0.1。 让我们尝试将污染(nu)设置为0.27。 现在是EE的最佳结果。
用于检查模型的代码:
def check_model(model,df_train,df_test,filt='S[123]'): model_type,model = model model.fit(df_train.drop('Time',axis=1).filter(regex=(filt))) y_preds = pd.Series(model.predict(df_test.drop(['Time','Label'],axis=1).filter(regex=(filt)))).map({-1:1,1:0}) print('F1 score for {}: {:.3f}'.format(model_type,f1_score(df_test['Label'],y_preds))) print('Precision score for {}: {:.3f}'.format(model_type,precision_score(df_test['Label'],y_preds))) print('Recall score for {}: {:.3f}'.format(model_type,recall_score(df_test['Label'],y_preds))) score = model.decision_function(df_test.drop(['Time','Label'],axis=1).filter(regex=(filt))) sns.distplot(score[df_test['Label']==0]) sns.distplot(score[df_test['Label']==1]) plt.title('Decision score distribution for {}'.format(model_type)) plt.show()
查看不同方法的异常指标的分布很有趣。 可以看出,LOF不适用于此数据。 EE指出该算法认为异常异常。 但是,正常点在那里。 IsoFor和OCSVM表明,选择截止阈值(污染度/ nu)很重要,这将改变准确性和完整性之间的权衡。
传感器的读数接近正态分布,接近固定值,这是合乎逻辑的。 如果我们确实有一个标记过的测试样品,最好还有一个经过验证的样品,那么可以对污染值进行着色。 下一个问题是,哪些错误的指向更准确:误报还是误报?
LOF结果非常低。 不太令人印象深刻。 但是请记住,OHE变量与StandardScaler转换的变量一起进入输入。 并且默认距离是欧几里得。 但是,如果仅根据S1和S2计算变量,则可以纠正这种情况,并且结果可以与其他方法进行比较。 但是,重要的是要了解列出的度量标准分类器的关键参数之一是邻居数。 它会严重影响质量,必须对其进行调整。 距离度量本身也很不错。
现在尝试结合两个模型。 一开始,我们从训练集中删除异常。 然后,我们将在“更干净”的训练集上训练OCSVM。 根据以前的结果,我们观察到了EE的最大完整性。 我们通过EE清除训练样本,对其进行训练OCSVM,得到F1 = 0.50,准确度= 0.34,完整性= 0.95。 不令人印象深刻。 但是我们只是要求nu = 0.27。 我们拥有的数据或多或少是“干净的”。 假设训练样本与EE具有相同的完整性,那么将保留5%的错误。 我们将自己设置为nu,得到F1 = 0.69,准确度= 0.59,完整性= 0.82。 太好了 重要的是要注意,在其他方法中,这样的组合将不起作用,因为它们暗示训练集中的异常数和测试数相同。 当在纯训练数据集上训练这些方法时,您将必须指定比真实数据少的污染,并且不接近零,但是最好选择它进行交叉验证。
查看指示序列上的搜索结果很有趣:
该图显示了7个组件的第一传感器和第二传感器的读数的一部分。 在图例中,相应错误的颜色(开始和结束由相同颜色的垂直线显示)。 点表示预测:绿色-真实预测,红色-假阳性,紫色-假阴性。 从图中可以看出,很难从视觉上确定错误时间,并且该算法很好地解决了这一任务。 尽管很重要的一点是,此处没有给出第三个传感器的读数。 此外,错误结束后还会出现假阳性读数。 即 该算法发现还有错误值,因此我们将该区域标记为无错误。 图的右侧显示了错误之前的区域,我们将其标记为错误的区域(错误发生前半小时),该区域被认为是无错误的,从而导致了假阴性模型错误。 在图的中心,识别出一个连贯的部分,被认为是一个错误。 结论可以得出如下:在解决搜索异常的问题时,您需要与了解需要预测其输出的系统本质的工程师紧密互动,因为检查标记上使用的算法并不能完全反映现实情况,并且无法模拟此类算法可以满足的条件。被使用。
绘制图表的代码:
def plot_time_course(df_test,dfc,y_preds,start,end,vert_shift=4): plt.figure(figsize=(15,10)) cols=df_train.filter(regex=('S[12]')).columns add=0 preds_idx=y_preds.iloc[start:end][y_preds[0]==1].index true_idx=df_test.iloc[start:end,:][df_test['Label']==1].index tp_idx=set(true_idx.values).intersection(set(preds_idx.values)) fn_idx=set(true_idx.values).difference(set(preds_idx.values)) fp_idx=set(preds_idx.values).difference(set(true_idx.values)) xtime=df_test['Time'].iloc[start:end] for col in cols: plt.plot(xtime,df_test[col].iloc[start:end]+add) plt.scatter(xtime.loc[tp_idx].values,df_test.loc[tp_idx,col]+add,color='green') plt.scatter(xtime.loc[fn_idx].values,df_test.loc[fn_idx,col]+add,color='violet') plt.scatter(xtime.loc[fp_idx].values,df_test.loc[fp_idx,col]+add,color='red') add+=vert_shift failures=dfc[(dfc['Start Time']>xtime.iloc[0])&(dfc['Start Time']<xtime.iloc[-1])] unique_fails=np.sort(failures['Type'].unique()) colors=np.array([np.random.rand(3) for fail in unique_fails]) for fail_idx in failures.index: c=colors[np.where(unique_fails==failures.loc[fail_idx,'Type'])[0]][0] plt.axvline(failures.loc[fail_idx,'Start Time'],color=c) plt.axvline(failures.loc[fail_idx,'End Time'],color=c) leg=plt.legend(unique_fails) for i in range(len(unique_fails)): leg.legendHandles[i].set_color(colors[i])
如果异常百分比低于5%和/或它们与“正常”指标的分离度很差,则上述方法效果不佳,值得使用基于神经网络的算法。 在最简单的情况下,这些将是:
- 自动编码器(受过训练的自动编码器的高错误将表示读数异常);
- 递归网络(按顺序学习以预测最后的读数。如果相差很大-表示异常)。
另外,值得注意的是使用时间序列的细节。 重要的是要了解,以上大多数算法(自动编码器和隔离林除外)在添加滞后特征(从先前时间点读取的数据)时可能会给出较差的质量。
让我们尝试在示例中添加滞后特征。 竞赛说明说,错误发生3小时之前的值与错误没有任何关系。 然后在3小时内添加标志。 共有259个标志。
结果,OCSVM和IsolationForest的结果几乎保持不变,而椭圆形信封和LOF的结果下降。
要使用有关系统动力学的信息,应使用具有递归或卷积神经网络的自动编码器。 或者,例如,自动编码器,压缩信息和基于压缩信息来搜索异常的常规方法的组合。 反向方法似乎也很有希望。 通过标准算法对最不典型的点进行初步筛选,然后在更干净的数据上训练自动编码器。
来源有一套处理一维时间序列的技术。 所有这些都旨在预测未来的读数,与预测背离的点被视为异常。
三重指数平滑,将序列分为3个部分:水平,趋势和季节性。 因此,如果以这种形式呈现系列,则该方法效果很好。 Facebook Prophet的工作原理类似,但是以不同的方式评估组件本身。 例如,可以
在此处阅读更多详细信息。
S(ARIMA)
在这种方法中,预测模型基于自回归和移动平均值。 如果我们谈论的是S(ARIMA)的扩展,那么它使我们可以评估季节性。 在
此处 ,
此处和
此处阅读有关该方法的更多信息。
其他预测服务方法
当涉及到时间序列并且有关于错误发生时间的信息时,您可以与老师一起应用教学方法。 在这种情况下,除了需要标记数据外,重要的是要了解错误预测将取决于错误的性质。 如果存在许多错误且性质不同,则很可能有必要分别预测每个错误,这将需要更多标记数据,但前景会更具吸引力。
在预测性维护中还有其他使用机器学习的方法。 例如,预测未来N天的系统故障(分类任务)。 重要的是要理解,这种方法要求系统操作中的错误之前要经过一段时间的降级(不一定是渐进的)。 在这种情况下,最成功的方法似乎是使用具有卷积和/或递归层的神经网络。 另外,值得注意的是增加时间序列的方法。 在我看来,
两种方法最有趣,同时又很简单:
- 选择该行的连续部分(例如70%,其余部分被删除)并拉伸到原始大小
- 选择该行的连续部分(例如20%)并拉伸或压缩。 之后,整个行将相应地压缩或拉伸到其原始大小。
还有一个选项可以预测剩余的系统寿命(回归任务)。 在这里,我们可以区分一种单独的方法:预测的不是寿命,而是威布尔分布参数。
您可以
在 此处了解有关分布本身的
信息 ,以及与循环网格结合使用的信息。 该分布具有两个参数α和β。 α表示事件何时发生,β表示算法的信心。 尽管这种方法的应用前景广阔,但在这种情况下训练神经网络会出现困难,因为与起预测适当寿命相比,算法一开始不安全很容易。
另外,值得注意的是
Cox回归 。 它使您可以在诊断后预测每个时间点的系统容错能力,并将其表示为两个功能的乘积。 一种功能是系统的降级,与系统的参数无关,即 任何此类系统的共同点。 其次是对特定系统参数的指数依赖。 因此,对于一个人来说,有一个与衰老相关的共同功能,每个人或多或少都是一样的。 但是健康状况的恶化也与内部器官的状态有关,这对每个人来说都是不同的。
希望您现在对预测性维护有所了解。 我敢肯定,您将对这种技术最常用的机器学习方法有疑问。 我很乐意在评论中回答他们每个人。 如果您不仅对询问编写的内容感兴趣,还想做类似的事情,我们的
CleverDATA团队将始终为有才华和热情的专业人员感到高兴。