我们所有人的硬盘驱动器都发生故障,而且常常是突然启动计算机并意识到您无法访问大量文件。这不是一个有趣的经历。当整个数据中心的驱动器对保持业务正常运行至关重要时,这尤其不好玩。如果我们可以预测这些驱动器之一何时会发生故障,并通过在数据丢失之前抢先更换硬件来领先于它,该怎么办?这是Datto发生预测性驱动器故障的历史的起点。
首先,要做出预测,您需要数据。硬盘驱动器具有一个内置的实用程序,称为SMART(自我监测,分析和报告技术),可报告有关驱动器工作方式的一系列统计信息。这是看起来的简略视图:
Datto每天从其存储服务器中的每个硬盘收集这样的报告。报告中的每个属性都有三个与之相关的重要数字:值,阈值和最差值。每个属性还具有一个名为raw_value的功能,但是由于驱动器制造商之间的报告标准不一致,因此将其丢弃。
值:1到253之间的数字(包括1和253)。该值反映驱动器相对于该属性的运行状况,其中1为最差,253为最佳。初始值由制造商任意确定,并且可以随驱动器型号而变化。
阈值:一个阈值,在正常操作中该值不应低于该阈值。如果该值低于阈值,则驱动器可能存在问题。
使用这些值进行有用预测的一种快速方法是选择一些看起来很重要的属性,并在它们的任何一个值超过关联的阈值时发出警报。这就是Datto的预测驱动器故障的第一次迭代的工作方式。这不是完美的,但绝对比没有强!
驱动器故障预测的下一个迭代是为每个驱动器分配加权的健康评分。通过根据权重的严重程度为几个不同的属性分配权重,然后将它们加在一起,来定义该分数。这种预测方法比其前身要好,但有可能进一步改进。
这使我们了解了Datto的驱动器故障预测的最新迭代,以及本文的主题:smarterCTL,这是一种使用SMART报告的大多数属性的机器学习模型,可以进行最明智的预测。 Smartctl是用于收集SMART报告的命令行实用程序。 SmarterCTL是一种使用smartctl的机器学习模型,因此它是smart-ER版本。是的,这是一个双关语,但我不是工程师,而是喜剧演员。
在深入介绍smarterCTL的细节之前,让我们简要介绍一下机器学习。机器学习的核心是将统计信息应用于数据集以在其中找到模式的过程。一旦找到模式,就可以将其应用于新数据,以对新数据的含义进行假设。机器学习的定义特征是程序员在确定数据模式方面没有任何输入;该算法通过反复试验自行完成此操作。有关机器学习的工作原理的高级概述,请观看以下两分钟的视频。
为了了解工作流程和术语,让我们逐步学习一下机器学习在驱动器故障预测上的简化应用。该示例掩盖了细节,并进行了一些逻辑上的飞跃,以保持范围广泛。要在基于决策树的机器学习模型的背景下获得更准确的外观,请查看本文以及本节中链接的其他资源。
为了进行预测,我们需要一个数据集来训练模型。在这种情况下,数据点是硬盘驱动器,而这些数据点的功能就是SMART提供的属性。
这些数据点被标记为否定或肯定类的成员,在这种情况下表示“硬盘驱动器正常运行”或“硬盘驱动器发生故障”。请注意,“积极阶层”中的“积极”并不意味着“好”。相反,它的意思是“此示例展示了我们正在寻找的行为。”机器学习模型将读取此数据集,然后在功能中寻找确定每个硬盘最终归入其类的原因的模式。
通常,会有足够多的数据点和特征,人们无法阅读整个数据集,更不用说在其中发现模式了!这个例子已经足够简化,使我们逐步完成模型可能遵循的过程。让我们在每个功能中寻找一种模式:
同样,我们不能仅基于此属性来确定。没有明显的分歧,例如高数字表示好,低数字表示坏。
这次看起来像是有图案!开机时间长的驱动器运行状况良好,开机时间低的驱动器将发生故障。不过,这没有逻辑上的意义-开机时间短的驱动器应该是最健康的,因为它最接近薄荷状态。让我们再深入一点,看看我们是否可以在此功能和另一个功能之间找到关联,从而告诉我们更多的逻辑。
哈!这两类之间在大小上仍然存在差异,但是这次有一个合理的解释:具有高加速时间的较旧驱动器会正常老化和退化,而具有高加速率的非常年轻的驱动器则会老化时间表明可能存在某种工厂缺陷。
现在我们已经弄清楚了模式,让我们看一下理论模型如何将这些新的SMART报告分类:
驱动器X的加速时间与加电时间的比率为0.0002,这表明它将保持健康。驱动器Y的比率为0.045,表示出现故障。那么我们如何知道模型是否做出正确的预测呢?好吧,我们只需要拭目以待。这个问题空间中最棘手的部分之一就是验证结果,因为这样做的主要目的是让我们能够在我们所预测的事情发生之前就采取行动。请记住,以后会再次咬我们。
SmarterCTL的工作是将硬盘驱动器归类为“故障”或“未发生故障”,这样Datto可以避免因丢失的驱动器而失明,并抢先将它们换成健康的驱动器。如果SMART统计信息中有表示驱动器故障的模式,smarterCTL将从Datto在过去3年中收集的SMART数据中学习这些模式。然后,smarterCTL可以监视新的每日SMART报告,并在驱动器呈现出指示故障的模式时发出警报。
我们拥有跨越3年的数百GB的SMART文件,以及用于训练机器学习模型的相对强大的服务器-下一步是对其进行设置并使其遍历数据,对吗?不幸的是,这项工作才刚刚开始。即使机器学习模型以花费数天甚至数周的时间进行训练而闻名,但准备数据通常是该过程中最耗时的部分!
软件人员知道计算机是“愚蠢的”,只会按照他们的指示去做。因此,需要非常仔细地整理输入到机器学习模型中的数据。该模型对得出的结论是否合乎逻辑没有直觉,因此无法准确描述整个问题空间的数据将导致该模型毫无疑问地吐出废话。
在机器学习中,程序员的职责不是发现数据中的模式;而是发现模型可能会遇到的反模式。良好的数据处理和准备工作是避免使用这些反模式的第一步。
第一步是将人类可读的SMART报告转变为更具机器可读性的内容。
我将智能报表的每一天中的所有数据都压缩到了自己的csv文件中,但是仍然缺少一些关键信息。由于此数据将用于训练模型,因此每个数据点都需要具有与之关联的类标签-模型需要知道这些驱动器是正常运行还是发生故障的驱动器,以便可以开始学习潜在的模式。
生产类标签最终会有些棘手-如果驱动器的运行状况足够差,无法成为失败类的成员,则它可能已经严重失败,无法报告SMART统计信息。为了更清楚地了解驱动器的运行方式以及何时发生故障,我编写了一个脚本,该脚本遍历了每天的SMART报告并跟踪每个驱动器发生故障的方式和时间。
我们的服务器使用文件系统ZFS,该文件系统将存储设备汇集在一起,称为“ zpools”。 zpool报告池中每个驱动器的运行状况。当我的脚本遇到驱动器的zpool故障状态时,它会记录发生故障的那一天,然后通过每天的csv进行检查,并将以下功能添加到该驱动器的行中:
如果是这样,则从该csv日期起的几天内,将会发生故障,并且
此时,数据集是一组csv文件,每天一个,其中包含:
似乎有足够的数据可以开始进行预测,对吧?好吧,有点!此时,数据的格式已经足够好,模型可以理解它并开始产生预测。但是,这些预测的质量很差。数据需要更多处理以消除潜伏在其中的陷阱。
目前,数据格式正确但混乱。形状正确,但缺少值和错误的输入。以下是来自数据集第一次迭代的一些真实样本:
除非清除数据,否则该模型将完全相信“找不到设备,无法获取智能数据!”是有效的硬盘驱动器大小。要清理数据,需要嗅出格式错误的值,并用一个标准化的NaN(非数字)表示形式替换。一旦缺失值被标准化,模型就可以适当地处理它们。
随机错误值消失了,但仅在1_val列中,超过10个条目中就有1个是NaN。即使模型知道忽略了这些值,但拥有这么多未使用的功能实际上可能会扭曲结果。当缺少许多其他要素时,与数据点关联的非NaN特征将具有更强的相对权重。有两种方法可以解决此问题:删除缺少数据的行或重新创建缺少的数据。
如果没有太多缺少值的行,则可以删除它们。不会有太多的数据丢失,而且我们可以完全确定NaN不会扭曲数据。
如果有很多行缺少值,那么首先是一个危险信号,即数据可能不够完整,无法继续前进。如果解决了这个问题并且数据合理,则可以通过归因来重新创建NaN:根据与之相关的其他值推断出缺失值可能是什么。有几种方法可以做到这一点,找出最适合任何问题的方法是反复试验的过程。
最终,成为smarterCTL的正确方法是两种方法的组合:删除丢失大量价值的行,但保留并修复仅有缺失的行。
在这一点上,数据的形状和超净度都很好,这似乎是向前进行预测的信号。不幸的是,硬盘制造商决定在该计划中使用扳手。尽管SMART属性名称和SMART报告格式在各个方面都遵循一致的标准,但与属性相关的值随品牌而变化。
这些都是全新的驱动器,此属性的默认值为“无错误”。数字是非常不同的,因为它们是由两个不同的制造商生产的。
机器学习模型没有直觉来知道,尽管这些值指的是相同的属性,但是它们的规模不同。这就像要某人描述重量为“ 10”的东西和重量为“ 40”的东西之间的区别,而没有告诉他们10的磅数和40的克数。这具有误导性,将导致模型在预测故障时大大偏爱某些制造商。
为了消除比例差异,我将数据集分为许多子集,其中每个子集仅具有一个制造商的驱动器。这对于保持数据一致非常有用,但是却带来了一个新问题:大多数数据集都太小。我们将在第4号法案的后面进行讨论。
至此,数据没有添加任何内容。我们还没有计算新功能或建立新数据点。我们要做的是使数据处于干净一致的状态,可用于训练模型而不会陷入任何明显的陷阱。
最后,该启动我们选择的机器学习库XGBoost了,让它撕裂!只是开个玩笑,实际上还有更多的数据处理要做。数据需要分为一组功能和一组类标签(称为X和Y),然后分为训练和测试集。
务必将X和Y分开,以确保类别标签不会影响预测结果;否则,该模型将能够“欺骗”并每次获得正确答案而无需弄清楚任何实际模式。
训练集是整个数据集的30-40%,是随机选择的。这是提供给模型以找出数据模式的要素。在训练期间,模型将可以访问班级标签以“检查其答案”,并查看其可疑模式是否正确。
其余数据包括测试集,直到训练完成后,这部分数据才被保留并从模型中保密。训练后,该模型可以使用测试集作为输入进行预测,以窥探该模型在看不见的数据中如何在生产中表现。通常,测试集较小,仅占数据的20%到30%,但是我更喜欢在处理不平衡数据时为测试集保留更多数据(稍后再介绍不平衡数据!)。
提供测试集非常重要!这是检查模型是否过拟合的主要方法。过度拟合是指模型对训练集“了解过多”,而无法跟踪其寻找的总体趋势。
现在,数据已分为训练和测试,最终可以将其放入XGBoost,机器可以学习了!首先,我们将使用默认设置的分类器模型。
在这一点上,分类器是我们训练有素的模型。要检查它的准确性,让我们看看它对测试集的含义。
准确性是正确预测与总预测之比。乍看之下,99.92%的准确性看起来令人难以置信!深入研究揭示了为什么精度实际上是解决该问题的一种误导性措施:各类之间的不平衡性令人难以置信。运行状况良好的驱动器有400,150个报告,而故障驱动器只有215个报告。如果该模型预测每个驱动器都不会发生故障,那么它仍然可以达到99.94%的准确度,而没有提供任何有用的信息。
马修斯相关系数是一种可以通过考虑真假正负之间的差异来处理不平衡数据的度量。 MCC是介于-1和+1之间的十进制值。零的MCC是随机预测,+ 1是完全预测,而-1是完全相反的预测。在这种情况下,MCC为0.1975很低,但仍然好于随机数。
混淆矩阵可以很好地了解模型的优缺点所在。在这种情况下,该模型非常适合预测真实的负面因素;它得到了其中的40万个正确答案。该模型的弱点之一是假阴性。在此样本中的总共215个故障驱动器中,它错误地预测其中175个将是健康的。
模型永远不会使每个预测正确,错误的答案通常会偏向一侧:更多的误报或更多的误报。模型应该偏向哪一个是业务决策。假阴性代表无法抢先交换的驱动器,浪费时间和人力。误报表示健康的驱动器,无论如何都会交换掉,浪费金钱在新的不必要的硬件上。取决于目标受众,这两种方法中的任何一种都可能是有利的,并且混淆矩阵可用于监视训练模型以偏向任一方向的程度。
数据格式正确,可以很好地描述问题空间,但是模型产生的结果中等。改进的首要目标是超越默认设置并开始调整超参数。超参数是模型的外部配置。这是程序员选择的东西,而不是从数据中学到的东西。可以将超参数想像成乐器上的调节旋钮。这是我如何调整对smarterCTL最重要的超参数的概述:
eval_metric:eval_metric是模型用来判断训练期间预测的准确性的度量。默认情况下,XGBoost使用错误率(精度的倒数)作为eval_metric。对于不平衡的数据,任何与准确性相关的度量都无济于事,因此我将eval_metric替换为用于检查MCC的自定义函数。
early_stopping_rounds:XGBoost轮训模型。每轮培训都会进行更改,并将准确性与上一版本进行比较。如果没有early_stopping_rounds,则模型将训练任意数量的回合,然后返回最佳迭代。如果使用Early_stopping_rounds,则模型在X轮中测试集的准确性没有提高的情况下将停止训练。目标是在模型开始过度拟合之前就停止训练,即使模型在训练集上的准确性可能仍在提高。
scale_pos_weight:Scale_pos_weight是阳性样本(故障驱动器)与阴性样本(健康驱动器)的比率。定义scale_pos_weight有助于提高在处理不平衡数据时的准确性,因为它可以使模型大致知道应归为正数的分类比例。可以将该指标设置为高于或低于阳性样本的真实比率,以鼓励模型偏向于假阳性或假阴性。极低的scale_pos_weight告诉模型假定绝大多数分类应为负数。
base_score:进行分类时,模型会为每个数据点赋予0(负)和1(正)之间的分数。越接近1,模型就越能肯定分类是肯定的。 Base_score与scale_pos_weight相似,可帮助处理不平衡数据,但可以通过定义默认分类得分来鼓励模型向正数或负数误差。如果base_score为0.1,则表明该模型在假定任何分类都为负的方面会出错。
这些超参数值中的一些是通过反复试验确定的,而某些则是借助XGBoost的cv(交叉验证)功能找到的。 Cv本质上是自动试验和错误;它使用不同的超参数值进行了几轮提升,并从最精确的迭代中返回值。交叉验证还提供了其他一些与统计意义有关的重要信息,可以在此处阅读。
绝对更好! MCC明显更高。相应地,考虑到随机抽取到该测试集中的故障总数,真实的肯定性上升而错误的否定性下降。尽管距离准确到足以有用还还有很长的路要走,所以可以追溯到数据处理。
通过这些数据处理的不同组合进行工作是一个反复的过程,跨越了很长一段时间,并且在此过程中训练了数百种不同的模型。我并没有保留所有模型,因此不会为每种数据处理提供准确的摘要,但是我将简要介绍一下哪些有效,哪些
......