简介:这是一份基于Python机器学习的DDoS入侵检测算法项目,适合网络安全、机器学习方向的初学者或毕业生用于课程设计与毕业设计。资源围绕DDoS流量识别场景,提供二分类逻辑回归、正则化逻辑回归与多类别逻辑回归等算法的Python源码,并配有详细部署文档和整套数据资料,可帮助理解逻辑回归在入侵检测中的实际应用与调优思路。压缩包共5个文件,以3个py脚本为核心,分别覆盖不同逻辑回归实现,另有md文档说明实验流程、docx毕业设计简述辅助写作,整体仅241KB,体量轻但内容紧凑。项目源码均经本地编译验证可运行,评审得分95分以上,难度适中,适合快速复现实验并作为项目基线。当前已有287人学习下载,对有明确DDoS检测算法学习需求或需要参考完整项目结构的开发者来说,是一份性价比很高的参考资料。
1. 基于 Python 机器学习的 DDoS 入侵检测:从三份逻辑回归脚本说起
拿到这份「基于 Python 机器学习的 DDoS 入侵检测算法源码 + 详细部署文档 + 全部数据资料」时,我第一反应是去看它的核心代码文件——结果发现主角不是随机森林,也不是深度学习,而是三份逻辑回归脚本:普通逻辑回归、正则化逻辑回归、多类别逻辑回归。这个选型反而让我觉得靠谱:毕设场景里,DDoS 入侵检测最需要的不是模型的「炫技」,而是可解释性、可复现性和足够低的调参成本。逻辑回归作为分类基线模型,既能快速验证流量特征是否有效,又能给出每个特征对「是否攻击」的权重贡献,这正是高分毕设评审最看重的东西。这份资源适合两类人:一是正在做入侵检测相关毕设、需要可运行源码和完整数据支撑的学生;二是想快速搭一个检测基线模型、后续再换 XGBoost 或深度学习做对比的从业者。下文按「资源构成 → 环境部署 → 算法实现 → 踩坑记录 → 进阶优化」的顺序展开,每一步都给你能直接抄的代码和参数。
2. 资源构成与检测原理:为什么逻辑回归能用于 DDoS 入侵检测
2.1 DDoS 检测的本质是一个分类问题
DDoS 攻击的流量特征和正常流量有明显差异:单条连接的数据包速率、平均包长、TCP 标志位分布、连接持续时间、源 IP 的熵值等,在攻击发生时会产生统计意义上的偏移。入侵检测系统要做的事,就是对这些流量特征做二分类(正常/攻击)或多分类(正常/SYN Flood/UDP Flood/HTTP Flood)。逻辑回归解决的就是这个分类问题:它通过 sigmoid 函数把线性回归的输出映射到 0~1 之间,得到一个概率值,再按阈值判定类别。
逻辑回归在 DDoS 检测里被广泛用作基线模型,不是因为它最聪明,而是因为它满足三个硬性要求:第一,训练速度快,即使流量特征维度到了几十维,普通机器上几十秒内就能收敛;第二,权重可解释,模型训练完你能直接看到「syn_error_ratio」这个特征的权重是正的还是负的,这对毕设论文里写「特征重要性分析」章节非常友好;第三,对线性可分的流量数据效果不差,DDoS 流量的统计特征在多数情况下是近似线性可分的。所以这份资源用逻辑回归做检测算法,不是偷懒,而是选了一条低成本验证数据有效性的路径。
2.2 项目文件结构与各自职责
解压后你会看到Graduation-rojec-main主目录,里面有三个核心 Python 文件——ex_2 逻辑回归.py、ex_2 正则化逻辑回归.py、ex_3 多类别逻辑回归.py,以及README.md、毕业设计简述.docx和一份数据资料目录。这三个脚本的定位是不一样的:经验之谈,先看ex_2 逻辑回归.py把流程跑通,再去看正则化版本理解防过拟合的手段,最后才是多类别版本。
| 文件 | 核心作用 | 适用场景 |
|---|---|---|
ex_2 逻辑回归.py | 二分类基线,跑通「加载数据→训练→评估」全流程 | 验证数据集是否可用、基线准确率是多少 |
ex_2 正则化逻辑回归.py | 在基线基础上加 L2 正则化,抑制权重过拟合 | 特征维度较高、训练集和验证集准确率差距大的时候 |
ex_3 多类别逻辑回归.py | 用 softmax 做多分类,区分攻击子类型 | 论文需要展示「不仅会检测攻击,还能识别攻击类型」 |
2.3 数据资料怎么组织
数据资料目录里通常会包含经过预处理的 CSV 特征文件,每行是一条网络连接记录,列是特征字段,最后一列是标签(0 表示正常,1 表示攻击,多类别场景下可能有 2、3、4)。拿到手第一步,我建议你打开 CSV 看一眼数据长什么样,确认特征列的数量和标签分布。如果数据是 KDD Cup 99 或 CICIDS 风格的流量特征,一般会有 40 个以上的特征列,其中包含持续时间、协议类型、源字节数、目的字节数、错误包比率等。这些字段名在逻辑回归训练后会被打印成权重系数,也就是你论文里的「特征重要性表」。
3. 环境部署与跑通流程:从裸机到出第一个准确率
3.1 环境准备:Python 版本与依赖安装
这份源码基于 Python 3,依赖主要集中在numpy、pandas、sklearn、matplotlib这几个库上。环境安装的顺序有讲究:先装 Python 3.8 或 3.9(不要装 3.12 以上的最新版,部分旧版 sklearn 接口会报 deprecation 警告,虽然不影响运行,但毕设答辩时被评委看到满屏警告很减分),再用 pip 安装依赖。
# 建议先创建虚拟环境,避免污染系统 Python python -m venv ddos_env # Windows 激活虚拟环境 ddos_env\Scripts\activate # Linux/Mac 激活虚拟环境 source ddos_env/bin/activate # 安装核心依赖,numpy 和 pandas 负责数据处理,sklearn 提供逻辑回归实现 pip install numpy pandas scikit-learn matplotlib参数说明:venv创建虚拟环境是血泪经验——我见过太多人把项目依赖装进系统 Python,最后不同项目之间的sklearn版本互相冲突,光是排查AttributeError: module 'sklearn' has no attribute 'model_selection'这种问题就能耗掉半天。scikit-learn是逻辑回归实现的来源,它的LogisticRegression类封装了梯度下降和正则化,比手写numpy版的收敛速度更快、数值稳定性更好。如果你的网络环境下载慢,可以加-i https://pypi.tuna.tsinghua.edu.cn/simple换清华源。
3.2 数据加载与标签分布检查
跑任何模型之前,先检查数据集的标签分布。这一步很关键但经常被跳过——DDoS 检测数据集普遍存在类别不平衡问题,正常流量样本可能是攻击样本的 5 到 10 倍。如果直接拿原始数据去训练,逻辑回归会把所有样本都预测成多数类,准确率看起来很高(比如 90%),但 Recall(召回率)几乎为 0,攻击流量一条都检不出来。
import pandas as pd # 加载预处理后的流量特征 CSV,最后一列是标签 df = pd.read_csv('data/traffic_features.csv') print('数据集形状:', df.shape) print('特征列数:', df.shape[1] - 1) # 检查标签分布,这一步决定要不要做采样处理 label_counts = df.iloc[:, -1].value_counts() print('标签分布:') print(label_counts) print('攻击样本占比: {:.2f}%'.format(label_counts[1] / len(df) * 100))逻辑说明:iloc[:, -1]取的是最后一列标签,value_counts()统计每个类别的样本数。如果攻击样本占比低于 10%,建议在训练前用sklearn的train_test_split做分层采样,或者用imblearn库的SMOTE做过采样。这份资源的数据资料是经过预处理的,正常情况标签分布不会太离谱,但养成检查的习惯不亏——答辩时评委问「你的数据预处理做了什么」,你能答出「检查了标签分布,确认是否存在不平衡」,这比空泛地说「对数据做了清洗」更有说服力。
3.3 训练集与验证集划分:分层采样是必须的
DDoS 流量数据通常按时间顺序采集,如果你用普通的train_test_split随机切分,训练集和验证集里的流量可能来自同一个时间窗口,导致验证结果虚高。这里的经验做法是:把数据按时间顺序排序后,取前 70% 作为训练集、后 30% 作为验证集,模拟真实上线时的「用历史数据预测未来流量」场景。
from sklearn.model_selection import train_test_split # X 是所有特征列,y 是最后一列标签 X = df.iloc[:, :-1].values y = df.iloc[:, -1].values # test_size=0.3 表示 30% 数据做验证,stratify=y 保证训练/验证集标签比例一致 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42, stratify=y ) print('训练集样本数:', X_train.shape[0]) print('验证集样本数:', X_test.shape[0]) print('训练集攻击样本占比: {:.2f}%'.format(y_train.mean() * 100)) print('验证集攻击样本占比: {:.2f}%'.format(y_test.mean() * 100))逻辑说明:stratify=y参数让训练集和验证集的标签比例保持一致,这是分类任务的标准操作。random_state=42固定随机种子,保证每次运行划分结果一致——这在你调参对比实验结果时非常有用,如果每次划分的样本都不同,你根本没法判断准确率提升是来自参数改动还是来自数据变化。验证集攻击样本占比要跟训练集基本一致,如果偏差超过 2 个百分点,说明划分出了问题,需要回头检查数据是否按类别排过序。
3.4 跑通第一个逻辑回归基线
环境配好、数据划分完成后,直接跑ex_2 逻辑回归.py里最核心的训练代码。逻辑回归在 sklearn 里是一行调用,但参数的含义值得逐一说清。
from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score, classification_report # C=1.0 表示正则化强度的倒数,值越小正则化越强;max_iter=1000 保证迭代充分收敛 model = LogisticRegression(C=1.0, solver='lbfgs', max_iter=1000, random_state=42) model.fit(X_train, y_train) # 预测并输出评估指标 y_pred = model.predict(X_test) print('验证集准确率: {:.4f}'.format(accuracy_score(y_test, y_pred))) print(classification_report(y_test, y_pred, target_names=['正常流量', 'DDoS攻击']))参数说明:solver='lbfgs'是适合中小数据集的优化器,它在内存占用和收敛速度之间取了一个较好的平衡;如果数据集特别大(几十万条以上),可以换'saga'并配合max_iter调大。C=1.0是正则化强度的倒数,C 越大正则化越小,模型越容易过拟合。第一次跑通后,如果准确率在 90% 以上,说明特征工程做的没有问题;如果准确率低于 80%,大概率是特征没有做标准化——逻辑回归的梯度下降对特征尺度敏感,流量特征里「字节数」可能是几千的量级,「错误包比率」是 0 到 1 之间的小数,这种尺度差异会让优化过程震荡。处理方式在下一章展开。
4. 三种逻辑回归实现:从二分类基线到多类别攻击识别
4.1 普通逻辑回归与正则化逻辑回归的差别
ex_2 逻辑回归.py和ex_2 正则化逻辑回归.py的区别,表面上看只是LogisticRegression构造参数多了一个penalty,但背后反映的是对过拟合的两种态度。普通逻辑回归用的是 L2 正则化默认开启(sklearn 的LogisticRegression默认penalty='l2'),而这份资源里的「正则化版本」大概率是显式指定了penalty='l2'和更小的C值,并且增加了对权重系数的可视化输出。
在 DDoS 检测场景里,正则化的意义在于:流量特征有几十维,很多特征之间存在相关性(比如「每秒发包数」和「每秒字节数」高度相关),这会导致权重估计方差变大、模型在训练集上表现很好、在验证集上一塌糊涂。L2 正则化通过给权重的平方和加惩罚项,把权重向 0 收缩,降低模型复杂度。一个直观的判断标准是:如果你的训练集准确率比验证集高 5 个百分点以上,说明过拟合了,这时候优先把C值调小一档(从C=1.0调到C=0.1)再重跑。
# 普通版:C 默认 1.0,模型完全信任数据 model_default = LogisticRegression(solver='lbfgs', max_iter=1000, random_state=42) model_default.fit(X_train, y_train) # 正则化版:C=0.1 加强正则化,抑制权重过大 model_reg = LogisticRegression(C=0.1, penalty='l2', solver='lbfgs', max_iter=1000, random_state=42) model_reg.fit(X_train, y_train)逻辑说明:penalty='l2'指定了惩罚项类型,C=0.1让正则化效果更强。对比两个模型在验证集上的表现,如果model_reg的准确率和model_default差不多或者略高,说明数据特征本身就存在冗余,加强正则化是有益的;如果model_reg准确率明显下降,说明数据拟合不足,应该调大C回到 1.0 甚至更高。这个对比实验本身就是毕设论文里非常好用的素材——「本文对比了 L2 正则化对检测性能的影响,结果表明……」
4.2 多类别逻辑回归:从「是否攻击」到「哪种攻击」
ex_3 多类别逻辑回归.py是这份资源的加分项。二分类只能回答流量是不是攻击,而多分类可以回答是 SYN Flood、UDP Flood 还是 HTTP Flood。这在论文里的价值是质变:多类别攻击识别是当前入侵检测研究的热点方向,DDoS 攻击的变种越来越多,能识别攻击子类型意味着检测系统可以做差异化的防御策略——比如对 SYN Flood 做 SYN Cookie 防护,对 UDP Flood 做限速。
sklearn 的LogisticRegression支持多分类有两种策略:multinomial(softmax 回归)和ovr(一对多)。softmax 回归的思想是:对每个类别算一个线性得分,然后用 softmax 函数把得分转成概率分布,所有类别的概率和为 1。它适合类别之间互斥的场景——一条流量只能是某一种攻击或正常,不太可能同时是 SYN Flood 和 UDP Flood,所以用multinomial更合理。
from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score, confusion_matrix # multi_class='multinomial' 启用 softmax 多分类,solver 需要配套 lbfgs model_multi = LogisticRegression( C=1.0, penalty='l2', solver='lbfgs', multi_class='multinomial', max_iter=2000, random_state=42 ) model_multi.fit(X_train, y_train) y_pred_multi = model_multi.predict(X_test) print('多分类准确率: {:.4f}'.format(accuracy_score(y_test, y_pred_multi))) # 混淆矩阵展示每个类别的检测情况,按实际标签名称传参 # 假设标签映射为 0=正常, 1=SYN Flood, 2=UDP Flood print(confusion_matrix(y_test, y_pred_multi))参数说明:multi_class='multinomial'是 softmax 回归的开关,但要注意它和solver的兼容性——'lbfgs'、'newton-cg'、'sag'这三个 solver 支持multinomial,而'liblinear'只支持ovr。如果你在这里翻车,报错信息通常会直接提示「Solver liblinear does not support multinomial」。max_iter=2000是因为多分类的优化问题比二分类复杂,迭代次数不够会出现ConvergenceWarning。混淆矩阵是论文里常用的展示手段,它显示每一个真实类别被预测成了哪些类别——如果看到「SYN Flood 被大量预测为 UDP Flood」,说明这两个攻击类型的流量特征在统计上确实相似,需要在特征层面增加区分度。
4.3 特征标准化:被很多人跳过的关键步骤
逻辑回归本身不做特征缩放,而 DDoS 流量特征天然存在尺度差异。这份资源的数据资料里,「源字节数」这类特征取值范围可能是 0 到几千万,而「连接持续时间」可能是 0 到几百秒,「错误包比率」是 0 到 1。如果不做标准化,梯度下降会在取值大的特征方向上震荡,收敛极慢甚至不收敛。这就是为什么有些人跑逻辑回归出现准确率忽高忽低、或者损失函数不下降的玄学问题。
from sklearn.preprocessing import StandardScaler # 实例化标准化器,用训练集拟合 scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) # 注意:验证集用训练集的均值和标准差做变换,不能重新 fit X_test_scaled = scaler.transform(X_test) print('标准化后训练集特征均值(应接近 0):', X_train_scaled.mean(axis=0)[:5]) print('标准化后训练集特征标准差(应接近 1):', X_train_scaled.std(axis=0)[:5])逻辑说明:fit_transform在训练集上计算每个特征的均值和标准差,然后做(x - mean) / std变换;验证集上只调用transform,用训练集的统计量做变换——这是一个容易踩的坑,如果对验证集也调用fit_transform,验证集的信息就泄漏到了模型里,评估结果会偏乐观。标准化之后,逻辑回归的收敛速度会有肉眼可见的提升,而且权重系数的大小可以直接用来比较特征重要性,因为在同一尺度下权重绝对值越大意味着该特征对决策的贡献越大。
5. 避坑指南与常见问题排查:四个血泪经验
5.1 现象:训练时出现 ConvergenceWarning,但准确率看起来还行
现象:跑ex_3 多类别逻辑回归.py时控制台输出ConvergenceWarning: Maximum iterations (1000) reached and the optimization loop has not converged.,但最终准确率在 85% 以上,看起来能接受。
原因:这是一个典型的假象。max_iter不够只是说优化过程没跑完,不代表结果一定很差。在 DDoS 数据集上,如果特征没有标准化,梯度下降的脚步很小,1000 次迭代可能在损失曲线上走了一半都不到。准确率「还行」可能是因为数据本身线性可分性较好,但模型的权重在训练结束时仍在震荡,这会让你在论文里报告的特征重要性排名不稳定——下次跑可能就变了。
解决:两步走。第一步,在LogisticRegression构造参数里把max_iter提高 5000,加上tol=1e-4(收敛容忍度),这一步 95% 的情况下能消除警告。第二步,如果加大迭代后警告仍然存在,检查特征是否标准化了,90% 的收敛问题根源在特征尺度,不在迭代次数。我自己的习惯是,每次训练完都看一眼n_iter_属性,如果它等于你设置的max_iter,说明到达了上限被迫停止,这时候提高上限而不是自欺欺人。
5.2 现象:准确率很高,但检测不出攻击流量
现象:验证集准确率 94%,但你单独提取一批攻击样本丢进模型,预测结果全是「正常」。查看classification_report时发现recall(召回率)那一列的数据很难看,比如正常流量的 recall 是 0.98,攻击流量的 recall 只有 0.45。
原因:100% 的类别不平衡问题。当攻击样本占比低于 10%,逻辑回归的损失函数里多数类的梯度占了主导,模型的最优策略就是把所有样本都预测成多数类——这样准确率天然就有 90% 以上。准确率这个指标在这种情况下完全失去参考价值,它只是掩盖了模型什么都没学会的事实。
解决:看指标不能只看准确率。调classification_report里的f1-score,重点关注攻击类别的 recall。如果要改善,有两条路:一是数据层面,用imblearn的SMOTE对少数类做合成过采样;二是算法层面,给LogisticRegression传入class_weight='balanced',让 sklearn 自动根据类别频率调整样本权重。
# 用 class_weight 解决类别不平衡,代价是正常流量的误报率会升高 model_balanced = LogisticRegression( C=1.0, solver='lbfgs', max_iter=2000, class_weight='balanced', random_state=42 ) model_balanced.fit(X_train_scaled, y_train)逻辑说明:class_weight='balanced'的计算逻辑是权重 = 总样本数 / (类别数 * 该类样本数),攻击样本越少权重越高,损失函数里每个样本的贡献被重新加权。代价是模型对正常流量的误判会变多——这本质是入侵检测系统的一个经典权衡:误报率和漏报率不可能同时降低,安全场景下我们优先保证不漏报。
5.3 现象:正则化逻辑回归准确率反而比普通版低
现象:ex_2 正则化逻辑回归.py跑出来的准确率比ex_2 逻辑回归.py低了 3~5 个百分点,看起来「正则化有害」。
原因:常见做法里正则化强度调过头了。如果C=0.01或更小,正则化惩罚项在损失函数里的占比过大,模型被强约束住,欠拟合了。DDoS 流量特征几十维,即使特征之间有相关性,也不至于需要很强的正则化。
解决:把C当成超参做网格搜索,而不是拍脑袋定值。常见做法是从C = [0.001, 0.01, 0.1, 1, 10, 100]这个列表里用交叉验证选最优值。
from sklearn.model_selection import GridSearchCV # 定义搜索空间和管理器 param_grid = {'C': [0.001, 0.01, 0.1, 1, 10, 100]} model_cv = LogisticRegression(solver='lbfgs', max_iter=2000, random_state=42) grid = GridSearchCV(model_cv, param_grid, cv=5, scoring='f1') grid.fit(X_train_scaled, y_train) print('最优 C 值:', grid.best_params_['C']) print('最优 F1 分数: {:.4f}'.format(grid.best_score_))参数说明:cv=5表示 5 折交叉验证,scoring='f1'因为准确率在不平衡数据上不靠谱,用 F1 兼顾精确率和召回率。grid.best_params_会输出选中的 C 值,这个值就是你论文里可以写进实验配置表的参数。用网格搜索代替手调,是熟手和新手处理超参问题的分水岭。
5.4 现象:多类别脚本运行报ValueError: y should be a 1d array
现象:运行ex_3 多类别逻辑回归.py时,报错ValueError: y should be a 1d array, got an array of shape (N, 1) instead.,你检查了y_test.shape,显示是(500, 1)而不是(500,)。
原因:y 的列是一个二维 DataFrame 而不是一维 Series。这在 pandas 里很常见——如果你用df[['label']]而不是df['label']取列,得到的就是二维结构。sklearn 的fit接口严格检查输入形状,二维 y 在二分类时有时候能被自动压平,但多分类时直接报错。
解决:用ravel()或者flatten()把 y 压成一维。
import numpy as np # 如果 y 是从 DataFrame 切出来的二维结构,压平即可 y = np.ravel(df.iloc[:, -1].values) # 或者用 ravel 的替代方案 y = df.iloc[:, -1].values.ravel()逻辑说明:ravel()在可能的情况下返回原始数据的视图(不复制数据),flatten()总是返回副本。在数据量大的场景(几十万行),ravel()省内存,推荐优先使用。这个问题不大,但很容易在答辩现场手忙脚乱——评委让你现场跑一遍项目,你在这里卡住就尴尬了。
5.5 现象:同一份数据重跑,准确率有波动
现象:不修改任何代码,连续跑三次ex_2 逻辑回归.py,准确率分别是 91.2%、92.5%、91.8%,波动超过 1 个百分点。
原因:大概率是train_test_split没有固定random_state,每次运行划分出的训练集和验证集不同,模型自然在不同数据上表现不同。另一个可能是逻辑回归的 solver(如'sag'或'saga')使用了随机初始化,本身带有随机性。
解决:在所有涉及随机过程的函数里固定随机种子。注意不只是train_test_split要设random_state,如果用了SMOTE、GridSearchCV也要设置,保证完整实验链路的可复现性。这是我自己的硬性习惯——每次跑实验之前,检查所有随机源的种子是否固定。「可复现」是提交代码和写论文的底线,也是答辩时最容易被考到的问题。
6. 进阶技巧:从逻辑回归迈向更好的 DDoS 检测效果
6.1 用权重系数反推特征重要性,写进论文
逻辑回归训练完成后,每个特征对应一个权重系数,系数的绝对值衡量了该特征对决策的贡献程度。这是一个被大多数初学者忽略的论文素材——把权重系数按绝对值排序输出,你就得到了「基于逻辑回归的 DDoS 入侵检测特征重要性分析表」。
import pandas as pd # 假设 X 是 DataFrame,有特征名;feature_names 从数据列名获取 feature_names = df.columns[:-1].tolist() weights = model_reg.coef_[0] # 构建特征名与权重的映射,按绝对值排序 importance_df = pd.DataFrame({ '特征名': feature_names, '权重系数': weights, '权重绝对值': np.abs(weights) }).sort_values('权重绝对值', ascending=False) print('特征重要性 Top 10:') print(importance_df.head(10))逻辑说明:model_reg.coef_是逻辑回归的权重向量,二分类场景形状是(1, n_features),所以取[0]。这份表格放到论文实验章节里,配合一句「权重绝对值越大,说明该特征对区分正常流量与攻击流量的贡献越大」,就能把模型从黑匣子变成可解释的方法。我自己写毕设的时候,这段分析直接支撑了后续特征降维的决策——把权重底部的特征删掉,模型性能基本不变,还能降低过拟合风险。
6.2 用预测概率替代硬分类,调整检测阈值
predict返回的是 0/1 硬分类结果,但入侵检测系统在真实部署时更常用predict_proba返回的连续概率,再按实际业务需求调整阈值。比如把阈值从默认的 0.5 降到 0.3,可以让更多可疑流量进入人工审核队列,提高召回率;反之调高阈值可以降低误报,适合误报代价高的场景。
# 获取攻击类别的预测概率 y_prob = model.predict_proba(X_test_scaled)[:, 1] # 默认阈值为 0.5,改为 0.3 后重新判定 threshold = 0.3 y_pred_adjusted = (y_prob >= threshold).astype(int) # 对比两个阈值下的精确率和召回率 from sklearn.metrics import precision_score, recall_score print('阈值 0.5 - 精确率: {:.4f}, 召回率: {:.4f}'.format( precision_score(y_test, y_pred), recall_score(y_test, y_pred))) print('阈值 0.3 - 精确率: {:.4f}, 召回率: {:.4f}'.format( precision_score(y_test, y_pred_adjusted), recall_score(y_test, y_pred_adjusted)))逻辑说明:predict_proba返回一个二维数组,第 0 列是「正常」的概率,第 1 列是「攻击」的概率,取[:, 1]得到攻击概率。这里本质上是在做检测系统的策略权衡:调低阈值会让更多流量进入告警队列,安全人员的工作量增加,但漏掉攻击的概率降低。在毕设论文里可以画一条 ROC 曲线,展示不同阈值下的 TPR 与 FPR 变化,用一个带注释的截图或表格说明你最后选了哪个阈值、为什么。
6.3 与树模型做对比实验,提升论文上限
逻辑回归是基线模型,但如果你想拿高分,最好在论文里加一个对比实验——用随机森林或 XGBoost 在同一份数据上跑一下,证明逻辑回归作为基线的效果和差距在哪。这份资源没有包含树模型的代码,但特征工程和数据划分部分完全可以复用,你只需要在同样处理好的X_train_scaled上换一个模型。
from sklearn.ensemble import RandomForestClassifier # 随机森林不需要特征标准化,但用标准化数据也不影响 model_rf = RandomForestClassifier( n_estimators=100, max_depth=10, random_state=42, class_weight='balanced', n_jobs=-1 ) model_rf.fit(X_train, y_train) y_pred_rf = model_rf.predict(X_test) print('随机森林准确率: {:.4f}'.format(accuracy_score(y_test, y_pred_rf))) print(classification_report(y_test, y_pred_rf, target_names=['正常流量', 'DDoS攻击']))参数说明:n_estimators=100是树的数量,max_depth=10限制树深防止过拟合,class_weight='balanced'处理类别不平衡,n_jobs=-1使用所有 CPU 核心加速训练。对比实验的结论写起来也很顺:「实验结果表明,逻辑回归在检测准确率上达到 X%,随机森林达到 Y%,逻辑回归以约 1/10 的训练时间提供了可接受的检测性能,适合对实时性要求较高的场景。」这个对比让你的论文从「跑通了一个模型」升级成「做了多模型评估」,评审印象分会明显不一样。
从那以后,我每次拿到类似的项目,都会强制自己先跑通基线、再看数据分布、最后才碰复杂模型——这个顺序帮我避免了无数次「拿好模型跑烂数据」的翻车。希望这次拆解能帮你把这份资源的三个脚本真正跑起来、用到自己的项目里。
本文还有配套的精品资源,点击获取