资讯动态

MITRE ATTCK文本标注实战:多标签分层分类模型解析

发布时间:2026/10/2 8:45:32 来源:尧图企业网站定制
安全运营这块做久了大家都会碰到同一个痛点手里积压了一堆告警日志、威胁情报报告、红队报告摘要需要把这些文本归到MITRE ATTCK框架里好知道攻击者到底走到哪一步了。但人工标注太慢几个分析师翻来覆去看文本一天也标不了几十条而且主观判断差异还大。我做的这个MITRE ATTCK文本标注的多标签分层分类模型项目就是为了解决这件事——让机器去读文本自动给出它对应的战术和技术标签。这篇文章我会把这个项目的完整思路、建模细节、踩坑过程和落地效果都拆开讲清楚适合正在做安全数据挖掘、威胁情报标签化、或者想用NLP处理安全域文本的朋友参考。很多人一听到文本分类就觉得是常规操作但实际上ATTCK标注这个任务坑很深。它不是给你几个固定类别让你选一个而是要给一段话打上多个标签同时这些标签之间还有严格的父子层级关系——战术Tactic下面挂着技术Technique技术下面还有子技术Sub-technique。如果直接当成普通的多标签分类问题做模型很容易预测出子技术对了但父技术错了这种逻辑上不存在的组合。下面我完整复盘一下这个项目是怎么从零到一落地的。1. ATTCK文本标注的难点为什么不能当普通多标签问题做1.1 结构化知识库与自然语言之间的鸿沟MITRE ATTCK框架本身是一张精心组织的攻击行为知识图谱目前涵盖十几个战术比如初始访问、执行、持久化、横向移动等每个战术下挂着几十个技术技术下再分子技术整棵树有几百个叶子节点。这套结构对人和机器都非常友好因为它的层次设计严谨每个节点的定义都有清晰的语言描述。但问题来了现实世界中的威胁情报文本、告警描述、事件响应报告语言风格极其发散。同一个通过钓鱼邮件投递恶意附件的行为在一条日志里可能被写成attachment contains malicious macro在另一份报告里可能被写为user opened phishing email with embedded payload在红队记录里又可能是send spearphish with link to staged zip。这些文本跟ATTCK节点的百科式定义之间并不是一一对应的关系而是一段嘈杂的自然语言到结构化树节点子集的映射。这种映射有三个特点直接决定了建模难度第一标签数量多且分布长尾热门技术出现频次极高冷门技术几乎没样本第二标签间存在强依赖如果不能利用好层次约束模型大概率会输出自相矛盾的结果第三语义边界模糊很多技术之间的差异非常细微比如通过Windows服务实现持久化和通过计划任务实现持久化在文本里可能只差一个词。1.2 多标签与层级依赖叠加带来的组合爆炸普通多标签分类问题比如给新闻打上体育、财经、国际这些标签标签之间是相对独立的。但ATTCK的标签不是这样它们被组织在一棵固定的树里而且MITRE官方文档明确规定如果一个文本涉及某个子技术那它必然也涉及该子技术所属的父技术。这意味着模型输出的标签集合必须满足一个封闭性条件如果预测包含A.T0001.001子技术则必须同时包含A.T0001父技术。如果模型是暴力式的多标签输出它很难天然满足这个条件因为每个标签都是独立二分类的模型根本不知道谁是谁的爸爸。从实际数据来看这种父子同时出现的情况不是少数很多长文本会同时覆盖战术、技术和子技术三个层级的信息。如果忽略这个结构直接训会出现两大类错误一类是认子不认父即预测出某个子技术但漏掉了父技术这在技术评审时看起来就是逻辑硬伤另一类是父对子错预测出某个技术大类但子技术归错了比如某文本明明是在描述用PowerShell做横向移动模型却给它标了个PowerShell执行下的另一个无关子技术。1.3 数据长尾与标注一致性难题这个项目最耗时间的部分不是建模而是数据准备。ATTCK技术的出现频率完全遵循幂律分布搜索、进程注入、命令与脚本解释器这些技术在样本里反复出现而像通过硬件附加组件实现持久化这类冷门技术可能整个数据集都凑不齐20条正样本。我们后来统计过项目中数据量能上500条的标签大概只有十几个剩下的一百多个标签都处于样本稀少甚至极少的状态。这种分布直接让常规的深度学习训练失去意义——模型很容易收敛到一个只预测头部常用技术的局部最优但从安全运营角度说漏掉冷门技术才是最大的风险因为高级持续性威胁恰恰喜欢用不常见的手法绕过检测。数据一致性是另一个头疼的问题。我们当时找了三个安全分析师对同一批200条文本进行独立标注计算的Cohens Kappa系数只有0.61这个一致性水平只能算中等偏上。每个人对这个攻击描述到底算不算某某技术的判断都有差异比如一个经验丰富的红队成员可能把使用Cobalt Strike的BITS任务功能下载载荷拆分成两个标签而另一个分析师觉得只标工具就够了不需要细化到具体技术。这种主观性会直接把噪声带进训练集模型学到的是三个分析师的平均偏好而不是ATTCK标准的客观语义。2. 分层约束建模树结构感知的多标签分类方案2.1 基线方案扁平化多标签直接预测我先说下入门做法是什么样的不然直接上分层方案大家会觉得悬空。最直接的多标签建模方式是把ATTCK的所有叶子节点也就是子技术和无子技术的技术摊平成一个巨大的标签集合用BERT或者类似预训练模型编码文本取[CLS]向量过一个全连接层输出维度等于标签数每个维度过sigmoid得一个0到1的概率训练时用Binary Cross-EntropyBCE做损失函数。推理时设定一个阈值概率高于阈值就算文本包含该标签。这个方案的优点是非常简单工程实现半小时就能跑通但缺点也很明显模型完全不感知标签之间的父子关系。训练数据里如果某父技术和某子技术同时出现的样本占比不高模型就无法学到这种关联预测时就会经常出现前面说的认子不认父或者父对子错的情况。而且长尾问题完全暴露冷门技术基本学不动因为BCE对每个标签独立算损失样本少的标签梯度贡献微乎其微。我们团队当时跑完这个基线微观F1大概在0.62左右看起来不差但一拆分错误案例就发现一个子技术都识别不准更别说细分类了30%以上的错误都属于层级内部混乱——要么只标了父没标子要么标了子但对应错了父。这类错误在只看宏观指标时完全看不出来但对下游运营人员来说等于给了个说了等于没说的标签因为没法指导后续的溯源分析。2.2 层级感知结构把ATTCK树编码进模型要解决层级混乱核心思路是让模型在结构上知道标签之间的依赖关系。我们采用了一种既简单又有效的方案把预测分成两步而不是一步到位。第一步用文本向量预测战术层标签TA开头的那批大概14个因为战术的数量很少、定义相对宽泛分类难度低但能给后续预测提供强上下文先验。第二步在已知战术标签的前提下预测该战术下的所有技术和子技术标签。这样每个技术标签的预测输入里拼接了对应的战术预测结果模型自然学会了只有当预测到横向移动战术时才会去认真考虑横向移动下面的技术是否成立。具体实现上我们没有用复杂的图神经网络而是用了一个条件概率建模的trick。假设文本为x战术标签集合为T技术标签集合为C。模型结构上是共享一个BERT编码器然后分出三组分类头TA_head、T_head、S_head。计算时先得TA_logits过sigmoid得到战术概率p_ta然后每个技术标签的logits不仅来自文本特征还会加上一个可学习的偏移项这个偏移项由相关战术概率加权求和得到。公式化表达就是tech_logit_i W_i · h[CLS] b_i sum_{t in tactics_of(tech_i)} alpha_t · p_ta_t gamma_i其中alpha_t和gamma_i都是可学习参数gamma_i可以理解为该技术的先验偏置。这样当一个战术的概率很高时它下面的技术logits会整体被抬高符合逻辑其他无关技术的logits不受影响甚至可被一个额外的负向约束压低。为了让模型更强地遵守父子约束我们在损失函数里加了一个层次一致性正则项。思路是把违反约束的预测当作惩罚如果模型预测子技术为1但父技术为0就额外施加一个较大的损失权重。实现上是对这类样本在BCE损失中乘以一个大于1的系数比如2.0相当于告诉模型你做这种事情我加倍罚你。2.3 损失函数与样本加权针对长尾做对策长尾分布是我们投入精力最多的部分之一。光靠常规BCE冷门技术几乎不可能被预测出来。我们做了两个层面的处理损失函数层面和样本采样层面。损失函数层面Focal Loss在这个项目里非常有效。它跟BCE的区别是给每个样本施加一个调制因子让容易分类的样本贡献的梯度变小让难以分类的样本贡献变大。对于ATTCK这种正样本量少、尾部技术难以学习的场景Focal Loss能显著提升对低频标签的召回率。我们用的参数是gamma2.0、alpha0.25这两个值在多个数据集上表现都比较稳。改完之后尾部技术的平均召回率大概提升了5到7个百分点代价是头部技术的精确率略微下降了1到2个百分点整体F1是涨的。样本采样层面我们采用了阈值移动加标签重平衡的组合策略。针对每个技术标签统计其在验证集上的精确率-召回率曲线单独寻优一个最优阈值。这样头部技术可能用0.6的阈值冷门技术用0.25的阈值策略是宁可多预测也不漏判的因为漏报的代价更高。还有个小技巧是做了负样本裁剪对超级常见的几个大标签比如T1059命令与脚本解释器随机丢弃一部分负样本避免模型被它们淹没。3. 训练数据准备开源语料与内部标注的取舍3.1 能用的公开数据集与它们的局限做安全领域的NLP最大的难题永远是数据。这个项目里我自己搭建的训练集几乎是大海捞针式凑出来的。MITRE官方本身有一个叫TRAMTechnique Reasoning and Mapping的开源项目里面的标注样本可以直接拿来用但数量非常有限覆盖的技术也很不均衡。另外一个公开的干活数据集是UMBC和其他几个高校联合出的包含大量经过安全专家标注的威胁报告映射结果但这些报告的语言风格偏正式跟实际告警日志文本有差距。用这些公开数据的最大好处是省时间几万条样本能覆盖大约200多个技术。但直接拿来训练项目里的模型会有个致命的分布偏移问题公开数据多来自完整的安全研究报告和CTF write-up而实际要部署时面对的是由壳、SOC告警连成的碎文本两者风格差异很大。比如公开报告里特别喜欢先说背景再讲攻击步骤但告警日志往往只有两行直接写Detected suspicious PowerShell command with encoded parameters。这种语料偏差会导致模型在真实上线时性能大幅度下跌。所以我们把这部分公开数据当作预训练语料先让模型熟悉ATTCK节点描述和攻击手法的常规表述方式再用内部数据进行微调。这样做的效果比直接在内部数据上从零训练要好得多因为内部数据量有限直接训容易过拟合到特定格式。3.2 内部标注流程与质量校准内部数据的标注我建议按这个流程来先准备一批包含告警描述、威胁情报摘要、红队月报摘要的文本合集去重清洗掉IP、哈希这类无关噪声但保留工具名和命令特征然后让2到3名分析师独立标注标注维度包括战术标签集、技术标签集和子技术标签集同时给每个标签标一个置信度高/中/低最后开一轮仲裁会对不一致的样本统一口径。要特别说一下置信度标记的价值。它在后面写规则过滤、设置阈值、甚至在损失函数里做样本加权时都能用上。比如置信度低的样本我通常在训练时给它的权重设为0.5高于置信度高的样本或者直接在损失函数里用置信度作为该样本的权重。当然这里有个度的问题权重要设下限不能完全为零否则等于放弃了那些语义模糊的样本。标注一致性统计也要做细一点。除了整体Kappa系数要按技术算各标签级别的一致性看哪些标签在标注里最常吵架。我们项目里最常吵架的是用户执行和网络钓鱼这类行为边界模糊的标签这些标签在模型训练时样本质量本身就不高后续需要人工重点清洗。3.3 数据增强与负样本构建技巧文本数据增强这块安全领域可以玩的花样比其他领域多一些因为攻击描述有很多格式化的变体。我们测试过几种增强手段效果比较好的包括同义词替换命令名称和文件名比如把PowerShell替换成powershell.exe或PS让模型学到大小写和扩展名不影响语义句式重排把一个长句拆成短句再合并模拟真实告警截断的情况以及模板填充利用ATTCK节点描述里的定义句作为模板替换其中的动作对象合成一批正样本用来补充冷门技术的样本量。负样本的构建策略同样重要。随手拿一批完全无关的文本网络设备日志、正常员工邮件摘要作为全负样本可以让模型学会这上面完全没有ATTCK相关行为时的判断。但这里有个坑真实世界里攻击行为往往是多层级的、多步骤的单一负样本如果只包含一个正常操作训练时模型容易变得过保守。我建议在负样本里混合一些包含攻击动作但不属于当前标签集的文本比如一条明确写着使用Mimikatz进行凭据转储的告警如果当前标签集跟凭据访问无关它也应该被当成负样本这样模型才不会在遇到类似攻击行为时乱贴标签。4. 模型选型与训练细节从TextCNN到预训练模型的演进4.1 为什么最终选了预训练模型而非轻量级方案我最初做了一个TextCNN版本因为想追求推理速度——毕竟在SOC环境里每天有海量日志进来模型要是跑得太慢没法在线接入。TextCNN的结构特别简单词嵌入加几个不同卷积核尺寸的卷积层池化后接全连接输出多标签概率。它的优点是参数少、推理快、CPU也能跑缺点是语义理解能力上限太低对同义改写和上下文依赖的建模能力非常弱。实测对比结果很清楚地说明了问题在相同的训练集下TextCNN的微观F1比BERT-base低了大约8到10个百分点差距在末尾的、语义精细的技术上尤其大。举例来说一些技术描述里只换了攻击工具名罪状指的就是同一种行为但TextCNN会因为重叠词汇少而判断为不同标签BERT虽然速度慢一些但至少能通过上下游文本信息捕捉到这是在描述同一种行为模式。所以最终方案是BERT-base-Uncased作为骨干模型。这里可以多说一句选型理由安全文本不像代码文本那样有大量的符号特征英文BERT学到的通用语义表示已经能覆盖大部分攻击描述中的动作词不需要专门去训练一个安全领域模型。如果你处理的是中文安全文本可以用哈工大开源的RoBERTa-wwm-ext效果同样不错。如果对推理性能有硬性要求可以考虑把模型蒸馏成一个小型的DistilBERT版本在F1掉1到2个百分点的情况下推理速度能提升3到4倍。4.2 训练配置与参数调优实测训练过程中有很多非常重要的细节。最大的模型BERT-base加全量标签头参数量大概在1.2亿左右单张V100可以很轻松跑但数据量非常有限的时候很容易过拟合。我们做了三手准备一是用10%的样本做验证集做早停二是给BERT层加了一个0.1的dropout三是用的warmup ratio是0.1即前面10%的步数用较低学习率预热避免大模型在一开始就蹦得太远导致收敛到坏的最优解。学习率这里要重点说下。用AdamW优化器BERT层学习率设2e-5新初始化的分类头可以用5e-5分开设置的原因是老预训练参数已经学得比较好不需要太大步长去更新新初始化的分类头需要快速收敛所以给大一点的学习率。这两个学习率设反了会造成严重的问题分类头还没收敛好BERT层的预训练知识已经被打乱了。训练的时候batch size是16max_len是128。可能有人会觉得128很短但实际看的话告警日志和威胁摘要很少超过这个长度对于超长文本我们可以做滑动窗口分词后再做标签合并预测。这个方案比直接截断要好因为ATTCK标签有时候是在长文的后半段才出现的直接截断等于主动扔掉关键信息。4.3 条件概率建模的具体实现前面提到的层级感知结构我在这里梳理一下实现代码逻辑方便看文章的人直接落地。核心模块分三段TA预测头、技术预测头、子技术预测头。技术预测头的输入特征除了BERT CLS向量还拼上了对应战术的预测概率向量。import torch import torch.nn as nn import torch.nn.functional as F class AttackHierarchyModel(nn.Module): def __init__(self, bert_model, num_tactics, num_techniques, tech_to_tactic_map, num_subtechs, subtech_to_tech_map): super().__init__() self.bert bert_model self.hidden_size bert_model.config.hidden_size self.num_tactics num_tactics self.num_techniques num_techniques self.num_subtechs num_subtechs # 三层分类头 self.tactic_head nn.Linear(self.hidden_size, num_tactics) self.tech_head nn.Linear(self.hidden_size num_tactics, num_techniques) self.subtech_head nn.Linear(self.hidden_size num_techniques num_tactics, num_subtechs) # 保存层级映射关系 self.tech_to_tactic_map tech_to_tactic_map # {tech_id: [tactic_ids]} self.subtech_to_tech_map subtech_to_tech_map # {subtech_id: tech_id} def forward(self, input_ids, attention_mask, token_type_idsNone): # 1. BERT编码 outputs self.bert(input_ids, attention_maskattention_mask, token_type_idstoken_type_ids) pooled outputs.pooler_output # [batch, hidden_size] # 2. 战术预测 tactic_logits self.tactic_head(pooled) tactic_probs torch.sigmoid(tactic_logits) # 3. 技术预测拼接战术概率 tech_input torch.cat([pooled, tactic_probs], dim1) tech_logits self.tech_head(tech_input) tech_probs torch.sigmoid(tech_logits) # 4. 子技术预测拼接技术概率 subtech_input torch.cat([pooled, tech_probs, tactic_probs], dim1) subtech_logits self.subtech_head(subtech_input) subtech_probs torch.sigmoid(subtech_logits) return tactic_probs, tech_probs, subtech_probs这个结构有两个显著优势第一训练时技术头的梯度可以反向传播到战术头的输出因为tech_input里包含tactic_probs所以模型不仅会用文本信息约束战术预测还会用这个技术到底成不成立来反向修正战术判断第二推理时天然满足层级约束因为技术预测已经看到了战术概率子技术预测看到了技术和战术概率逻辑上子技术不可能跳脱父技术存在。当然这个方案不是完全无懈可击。一个明显的风险是错误传播如果战术层预测错了技术层会被带偏。我们用的缓解手段是在训练阶段对战术概率做dropout风格的随机mask以让模型不把战术预测当成一个完全可靠的事实从而学会在战术预测可能错误时仍然能从文本里独立判断技术。这个trick在实际中让整体F1提升了约1.5个百分点非常值。5. 评估体系不只是看Accuracy要按层级拆解5.1 层次化评估指标的设计ATTCK标注模型不能只用一组全局F1糊弄自己因为全局指标对层级内部错误的感知太迟钝了。我们做了一套按树结构拆分的评估方案这里详细说一下。第一组是战术级精确率、召回率、F1它评价模型对攻击阶段判断的宏观正确性。这个指标最容易达标因为战术数量少、语义范畴大一般准确率都在85%以上。第二组是技术级和子技术级的严格F1它要求预测的标签集合跟真实标签集合完全一致才算正确。这是最严苛的评估方式也是真正考验模型能力的指标。我们最终的micro-F1大概在0.71左右但拆分到不同层级看技术级的macro-F1只有0.58子技术级更低一些说明尾部标签拉低了整体。第三组是部分正确率。一个预测如果预测对了父技术但子技术错了它不算全对但也绝不是全错——至少把攻击者所处的战术阶段定位对了。我们把它定义为一个单独的评估项用来区分模型的方向是否对与细节是否到位。这个指标对运营的人来说很有参考价值因为当模型给出一条告警说这是横向移动大类下的某个技术哪怕子技术分错了分析师也只需要在小范围内排查比完全没有提示强得多。5.2 基线对比实验与结论我们测了好几组模型配置来做对照实验关键是各种配置下的评估结果差异在哪。最终汇报呈现结果是按这五组来做的扁平BERT基线、加入Focal Loss的扁平BERT、层级感知结构、层级感知加Focal Loss、层级感知加Focal Loss再加后处理规则。评估使用一个包含600条样本的内部测试集涵盖大约120种不同技术。结果显示层级感知结构单独带来的提升其实有限micro-F1从0.62到0.65但它对层级内部错误的抑制非常明显认子不认父错误率降低了约70%。Focal Loss的加入让尾部技术的召回率大幅上涨micro-F1又能进一步从0.65提升到0.69。最后加上的后处理规则比如预测出子技术时强制补充父技术、对低置信度技术标签做非极大值抑制把micro-F1稳定到了0.71。我特别想提醒大家不要过度追求测试集上的F1。实际部署场景下模型面对的是全新数据分布真实F1比测试集上低3到5个百分点太正常了。做评估时最好做一次时间序列切分用时间在前的数据训练时间在后的数据测试模拟未来数据的样子这样测出来才是最贴近上线后真实性能的。5.3 阈值选择与决策偏移最终模型给每个技术都算出一个0到1的概率但怎么把这个概率转成有或没有的二元标签需要仔细考虑。大多数项目习惯直接用0.5当阈值这是最简单的做法但对长尾分布来说并不合适。我们用的是最优阈值寻优在验证集上对每个标签画PR曲线找到精确率和召回率最平衡的点或者根据运营需求选择召回率优先的点比如全部标签阈值设为召回率超过0.85时对应的值。这个操作很简单就是几行sklearn代码的事但对最终效果的影响比换模型还大。还有个额外的小技巧是设定一个概率下限。有的技术频率极低模型给它的概率永远不会太高这种情况下如果固定阈值它永远无法被激活。我们通过对这类技术单独降低阈值比如降到0.15换来了对冷门技术的识别率大幅提升代价是精确率下降一些。在安全运营里对未知攻击的召回率从来都比精确率重要——多猜几个标签让分析师去排查比漏掉一个真正的攻击动作好得多。6. 上线部署与后续迭代跳出实验室思维6.1 推理性能优化与缓存策略模型上线之前我们做了详细的性能测试。BERT-base在GPU上一次前向推理大概需要20到40毫秒看起来很快但在每天有几十万条告警的SOC里这个速度是撑不住的。如果把所有告警都直接送进模型至少需要一台中等配置的GPU服务器才能实时跟上。优化方案分两路一个是场景分流简单文本走轻量规则加TextCNN快速过滤只有规则引擎判定疑似攻击的高优先级告警才送进BERT另一个是向量化批量推理将一天内的告警文本累积成一个batch一次性跑完整批比逐条推理快不止5倍。实际工程配置上我们最后用的是一个8G显存的GPU加一个100G的SSD做向量缓存线上可以支撑日处理量约30万条短文本。另外一个非常重要的优化是相似样本缓存。很多告警来自同一个攻击团伙的同一套工具链文本内容几乎是重复的。我们给每条文本算一个MinHash指纹如果跟之前已经推理过的样本相似度大于0.95就直接复用上一次的预测结果不再重新调用模型。这一步实测定值地省下了大概40%的推理资源。6.2 ATTCK版本更新的适配问题MITRE ATTCK框架并不是静止的差不多每半年就会有一次大的版本更新新增或调整部分技术和子技术。模型训练时标签集合是固定的一旦上游框架变了模型的一处标签头就变得不匹配需要重新调整。我们在版本更新这件事上踩过坑第一次做模型更新时只是简单地把新版本的技术描述追加到训练集里然后训练了10个小时结果上线后发现旧版本数据里的标签都对了新版本特有的技术几乎全部预测不出来。后来反思问题出在旧数据没做标签映射新版本的标签跟旧版本的标签有一部分是一对多或多对一的合并拆分关系如果不重新映射旧标签训练数据里新旧标签混在一起就是一场灾难。这里提供给大家一个可行的方案先做一次标签映射把旧版本数据中的标签映射到新版本的相应标签映射不了的旧标签样本直接丢弃或降权然后用新版本节点的官方描述做一组模板数据跟历史映射数据合并微调最后在验证集上重点检查新增与变更标签的单独指标。这套流程走下来版本升级的处理时间可以控制在很小的范围内效果也不错。6.3 持续迭代机制人工闭环反馈模型上线后肯定会遇到新的攻击手法和新的自然语言表达方式。如果模型是静态的每隔半年训练一次它对新型攻击的敏感度会越来越低。比较有效的做法是建立一个人工闭环反馈机制每天被分析师复核过的标注结果自动回流到一个daily标注库一旦某个标签当天的预测置信度整体偏低说明模型开始搞不定这类文本了就把这些case抽出来单独做一次增量训练。增量训练的细节也很重要。不能直接把新数据concat到旧数据里重新训练那样容易出现灾难性遗忘。稳妥的做法是用一个小的学习率比如1e-5在旧模型基础上继续训练只更新BERT输出层之上的分类头参数BERT主体参数的更新幅度要控制得很小。我们一般是一周用新增的人工复核数据做一次轻量增量训练每两周做一次全量重训。这样模型既跟得上新型攻击的描述方式又不至于丢失旧知识。6.4 部署形态的思考不仅是一个模型服务这项目最后做出来的不只是一个可调用的模型API而是一套围绕ATTCK的文本分析服务。因为用户真正需要的不是一串概率值而是能直接落到安全运营流程里的结构化结果。所以最终输出的结构包含四个部分必备的标签集、每条标签对应的置信度、标签关系树上的路径比如横向移动 T1570 T1570.001、以及模型定位到文本中支持该标签的片段。最后这一项其实非常有价值。当分析师看到一条模型给出的标签时他最想知道的不是模型为什么觉得是攻击而是哪句话让模型做出了这个判断。我们通过在模型输出的注意力权重里找到权重最高的几个词来生成一个简短的证据片段效果出奇地好。它既能让分析师快速验证模型判断是否合理也能作为告警的附加上下文直接展示在工单系统里省去分析师很多从头看日志的时间。回到开头说的那个痛点其实做这个项目的核心收获可以概括成一句话安全文本分类问题真正难的从来不是深度学习模型本身而是如何把领域知识ATTCK的树状结构、标签的长尾分布、真实业务中对召回率的偏好转化成训练数据、损失函数和评估指标这些工程细节。多标签已经不是稀奇事了但当一个多标签问题里的标签还有着强结构依赖时就不只是换个损失函数那么简单了。要把这套方案的各个细节真正适配到你们自己的数据格式里建议从我做过的那个时间序列评估方法开始先拿到自己数据上真实的性能底数再决定在哪个环节投入优化精力会比自己闭着眼睛从零训练模型要少走很多弯路。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑