1. 项目概述与核心挑战

勒索软件这几年已经从一个技术圈的话题,变成了几乎所有企业IT部门头上的达摩克利斯之剑。我处理过不少应急响应案例,亲眼见过一个简单的钓鱼邮件附件,如何在几小时内加密掉整个部门的文件,然后弹出那个令人绝望的支付界面。传统的基于签名的杀毒软件,在面对层出不穷的变种和零日攻击时,常常力不从心。这就引出了我们今天的主题:如何利用机器学习,让检测系统变得更“聪明”,能够识别出那些它从未见过的勒索软件。

简单来说,这个项目的目标,就是构建一个能够自动分析文件或网络行为,并判断其是否为勒索软件的智能系统。它不依赖已知的病毒库特征,而是通过学习大量正常软件和恶意软件的行为“模式”,自己总结出勒索软件的“坏习惯”。你提供的资料里提到了很多关键的研究和工具,比如利用深度学习检测勒索软件、分析网络流量、甚至像ShieldFS这样的自愈文件系统,这些都是构建一个完整检测方案的重要拼图。

这个内容适合谁呢?如果你是网络安全领域的研究人员、安全运维工程师,或者是对AI在安全落地感兴趣的数据科学家、机器学习工程师,那么这篇从理论到实操的完整复盘应该能给你不少启发。即使你只是对机器学习应用感兴趣,想了解一个真实的项目是如何从数据到模型一步步构建的,这里面的思路和踩过的“坑”也很有参考价值。

2. 整体技术路线与方案选型

面对勒索软件检测这个问题,我们首先要决定“看什么”和“怎么看”。你提供的参考文献给出了几个主流方向,我在实际项目中通常会采用一种混合策略,不把鸡蛋放在一个篮子里。

2.1 检测对象的选择:静态、动态与网络流量

静态分析 就像是给软件“验尸”。我们不运行它,而是直接检查它的“尸体”——即可执行文件本身。我们可以提取它的字节序列、导入的函数表(比如它是否大量调用了加密相关的API如 CryptEncrypt )、字符串信息(是否有“你的文件已被加密”、“支付比特币”等勒索字样)、文件结构特征等。这种方法速度快、资源消耗低,适合做第一道快速筛查。参考文献中Al-Bakri等人利用马尔可夫链分析API调用序列,本质上就是一种静态层面的行为模式预测。

注意 :静态分析最大的软肋是混淆和加壳。高级勒索软件会把自己的代码加密或变形,让静态分析工具看到的是一堆乱码。因此,纯静态分析在实战中误报和漏报率会比较高,通常作为辅助手段。

动态分析 则是给软件提供一个“沙箱”环境,让它实际跑起来,我们在一旁观察它的一举一动。我们会监控它在运行过程中对文件系统的操作(是否大量、快速地对不同格式的文件进行重写)、对注册表的修改、进程行为、以及最关键的网络通信行为。ShieldFS文件系统的工作方式就极具启发性,它通过监控文件访问模式(如大量文件的熵值突然改变)来实时感知勒索行为。动态分析能捕捉到运行时最真实的行为,对抗混淆能力强,但代价是速度慢、需要隔离环境,且可能被沙箱检测技术规避。

网络流量分析 是另一个极其重要的维度。很多勒索软件在加密完成后,会与命令控制服务器通信,或进行比特币地址查询等。Alhawi等人的研究就是专注于从网络流量中检测勒索软件。通过分析流量中的TLS证书信息、域名特征、数据包时序、载荷特征等,可以在恶意软件造成实质性破坏前,在网络边界就将其阻断。这对于防御勒索软件横向移动和外部通信至关重要。

我的策略是: 入口处用静态分析快速过滤,对可疑样本送入沙箱进行动态行为分析,同时在网络层部署流量检测模型,形成纵深防御

2.2 机器学习模型选型的考量

选什么模型,取决于我们有什么样的数据,以及我们追求的是精度、速度还是可解释性。

  1. 传统机器学习模型(如随机森林、XGBoost) :当我们的特征是基于专家经验手工构建的(例如,文件操作次数、注册表修改项、特定API调用频率),这类树模型表现非常出色。它们训练和预测速度快,对特征量纲不敏感,而且通过特征重要性排序,还能给我们一些“为什么”的洞察。在项目初期,特征维度可控时,我通常会先用XGBoost跑一个基线模型,它的性能往往能超越很多更复杂的模型。

  2. 深度学习模型(如CNN、LSTM/GRU) :当我们拥有更“原始”的数据时,深度学习的威力就显现出来了。

    • 用于静态分析 :可以将可执行文件的二进制字节流直接作为一维信号,输入到一维卷积神经网络中。CNN能自动学习字节序列中的局部模式,比如某些特定的指令序列组合。Tseng等人的研究就采用了这种方法。
    • 用于动态分析 :系统调用序列或API调用序列是典型的时间序列数据。这时,循环神经网络(RNN),特别是它的变体LSTM或GRU,就非常适合捕捉行为序列中的长期依赖关系。例如,勒索软件通常会遵循“遍历目录->读取文件->加密->写入新文件->删除原文件”的序列模式,LSTM能很好地学习这种模式。
    • 用于网络流量 :可以将数据包载荷或流量统计特征(如每秒包数、流量大小)序列化,同样使用LSTM进行分析。
  3. 集成与多分类策略 :勒索软件家族繁多(如WannaCry, Locky, Ryuk),我们可能不仅想区分“恶意”与“良性”,还想识别出具体的家族。这就变成了一个多分类问题。参考文献中提到了“一对多”和“一对一”策略。 一对多 是为每个家族训练一个二分类器(判断是否属于该家族),简单但可能面临类别不平衡问题。 一对一 是为每两个家族训练一个分类器,然后通过投票决定最终类别,训练的分类器数量多,但每个分类器的任务更简单。在实际中,如果家族数量不多(<10),我会优先用“一对多”配合能处理多类的模型(如随机森林、神经网络);如果家族很多,则考虑“一对一”或使用深度学习模型直接进行多分类输出。

为什么最终选择混合模型架构? 单一模型总有局限。在最终部署的原型中,我设计了一个两级流水线:第一级是一个轻量级的随机森林模型,使用从静态分析和简单动态沙箱中提取的快速特征,进行初步高危预警。被第一级标记为可疑的样本,会进入第二级,由一个基于LSTM的动态行为序列分析模型进行深度研判。这样既保证了整体检测的实时性,又对高威胁样本进行了精准分析。

3. 数据获取、特征工程与预处理

机器学习项目,七分在数据,三分在模型。对于勒索软件检测,数据质量直接决定了天花板。

3.1 数据来源与采集

你提供的资料里提到了几个非常关键的数据源,我在项目中都有用到:

  • 恶意样本库
    • VirusShare :这是一个庞大的恶意软件样本仓库,是获取原始勒索软件样本的宝库。但需要注意,下载和处理这些样本必须在绝对隔离的物理或虚拟环境中进行,通常是在一个没有网络连接的“冰点”分析机上操作。
    • theZoo :另一个活跃的恶意软件样本库,管理相对更规范一些。
    • GitHub项目 :像 rmowri/GetRansomware 这样的项目,有时会提供整理好的样本列表或获取脚本,可以作为补充。
  • 良性样本 :这同样重要且棘手。我们需要大量的正常软件、系统文件作为负样本。来源可以是操作系统安装镜像、官方软件仓库(如Windows Store, Ubuntu apt源)、常用办公软件等。确保其纯净无污染是关键。
  • 动态行为数据 :我们需要让样本在受控环境中运行并记录其行为。
    • Cuckoo Sandbox :一个开源的自动化恶意软件分析系统,可以生成详细的报告,包含文件操作、进程、网络、注册表等几乎所有行为日志。这是我首选的沙箱工具。
    • Hybrid Analysis (Falcon Sandbox) :一个优秀的在线沙箱服务,提供免费和付费的API。当本地资源不足时,可以通过其API提交样本并获取结构化报告,非常方便。
  • 网络流量数据
    • malware-traffic-analysis.net :这个网站提供了大量与恶意软件感染相关的真实网络流量包(pcap文件),是训练网络检测模型的绝佳资源。
    • 自行捕获 :在隔离沙箱中运行样本,同时使用 Wireshark (资料中也提到了)捕获其产生的所有网络流量。Wireshark的 tshark 命令行工具非常适合自动化脚本调用。

3.2 特征工程:从原始数据到模型“语言”

这是最体现工程师经验的部分。特征工程的目标是把原始日志、二进制流、网络数据包,转换成一组能够表征勒索软件本质的数值型特征。

1. 静态特征提取:

  • 基础特征 :文件大小、熵值(衡量文件随机性,加壳或加密的文件熵值通常很高)、节区数量、时间戳。
  • 字符串特征 :提取文件中所有可打印字符串,统计是否包含勒索相关关键词(如“encrypt”、“bitcoin”、“decrypt”、“.locked”等)及其频率。
  • PE头信息 :对于Windows可执行文件,解析其PE结构,提取导入函数表。重点统计与文件操作( CreateFile , WriteFile )、加密( CryptEncrypt , CryptDecrypt )、网络( WinHttpConnect )、进程( CreateProcess )相关的API数量及比例。

2. 动态行为特征提取: 从沙箱报告(如Cuckoo的JSON报告)中,我们可以提取出数百个特征:

  • 文件系统操作 files_written (写入文件数)、 files_deleted (删除文件数)、 files_read (读取文件数)。勒索软件通常会表现出“高写入、高删除、高读取”的特征。计算文件操作速率(如每秒操作数)。
  • 文件类型分布 :统计被操作的文件后缀名,勒索软件倾向于加密文档( .docx , .pdf )、图片( .jpg , .png )、数据库( .mdb , .sql )等用户价值高的文件。
  • 注册表操作 :修改自启动项、修改文件关联等行为的次数。
  • 进程行为 :创建的进程数、注入的进程数。
  • API调用序列 :这是黄金特征。将沙箱记录的系统调用按时间顺序排列,形成一个序列。我们可以直接使用这个序列训练LSTM,也可以从中统计特定高危API调用的频率。

3. 网络流量特征提取: 使用 tshark 或Python的 scapy 库分析pcap文件:

  • 流量统计特征 :总数据包数、总字节数、上行/下行流量比、平均数据包大小、数据包时间间隔的均值和方差。勒索软件在加密完成后与C2通信或进行密钥交换时,可能会产生特定的流量脉冲。
  • 协议分布 :TCP、UDP、DNS、HTTP/S流量的占比。
  • TLS/SSL特征 :如果流量是加密的,可以提取TLS握手中的信息,如证书有效期(勒索软件C2服务器的证书可能刚申请不久)、证书颁发者(是否来自不常见的CA)、支持的加密套件等。
  • DNS特征 :查询的域名是否具有DGA(域名生成算法)特征,如长度随机、字符混乱、TTL时间短等。
  • HTTP特征 :User-Agent字符串是否异常、URI路径是否规律性差、是否有POST加密数据等。

3.3 数据预处理与特征编码

原始特征提取出来后,必须经过处理才能喂给模型。

  1. 处理缺失值与异常值 :某些样本可能因为运行失败而缺少某些行为特征。对于数值特征,我通常用中位数填充;对于类别特征,用众数或单独设一个“缺失”类别。
  2. 数值特征标准化/归一化 :像文件大小、操作次数这类特征,量纲差异巨大。使用 StandardScaler (标准化)或 MinMaxScaler (归一化)将其缩放到相近的范围,有助于梯度下降类模型(如神经网络)的收敛。
  3. 类别特征编码 :像“文件后缀名”、“协议类型”这类文本特征,需要转为数字。最常用的是 独热编码 。例如,文件后缀有 .docx , .jpg , .exe 三种,就生成三个二进制特征列。Pandas的 get_dummies() 函数(资料中提及)可以很方便地完成这个工作。但要注意,如果类别非常多(如所有可能的API函数名),独热编码会导致特征维度爆炸,这时可以考虑使用目标编码或嵌入层(对于深度学习)。
  4. 特征选择 :我们可能生成了成百上千个特征,但其中很多是冗余或无关的。直接全部使用会导致模型臃肿、易过拟合、训练慢。我会使用以下方法:
    • 过滤法 :计算每个特征与目标变量的相关性(如卡方检验、互信息),保留相关性最高的前K个。
    • 包裹法 :如 递归特征消除 。它通过反复构建模型(比如用随机森林),并根据模型的特征重要性排序,剔除最不重要的特征,直到达到指定的特征数量。这个过程计算量大,但效果通常更好。Scikit-learn提供了 RFECV 工具,可以结合交叉验证自动选择最优特征数。
    • 嵌入法 :使用自带特征选择能力的模型,如Lasso回归,或者直接利用树模型训练后的特征重要性排序。

经过这一系列处理,我们终于得到了一个干净、规整的特征矩阵,可以送入模型进行训练了。

4. 模型构建、训练与调优实战

有了高质量的数据,接下来就是搭建和打磨我们的检测引擎。这里我以构建一个基于动态行为特征的集成检测系统为例,拆解整个过程。

4.1 构建训练与测试数据集

首先,我们必须严格划分数据集,防止数据泄露,这是评估模型真实性能的基础。

  • 数据划分 :将总样本集(包含勒索软件和良性软件)按7:1.5:1.5的比例随机划分为 训练集 验证集 测试集 。训练集用于模型学习参数,验证集用于在训练过程中调整超参数和选择模型,测试集则是在所有开发完成后,用于最终评估的“期末考试”,在整个调优过程中绝对不能触碰。
  • 类别平衡 :勒索软件样本数量通常远少于良性样本。直接训练会导致模型倾向于将所有样本都预测为良性,也能获得很高的准确率,但这毫无意义。我们必须处理这种不平衡。常用方法有:
    • 对少数类(勒索软件)上采样 :使用SMOTE等方法生成合成样本。
    • 对多数类(良性软件)下采样 :随机丢弃一部分良性样本。
    • 在模型层面赋予不同权重 :在训练时,给勒索软件样本的损失函数赋予更高的权重。例如,在Scikit-learn的模型中设置 class_weight='balanced' 。 我的经验是,结合 轻微的下采样(让良性样本数约为恶意样本的2-3倍)和类别权重 ,效果比较稳定。

4.2 模型训练与超参数调优

我通常会并行尝试几个不同类型的模型,看看哪个更适合当前的数据。

1. 传统机器学习模型(以XGBoost为例):

import xgboost as xgb
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform, randint

# 定义模型
xgb_model = xgb.XGBClassifier(objective='binary:logistic', eval_metric='logloss', random_state=42, use_label_encoder=False)

# 定义超参数搜索空间
param_dist = {
    'n_estimators': randint(100, 500),
    'max_depth': randint(3, 10),
    'learning_rate': uniform(0.01, 0.3),
    'subsample': uniform(0.6, 0.4),
    'colsample_bytree': uniform(0.6, 0.4),
    'gamma': uniform(0, 0.5)
}

# 使用随机搜索进行调优
random_search = RandomizedSearchCV(
    estimator=xgb_model,
    param_distributions=param_dist,
    n_iter=50,
    cv=5,
    scoring='f1',
    verbose=2,
    random_state=42,
    n_jobs=-1
)
random_search.fit(X_train, y_train)

# 输出最佳参数和模型
best_xgb = random_search.best_estimator_
print(f"Best F1 Score on Validation: {random_search.best_score_:.4f}")

这里没有用传统的网格搜索,而是用了 随机搜索 。因为超参数组合空间巨大,随机搜索在有限的计算资源下,有更高概率找到较优解,效率更高。评估指标我选择了 F1分数 ,因为它同时考虑了精确率(Precision)和召回率(Recall),对于不平衡的二分类问题(勒索软件检测)比单纯看准确率(Accuracy)更有意义。

2. 深度学习模型(以LSTM处理API序列为例): 对于API调用序列,我们需要先进行预处理,将每个API函数名映射为一个整数ID,然后将序列填充到相同长度。

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout
from tensorflow.keras.preprocessing.sequence import pad_sequences

# 假设我们已经将API序列转换为整数列表,并存储在`sequences`中
max_len = 500  # 设定序列最大长度
X_seq = pad_sequences(sequences, maxlen=max_len, padding='post', truncating='post')

# 构建LSTM模型
model = Sequential()
model.add(Embedding(input_dim=vocab_size, output_dim=128, input_length=max_len))
model.add(LSTM(units=128, return_sequences=False, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))  # 二分类输出

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy', tf.keras.metrics.Precision(), tf.keras.metrics.Recall()])

# 训练模型,使用验证集监控
history = model.fit(X_seq_train, y_train, epochs=20, batch_size=32,
                    validation_data=(X_seq_val, y_val),
                    class_weight={0: 1, 1: 5})  # 给恶意样本更高权重

深度学习模型的调优更复杂,包括调整网络层数、LSTM单元数、Dropout率、学习率等。通常需要结合验证集上的表现进行手动或自动调优。

4.3 模型评估与选择

模型训练好后,我们不能只看它在训练集上的表现,必须用 验证集 进行客观评估。我会看以下几个关键指标:

指标 计算公式 意义 在勒索软件检测中的侧重点
精确率 (Precision) TP / (TP + FP) 预测为恶意的样本中,真正是恶意的比例。 高精确率意味着误报少 。对于安全运营中心来说,误报过多会淹没告警,导致“告警疲劳”。
召回率 (Recall) TP / (TP + FN) 真正的恶意样本中,被模型找出来的比例。 高召回率意味着漏报少 。漏掉一个勒索软件可能导致灾难性后果。
F1 Score 2 * (P * R) / (P + R) 精确率和召回率的调和平均数。 综合平衡指标 。通常作为模型选择的 核心指标 ,因为它同时惩罚了误报和漏报。
ROC-AUC ROC曲线下面积 模型区分正负样本能力的综合度量。 对类别不平衡不敏感,能很好地反映模型的整体排序能力。

在安全场景下, 召回率往往比精确率更重要 。宁可误报一些(让分析师多看一眼),也绝不能漏报。因此,在调优时,我会在保证召回率高于某个阈值(例如95%)的前提下,尽可能优化F1分数。

比较XGBoost和LSTM模型在验证集上的表现后,我可能会发现:XGBoost在结构化特征上表现快且好,而LSTM在序列模式识别上更优。这时, 模型融合 是一个很好的策略。例如,可以将两个模型的预测概率进行加权平均,或者用一个简单的逻辑回归模型将两个模型的输出作为新特征,再进行一次学习(Stacking)。

5. 模型解释性与系统集成

模型效果再好,如果是个“黑盒”,安全分析师也不会信任它。特别是在误报发生时,我们需要知道模型是“根据什么”做出的判断,才能进行人工复核和规则优化。

5.1 可解释性技术应用

对于像XGBoost这样的树模型,我们可以直接输出 特征重要性 ,看到是“文件删除次数”还是“特定API调用”对决策影响最大。这本身就具有很强的解释性。

对于深度学习“黑盒”模型,我们需要借助专门的工具:

  • SHAP :这是目前最流行的模型解释框架之一。它基于博弈论,可以计算每个特征对于单个样本预测结果的贡献值。例如,对于一个被判定为勒索软件的样本,SHAP可以显示,是因为它的“文件熵值高”贡献了+0.3分,“调用了CryptEncrypt”贡献了+0.5分,而“进程树简单”贡献了-0.1分,最终总分超过了阈值。这种可视化的解释非常直观,能让分析师快速理解模型的决策依据。
  • LIME :针对单个样本,在局部用一个可解释的简单模型(如线性模型)去近似复杂模型的预测,从而解释这个样本。

在项目中,我会对验证集上的一些典型样本(特别是被模型高置信度判定,但结果有争议的样本)进行SHAP分析,生成力力图。这不仅增强了系统的可信度,还能帮助我们发现特征工程中的问题,或者识别出一些新的、之前未考虑到的恶意模式。

5.2 构建端到端的检测系统原型

模型训练好、可解释性也解决了之后,我们需要把它变成一个可以运行的系统。一个简单的原型可以这样设计:

  1. 数据采集模块 :部署一个轻量级代理在终端或服务器上,实时监控文件系统操作和进程创建事件,生成行为日志流。同时,在网络边界部署流量镜像,将流量发送给分析模块。
  2. 特征提取与向量化模块 :这是一个核心服务。它接收原始行为日志和网络流量,运行我们之前开发的特征提取代码,将原始数据实时转化为特征向量。这个模块需要高效、稳定。
  3. 模型推理服务 :将训练好的模型(如XGBoost和LSTM模型)用 pickle joblib 保存下来。使用Flask或FastAPI搭建一个简单的REST API服务。特征向量化模块将特征向量通过API发送过来,该服务加载模型进行预测,并返回结果(恶意/良性)及置信度。
  4. 决策与告警模块 :接收推理结果。可以设置多级阈值:例如,置信度>0.9直接告警并隔离;置信度在0.7-0.9之间,发出可疑警告,并附上SHAP解释图,供安全分析师研判;置信度<0.7则放行。告警信息可以集成到SIEM(安全信息与事件管理)系统或工单系统中。
  5. 反馈闭环 :安全分析师对告警的处置结果(真阳性、假阳性)应被记录下来,作为新的标注数据,定期回流到训练集中,用于模型的迭代更新。这就是一个完整的 主动学习 循环,能让系统越用越聪明。

6. 实战中的挑战、陷阱与优化心得

理论很美好,但实际落地时坑非常多。这里分享几个我踩过的“坑”和总结的经验。

6.1 数据质量与概念漂移

  • 问题 :最大的挑战是“概念漂移”。勒索软件作者也在不断进化,他们会针对现有的检测方法进行规避。你今天训练的模型,可能三个月后对新变种的检测率就大幅下降。你从VirusShare下载的样本,可能很多是同一家族的不同变种,导致数据多样性不足,模型过拟合。
  • 对策
    1. 数据源的持续更新 :必须建立一个自动化或半自动化的样本收集管道,定期从多个源头获取最新样本。
    2. 数据增强 :对于行为序列,可以采用随机丢弃部分API调用、轻微打乱顺序(保持因果关系的条件下)等方式进行增强,提升模型鲁棒性。
    3. 在线学习/定期重训 :系统设计上要支持模型的热更新。可以定期(如每周)用新数据对模型进行增量训练或完全重训。

6.2 对抗性攻击与规避

  • 问题 :高级勒索软件会检测沙箱环境(如检查内存大小、进程列表、是否存在鼠标移动),如果在沙箱中,就执行无害行为。它们也会故意延迟执行、增加垃圾API调用以干扰序列模型。
  • 对策
    1. 提升沙箱隐蔽性 :使用定制化的、更接近真实用户环境的沙箱,隐藏沙箱特征。
    2. 关注不变性特征 :寻找那些难以伪装的核心恶意特征。例如,无论怎么延迟,最终大量文件被加密的本质不会变。因此,“文件写入内容的熵值变化”是一个比“文件写入操作发生的时间点”更鲁棒的特征。
    3. 集成多种检测方法 :正如我们采用的混合策略,静态、动态、流量分析多管齐下,规避其中一两种方法的难度远大于规避全部。

6.3 性能与误报的平衡

  • 问题 :动态分析耗时耗资源,无法对每个文件都做。LSTM模型计算量相对较大,可能影响实时性。过于敏感的模型会产生大量误报,淹没安全团队。
  • 对策
    1. 分级检测流水线 :这就是我之前采用的两级策略。第一级用轻量级模型和静态特征快速过滤,只对高分可疑样本启动重量级分析。这能极大提升整体吞吐量。
    2. 精心设计特征阈值 :不要只依赖模型的最终输出。可以为某些关键特征设置硬性规则。例如,如果一个进程在短时间内尝试修改超过100个不同后缀的用户文档文件,无论模型得分如何,都直接告警。这种“规则+模型”的混合系统非常有效。
    3. 置信度校准与阈值调整 :在验证集上仔细调整模型的决策阈值。通过绘制P-R曲线,根据安全团队可承受的误报率,找到对应的阈值,从而确定一个合适的召回率水平。

6.4 工程化部署的细节

  • 特征一致性 :训练时做的所有预处理(标准化、编码),必须原封不动地保存下来(使用 sklearn Pipeline ColumnTransformer ),并在推理服务中严格应用。线上数据和训练数据特征处理的丝毫偏差都会导致预测失效。
  • 模型监控 :上线后要持续监控模型的性能指标,如每日的请求量、正负样本分布、预测置信度分布、以及人工复核的准确率。一旦发现指标显著漂移(例如,平均置信度持续下降),就要触发警报,检查数据或模型是否需要更新。
  • 日志与可追溯性 :系统必须记录每一个检测请求的原始数据、提取的特征、模型预测结果和置信度。这对于事后溯源、分析误报/漏报原因至关重要。

更多推荐