机器学习与深度学习入侵检测实战:从NSL-KDD到随机森林与CNN模型
简介基于Python的机器学习与深度学习入侵检测项目面向计算机相关专业需完成毕业设计、课程设计或期末大作业的学生也适合希望获得完整实战经验的学习者。项目为导师指导并获99分的高分设计覆盖CNN、LSTM等深度模型及多种经典机器学习算法包含从数据预处理、特征工程到模型训练与预测的完整流程代码可直接运行并附有详细项目文档、参考论文和使用说明便于快速上手与二次开发。压缩包共31个文件以Python脚本为主辅以文本说明、CSV数据集、Markdown文档、HDF5模型权重、Word技术方案等整体约26.58MB结构清晰涵盖数据处理、模型实现、结果分析和文档资料等模块。目前已有95人学习下载适合作为毕业设计、课程设计的完整参考。1. 入侵检测项目到底在做什么先看清这个源码包的真实构成与适用人群拿到一个 python基于机器学习/深度学习实现的入侵检测项目源码项目文档参考论文使用说明 的压缩包第一件事不是急着跑demo而是拆开目录看它的输入到底是什么是pcap原始流量还是NSL-KDD这类已经抽好特征的CSV。这一步决定后面所有步骤也是很多人在第一天就翻车的地方。入侵检测在机器学习/深度学习这条路上本质是把网络流量或主机日志的特征向量喂给分类器让它区分正常行为和攻击行为。常见实现是拿公开数据集做监督学习用随机森林当基线再用CNN或MLP做深度模型。这个方向适合做毕设和课程设计的学生、想快速搭一个可演示安全检测原型的研发、以及需要评估机器学习检测效果的安全团队。有项目文档和参考论文作为支撑复现起来会比裸代码顺畅很多但前提是你会正确地使用它。2. 从流量到特征入侵检测里的机器学习/深度学习选型与数据准备2.1 特征工程为什么多数IDS项目先用NSL-KDD而不是原始流量入侵检测的数据来源五花八门最原始的是抓包文件pcap但pcap不能直接送进分类器。你得先把报文解析成协议、端口、标志位、包长、时间间隔这类数值特征这个预处理量级非常大。所以绝大多数课程设计和开源项目会直接采用公开的特征数据集其中最经典的就是NSL-KDD。NSL-KDD是KDDCUP99的精简改进版每条记录有41个特征包含protocol_type、service、flag、src_bytes、dst_bytes等标签是normal或attackattack又细分为DoS、Probe、R2L、U2R。它的好处是特征已经数值化能用pandas直接读进来省去协议解析工作。另一个常见选择是CICIDS2017它使用CICFlowMeter提取80多个双向流特征更新、更贴近现实但文件体积大而且样本分布同样不均衡。做项目时我一般建议先按资料里的参考论文来确定数据集如果论文用的是NSL-KDD那就别硬换CICIDS2017否则后续特征预处理脚本全部要重写。选型理由也很直接如果特征维度不高机器学习里的随机森林和XGBoost通常已经能拿到很好的基线深度学习模型不会在结构化特征上碾压树模型它的优势体现在两类地方——一是流量特征特别多、时序关系明显时用1D-CNN/LSTM自动提取局部模式二是直接把原始字节序列当输入做端到端检测也就是常说的深度学习模型cnn识别恶意软件那类方案。对于这个源码包来说通常既有sklearn的机器学习脚本也有PyTorch/TensorFlow的深度学习脚本先跑哪个取决于你想把哪部分作为论文的重点。2.2 标签分布与数据切分训练集/验证集/测试集的坑NSL-KDD数据集本身划分好了Train和TestTrain约12.5万条Test约2.2万条而且Test包含Train中没见过的新攻击变体。这是故意模拟真实环境也是评估模型泛化能力的关键。很多新手拿到数据后把这些文件合并再随机切分训练/测试结果把测试集里的新攻击提前混进了训练集导致准确率虚高到99%换到真实流量立刻翻车。正确的做法是保持原始划分Train用来训练Test用来做最终评估再单独从Train中切一小部分做验证集。另外这41个特征里protocol_type、service、flag是文本属性需要编码成数值数值特征之间量纲差异很大比如src_bytes可能是0到几十万必须做归一化或标准化否则深度学习的梯度更新会很慢甚至不收敛。下面这步是拿到任何结构化IDS数据后都要做的第一件事看标签分布。import pandas as pd # NSL-KDD的Train和Test文件通常不带表头这里手动指定41个特征列名 columns [duration, protocol_type, service, flag, src_bytes, dst_bytes, land, wrong_fragment, urgent, hot, num_failed_logins, logged_in, num_compromised, root_shell, su_attempted, num_root, num_file_creations, num_shells, num_access_files, num_outbound_cmds, is_host_login, is_guest_login, count, srv_count, serror_rate, srv_serror_rate, rerror_rate, srv_rerror_rate, same_srv_rate, diff_srv_rate, srv_diff_host_rate, dst_host_count, dst_host_srv_count, dst_host_same_srv_rate, dst_host_diff_srv_rate, dst_host_same_src_port_rate, dst_host_srv_diff_host_rate, dst_host_serror_rate, dst_host_srv_serror_rate, dst_host_rerror_rate, dst_host_srv_rerror_rate, class] train_df pd.read_csv(KDDTrain.csv, headerNone, namescolumns) test_df pd.read_csv(KDDTest.csv, headerNone, namescolumns) # 把多分类标签统一成二分类方便先跑通pipeline def clean_label(s): s str(s).strip().lower() return normal if s normal else attack train_df[label] train_df[class].apply(clean_label) test_df[label] test_df[class].apply(clean_label) print(Train样本数:, train_df.shape[0], Test样本数:, test_df.shape[0]) print(Train标签分布:) print(train_df[label].value_counts()) print(Test标签分布:) print(test_df[label].value_counts())逻辑说明先读取两个原始文件指定41个列名然后清洗标签为二分类打印分布。很多源码包里的使用说明不会提醒你去验证标签比例这一步必须自己做因为后面所有评估指标都建立在这个分布上。参数说明headerNone表示文件里没有列名如果你的数据文件自带表头要改成header0并把names参数去掉否则会出现列错位。提示如果train_df[label].value_counts()显示 normal 和 attack 比例接近 1:1这是 NSL-KDD 的原始分布不代表真实网络环境。真实流量中攻击占比通常远低于 1%这也是为什么只靠 accuracy 做评价会骗人。2.3 从CSV到numpy第一个能跑的数据加载代码结构化数据进入模型之前必须完成三件事文本特征编码、数值特征标准化、数据集切分。在 NSL-KDD 里protocol_type只有 3 类service有 70 类flag有 11 类。如果直接用 pandas 的factorize()也能跑但LabelEncoder更方便复用。这里有一个新手常犯的错误在测试集上单独训练一个LabelEncoder。一旦未来出现训练集里没见过的 service 值就会报transform失败。正确做法是只拿训练集的编码器去转换测试集。from sklearn.preprocessing import LabelEncoder, StandardScaler from sklearn.model_selection import train_test_split # 只对训练集训练编码器测试集复用 encoders {} for col in [protocol_type, service, flag]: le LabelEncoder() train_df[col] le.fit_transform(train_df[col]) encoders[col] le # 测试集使用训练集训练好的encoder没见过的新值用-1占位 for col in [protocol_type, service, flag]: le encoders[col] test_df[col] test_df[col].map(lambda x: x if x in le.classes_ else unknown) # 把unknown也加入classes_再transform if unknown not in le.classes_: le.classes_ list(le.classes_) [unknown] test_df[col] le.transform(test_df[col]) # 特征列排除class和label feature_cols [c for c in train_df.columns if c not in [class, label]] X_train_raw train_df[feature_cols].values X_test_raw test_df[feature_cols].values y_train (train_df[label] attack).astype(int).values y_test (test_df[label] attack).astype(int).values # StandardScaler只能fit在训练集上再transform测试集 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train_raw) X_test_scaled scaler.transform(X_test_raw) # 从训练集里切出20%做验证集按类别分层抽样 X_tr, X_val, y_tr, y_val train_test_split( X_train_scaled, y_train, test_size0.2, random_state42, stratifyy_train) print(训练集, X_tr.shape, 验证集, X_val.shape, 测试集, X_test_scaled.shape)逻辑说明LabelEncoder的classes_保存了训练集见过的所有类别测试集遇到新值时先映射成unknown再把它追加到classes_里这样transform不会崩。StandardScaler只 fit 训练集测试集用同一个均值和方差做transform这是防止数据泄露的基本要求。最后用stratifyy_train切分验证集确保 normal 和 attack 在训练集和验证集中比例一致。参数说明test_size0.2表示从训练集切出 20% 做验证集random_state42是常见的固定随机种子方便复现。如果你后面要做论文复现建议把随机种子统一写在配置项里避免多次实验对不上。3. 用Scikit-learn把基线模型跑通随机森林与梯度提升的配置3.1 最小可运行代码二分类还是多分类大多数项目源码包里会同时提供二分类和五分类两个版本的评估脚本。二分类把 label 简化为 normal/attack适合快速验证 pipeline五分类则要区分 Normal、DoS、Probe、R2L、U2R适合写论文。我建议先跑二分类把数据流、评估流程跑通再切换到五分类看具体攻击类型的检出能力。最小可运行代码用随机森林这是入侵检测机器学习方案里最稳的基线模型。它不需要做太多特征工程也能给出不错的结果。from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report, roc_auc_score model RandomForestClassifier( n_estimators150, max_depth20, min_samples_leaf2, class_weightbalanced, n_jobs-1, random_state42 ) model.fit(X_tr, y_tr) # 验证集预测用于调参时的横向比较 y_pred_val model.predict(X_val) print(验证集结果) print(classification_report(y_val, y_pred_val, target_names[normal, attack])) # 测试集预测模拟真实场景中的未知数据 y_pred_test model.predict(X_test_scaled) print(测试集结果) print(classification_report(y_test, y_pred_test, target_names[normal, attack])) y_prob_test model.predict_proba(X_test_scaled)[:, 1] print(测试集AUC:, roc_auc_score(y_test, y_prob_test))逻辑说明fit 只用训练集验证集用于调参测试集最后评估。class_weightbalanced会按类别比例自动给少数类加权这是面对攻击样本不均衡时最省事的做法。n_jobs-1让所有 CPU 核并行特征集只有 41 维并行开销很小。AUC 表示正负样本排序能力比 accuracy 更稳。参数说明random_state固定能复现换数据时要保持同一个值min_samples_leaf2能防止单叶节点过拟合如果训练集 F1 很高但测试集掉下来就调大这个值。二分类在 NSL-KDD 上很容易做到 99% 以上的 accuracy但注意测试集里包含新攻击变体你真正要关注的是 R2L 和 U2R 这两个少数类的召回率。3.2 关键参数n_estimators、max_depth、class_weight怎么设随机森林在 NSL-KDD 上n_estimators超过 200 以后收益会趋于饱和反而增加训练时间。树深则要控制太深会记住噪声。class_weight在二分类时不一定有显著影响因为 normal 和 attack 比例接近 1:1但五分类时必须设置因为 U2R 和 R2L 样本可能只有几百条不设权重模型会直接无视它们。参数二分类建议五分类建议原因n_estimators150-200200-300树多了方差下降但训练时间线性增加max_depth20-3030-40五分类特征交互复杂需要更深min_samples_leaf2-52-4防止叶子节点过拟合class_weightbalanced 或 Nonebalanced五分类中 U2R/R2L 样本极少必须加权不要一上来就全自动搜索那样容易把机器跑卡。用小范围网格搜索就够了from sklearn.model_selection import GridSearchCV param_grid { n_estimators: [100, 200], max_depth: [15, 25], min_samples_leaf: [2, 4] } gs GridSearchCV( RandomForestClassifier(class_weightbalanced, n_jobs-1, random_state42), param_grid, cv3, scoringf1_macro, n_jobs-1 ) gs.fit(X_tr, y_tr) print(最优参数:, gs.best_params_) print(交叉验证F1 macro:, gs.best_score_)逻辑说明cv3表示 3 折交叉验证数据量足够大时不需要 5 折或 10 折省时间。scoringf1_macro会给少数类同等权重这正是入侵检测评估需要的。n_jobs-1同时出现在 GridSearchCV 和模型里时小机器会吃掉大量内存建议把其中一个改为 1。参数说明如果你发现best_params_落在搜索范围的边缘比如max_depth25已经是上限说明应该扩大搜索范围继续试如果落在中间就采用这个结果。best_score_是交叉验证平均 F1不是测试集分数两者差距太大多半是因为数据切分不严谨。3.3 评估指标为什么不看accuracy而看F1和AUC入侵检测的测试集里样本分布和真实环境差异很大。accuracy 的公式让多数类主导结果某个模型把所有流量都预测为 normal 也可能有很高的准确率。而且 NSL-KDD 的 Test 含大量新攻击变体模型对已知攻击准确率高对变体召回低。所以要看 precision、recall、F1尤其是 macro-F1。AUC 评估的是模型给样本排序的能力不依赖阈值。实际部署时你可以调低阈值提高召回率——宁愿多出误报也不能放过攻击——AUC 能帮你判断这个模型是否具备这种调节空间。如果 AUC 接近 0.9 而默认阈值下 F1 不高说明是阈值问题而不是模型问题。五分类时roc_auc_score不能直接用默认参数需要指定multi_class# 假设五分类标签已经是整数编码 0-4模型是 train_multi # y_test_multi 是测试集整数标签model_multi.predict_proba 返回 n_samples x 5 from sklearn.metrics import roc_auc_score auc_macro roc_auc_score( y_test_multi, model_multi.predict_proba(X_test_scaled), multi_classovo, averagemacro ) print(五分类Macro AUC:, auc_macro)逻辑说明multi_classovo使用一对一方式计算多分类 AUCaveragemacro把五个类别的 AUC 做算术平均这样 U2R 这类罕见攻击也能在指标里占一席之地。参数说明如果类别数非常多ovo会慢一些但对 5 分类没问题。predict_proba返回每个类别的概率矩阵行和要等于 1。4. 用深度学习模型做入侵检测CNN/MLP/RNN哪条路线最省事4.1 一维卷积处理流量特征输入形状的坑深度学习方案里MLP 是结构化特征最省事的选择。输入就是 41 维向量输出是类别概率。如果你想试 CNN就必须把输入 reshape 成[batch, channels, sequence_length]很多人把 sklearn 那边的(n, 41)直接扔进 Conv1d报错说 Expected 3D input这就是典型坑。# X_train_scaled 当前形状是 (样本数, 41) # 把特征看成一条长度为41、通道数为1的序列 X_cnn X_train_scaled.reshape(-1, 1, 41)逻辑说明-1表示自动推导样本数量1是通道数因为只有一个特征序列41是序列长度。如果你以后换成原始字节流那 41 就要换成你截断/填充后的字节长度。卷积核大小一般设 3 或 5只沿序列方向滑动。参数说明在结构化特征上1D-CNN 并不一定比 MLP 强它的价值在读原始流量和恶意软件二进制序列时更明显也就是cnn识别恶意软件的场景。4.2 用PyTorch写一个最小的MLP检测器用 PyTorch 写一个可 CPU 跑通的 MLP不需要引入额外框架。下面的代码可以直接替换第 3 章的随机森林用来对比机器学习基线和深度学习模型的差距。import torch import torch.nn as nn from torch.utils.data import DataLoader, TensorDataset device torch.device(cuda if torch.cuda.is_available() else cpu) class MLP(nn.Module): def __init__(self, input_dim41, hidden_dim64): super().__init__() self.net nn.Sequential( nn.Linear(input_dim, hidden_dim), nn.ReLU(), nn.Dropout(0.3), nn.Linear(hidden_dim, 32), nn.ReLU(), nn.Dropout(0.2), nn.Linear(32, 2) # 二分类输出2个logits ) def forward(self, x): return self.net(x) model MLP().to(device) # 转成TensorDatasetDataLoader自动分batch train_dataset TensorDataset( torch.tensor(X_tr, dtypetorch.float32), torch.tensor(y_tr, dtypetorch.long) ) train_loader DataLoader(train_dataset, batch_size64, shuffleTrue) criterion nn.CrossEntropyLoss() optimizer torch.optim.Adam(model.parameters(), lr1e-3) for epoch in range(10): model.train() total_loss 0.0 for xb, yb in train_loader: xb, yb xb.to(device), yb.to(device) optimizer.zero_grad() out model(xb) loss criterion(out, yb) loss.backward() optimizer.step() total_loss loss.item() * xb.size(0) avg_loss total_loss / len(train_dataset) print(fepoch {epoch 1}, loss: {avg_loss:.4f})逻辑说明DataLoader自动打乱和分 batchbatch_size64在 CPU 上也能跑epochs10 对结构化特征足够过多会过拟合。CrossEntropyLoss里面已经包含了 softmax所以模型最后一层不需要nn.Softmax。参数说明hidden_dim64不算大如果数据量少可以降到 32Dropout只在训练时生效预测时自动关闭这是 PyTorch 的机制。训练完之后评估代码要放在model.eval()里model.eval() with torch.no_grad(): x_test_t torch.tensor(X_test_scaled, dtypetorch.float32).to(device) prob torch.softmax(model(x_test_t), dim1).cpu().numpy() y_pred prob.argmax(axis1) from sklearn.metrics import classification_report print(classification_report(y_test, y_pred, target_names[normal, attack]))逻辑说明eval()让 Dropout 失效no_grad()关闭梯度计算二者必须成对使用否则预测结果会带随机性。softmax把 logits 转成概率argmax取概率最大的类别。参数说明如果你的显存不足可以把x_test_t分批传入而不是一次性放进去。4.3 训练循环里必须留意的过拟合信号训练 loss 下降但验证 F1 不涨甚至下降是深度学习方案最常见的翻车原因。原因很简单模型容量超过数据规模把训练集噪声背下来了。解决办法是增加 Dropout、减小 hidden_dim、减少 epochs或者加早停。下面是一个简单的早停框架from sklearn.metrics import f1_score best_f1 0 patience 3 wait 0 for epoch in range(20): # ... 上面训练循环的代码 ... # 每个epoch结束后在验证集上算F1 model.eval() with torch.no_grad(): val_logits model(torch.tensor(X_val, dtypetorch.float32).to(device)) val_pred val_logits.argmax(dim1).cpu().numpy() val_f1 f1_score(y_val, val_pred) if val_f1 best_f1: best_f1 val_f1 torch.save(model.state_dict(), best_model.pt) wait 0 else: wait 1 if wait patience: print(f第 {epoch 1} 轮触发早停) break逻辑说明best_f1保存目前最好的分数patience3表示连续 3 个 epoch 没有提升就停止训练。torch.save只保存模型权重不保存优化器状态适合这里简单场景。参数说明如果验证集 F1 一直在抖动可以把patience提高到 5如果训练集 F1 已经接近 1 而验证集远低于它优先检查数据切分和标签分布。另外学习率从1e-3降到1e-4通常能让 loss 更稳定如果 loss 出现 nan先检查数据是否标准化再检查学习率是否过大。5. 入侵检测项目的常见避坑与排错从环境依赖到论文复现5.1 现象pip install之后numpy或torch版本冲突按项目文档里的 requirements.txt 安装依赖后一跑代码就报AttributeError: module numpy has no attribute float或者 PyTorch 和 CUDA 版本不匹配。这在老项目里特别常见——文档写的是若干年前的环境你现在的 Python 3.11 和最新的 numpy 已经不兼容了。原因项目文档锁定的依赖和你当前系统版本差异太大numpy 1.24 以上移除了np.float等别名PyTorch 2.x 要求特定 CUDA 版本CPU 版本换到 GPU 机器上也会出问题。解决不要用全局 Python 环境先新建虚拟环境。我一般用 condaconda create -n ids python3.8 conda activate ids pip install -r requirements.txt如果项目没有 requirements.txt根据代码里的 import 手动安装装完固定版本pip install numpy1.23.5 pandas1.5.3 scikit-learn1.2.2 torch2.0.0安装后先跑项目自带的demo.py或test.py再跑你的训练脚本。如果还报版本错误就按报错信息逐个降级/升级。注意 PyTorch CPU 版本和 GPU 版本的安装命令不同不要混装。提示conda create -n ids python3.8里的 Python 3.8 是保守选择兼容大部分老代码。如果项目文档明确要求 Python 3.10就用 3.10别硬降。5.2 现象训练loss下降但验证集F1不动随机森林训练集 F1 有 0.999验证集 F1 只有 0.8深度学习 loss 收敛得很好但 U2R 类别的召回率始终是 0。这个现象在五分类时尤其明显。原因类别不均衡U2R 样本可能只有几百条模型把它们当作噪声忽略了或者你直接把所有数据合并后随机切分导致测试集里的新攻击变体出现在训练集里模型在训练集上表现好一碰到没见过的变体就崩。解决先打印标签分布确认每一类样本数量。五分类时必须设置class_weightbalanced或者对少数类做上采样。再检查数据切分方式保持 NSL-KDD 原始 Train/Test 划分不要全局洗牌。如果模型还是学不动少数类试试点级损失函数比如对 U2R 单独加大 loss 权重。# 简单的类别权重计算 from sklearn.utils.class_weight import compute_class_weight weights compute_class_weight( class_weightbalanced, classesnp.array([0, 1, 2, 3, 4]), yy_train_multi ) print(五分类权重:, weights)逻辑说明compute_class_weight会自动计算每个类别的权重逻辑是让整体样本数乘以权重后的贡献相等。balanced模式是最常用的如果你发现 U2R 召回还是低可以把 U2R 对应的权重再手动乘 2。参数说明classes必须列出所有类别顺序要和模型输出层一致。5.3 现象参考论文里的数据集和代码里的不一致项目文档里的参考论文写的是 KDDCUP99代码里默认加载的却是 NSL-KDD或者论文用 CICIDS2017 做实验代码只支持 NSL-KDD 的 41 维特征。照着论文改数据路径一跑就报列数不匹配。原因参考论文可能是项目作者早期发的一篇研究源码在后期为了教学或演示换成了更易获取的数据集但文档没同步更新。论文是理想实验设置代码是能跑的简化版本两者往往不一致。解决先看项目文档里的 README 是否画了目录结构和数据流再打开代码里负责数据加载的脚本确认它读的文件路径、列名、特征维度。如果代码里写死了 41 列那就用 NSL-KDD 而不是论文里的 KDDCUP99。如果论文里有特征重要性分析而代码里的特征列名对不上就用代码里的特征名去论文里找映射关系。不要盲目替换数据集。CICIDS2017 的 80 多个特征和 NSL-KDD 的 41 个特征不是一回事模型输入维度直接会崩。如果你一定要复现论文需要先写一个特征对齐脚本把两个数据集的覆盖列抽取出来再重新训练。5.4 现象内存爆炸与DataLoader num_workers设置深度学习训练时模型跑着跑着内存占用持续升高最后进程被杀掉。或者 PyTorch 的 DataLoader 设置num_workers8一启动就报 OOM。原因结构化数据本身不大NSL-KDD 也就几十万条但如果你一次性把整个测试集搬上 GPU显存不够就会报 CUDA out of memorynum_workers设得过高时每个 worker 都会拷贝一份数据到内存加上系统共享内存限制就会 OOM。解决用 DataLoader 分 batch 加载而不是.to(device)全量送进去。num_workers在数据量不大的情况下设 0 或 2 就够了设 8 反而增加内存峰值和数据加载开销。另外把特征先转成np.float32能省一半内存。from torch.utils.data import DataLoader, TensorDataset # 用float32而不是默认float64内存减半 X_test_t torch.tensor(X_test_scaled, dtypetorch.float32) y_test_t torch.tensor(y_test, dtypetorch.long) test_dataset TensorDataset(X_test_t, y_test_t) # num_workers0表示不额外开进程最稳 test_loader DataLoader(test_dataset, batch_size512, shuffleFalse, num_workers0)逻辑说明batch_size512意味着一次只评估 512 条样本内存占用和batch_size成正比。num_workers0在主进程里加载数据不产生额外复制。如果你的机器内存很大可以把num_workers调到 2但不要超过 CPU 核心数。参数说明shuffleFalse在测试集上必须关掉保证预测顺序和原始标签顺序一致。6. 从源码包到可用系统把训练好的模型接上流量采集与告警6.1 用tcpdump抓包并转成特征的简易管道模型跑通后下一步是把离线评估变成可用系统。最简单的入口是用 tcpdump 抓一段流量再用 CICFlowMeter 转成特征 CSV最后交给训练好的模型预测。这个管道能跑通就说明源码包值得继续投入。# 抓取eth0网卡上的前10000个包存到capture.pcap sudo tcpdump -i eth0 -c 10000 -w capture.pcap # 用CICFlowMeter把pcap转换成双向流特征CSV # 如果已经在环境变量里配置了CICFlowMeter路径则直接调用 ./CICFlowMeter/bin/cicflowmeter -i capture.pcap -c capture_features.csv逻辑说明-i eth0指定网卡-c 10000限定报文数量避免抓包文件过大。CICFlowMeter 会对 pcap 做协议解析输出 80 多个双向流量特征。参数说明如果你训练用的是 NSL-KDD这套特征并不能直接送进模型因为列数不同。CICFlowMeter 更适合 CICIDS2017 数据集训练出来的模型这是常见做法之下的前提。6.2 离线批量检测与在线实时检测的取舍模式延迟吞吐适用场景离线批量分钟~小时级高安全审计、取证分析、日志回放在线实时毫秒~秒级低边缘网关、防火墙联动、实时告警如果源码包只给了训练和评估脚本没有推理接口你可以针对离线批量检测先做一个接收 CSV、输出告警行的小工具这比硬上实时检测要稳妥得多。在线实时检测要处理抓包、特征提取、模型预测三者的同步任何一个环节超时都会丢包。我个人的习惯是先把离线批量检测的准确率、误报率、单条样本延迟测清楚再用同样的模型转成实时检测否则模型本身没调好就上在线只会收获一堆告警噪音。这个项目方向值不值得继续投入关键就看离线评估阶段 F1 是否达到你的预期。希望帮到你。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →