基于机器学习的网络入侵检测与特征选择及随机森林分类器性能评估(NSL-KDD数据集)

news2025/6/18 16:59:19

简介

本文将详细介绍如何利用Python和相关机器学习库对NSL-KDD数据集进行预处理,特征选择,并通过随机森林算法构建网络入侵检测模型。同时,还将展示如何计算并可视化模型的ROC曲线以评估其性能。

首先,我们导入了必要的库,如pandas、seaborn、numpy以及scikit-learn等,并加载了KDDTrain+和KDDTest+两个数据集。通过对数据集进行初步探索,我们将列名重置为实际含义,并将标签(attack_type)以及其他类别型特征进行了编码转换。

在特征工程阶段,我们分析了攻击类型特征的相关性,通过找出与攻击类型关联最小的10个特征以及标准差较小的5个特征,确定了一组待删除的冗余特征。通过剔除这些特征,我们得到了精简后的数据集combined_data_reduced,并进一步将其划分为特征矩阵X和目标向量y。

接下来,我们使用随机森林分类器作为模型,设置了参数n_estimators为10,criterion为’entropy’,max_features为’auto’,bootstrap设置为True,以便训练模型并对测试集进行预测。获取模型在测试集上的得分,并输出了特征重要性。

为了更深入地评估模型的性能,我们还绘制了ROC曲线。ROC曲线是一种用于二分类问题中直观展示模型性能的工具,它展示了假正率(False Positive Rate, FPR)与真正率(True Positive Rate, TPR)之间的权衡关系。这里我们生成了一个示例数据集,并使用同样的随机森林模型计算出其ROC曲线。最后,我们在图表中添加了“无技能”基准线(即随机猜测的结果),并与模型的实际ROC曲线进行了对比。

总结来说,本篇文章展示了从原始数据预处理到特征选择,再到建立随机森林模型并评估其性能的全过程,为我们提供了在网络入侵检测领域运用机器学习技术的一个实践案例。

步骤

  1. 数据加载与初步预处理:读取KDDTrain+和KDDTest+两个CSV文件,合并为一个数据集,并重新命名列名。
  2. 特征工程:对类别型特征如攻击类型、协议类型等进行标签编码,分析特征与目标变量之间的相关性,基于相关性和标准差筛选出最不相关的特征予以删除,优化特征空间。
  3. 数据划分:将精简后的数据集划分为特征矩阵X和目标向量y,并进一步划分为训练集和测试集。
  4. 模型建立与训练:使用随机森林分类器进行训练,设置参数优化模型性能。
  5. 模型评估:计算模型在测试集上的准确率,并提取特征重要性;此外,还通过生成二分类示例数据集,展示了模型的ROC曲线,以更全面地评估模型在区分正常流量与攻击流量时的性能。

代码实现

导入必要的库

# 配置IPython自动补全为贪心模式
%config IPCompleter.greedy=True
# 导入数据处理和可视化库
import pandas as pd
import seaborn as sns
import numpy as np
import re
import sklearn

# 忽略警告信息
import warnings
warnings.filterwarnings("ignore")

# 导入绘图库及其配置
import matplotlib.pyplot as plt
import matplotlib as matplot
%matplotlib inline

# 设置IPython交互模式为全节点
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

# 导入数据集划分工具
from sklearn.model_selection import train_test_split

数据加载及预处理

从指定路径读取NSL-KDD99数据集的训练集和测试集;
重置训练集和测试集的列名,以便后续处理;
将训练集和测试集合并为一个大的数据集,以便进行统一的分析和处理;
调整数据集的列名,以符合特征的实际情况;
删除不需要的特征列,以简化数据集。

# 导入训练集和测试集
train = pd.read_csv('/kaggle/input/nsl-kdd99-dataset/KDDTrain+.txt')
test = pd.read_csv('/kaggle/input/nsl-kdd99-dataset/KDDTest+.txt')

# 获取训练集和测试集的形状(行数和列数)
train.shape
test.shape 

# 重命名训练集和测试集的列,使用列的序号作为列名
train.columns = range(train.shape[1])
test.columns = range(test.shape[1])

# 定义标签列表,对应数据集中的特征含义
labels = ['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', 'attack_type', 'difficulty_level']# subclass - > attack_type

# 将训练集和测试集合并为一个数据集
combined_data = pd.concat([train, test])

# 获取合并后数据集的形状
combined_data.shape

# 显示合并后数据集的前5行
combined_data.head(5)

# 将合并后数据集的列名替换为定义的标签列表
combined_data.columns = labels

# 删除合并后数据集中的'difficulty_level'列
combined_data = combined_data.drop('difficulty_level', 1)

# 显示处理后的合并数据集的前3行
combined_data.head(3)
0123456789...33343536373839404142
00udpotherSF14600000...0.000.600.880.000.000.000.00.00normal15
10tcpprivateS0000000...0.100.050.000.001.001.000.00.00neptune19
20tcphttpSF23281530000...1.000.000.030.040.030.010.00.01normal21
30tcphttpSF1994200000...1.000.000.000.000.000.000.00.00normal21
40tcpprivateREJ000000...0.070.070.000.000.000.001.01.00neptune21

5 rows × 43 columns

durationprotocol_typeserviceflagsrc_bytesdst_byteslandwrong_fragmenturgenthot...dst_host_srv_countdst_host_same_srv_ratedst_host_diff_srv_ratedst_host_same_src_port_ratedst_host_srv_diff_host_ratedst_host_serror_ratedst_host_srv_serror_ratedst_host_rerror_ratedst_host_srv_rerror_rateattack_type
00udpotherSF14600000...10.00.600.880.000.000.000.00.00normal
10tcpprivateS0000000...260.10.050.000.001.001.000.00.00neptune
20tcphttpSF23281530000...2551.00.000.030.040.030.010.00.01normal

3 rows × 42 columns

数据编码

from sklearn import preprocessing
# 导入预处理模块

le = preprocessing.LabelEncoder()
# 创建标签编码器对象

# 打印攻击类型集合,以查看原始值
print(set(list(combined_data['attack_type']))) 

# 对数据集中的'attack_type''protocol_type''service''flag'列进行标签编码
combined_data['attack_type'] = le.fit_transform(combined_data['attack_type'])
combined_data['protocol_type'] = le.fit_transform(combined_data['protocol_type'])
combined_data['service'] = le.fit_transform(combined_data['service'])
combined_data['flag'] = le.fit_transform(combined_data['flag'])

# 描述编码后的攻击类型数据
print('\nDescribing attack_type: ')
print("min", combined_data['attack_type'].min()) # 最小值
print("max", combined_data['attack_type'].max()) # 最大值
print("mean", combined_data['attack_type'].mean()) # 平均值
print("mode", combined_data['attack_type'].mode()) # 模式,即出现频率最高的值
print("looks like 16 is 'normal' ")
# 根据编码结果推断,16可能代表'normal'攻击类型

特征消除和数据集分割

根据攻击类型与其他特征的相关性以及特征的标准差,进行特征选择和消除

# 计算特征之间的相关性矩阵,并按'attack_type'的绝对相关性值进行排序
corr_matrix = combined_data.corr().abs().sort_values('attack_type')

# 选择与'attack_type'相关性最低的前10个特征
leastCorrelated = corr_matrix['attack_type'].nsmallest(10)
leastCorrelated = list(leastCorrelated.index)

# 选择标准差最低的前5个特征
leastSTD =  combined_data.std().to_frame().nsmallest(5, columns=0)
leastSTD = list(leastSTD.transpose().columns)

# 结合相关性和标准差,得到需要消除的特征集合
featureElimination = set(leastCorrelated + leastSTD)
len(featureElimination)
featureElimination

# 根据特征集合,从数据集中删除选定的特征
combined_data_reduced = combined_data.drop(featureElimination,axis=1)

# 分离特征和标签,并将数据集划分为训练集和测试集
data_x = combined_data_reduced.drop('attack_type', axis=1)
data_y = combined_data_reduced.loc[:,['attack_type']]
X_train, X_test, y_train, y_test = train_test_split(data_x, data_y, test_size=.5, random_state=42)  # 待完成:说明train_test_split的具体作用和参数意义

{‘dst_bytes’,
‘is_host_login’,
‘land’,
‘logged_in’,
‘num_access_files’,
‘num_compromised’,
‘num_file_creations’,
‘num_outbound_cmds’,
‘num_root’,
‘num_shells’,
‘root_shell’,
‘srv_rerror_rate’,
‘su_attempted’,
‘urgent’}

训练随机森林分类器模型

# 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from itertools import cycle

from sklearn import svm, datasets
from sklearn.metrics import roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
from sklearn.metrics import roc_auc_score
from sklearn import metrics

from sklearn import linear_model

from sklearn.ensemble import VotingClassifier

from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import IsolationForest

from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier

import gc 
gc.collect()

# 初始化随机森林分类器
RF = RandomForestClassifier(n_estimators=10, criterion='entropy', max_features='auto', bootstrap=True)

# 训练模型
RF.fit(X_train, y_train)
# 获取特征重要性
RF_feature = RF.feature_importances_

# 在测试集上评估模型性能
rf_score = RF.score(X_test, y_test)
print('RandomForestClassifier processing ,,,')

# 多类别问题的二进制化处理
y = preprocessing.label_binarize(y_train, classes=[0, 1, 2, 3])
n_classes = y.shape[1]

# 示例:绘制预测模型的ROC曲线
# 生成二分类数据集
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_curve
from matplotlib import pyplot

X, y = make_classification(n_samples=1000, n_classes=2, random_state=1)
# 划分训练集和测试集
trainX, testX, trainy, testy = train_test_split(X, y, test_size=0.5, random_state=2)
# 训练模型
model = RandomForestClassifier()
model.fit(trainX, trainy)
# 预测概率
yhat = model.predict_proba(testX)
# 获取正类的概率
pos_probs = yhat[:, 1]
# 绘制无技能的ROC曲线
pyplot.plot([0, 1], [0, 1], linestyle='--', label='No Skill')
# 计算模型的ROC曲线
fpr, tpr, _ = roc_curve(testy, pos_probs)
# 绘制模型的ROC曲线
pyplot.plot(fpr, tpr, marker='_', label='RFC_Performance')
# 添加轴标签
pyplot.xlabel('False Positive Rate')
pyplot.ylabel('True Positive Rate')
# 显示图例
pyplot.legend()
# 显示图形
pyplot.show()

在这里插入图片描述
在这里插入图片描述

优化建议

  1. 特征选择方面,可以尝试更多的特征选择方法,如递归特征消除(RFE)、基于树的特征重要性排序等,寻找最优特征子集。
  2. 超参数调优:针对随机森林分类器,可以通过网格搜索或随机搜索等方式调整n_estimators、max_depth、min_samples_split等超参数,寻找最佳模型配置。
  3. 类别不平衡问题处理:由于实际场景中正常流量可能远大于异常流量,可考虑引入过采样、欠采样或SMOTE等技术平衡各类别样本。
  4. 模型集成:结合AdaBoostClassifier、GradientBoostingClassifier等多种分类器进行集成学习,提高整体预测性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1503633.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【机器学习】在Python中进行K-Means聚类和层次聚类

Python中聚类算法API的使用指南 聚类分析是数据分析中一种常见的无监督学习方法,通过将相似的对象分组在一起,我们能够识别出数据集中的自然分群。本文将介绍如何使用Python中的聚类算法接口,KMeans和层次聚类方法。 K-Means 聚类 K-Means…

保姆级讲解字符串函数(上篇)

目录 字符分类函数 导图 函数介绍 1.getchar 2. isupper 和 islower 字符转换函数:(toupper , tolower) 与 putchar 字符串函数 导图 string函数的使用和模拟实现 string的使用 求字符串长度 字符串的比较 string函数的模拟实现…

苍穹外卖-day01

苍穹外卖-day01 目录 苍穹外卖-day01课程内容1. 软件开发整体介绍1.1 软件开发流程1.2 角色分工1.3 软件环境 2. 苍穹外卖项目介绍2.1 项目介绍2.2 产品原型2.3 技术选型 3. 开发环境搭建3.1 前端环境搭建3.2 后端环境搭建3.2.1 熟悉项目结构3.2.2 Git版本控制3.2.3 数据库环境…

【考研数学】129高分学姐二战经验+资料分享

21年数学三87分 22年数学三129分 可以说这两年该踩的雷我都踩了、该做的题我都做了。 进来看看是什么使我突然醒悟让我数学提分40多分的叭。 李林的880题我也做过,先来说说这本书的优缺点以及适用人群吧。 习题优点 李林老师的880题难度适中,很贴近…

013 Linux_互斥

前言 本文将会向你介绍互斥的概念,如何加锁与解锁,互斥锁的底层原理是什么 线程ID及其地址空间布局 每个线程拥有独立的线程上下文:一个唯一的整数线程ID, 独立的栈和栈指针,程序计数器,通用的寄存器和条件码。 和其…

基于springboot实现大学外卖管理系统项目【项目源码+论文说明】

基于springboot实现大学外卖管理系统演示 摘要 如今,信息化不断的高速发展,社会也跟着不断进步,现今的社会,各种工作都离不开信息化技术,更离不开电脑的管理。信息化技术也越来越渗透到各小型的企业和公司中&#xff…

pytorch(九)卷积神经网络

文章目录 卷积神经网络全连接神经网络与卷积神经网络的区别概念性知识mnist数据集(卷积神经网络) GoogLeNetInception 残差网络ResNet残差块结构 卷积神经网络 全连接神经网络与卷积神经网络的区别 全连接神经网络是一种最为基础的前馈神经网络,他的每一个神经元都…

AndroidStudio跑马灯实现

在activity_main.xml中编写如下代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_h…

【考研数学】打基础,张宇《30讲》还是武忠祥《基础篇》?

张宇的30讲还是不太适合零基础的考研党去听...因为宇哥整体节奏较快&#xff0c;如果目标分较高&#xff0c;有一定的基础还是建议的 身边真的很多130-140的大佬都是跟着张宇从头到尾&#xff0c;张宇老师的习题册非常适合基础扎实&#xff0c;想冲刺高分的考研党 我是属于基…

R语言的数据类型与数据结构:向量、列表、矩阵、数据框及操作方法

R语言的数据类型与数据结构&#xff1a;向量、列表、矩阵、数据框及操作方法 介绍向量列表矩阵数据框 介绍 R语言拥有丰富的数据类型和数据结构&#xff0c;以满足各类数据处理和分析的需求。本文将分享R语言中的数据类型&#xff0c;包括向量、列表、矩阵、数据框等&#xff…

Skywalking官方的实战模拟项目Live-Demo

Skywalking 官方的实战模拟项目Live-Demo Live-Demo 是 Skywalking 官方的实战模拟项目&#xff0c;其中包含4个子模块项目 projectA访问projectB、projectC两个SpringBoot项目 projectB访问本地的H2数据库 projectC访问www.baidu.com并同时向一台Kafka消息队列写入数据 proje…

VSCODE解决git合并过程中的冲突问题;error: failed to push some refs to

1&#xff1a;异常现象 推送有冲突的git修改到远端的时候&#xff0c;会有如下提示 git.exe push --progress “origin” master:master To http://gitlab.xxx.com/dujunqiu/test.git ! [rejected] master -> master (fetch first) error: failed to push some refs to ‘…

解决“ModuleNotFoundError: No module named ‘RPi._GPIO‘”

背景描述 树莓派4B Ubuntu20.04 Python3.9安装RPi.GPIO后无法使用 解决办法 使用sudo pip3 install RPi.GPIO --upgrade尝试更新&#xff0c;发生红字报错&#xff0c;提示在编译过程中缺少Python开发头文件&#xff08;Python.h&#xff09;&#xff0c;因此应该先安装他&…

短视频矩阵系统--抖去推---年后技术还能迭代更新开发运营吗?

短视频矩阵系统#短视频矩阵系统已经开发3年&#xff0c;年后这个市场还能继续搞吗&#xff1f;目前市面上开发短视频账号矩阵系统的源头公司已经不多了吧&#xff0c;或者说都已经被市场被官方平台的政策影响的不做了吧&#xff0c;做了3年多的矩阵系统开发到现在真的是心里没有…

excel 动态列导出

excel动态列&#xff0c;只好用poi来写了&#xff0c;也并不复杂&#xff0c;一样就这个件事情抽像为几步&#xff0c;就是套路了&#xff0c;开发效率就上去了。 1 准备空模板 导出操作与excel模板的导出一样&#xff0c;可以参考excel导出标准化 2 自定义SheetWriteHandler …

TI IWR6843ISK ROS驱动程序搭建

1、设备准备 1.1 硬件设备 1&#xff09;TI IWR 6843 ISK 1块 2&#xff09;Micro USB 数据线 1条 1.2 系统环境 1&#xff09;VMware Workstation 15 Player 虚拟机 2&#xff09;Ubuntu18.04 并安装有 ROS1 系统 如若没有安装 ROS 系统&#xff0c;可通过如下指令进行…

HTML 02

1.列表 布局内容排列整齐的区域 (1)无序列表 写法&#xff1a; <ul><li>列表条目1</li><li>列表条目2</li><li>列表条目3</li></ul> 浏览器中显示&#xff1a; 注意&#xff1a; ul标签里只能包裹li标签 li标签里可以包…

算法学习系列(四十):贡献法

目录 引言概念一、孤独的照片二、牛的基因学三、字串分值 引言 关于这个贡献法考的不是很多&#xff0c;主要题型是出现在需要枚举每一个组合这类题&#xff0c;出现的次数较多。没有固定的模板&#xff0c;就是一种思想&#xff0c;跟贪心一样&#xff0c;每个题都是不一样的…

探讨系统测试的最佳实践与思维模式!

这是测试活动过程详解系列的最后一篇文章。之前的想法&#xff0c;是对测试过程各重要环节进行拆解&#xff0c;然后介绍这个环节重点要做的事情&#xff0c;为什么要做这些事&#xff0c;以及注意事项。 前面几篇文章分别介绍了单元测试、集成测试、回归测试阶段要解决的问题…

yolo模型中神经节点Mul与Sigmoid 和 Conv、Concat、Add、Resize、Reshape、Transpose、Split

yolo模型中神经节点Mul与Sigmoid 和 Conv、Concat、Add、Resize、Reshape、Transpose、Split 在YOLO&#xff08;You Only Look Once&#xff09;模型中&#xff0c;具体作用和用途的解释&#xff1a;