1. 项目概述与方案设计思路
1.1 工业设备故障诊断到底难在哪
先聊点实际的。工业设备故障诊断这件事,真正做过的人都知道,难点从来不在“采集数据”这一步,而在“从数据里看出问题”这一步。传感器一铺,振动、温度、电流、压力这些信号哗哗往数据库里灌,一天下来几百万条记录很常见,但真要让人盯着波形图找故障,一是效率太低,二是人的眼睛和大脑在这种重复性劳动里撑不了多久,漏判误判是迟早的事。
我接手过一条汽车零部件产线的设备健康管理项目,减速机、主轴、冷却泵加起来七八十台设备,每台设备上挂了六七个传感器,采集频率动辄上千赫兹。以前的做法是老师傅凭经验巡检,听声音、摸温度、看油渍,确实能发现一些问题,但成本高、周期长,而且很多早期故障的征兆在感官层面根本察觉不到。等真正出现报警,往往已经是中后期故障,维修窗口被严重压缩,停产损失居高不下。
后来我把思路转到了机器学习这条路上,目标很明确:用Python搭一套自动化的故障诊断流水线,让模型代替人去盯数据,在故障刚冒头的时候就把异常揪出来。这套方案里用到的核心算法是随机森林和孤立森林,很多人把这两个名字放在一起就懵,觉得都是树模型、都是森林,好像差不多,其实这俩东西干的活完全不同,甚至可以说天生互补。孤立森林负责“抓异常”——也就是判断设备当前有没有出问题;随机森林负责“分类型”——也就是判断出了什么问题,是轴承磨损、转子不平衡还是润滑不良。两阶段串联起来,就构成了一套从“有没有病”到“什么病”的完整诊断链路。
1.2 为什么是“孤立森林+随机森林”组合
先说一个反直觉的现象:真正的工业故障数据里,正常样本占了绝大多数,故障样本凤毛麟角。某台设备可能连续运行一两个月都是正常的,只在某一天某一刻开始出现异常。这种极端不平衡的数据,直接丢给常规分类模型训练,模型会毫不犹豫地学成一个“永远说正常”的懒汉,准确率能做到99%以上,但一个故障都抓不住——因为故障太少,对模型来说“认错”几乎不损失什么。
孤立森林解决的正是这个问题,它是无监督的异常检测算法,训练的时候根本不需要知道哪些数据是故障、哪些是正常,它只做一件事:找到那些“格格不入”的点。原理我后面细讲,但核心思想就是“异常点更容易被隔离”,就像人群里突然出现一个穿着奇装异服的人,你一眼就能注意到他,因为他和周围环境差异太大。
但孤立森林有一个天生的短板:它只告诉你“这个样本异常”,不告诉你“怎么个异常法”。设备坏了和传感器接线松了,在孤立森林眼里都是异常分数很高,它分不出来。这时候随机森林就派上用场了——它是经典的有监督分类算法,把已经确认为故障的样本打上标签(轴承磨损、齿轮断裂、对中不良),训练出一个能区分故障类型的分类器。
所以这套组合的逻辑是:孤立森林做第一道哨兵,全天候盯防,发现异常立刻报警;随机森林做第二道裁判,收到异常样本后给出具体故障类型。哨兵不需要懂医学,只需要发现有人不舒服;裁判不需要巡逻,只需要做出精准诊断。各司其职,互不干扰,这套流水线就能稳定运转。
1.3 整体技术架构与工作流程
整套系统的运行流程我整理成了三条主线,每条线之间通过数据衔接,模块耦合度低,后期替换算法或者增加数据源都很方便。
- 特征提取层:原始传感器数据进来,先做清洗和降噪,然后按时间窗口切分,提取统计特征、频域特征和时频特征。这一步的目的是把原始波形转变成模型能“吃”的特征矩阵,后面会详细展开。
- 异常检测层:特征矩阵进入孤立森林模型,每条样本得到一个异常分数。设置阈值判断是否报警,这里的关键是阈值的标定,太松漏报、太紧误报,我后面会分享自己踩过的坑。
- 故障分类层:被判定为异常的样本,连同历史故障样本一起输入随机森林分类器,输出具体的故障类型和置信度。同时加入一个反馈环节,把人工确认的结果回填到训练集里,让分类器越用越准。
这套架构最大的好处是可解释性和可维护性兼顾。孤立森林和随机森林都是树模型,不像深度神经网络是个黑盒,工程师能直接查看特征重要性排序,知道模型是根据哪个传感器特征做出判断的,这对于工业场景的信任建立至关重要。我在产线上跑这套方案跑了将近四个月,整体效果稳定,后续可以慢慢跟大家分享细节。
2. 算法核心原理与选型理由
2.1 孤立森林的核心思想
孤立森林和其他异常检测算法的思路完全不同。大多数算法(比如基于距离的KNN、基于密度的LOF)都在想办法描述“正常数据长什么样”,然后再看哪些数据不符合这个描述。但孤立森林反着来:它不去建“正常模型”,而是直接问一个问题——每个样本需要“切几刀”才能被单独分离出来?
想象一下把一堆点撒在二维平面上。正常点聚集在一起,彼此挨得很近,你要想用一把尺子横一刀竖一刀把它单独切出来,得切很多刀;但一个孤悬在角落的离群点,可能一刀下去就能把它和其他点分开。孤立森林把每一棵树当成一次“切割实验”,随机选特征、随机选切割点,把样本空间反复切分。每个样本在所有树上的“平均切割次数”就是一个核心指标——路径长度。异常点的路径长度通常显著短于正常点,因为它们是那种“一刀就能隔离”的点。
这个思路的巧妙之处在于计算成本极低。它不需要算距离、不需要算密度,每次切割只是比较一个特征值和阈值的大小,复杂度接近线性。我在实际处理产线数据时,一天百万级的数据量,用孤立森林做全量扫描,单台普通服务器上只需要几分钟就能跑完一轮,这在大规模工业场景里极其重要——你的诊断系统必须是实时的,不能等模型算完了设备早就烧坏了。
孤立森林有一个关键参数叫contamination,代表你预估的数据集中异常样本的比例。这个参数的设置直接影响了判断阈值。我在参数调优部分会重点讲它——这里先卖个关子,只说一句话:千万不要盲目相信默认值0.1,工业场景里不同设备、不同工况下的异常比例差异极大,盲目套用默认值很容易翻车。
2.2 随机森林的核心思想
随机森林是装袋法(Bagging)的代表作。它训练了一堆决策树,每棵树用的都是数据的随机子集,而且每棵树分裂时只随机挑选一部分特征来寻找最佳切分点。这两层随机性带来一个非常重要的好处:单棵决策树容易过拟合,但几百棵决策树投票,过拟合会被显著抑制。
为什么在故障分类场景中我选随机森林而不是深度学习?首先是数据量的问题。故障样本本来就稀有,深度学习动辄需要成千上万条带标签样本才能训出像样的模型,但在工业场景里,能拿到的故障样本往往只有几百条。随机森林对这种小样本、高维度的表格数据适应得极好,几百条样本照样能训练出一个可用的分类器。
其次是可靠性问题。随机森林输出的是概率投票结果,你能看到“轴承磨损80%概率、不对中15%概率、润滑不良5%概率”,这种分布信息在工业决策中极其有用。维修工程师拿到这个结果,不是收到一个冰冷的“轴承故障”指令,而是能看到置信度和备选可能性,然后结合现场情况做综合判断。我在做系统对接时,把这几个概率值直接推到了车间的看板大屏上,老师傅们反映,这种“不确定性的呈现”反而让他们更信任系统——因为机器没有装懂,而是把判断依据摊开给你看。
2.3 为什么融合能产生1+1>2的效果
这套方案最核心的设计理念,是用两种算法各干自己所擅长的事,而不是让一种算法包打天下。
- 孤立森林的优势是“广”:它无监督,不需要标签,天生就能捕捉到“没见过”的异常。工业设备故障最可怕的就是新故障——以前从未记录过的故障模式。用有监督模型去识别新故障是必死的,因为它只知道训练集里的那几类;但孤立森林没有这个限制,任何偏离常态的模式都会被它标记出来。
- 随机森林的优势是“准”:一旦确认异常,它能在已知故障类别中做出精准区分。孤立森林发现不了的细微类别差异,随机森林可以轻松捕捉。
这就好比一个医院的流程:孤立森林是分诊台护士,快速判断你是不是身体出了问题;随机森林是专科医生,确诊你到底是哪里出问题。分诊台不会直接下诊断,专科医生也不会满医院乱转去找病人。两个角色不重叠,配合起来,整个就诊流程效率最高。
这里要强调一点,很多人以为融合就是把两个模型打成一个混合模型,这是误区。我的做法是流水线式的串联,前一阶段的输出是后一阶段的输入门槛。这么做最大的好处是可以分别调优、分别升级——孤立森林误报率高了,单独调它的阈值;随机森林某个故障类型识别不准,单独补充对应类别的训练样本。两个模型的风控逻辑和迭代节奏完全解耦,在实际维护时非常省心。
3. 实操过程:从数据到代码实现
3.1 数据准备与特征工程
我先说明一下数据的形态。产线上最常见的传感器数据是振动加速度信号,采样率通常在10kHz到50kHz之间。以32kHz采样率为例,1秒就产生32000个点,不能直接把原始点序列喂给模型,必须做特征工程。
我采用的方法是按时间窗口切片。每次取4096个点作为一个快照(对应0.128秒),相邻窗口有50%重叠,然后把每个窗口变成一组特征。这个4096不是随便选的,它是2的12次方,方便做快速傅里叶变换(FFT),而且能覆盖常见故障特征频率的多个周期。
从每个窗口里提取的特征分成三类,组合成一个43维的特征向量:
统计特征:
- 均值、标准差、峰值、峰峰值
- 偏度:反映信号分布的不对称性,轴承磨损早期会改变波形对称性
- 峭度:这是轴承故障的经典指标,正常滚动轴承的峭度约等于3,故障状态下会显著增大
频域特征:
- 频谱质心、频谱带宽
- 特定频带的能量占比:比如0~1kHz、1kHz~5kHz、5kHz~10kHz三个频带的能量比例
- 主频峰值频率和幅值,转频及其倍频的幅值——这些和转子不平衡、轴弯曲直接相关
时频统计特征:
- 用经验模态分解(EMD)或者小波包分解后提取的能量熵
- 这个特征对非平稳信号、瞬态冲击(比如齿轮断齿)特别敏感
数据不平衡的问题我从源头就开始处理。正常工况的数据量是巨大的,我直接按比例抽样,把正常样本控制在一定规模;故障样本本来就少,全部保留。同时用SMOTE算法合成少量合成故障样本,防止随机森林在类别极少的情况下学不好。但SMOTE的使用要谨慎,合成样本不能超过真实故障样本的50%,否则会引入大量噪声。
3.2 第一阶段:孤立森林异常检测
这是整个流水线的第一道关口。我直接贴核心代码,把关键的部分标出来。
from sklearn.ensemble import IsolationForest # 数据准备 # X_train是形状为(n_samples, 43)的特征矩阵 # 注意:这里不需要标签!孤立森林是无监督训练 model_if = IsolationForest( n_estimators=200, # 树的数量,工业数据量级下200够用,多了边际收益下降明显 max_samples=4096, # 每棵树采样的样本数,实际用下来取总样本的10%-20%比较合理 contamination=0.05, # 预估异常比例,这个参数必须根据工况调整 max_features=0.8, # 每棵树用的特征比例 random_state=42, # 固定随机种子,保证结果可复现 n_jobs=-1 # 并行计算,全核跑 ) model_if.fit(X_train) # 获取异常分数 # model_if.score_samples返回的是负的异常分数,数值越小代表越异常 anomaly_scores = model_if.score_samples(X_train) # decision_function是另一种表示,>0表示正常,<0表示异常 decision_values = model_if.decision_function(X_train) # 预测标签 # -1代表异常,1代表正常 labels = model_if.predict(X_train)这里最大的坑是contamination参数的选择。默认0.1意味着“我假设数据集里10%是异常”,但在真实的产线数据里,正常工况占比可能高达99%,异常只有1%。如果盲目用默认值,模型会把大量正常样本误判为异常,导致随机森林分类器被淹没在假警报里。
我的做法是先用一种更简单的方法估算异常比例:先对每个特征做四分位距(IQR)离群点检测,统计被至少3个特征同时标记为离群点的样本占比,用这个比值作为contamination的初始值。这比拍脑袋准得多,后面再根据实际漏报误报情况做增减。
阈值选取另一个重要手段是看异常分数的分布直方图。正常的样本分数会集中在某个区间,异常样本会拖出长长的尾巴。我通常在那个“尾巴”的起点附近选阈值,而不是直接信任predict函数默认的0分界线。用score_samples拿到连续分数之后,自己画分布图、选阈值,灵活性和准确率都远高于默认方案。
3.3 第二阶段:随机森林故障分类
第一阶段的输出是两类:正常样本(直接归档不处理)和异常样本(送入第二阶段)。第二阶段要做的,是把异常样本精确归类到已知的故障类型中。
from sklearn.ensemble import RandomForestClassifier # X_fault:第一阶段标记为异常的样本特征 # y_fault:这些样本对应的故障类型标签(需要人工标注或来自历史维修记录) # 例如:0=轴承磨损, 1=转子不平衡, 2=齿轮断齿, 3=润滑不良, 4=不对中 model_rf = RandomForestClassifier( n_estimators=500, max_depth=12, min_samples_split=4, min_samples_leaf=2, max_features='sqrt', class_weight='balanced', # 类别不平衡时让少数类获得更高权重 random_state=42, n_jobs=-1 ) model_rf.fit(X_fault, y_fault) # 预测故障类别和概率 pred_class = model_rf.predict(X_test) pred_prob = model_rf.predict_proba(X_test) # 特征重要性:哪个特征对判断故障类型贡献最大 importance = model_rf.feature_importances_ # 把特征名和重要性排序输出,方便工程师理解模型逻辑一个关键的经验:随机森林的参数,能用融合反馈不断调优。模型上线初期,会把预测结果和维修工程师的最终诊断结果做对比,发现问题就回填修正。比如模型把某个样本判成了“轴承磨损”,但拆开后发现是“保持架断裂”,这都属于轴承类故障但细分不同——那就把样本标签修正后重新训练。
class_weight='balanced'这个参数很有用。工业故障数据天然不平衡,轴承磨损可能占故障总数的60%,齿轮断齿只占5%。不加权重,模型会偷懒,把所有模糊样本都判成轴承磨损,因为这样准确率最高。加了balanced权重后,模型被迫关注少数类,会显著提升对稀有故障的敏感度,代价是总体准确率略微下降——但在工业场景中,漏掉一个稀有故障的损失远大于多跑几次维修。
随机森林还有一个我很常用的特性:利用predict_proba输出的置信度来做二次过滤。如果某个异常样本被判为“轴承磨损60%、转子不平衡25%、不对中15%”,这个结果其实是比较模糊的。我的策略是设定一个置信度阈值,比如大于85%才直接输出诊断结果,低于这个阈值就标记为“待人工复核”,把原始波形和特征一并推送给工程师。这个机制极大地提升了系统在实战中的可靠性——模型知道什么时候该说自己不确定,这在工业应用中反而比死磕准确率更有价值。
3.4 模型评估与阈值调参
评估指标体系上,只盯着准确率是远远不够的。在异常检测场景,我更关注这几个指标:
- 召回率:故障样本里有多少被正确查出来了。在设备诊断场景,召回率是第一优先级的指标——漏诊的代价远高于误诊。
- 误报率:正常样本里有多少被错判成了故障。误报率太高会触发“狼来了”效应,车间迟早会无视报警信息。
- F1分数:召回率和精确率的调和平均,找一个平衡点。
我做了两组对照实验分享给大家。第一组是“直接用随机森林做全量分类”而不经过孤立森林过滤;第二组是“孤立森林+随机森林”的流水线方案。同样的数据规模下,第一组的误报率相比第二组要高不少,原因是随机森林面对海量正常样本时,会倾向于把它们都分类到占比最高的故障类里,只有第二组这种先过滤、再分类的结构化方案,让每个模型只处理自己擅长的一环,整体性能才能达到可用的水平。
阈值调优时我用一个自定义代价函数来定阈值——漏报罚10分,误报罚1分。因为一次故障漏检可能造成设备损坏、产线停机,动辄损失几十万;一次误报顶多让维修人员白跑一趟,成本可接受。这种以代价为导向的调参方式,比单纯追求F1分数更贴合工业实际。
4. 把DeepSeek用在开发流程里
4.1 DeepSeek在方案设计阶段能帮什么
这块想单独拿出来聊聊。做这个项目的时候,我大量使用了DeepSeek辅助编码和方案设计,体验下来确实效率提升明显。
很多人用AI助手还停留在“帮我写一段代码”的层面,其实它最值钱的是帮你快速理解一个陌生领域中你没接触过的细节。比如我刚开始做孤立森林调参时,对max_samples参数的理解比较模糊,就问DeepSeek“孤立森林的max_samples怎么选?”它给出的解释比我翻书还清楚——这个参数是每棵树的采样量,不是全部数据,是为了减少计算复杂度,而且采样量越小,算法对局部异常越敏感,但也越容易把正常边界样本误判。它还会提醒你平衡计算效率和鲁棒性。
初次写孤立森林代码时,我对输出分数含义的理解有些模糊,直接问了DeepSeek“IsolationForest的score_samples为什么返回负数?”得到的解释非常清晰:它返回的是异常分数的负值,负得越多越异常,之所以取负号是为了对齐decision_function的“越大越好”语义。这类用法细节,光读官方文档很容易忽略,有经验的助手直接给你点破,省了很多试错时间。
DeepSeek另一个巨大的好处是免去了搜索来搜索去的麻烦。以前写代码遇到不熟的API,要么翻文档、要么翻CSDN、要么问人,上下文切换成本极高。现在直接在IDE里打开DeepSeek对话窗,把我说不清的报错信息整段粘贴进去,问它这是什么问题、该怎么改,往往几轮对话就解决了。我整个项目里,这种“边写边问”的工作流帮我大概省了20%到30%的编码时间和大量查资料的碎片时间。
4.2 用DeepSeek辅助调试和优化代码
代码优化方面我举几个典型例子。第一阶段孤立森林上线后,工业现场反映处理速度跟不上数据采集速度,我拿到排查方向后先自己分析了瓶颈,确认是特征提取和模型推理占用了大部分时间,于是把目标锁定在这两块。我把核心代码段发给DeepSeek,问“这段特征提取循环有没有可能加速?”它给我列出了几个优化方向——把循环改成numpy向量化、用joblib做并行、用numba加速FFT、减少不必要的数组拷贝。
最终我采纳了对现有代码改动最小、收益最大的两个优化:特征提取部分用numpy重写循环,推理部分把多个固定大小的窗口拼成一个大数组批量过模型。整体耗时降到了原来的40%左右,完全满足了实时性要求。
还有一次排查一个奇怪的现象:训练集中随机森林的交叉验证分数很高,但现场上线后对某些设备类型的故障诊断准确率特别低。我分析后怀疑是这些设备的特征分布和训练集差异太大,属于典型的“训练部署分布漂移”。我用DeepSeek帮我整理了排查清单,从特征分布对比、到按设备分组重训、再到增量更新训练数据的层级策略。跟着这个思路,我用KS检验对比了各设备特征分布的差异程度,最终确认问题所在,并改成按设备分组训练多个模型,准确率得以恢复。
4.3 注意事项与实际体验
用DeepSeek做工程开发,有三条经验分享给大家:
- 不要把AI输出当最终答案。AI给的代码和方案大概率是可用的,但你必须自己理解每一行的含义,特别是涉及模型参数和数据范围的地方。我的习惯是让AI解释完代码逻辑之后,自己再核一遍关键步骤,确认数据流是正确的,不搞“复制粘贴直接上线”。
- 学会问“为什么”比问“怎么做”更有价值。很多时候一个问题深挖下去,AI会引导你去思考自己之前忽略的约束条件。工业场景里环境噪音、传感器退化、数据漂移这些AI可能根本不知道——你问“为什么这个结果不对”,AI会列举十几种可能原因,但最终哪个才是真正的原因,还是要靠你在现场的经验和判断。
- 上下文要一次性给足。问问题的时候把数据规模、特征维度、代码结构、报错信息都完整交代,AI给出的答案精准度会大幅提升。我见过很多同事问问题只丢一句“这个报错怎么回事”,AI只能瞎猜,来回问答消耗的时间比自己去查报错还久。
DeepSeek目前完全免费,而且我已经在实测中验证了,无论是写模型骨架代码、做特征工程分析、还是排查调参逻辑,它都能胜任。但不建议用AI直接生成完整业务代码直接就上产线,要渐进式替换、逐步验证,先用小流量验证稳定了再全面上。
5. 常见问题与排查技巧实录
5.1 数据不平衡问题
前面说过,工业故障数据天然不平衡,正常数据占了绝大多数,故障只有零星几条。这个问题的处理直接决定了系统能否落地。
我的策略分三层:
- 第一层,采样策略:正常样本不是全量使用,而是按时间跨度从不同工况抽取,保持覆盖面,控制总量。比如连续一周的数据里,均匀抽1%作为正常样本,大约几万条,够用了。
- 第二层,模型设计:随机森林设置
class_weight='balanced',让模型对少数类更敏感;孤立森林的contamination参数按实际异常率设置。 - 第三层,合成样本:对极度稀少的故障类别,用SMOTE做数据增强。但前面提过,合成比例建议控制在50%以内,过多会失真。
5.2 孤立森林误报太多怎么办
这是上线初期最常见的投诉——“你们这个系统一天报十几个异常,拆开全没事”。误报过多的原因往往有两个:
- contamination参数设大了:模型默认认为数据里有那么多比例是异常,但实际上异常率没那么高。解决方案是降低contamination值,或者用
score_samples画分布图自己定阈值。 - 正常工况本身变化大:比如设备负载随订单波动剧烈,正常时的特征空间本身就分布得很散,模型把边界上的正常点也当成了异常。解决方案是按工况分段建模——把满负载、半负载、空载分别建独立的孤立森林。这个操作我在产线上实测过,误报率降了不止一半。
还有一个有用的技巧:对孤立森林打上“临时异常”和“持续异常”的标签。单次偶发异常可能是外界干扰,比如旁边行车的振动传过来了;连续多次都异常才是真正的设备故障。我在系统里做了一个简单的计数窗口:单条异常样本先标记为“关注”,连续5个窗口内出现3次以上异常才触发真正的报警。这个“防抖”机制让误报率降低了约2/3。
5.3 随机森林过拟合问题
随机森林虽然抗过拟合能力强,但不是免疫。我在早期调试中发现一个典型现象:训练集上F1分数高达0.98,但验证集只到0.82,明显过拟合了。
排查之后发现几处问题:
- max_depth太深:默认不限制深度的话,树会尽量把每个训练样本都分开,但学到的规则过于琐碎。限制
max_depth=10~15之间效果通常比较稳。 - min_samples_split太小:节点的最小样本数太少,导致树的末端节点只覆盖几个样本,纯属“背答案”。提升到
min_samples_split=5~10,让树必须基于更多样本做判断。 - 特征泄漏:这是最隐蔽的坑。我一度发现振动频谱里有一个特征重要性奇高,查了很久才发现那个特征其实是标签编码的一部分——数据记录时把“维修工单号”直接作为一列了,模型学到的是“工单号不同则故障不同”的假规则。这直接给大家提了个醒:特征工程做完之后,必须人工检查一遍每个特征的业务含义,不要只做数值校验。
5.4 基于实战经验的参数速查表
| 参数 | 推荐值范围 | 实测心得 |
|---|---|---|
IsolationForestn_estimators | 100~300 | 超过300提升很小,主要增加计算量 |
IsolationForestmax_samples | 总样本量10%~20% | 太小:局部异常敏感、误报多;太大:失去算法优势 |
IsolationForestcontamination | 0.02~0.08 | 必须结合IQR估算和现场误报反馈调整 |
RandomForestn_estimators | 300~500 | 工业数据量下500棵左右足够稳定 |
RandomForestmax_depth | 10~15 | 不限制有较大过拟合风险 |
RandomForestclass_weight | balanced | 平衡后少数类召回率提升明显 |
| 置信度阈值 | 0.80~0.90 | 低于此值推给人工复核,避免误判 |
提示:以上参数基于振动传感器场景,如果换到电流、温度、压力信号场景,阈值需要重新标定。故障诊断的模型没有万能参数,只有针对场景调优后的合适参数。
5.5 现场部署的额外经验
最后一条经验是关于部署架构的。模型文件用joblib保存,推理服务直接用FastAPI包一层HTTP接口,车间看板通过接口实时拉取诊断结果。模型更新不需要停服务,训练好新模型后,用一个命名版本号的热切换机制来替换当前模型,接口层无感知。
推理性能和模型加载时的内存占用在一个可接受的范围。我在一台普通的Intel服务器上,用200棵树的孤立森林 + 500棵树的随机森林,同时服务80台设备的实时数据完全够用。关键还是前面说的那个优化:批量推理代替单条推理,吞吐量能提升好几倍。
分享一个小技巧作为收尾吧。整个系统跑了一段时间之后,我养成了一个习惯:定期把孤立森林抓出来的“异常分数最高”的样本翻出来看原始波形。这不是浪费时间,因为这些样本往往意味着某种尚未被纳入随机森林分类体系的“新故障模式”。我有一台数控机床就是这个方式提前发现的新型刀具磨损模式,在它造成精度超差之前就被处理掉了。这类“从异常检测结果反推新知识”的闭环,是在不断维护算法,比任何调参技巧都更有效。