GSMOTE+AE+DNN(CIC-IDS-2017数据集)
前言
经过多次实验最终还是决定用回最初的方案GSMOTE+AE+DNN,因为用别的方法很难处理UNSW-NB15数据集。网上传的各种UNSW-NB15高Acc、高Recall、低FAR的实验方案都多多少少有些问题,要么就是不用官方提供的训练集和测试集,自己通过那四个csv文件构造训练集和测试集,那个本身就有87%的正常流量,怎么做效果都不会差,要么就是没去掉attack_cat那一列标签列,导致标签泄露,结果也不会差,所以我也要在训练集和测试集中保存attack_cat列,分类效果出来很好,虽然这样做不对,但是不公开源码,保不准别人都是这样玩的,不管了,就用这种方法吧,起码模型复杂度高一点,看起来效果也好,论文就是编故事,看起来效果好就行了。
实验结果
从现在的情况来看实验结果都大差不差,都不是很满意,主要是精确率和召回率低,而且没有哪一项指标能达到98%的效果的,后续再优化一下自动编码器,争取把指标提到98%左右
| 参数 | 结果 | 混淆矩阵 |
|---|---|---|
| 预测阈值:0.5 epochs: 20 |
准确率: 0.9722 精确率: 0.9240 召回率: 0.9601 F1分数: 0.9417 误报率: 0.0241 |
混淆矩阵: [[354233 8749] [ 4423 106445]] |
| 预测阈值: 0.6,epochs: 30 | 准确率: 0.9760 精确率: 0.9432 召回率: 0.9551 F1分数: 0.9491 误报率: 0.0176 |
混淆矩阵: [[356604 6378] [ 4977 105891]] |
| 预测阈值: 0.7,epochs: 40 | 准确率: 0.9723 精确率: 0.9604 召回率: 0.9195 F1分数: 0.9395 误报率: 0.0116 |
混淆矩阵: [[358776 4206] [ 8929 101939]] |
| 预测阈值: 0.79,epochs: 50 | 准确率: 0.9735 精确率: 0.9652 召回率: 0.9198 F1分数: 0.9419 误报率: 0.0101 |
混淆矩阵: [[359308 3674] [ 8896 101972]] |
| 预测阈值: 0.89,epochs: 60 | 准确率: 0.9681 精确率: 0.9792 召回率: 0.8825 F1分数: 0.9283 误报率: 0.0057 |
混淆矩阵: [[360908 2074] [ 13030 97838]] |
| 预测阈值: 0.6,epochs: 20 在AE中使用 binary_crossentropy作为损失函数 所以不能在AE中使用这个损失函数 只能在DNN分类时使用,不然会出大问题 |
准确率: 0.7760 精确率: 0.0000 召回率: 0.0000 F1分数: 0.0000 误报率: 0.0000 |
【362982 0 110868 0】 |
| 预测阈值: 0.6,epochs: 20 在AE中将损失函数重新换为mse 与之前使用的损失函数相同 |
准确率: 0.9761 精确率: 0.9532 召回率: 0.9443 F1分数: 0.9487 误报率: 0.0142 |
混淆矩阵: [[357838 5144] [ 6172 104696]] |
| 预测阈值: 0.6,epochs: 20 DNN学习率为0.0001 上面的是没调学习率的 |
准确率: 0.9493 精确率: 0.8361 召回率: 0.9745 F1分数: 0.9000 误报率: 0.0584 |
[[341802 21180] [ 2825 108043]] |
| 预测阈值: 0.6,epochs: 20 DNN学习率为0.001 |
准确率: 0.9776 精确率: 0.9382 召回率: 0.9680 F1分数: 0.9529 误报率: 0.0195 |
混淆矩阵: [[355907 7075] [ 3546 107322]] |
| 预测阈值: 0.6,epochs: 20 AE和DNN的batch_size都设为256 效果变差了 |
准确率: 0.9590 精确率: 0.9215 召回率: 0.9013 F1分数: 0.9113 误报率: 0.0234 |
混淆矩阵: [[354473 8509] [ 10941 99927]] |
| 预测阈值: 0.5,epochs: 20 DNN学习率为0.001 DNN batch_size=1024 |
准确率: 0.9556 精确率: 0.9029 召回率: 0.9081 F1分数: 0.9055 误报率: 0.0298 |
[[352149 10833] [ 10185 100683]] |
| 预测阈值: 0.5,epochs: 20 DNN学习率为0.001 DNN batch_size=128 AE batch_size=128 epoch=15 |
准确率: 0.9771 精确率: 0.9310 召回率: 0.9745 F1分数: 0.9522 误报率: 0.0221 |
[[354971 8011] [ 2832 108036]] |
| 同上 | 准确率: 0.9723 精确率: 0.9150 召回率: 0.9721 F1分数: 0.9427 误报率: 0.0276 |
[[352965 10017] [ 3093 107775]] |
| encoding_dim=50 AE输出维度变为50,其他不变 阈值也0.5 |
准确率: 0.9797 精确率: 0.9424 召回率: 0.9728 F1分数: 0.9574 误报率: 0.0182 |
[[356390 6592] [ 3016 107852]] |
| DNN训练次数从20改为50,其他同上 | 准确率: 0.9667 精确率: 0.9210 召回率: 0.9383 F1分数: 0.9296 误报率: 0.0246 |
[[354061 8921] [ 6843 104025]] |
| 同上,重复实验 | 准确率: 0.9794 精确率: 0.9301 召回率: 0.9863 F1分数: 0.9574 误报率: 0.0226 |
混淆矩阵: [[354762 8220] [ 1520 109348]] |
| AE输出维度变为60,其他不变 | 准确率: 0.9665 精确率: 0.9175 召回率: 0.9417 F1分数: 0.9294 误报率: 0.0259 |
[[353597 9385] [ 6468 104400]] |
| 同上,重复试验 AE输出维度变为6 |
准确率: 0.9578 精确率: 0.8715 召回率: 0.9614 F1分数: 0.9142 误报率: 0.0433 |
|
| DNN 训练50轮 阈值=0.5 | 准确率: 0.9795 精确率: 0.9554 召回率: 0.9571 F1分数: 0.9563 误报率: 0.0136 |
[[358033 4949] [ 4757 106111]] |
| DNN batch_size=64 阈值=0.6 AE维度输出=65 其余同上 |
准确率: 0.9774 精确率: 0.9428 召回率: 0.9615 F1分数: 0.9521 误报率: 0.0178 |
[[356519 6463] [ 4268 106600]] |
| 同上,重复试验 | 准确率: 0.9657 精确率: 0.9264 召回率: 0.9270 F1分数: 0.9267 误报率: 0.0225 |
[[354811 8171] [ 8090 102778]] |
存在问题
主要是加了个自动编码器拖累了分类结果,没有自动编码器时,无论是DNN还是CNN,都能轻易达到98%~99%的效果,但是加上了一个自动编码器,进行降维时损失了一些重要特征,导致效果下降比较明显。
后续还需要优化一下关于自动编码器的代码,降低降维损失,可以提高降维的维度或者选择一个合适的维度,也可以继续减少维度试试看,这个是可以自定义的,本身进行数据预处理后剩下的是66维,但是当前选择保留的维数为40,相当于少了26维
改进思路
多尝试超参数,可以通过循环来实现,例如
1 | for i in range(1,100): # 这样子会跑100次代码,从1~99,相当于做了多次试验 |
可尝试修改的超参数:
- 自动编码器层数结构、保存的数据维度
- 自动编码器epochs、batch_size、validation_data
- DNN层数结构
- DNN epochs、batch_size,learning_rate
- GSMOTE的参数,合成样本的数量等
- 激活函数、优化器
当前实验代码
autoencoder_model.py
1 | # DNN.py |
DNN+AE.py
1 | # DNN.py |
imbalance_process.py
1 | from typing import Tuple |
preprocess.py
1 | import numpy as np |

