基于UNSW-NB15与机器学习的入侵检测系统毕设实战解析 📅 发布时间:2026/9/7 4:01:33 👁 浏览次数: 简介这是一份面向计算机相关专业学生与初学者的机器学习实践资源聚焦于使用UNSW-NB15基准数据集进行网络攻击检测。项目源自个人课程设计与毕业设计代码已经测试通过能够直接部署运行适合用于毕设、课设、大作业或初期项目演示。压缩包共4个文件包括3个Python源代码文件和1个README说明文档整体仅12KB结构轻量、易于阅读。数据集包含多种攻击类型可验证算法在异常检测场景下的表现源码实现了逻辑回归二分类、KNN分类器等经典机器学习算法并提供决策树等模型的相关实现方便读者对照比较不同算法在入侵检测任务中的分类效果。说明文档对各文件的作用与运行方式进行了简要说明降低了上手门槛也便于在此基础上修改扩展实现其他功能。目前已有143人学习浏览适合希望快速获得可运行参考实现、理解网络攻击检测建模流程的在校学生与开发者下载使用。 做毕业设计选到这个题目的同学十有八九是被“UNSW-NB15 数据集”和“机器学习算法”这两个关键词吸引的。这个题目确实很经典既有网络安全方向的应用背景又有算法模型可以展开讲哪怕之前完全没接触过安全领域只要代码能跑通、指标能出来、答辩能讲清楚就是一套很稳的毕设方案。项目配套的源码和教程基本做到了“简单部署即可运行”功能覆盖数据预处理、特征编码、模型训练、指标评估和可视化适合网络空间安全、计算机科学与技术等专业的本科毕业设计也适合刚接触安全AI方向的开发者快速入门。我会从项目设计思路、数据与特征处理、核心代码实操、常见问题排查四个方面把这个项目完整拆解一遍把我在实际跑这类项目时踩过的坑和总结的经验一并写出来。1. 项目整体设计与思路拆解1.1 为什么选 UNSW-NB15 而不是 KDD99很多同学在选题时会纠结数据集选哪个。说实话UNSW-NB15 是目前做入侵检测方向最合适的选择之一原因并不复杂它足够新、足够真实、有权威出处而且分类粒度细。UNSW-NB15 由澳大利亚新南威尔士大学网络安全中心ACCS发布通过 IXIA PerfectStorm 工具采集真实网络流量并融合了合成攻击流量总共包含约 250 万条记录。训练集大约 175 万条测试集约 82 万条覆盖九类攻击Fuzzers、Analysis、Backdoors、DoS、Exploits、Generic、Reconnaissance、Shellcode、Worms。拿它和早期的 KDD99 / NSL-KDD 对比一下优势很明显。下面这个表基本能回答“为什么选它”数据集发布时间背景环境攻击类型现代代表性适合场景KDD991999年模拟军事网络仿真环境4类较差特征老旧只能做入门演示NSL-KDD2009年基于 KDD99 处理冗余后得到4类消除了冗余但本质仍是老数据算法对比实验UNSW-NB152015年真实网络流量 现代攻击工具生成9类强特征设计更接近真实环境毕设、论文、实战项目所以如果你在开题阶段还在纠结数据集直接选 UNSW-NB15 就对了。它既有二分类的“正常/攻击”标签Label也有多分类的“攻击具体类型”标签attack_cat一个数据集能同时支持两种实验设计做毕设内容非常划算。1.2 为什么用传统机器学习而不是直接上深度学习既然都做“检测网络攻击的机器学习算法”了为什么不直接堆 LSTM、Transformer这个问题答辩老师大概率会问我自己做的时候也认真想过。核心原因是传统机器学习在这个题目上有不可替代的优势尤其是可解释性。毕业设计需要你把“为什么这么做”讲明白决策树和随机森林可以直接输出特征重要性逻辑回归有明确的权重系数这些都能在答辩 PPT 里直观展示。反观深度学习模型参数动辄百万级调一次训练半天答辩时被问到“你这个模型为什么效果好”很容易被问住。另外从工程角度看传统机器学习方案在 CPU 环境下就能跑完整个实验流程。scikit-learn 训练一个随机森林在抽样后的数据集上几分钟内就能出结果而同样的时间深度学习连数据预处理可能都没跑完。当然UNSW-NB15 数据集也完全可以作为深度学习的输入做毕设时如果学有余力在传统机器学习方法的基础上加一个“CNN/RNN 对比实验”是很加分的扩展但核心方案用传统机器学习是完全合理且安全的选择。1.3 项目整体流程与架构整个项目的核心流程可以概括为一条数据管道CSV 加载 → 数据清洗缺失值 / INFINITE→ 类别特征编码 → 特征标准化 → 训练/测试划分 → 模型训练 → 指标评估 → 可视化源码的组织思路也按照这条链路拆。每个环节都是独立的函数或脚本这样做的最大好处是你可以单独替换任意一环而不影响整体。比如今天想试试 XGBoost只需要在“模型训练”函数里加一个新模型对象想换一套特征组合只改“特征选择”处的代码就行。我建议拿到源码之后不要急着全量跑先按流程理解数据管道再逐步跑通这样后面调参、扩展都会顺手很多。2. 核心细节解析数据和特征处理是关键2.1 数据集字段结构49 列分别是什么UNSW-NB15 的每条数据有 49 列其中 45 列是特征最后几列是标签信息。常见的几个核心字段如下字段分类字段名含义说明流基础信息srcip、sport、dstip、dsport源/目的 IP 和端口协议状态proto、state、service协议类型、连接状态、应用层服务时间特征dur、spkts、dpkts连接时长、源/目的包数负载流量sbytes、dbytes、sttl、dttl字节数、TTL 等信息统计特征ct_srv_src、ct_dst_sport_ltm 等连接计数、并发连接数第 47 列是Label二分类标签0 正常 / 1 攻击这是我们做二分类实验的预测目标。第 48 列是attack_cat攻击类别标注9 类攻击加 Normal 共 10 个值这是做多分类实验的预测目标。做实验时一个最常见的误操作是把 49 列全部当成特征丢进模型。如果 attack_cat 被当成了输入特征模型准确率会虚高到 99% 以上这在论文里叫“标签泄露”label leakage是非常严重的错误。正确做法是特征列只取前 45 列或根据需求剔除部分列标签列单独切片。2.2 数据清洗处理 INFINITE 和缺失值的正确姿势拿到原始 CSV 直接跑训练十有八九会报错原因就藏在数据本身。UNSW-NB15 里的某些字段尤其是一些计数类字段存在INFINITE字符串pandas 读进来之后默认变成 object 类型直接喂给机器学习模型必然类型报错。标准处理流程是加载数据后先统一替换异常值再检查缺失量。可以这样做import pandas as pd import numpy as np df pd.read_csv(UNSW_NB15_training-set.csv, low_memoryFalse) # 把 INFINITE 替换为 NaN再看每列缺失情况 df.replace(INFINITE, np.nan, inplaceTrue) missing df.isnull().sum() print(missing[missing 0])处理缺失值一般就三种策略缺失率较低的直接删除行缺失率中等且对结果影响小的用均值/中位数填充缺失率很高且是干扰特征的直接删列。做毕设时不用纠结优先用“删除行 数值列中位数填充”的组合稳定省事。2.3 特征编码和标准化新手最容易忽略的一步UNSW-NB15 里proto、service、state这几个字段是字符串类别特征标签编码LabelEncoder是把它们变成数字的方法。这里有个不少新手会踩的坑LabelEncoder 只是给字符串分配了一个编号比如把 0、1、2 分配给不同协议这个编号本身没有大小含义。如果把这个编码后的结果直接当数值特征用模型可能会学到错误的“顺序关系”。所以更稳妥的做法是类别特征用独热编码One-Hot Encoding或者至少要多留一个心眼确认编码后的特征没有被模型当成连续值。毕设场景下不要求绝对最优但用了独热编码答辩被问到时答起来更顺。标准化这一步同样关键。UNSW-NB15 特征的量纲差异巨大有的特征在 0~1 之间有的是几千几万。如果不做标准化SVM 和 KNN 这类距离敏感的算法会被数值范围大的特征彻底主导。标准做法是用StandardScaler先把训练集 fit 再 transform测试集只做 transform。这里千万注意标准化是先在训练集上拟合再应用到测试集不能把整个数据集一起 fit否则会引入测试集信息导致评估结果虚高。3. 实操过程与核心环节实现3.1 环境准备与依赖拿到源码后第一件事不是改代码而是先把环境搭好。项目依赖非常标准都是 Python 生态里的老熟脸pip install pandas numpy scikit-learn matplotlib seaborn如果你打算扩展试验可以再加一个xgboost后面我会讲它在毕设中的加分用法。Python 版本建议 3.8 以上scikit-learn 别装太老1.0 以上版本在 API 上更友好。核心模块功能如下模块/脚本负责功能数据处理加载 CSV、清洗异常值、标签编码、标准化模型训练定义多个分类器、训练与测试集划分评估可视化生成准确率、F1、召回率、混淆矩阵、特征重要性主入口串联整个流程一键运行3.2 核心代码骨架与说明整个源码的“灵魂”可以浓缩成下面这段代码逻辑。拿到项目后优先理解这段链路后面改参数、加功能都是在它上面做文章。from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder, StandardScaler from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report, confusion_matrix, accuracy_score import pandas as pd # 1. 加载数据以训练集为例 df pd.read_csv(UNSW_NB15_training-set.csv, low_memoryFalse) df.replace(INFINITE, pd.NA, inplaceTrue) df df.dropna() # 2. 构造特征矩阵 X 和标签 y只取特征列 Label 列 X df.iloc[:, :45].copy() y df[Label].values # 3. 将类别特征做标签编码 cate_cols X.select_dtypes(include[object]).columns for col in cate_cols: le LabelEncoder() X[col] le.fit_transform(X[col].astype(str)) # 4. 标准化先划分再 fit/transform避免数据泄露 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42, stratifyy ) scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 5. 训练随机森林 rf RandomForestClassifier(n_estimators60, random_state42, n_jobs-1) rf.fit(X_train_scaled, y_train) y_pred rf.predict(X_test_scaled) # 6. 输出指标 print(Accuracy:, accuracy_score(y_test, y_pred)) print(classification_report(y_test, y_pred))这段代码虽然短但已经完成了“加载→清洗→编码→标准化→训练→评估”的全流程。有一点需要特别提一下代码里用了stratifyy也就是分层抽样划分数据集目的是保证训练集和测试集里正常流量/攻击流量的比例与原始数据一致。在类别不平衡的入侵检测场景中分层抽样是必须的否则随机划分很容易让测试集里某一类样本比例失衡指标波动会很大。3.3 各模型参数怎么调先跑通再优化源码默认可能包含逻辑回归、决策树、KNN、随机森林、SVM 等常见模型实际使用时我建议按下面的优先级来做模型推荐参数范围毕设定位逻辑回归C0.1~10基线对比训练最快决策树max_depth10~30最易解释出图好看随机森林n_estimators50~200, max_featuressqrt主推模型效果稳定KNNk5~20能体现标准化重要性SVMC1~10, kernelrbf小样本可用太大跑不动XGBoostn_estimators100, learning_rate0.1追求精度时可以加以随机森林为例n_estimators是我个人最常调的参数。它在 60 到 100 之间能取得不错的性能和速度平衡超过 200 之后收益很小而训练时间明显增加。max_depth建议从默认值往下调因为攻击检测数据里存在大量复杂非线性关系深度过大容易过拟合训练噪声。SVM 是我特别想提醒的UNSW-NB15 全量数据太大直接用 RBF 核 SVM 训练非常慢可能要跑几个小时。源码里如果带了 SVM大概率是在抽样子集上跑的。毕设里使用 SVM 时我的建议是要么做随机抽样 5~10 万条数据再训练要么干脆把 SVM 定位成“小样本对比实验”别让它拖慢整体节奏。3.4 结果呈现别只贴准确率做毕设最容易踩的另一个坑是只输出一个准确率。UNSW-NB15 数据集中正常流量和攻击流量不是完全均衡的准确率高不一定代表模型好。正确做法是至少展示下面三项分类报告Precision、Recall、F1-score重点看攻击类别的召回率因为漏报攻击的代价远高于误报正常流量。混淆矩阵用 seaborn 画热力图能直观看到哪类攻击被漏掉了。这在答辩演示时非常加分。ROC-AUC画出 ROC 曲线并计算 AUC 值体现模型在不同阈值下的检测能力。画混淆矩阵的核心代码很固定import matplotlib.pyplot as plt import seaborn as sns cm confusion_matrix(y_test, y_pred) sns.heatmap(cm, annotTrue, fmtd, cmapBlues) plt.xlabel(Predicted) plt.ylabel(Actual) plt.show()可视化不一定要多炫但逻辑要清晰。比如既然数据集支持多分类标签就可以在二分类结果之后再用attack_cat做一次九分类实验画一张多分类混淆矩阵热力图这会让整个项目内容立刻丰富一截。4. 常见问题与排查技巧实录这部分内容是我实际跑类似项目时踩过坑之后沉淀下来的遇到问题可以直接对照排查。4.1 内存不足加载数据卡死UNSW-NB15 训练集 CSV 文件比较大如果电脑配置一般直接用 pandas 读全量数据可能内存占用到 90% 以上。解决办法有三个一是读数据时根据实际需求只保留用得到的列用usecols参数指定二是先对数据做随机抽样比如取 30~50 万条做实验训练结果仍然很有代表性三是确认不再需要某些中间 DataFrame 后及时del释放内存。我在自己机器上跑的时候抽样 40 万条数据随机森林 60 棵树的训练时间基本在 1~3 分钟内完全可靠。4.2 特征处理顺序错误导致结果虚高这是我见过最多的问题。有同学先对整个数据集做标准化再划分训练测试集导致测试集的信息在训练时就已经被模型“见过”最终准确率高到不真实答辩时一被追问就露馅。正确顺序永远是先划分 train/test再在训练集上 fit 预处理器最后用同一个预处理器 transform 测试集。4.3 准确率高但召回率低模型全被偏置带跑了如果发现准确率 90% 以上但攻击类别的召回率只有 60%基本是类别不平衡或者特征泄漏之外的“偏置问题”。这时优先做的三件事是调整类别权重在随机森林里设置class_weightbalanced使用分层抽样划分数据集观察混淆矩阵确认是哪一类攻击被大量误判。被误判的往往是小样本攻击类型比如 Shellcode、Worms这类攻击记录数少模型很难学到特征可以在论文中诚实地分析这一点这反而是加分项。4.4 关于答辩抓住三个必答点做这个题目答辩时一定会被问到的三个问题是为什么选这些特征回答思路结合 45 个特征的含义从“连接基础属性、流量负载、连接历史统计”三个维度解释并说明利用了随机森林的特征重要性排序做了筛选。为什么选这几个模型回答思路对比逻辑回归线性基线与可解释性、决策树/随机森林集成学习、特征重要性分析、SVM高维分类能力说明是为了覆盖不同类别的算法思想。这套方案在真实环境中能用吗回答思路强调本项目是研究性验证真实场景需要处理在线流量采集、实时特征提取、模型更新等问题。承认局限再加一句“后续可以结合流式处理框架做扩展”这个回答很稳妥。最后分享一个实操中的小经验实验的随机种子一定要固定。训练测试集划分、模型初始化都设置random_state42固定一个可复现的种子。否则每次跑出来的结果都不一样不仅自己调试时容易慌被要求复现实验时更是大麻烦。我见过有同学答辩前一天调参跑出一个很好的准确率第二天想复现结果不固定种子换了随机划分后结果掉了一大截那种情况非常狼狈。固定住随机种子整体实验数据就稳住了后续怎么改特征和参数对比起来才有可信度。这个题目扩展空间也很大后续想加内容的话可以从多分类攻击识别、特征选择优化、实时流量检测这些方向入手能做的方向很多。先把现有的二分类主流程跑透把指标和图表整理好这套毕设项目就已经非常扎实了。本文还有配套的精品资源点击获取