发布时间:2025-12-10 11:36:29 浏览次数:6
您或许知道,作者后续分享网络安全的文章会越来越少。但如果您想学习人工智能和安全结合的应用,您就有福利了,作者将重新打造一个《当人工智能遇上安全》系列博客,详细介绍人工智能与安全相关的论文、实践,并分享各种案例,涉及恶意代码检测、恶意请求识别、入侵检测、对抗样本等等。只想更好地帮助初学者,更加成体系的分享新知识。该系列文章会更加聚焦,更加学术,更加深入,也是作者的慢慢成长史。换专业确实挺难的,系统安全也是块硬骨头,但我也试试,看看自己未来四年究竟能将它学到什么程度,漫漫长征路,偏向虎山行。享受过程,一起加油~
首先,祝大家1024程序员节快乐,祝CSDN越来越好,感谢大家十年的陪伴。
随着互联网的繁荣,现阶段的恶意代码也呈现出快速发展的趋势,主要表现为变种数量多、传播速度快、影响范围广。在这样的形势下,传统的恶意代码检测方法已经无法满足人们对恶意代码检测的要求。比如基于签名特征码的恶意代码检测,这种方法收集已知的恶意代码,以一种固定的方式生成特定的签名,维护这样的签名库,当有新的检测任务时,通过在签名库中检索匹配的方法进行检测。暂且不说更新、维护签名库的过程需要耗费大量的人力物力,恶意代码编写者仅仅通过混淆、压缩、加壳等简单的变种方式便可绕过这样的检测机制。
为了应对上面的问题,基于机器学习的恶意代码检测方法一直是学界研究的热点。由于机器学习算法可以挖掘输入特征之间更深层次的联系,更加充分地利用恶意代码的信息,因此基于机器学习的恶意代码检测往往表现出较高的准确率,并且一定程度上可以对未知的恶意代码实现自动化的分析。下面让我们开始进行系统的介绍吧~
作者作为网络安全的小白,分享一些自学基础教程给大家,主要是在线笔记,希望您们喜欢。同时,更希望您能与我一起操作和进步,后续将深入学习AI安全和系统安全知识并分享相关实验。总之,希望该系列文章对博友有所帮助,写文不易,大神们不喜勿喷,谢谢!如果文章对您有帮助,将是我创作的最大动力,点赞、评论、私聊均可,一起加油喔!
前文推荐:
作者的github资源:
本文将分享机器学习在安全领域的应用,并复现一个基于机器学习的入侵检测和攻击识别。严格意义上来说,这篇文章是数据分析,它有几个亮点:
文章中也有很多不足之处,恶意代码或入侵检测作者还会继续深入,包括源代码、二进制分析。作者作为网络安全的小白,分享一些自学基础教程给大家,希望你们喜欢。同时,更希望你能与我一起操作进步,争取能入门,后续也将深入学习网络安全和系统安全知识并分享相关实验。总之,希望该系列文章对博友有所帮助,写文不容易,大神请飘过,不喜勿喷,谢谢!
KDD是数据挖掘与知识发现(Data Mining and Knowledge Discovery)的简称,”KDD CUP 99 dataset”是KDD竞赛在1999年举行时采用的数据集。从官网下载KDD99数据集,如下图所示:
http://kdd.ics.uci.edu/databases/kddcup99/kddcup99.html
This is the data set used for The Third International Knowledge Discovery and Data Mining Tools Competition, which was held in conjunction with KDD-99 The Fifth International Conference on Knowledge Discovery and Data Mining. The competition task was to build a network intrusion detector, a predictive model capable of distinguishing between bad connections, called intrusions or attacks, and good normal connections. This database contains a standard set of data to be audited, which includes a wide variety of intrusions simulated in a military network environment.
KDD Cup 1999数据集: 是KDD知识发现和数据挖掘会议的比赛数据集,主要为军事网络环境中模拟的多种入侵,是入侵检测应用的常用数据集,后续衍生出NSL-KDD。建议读者结合论文和官网数据集进行分析:
数据文件包括:
kddcup.names 功能列表。kddcup.data.gz 完整数据集(18M; 743M未压缩)kddcup.data_10_percent.gz 10%的数据集(2.1M; 75M未压缩)kddcup.newtestdata_10_percent_unlabeled.gz(1.4M; 45M未压缩)kddcup.testdata.unlabeled.gz (11.2M; 430M未压缩)kddcup.testdata.unlabeled_10_percent.gz (1.4M; 45M未压缩)corrected.gz 正确标签的测试数据training_attack_types 入侵类型列表typo-correction.txt 关于数据集中的简要说明1998年美国国防部高级规划署(DARPA)在MIT林肯实验室进行了一项入侵检测评估项目。林肯实验室建立了模拟美国空军局域网的一个网络环境,收集了9周时间的TCPdump()网络连接和系统审计数据,仿真各种用户类型、各种不同的网络流量和攻击手段,使它就像一个真实的网络环境。这些TCPdump采集的原始数据被分为两个部分:7周时间的训练数据,大概包含5,000,000多个网络连接记录,剩下的2周时间的测试数据大概包含2,000,000个网络连接记录。
4种异常类型分别是:
随后来自哥伦比亚大学的Sal Stolfo 教授和来自北卡罗莱纳州立大学的 Wenke Lee 教授采用数据挖掘等技术对以上的数据集进行特征分析和数据预处理,形成了一个新的数据集。该数据集用于1999年举行的KDD CUP竞赛中,成为著名的KDD99数据集。虽然年代有些久远,但KDD99数据集仍然是网络入侵检测领域的事实Benckmark,为基于计算智能的网络入侵检测研究奠定基础。
数据分布如下图所示(作者自己论文截图):每个网络连接被标记为正常(normal)或异常(attack),异常类型被细分为4大类共39种攻击类型,其中22种攻击类型出现在训练集中,另有17种未知攻击类型出现在测试集中。
下载的数据集如下图所示,这里以10%的数据集来进行实验。
下面展现了其中3条记录,总共有42项特征,最后一列是标记特征(Label),其他前41项特征共分为四大类。
0,tcp,http,SF,239,486,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,8,8,0.00,0.00,0.00,0.00,1.00,0.00,0.00,19,19,1.00,0.00,0.05,0.00,0.00,0.00,0.00,0.00,normal.
0,icmp,ecr_i,SF,1032,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,511,511,0.00,0.00,0.00,0.00,1.00,0.00,0.00,255,255,1.00,0.00,1.00,0.00,0.00,0.00,0.00,0.00,smurf.
0,tcp,private,S0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,13,1.00,1.00,0.00,0.00,0.25,0.10,0.00,255,13,0.05,0.07,0.00,0.00,1.00,1.00,0.00,0.00,neptune.
数据集特征如下表所示:
接下来按顺序解释各个特征的具体含义,这是进行数据分析之前非常必要的一个环节。
基本连接特征包含了一些连接的基本属性,如连续时间,协议类型,传送的字节数等。
第二部分特征是TCP连接的内容特征,共13种。对于U2R和R2L之类的攻击,由于它们不像DoS攻击那样在数据记录中具有频繁序列模式,而一般都是嵌入在数据包的数据负载里面,单一的数据包和正常连接没有什么区别。为了检测这类攻击,Wenke Lee等从数据内容里面抽取了部分可能反映入侵行为的内容特征,如登录失败的次数等。
第三类特征是基于时间的网络流量统计特征。包括相同目标主机和相同服务。
由于网络攻击事件在时间上有很强的关联性,因此统计出当前连接记录与之前一段时间内的连接记录之间存在的某些联系,可以更好的反映连接之间的关系。这类特征又分为两种集合:
具体翻译内容如下:
注意:这一大类特征中,23、25、27、29、30这5个特征是 “same host” 特征,前提都是与当前连接具有相同目标主机的连接;24、26、28、31这4个特征是 “same service” 特征,前提都是与当前连接具有相同服务的连接。
基于时间的流量统计只是在过去两秒的范围内统计与当前连接之间的关系,而在实际入侵中,有些 Probing攻击使用慢速攻击模式来扫描主机或端口,当它们扫描的频率大于2秒的时候,基于时间的统计方法就无法从数据中找到关联。所以Wenke Lee等按照目标主机进行分类,使用一个具有100个连接的时间窗,统计当前连接之前100个连接记录中与当前连接具有 相同目标主机 的统计信息。
KDD99数据集总共由500万条记录构成,它还提供一个10%的训练子集和测试子集,它的样本类别分布如下:
具体的数据描述如下:
入侵检测
入侵检测的方法从根本上讲就是设计一个分类器,能将数据流中的正常与异常数据区分出来,从而实现对攻击行为的报警。本文KDD99数据集的目的就是为入侵检测系统提供统一的性能评价基准,常用来在学术圈检验入侵检测算法的好坏。本文将数据集中的10%训练集来训练分类器,然后用corrected测试集测试分类器性能,这个分类器可以是基于贝叶斯的、决策树的、神经网络的或者是支持向量机的。
特征选择
特征选择是KDD99数据集的另一个主要应用。KDD99数据集中,每个连接有41个特征,对于一个分类器来说,要从这么多特征中提取规则是费时且不精确的,这体现在一些无关或冗余的特征往往会降低分类器模型的检测精度和速度。而且对于从原始的tcpdump数据中提取特征这一过程,也将是困难和费时的,这对于在线入侵检测系统是致命的。因此去除冗余特征或不重要特征,对于提高分类器训练速度和检测精度来说,是必要的。要说明的是对于不同的分类器来说,最优的特征子集可以是不同的。
数据集评价
KDD 99数据集是入侵检测领域的Benchmark(基准),为基于计算智能的网络入侵检测研究奠定了基础,从那以后很多学者开始研究入侵检测算法,当然不能不提到众所周知的“功夫网”,实际上它就是一个大规模的入侵检测系统。KDD99从1999年创建已经过去多年,当年的实验条件和攻击手段放到今天早已过时,而且从原来的网络层攻击进化为针对应用层的攻击,例如跨站脚本、数据库注入等等(当然,针对应用层攻击自有新的解决方案)。你可以说,要解决这个问题,重新做一遍98年那个实验,用新的设备新的攻击手段,产生新的数据集不就行了吗?事实是据我所知还没有学术组织公开新的且质量较高的数据集,安全软件公司里肯定有足够的数据库,当然,人家是不会共享出来的,就靠这个赚钱。另一个解决办法是你自己搭建网络环境,自己做实验,就是累点,当然可行。
所以,希望这篇基础性文章对您有所帮助。
在数据挖掘的过程中,数据的预处理一直都是非常重要的一个环节,只有把数据转化为分类器认可的形式才可以对其进行训练。下面这段代码参考CSDN asialee_bird大神的文章及Github代码,非常厉害的一位博主,推荐大家阅读他的文章(https://blog.csdn.net/asialee_bird)。
个人认为这段代码最大的亮点是:
(1) 有效地将数据集中字符型转换为数值型,这是数据集预处理常见的方法。
(2) 训练集和测试集的类标不同,通过全局变量动态增加新类标,对未知类型的检测是评价算法的重要指标。
处理后的结果如下图所示:
0,2,12,9,520,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,457,457,0.00,0.00,0.00,0.00,1.00,0.00,0.00,255,255,1.00,0.00,1.00,0.00,0.00,0.00,0.00,0.00,5
0,0,21,9,428,7512,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,7,18,0.00,0.00,0.00,0.00,1.00,0.00,0.11,255,255,1.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0
这里通过KNN算法实现一个最简单的入侵检测。
K最近邻(K-Nearest Neighbor,简称KNN)分类算法是数据挖掘分类技术中最简单常用的方法之一。所谓K最近邻,就是寻找K个最近的邻居的意思,每个样本都可以用它最接近的K个邻居来代表。本小节主要讲解KNN分类算法的基础知识及分析实例。
KNN分类算法是最近邻算法,字面意思就是寻找最近邻居,由Cover和Hart在1968年提出,简单直观易于实现。下面通过一个经典的例子来讲解如何寻找邻居,选取多少个邻居。下图是非常经典的KNN案例,需要判断右边这个动物是鸭子、鸡还是鹅?它涉及到了KNN算法的核心思想,判断与这个样本点相似的类别,再预测其所属类别。由于它走路和叫声像一只鸭子,所以右边的动物很可能是一只鸭子。
所以,KNN分类算法的核心思想是从训练样本中寻找所有训练样本X中与测试样本距离(欧氏距离)最近的前K个样本(作为相似度),再选择与待分类样本距离最小的K个样本作为X的K个最邻近,并检测这K个样本大部分属于哪一类样本,则认为这个测试样本类别属于这一类样本。假设现在需要判断下图中的圆形图案属于三角形还是正方形类别,采用KNN算法分析如下:
1.当K=3时,图中第一个圈包含了三个图形,其中三角形2个,正方形一个,该圆的则分类结果为三角形。
2.当K=5时,第二个圈中包含了5个图形,三角形2个,正方形3个,则以3:2的投票结果预测圆为正方形类标。
总之,设置不同的K值,可能预测得到不同的结果。
KNeighborsClassifier可以设置3种算法:brute、kd_tree、ball_tree,设置K值参数为n_neighbors=3。
调用方法如下:
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=3, algorithm=“ball_tree”)
它也包括两个方法:
接下来开始进行KNN算法分类分析,其中KNN核心算法主要步骤包括五步:
上面代码非常简单,其输出结果如下图所示。但也存在几个缺点:
数据高度重叠,所以接下来我们对KNN算法进行优化。
数据标准化是机器学习、数据挖掘中常用的一种方法。
数据标准化主要是应对特征向量中数据很分散的情况,防止小数据被大数据(绝对值)吞并的情况。另外,数据标准化也有加速训练,防止梯度爆炸的作用。下面是从李宏毅教授视频中截下来的两张图,左图表示未经过数据标准化处理的loss更新函数,右图表示经过数据标准化后的loss更新图。可见经过标准化后的数据更容易迭代到最优点,而且收敛更快。
在聚类\分类算法中,使用计算距离的方法对数据进行聚类\分类,而连接记录的固定特征属性中有两种类型的数值——离散型和连续型。对于连续型特征属性,各属性的度量方法不一样。一般而言,所用的度量单位越小,变量可能的值域就越大,这样对聚类结果的影响也越大,即在计算数据间距离时对聚类的影响越大,甚至会出现“大数”吃“小数”的现象。
因此为了避免对度量单位选择的依赖,消除由于属性度量的差异对聚类\分类产生的影响,需要对属性值进行标准化。对于离散型特征属性本文中并不作标准化处理,而是放在聚类算法中计算距离时处理。所以数据标准化是针对连续型特征属性的。
设训练数据集有n条网络连接记录,每个记录中有22个连续型属性向量记作 Xij(1≤i≤n,11≤j≤41) 。对 Xij 数据预处理分为两步:数值标准化和数值归一化。
Z-score标准化:
基于数据均值和方差的标准化化方法。标准化后的数据是均值为0,方差为1的正态分布。这种方法要求原始数据的分布可以近似为高斯分布,否则效果会很差。标准化公式如下,
x′=x−meanstdx' = \frac{x-mean}{std} x′=stdx−mean
核心代码为:
#Z-score normaliaztiondef ZscoreNormalization(x):x = (x - np.mean(x)) / np.std(x)return x针对该数据集,通过标注化处理连续型特征,具体公式如下:
xij′=xij−AVGjSTDjx'_{ij} = \frac{x_{ij}-AVG_j}{STD_j} xij′=STDjxij−AVGj
AVGi=1n(X1j+X2j+...+Xnj)AVG_i = \frac{1}{n}(X_{1j}+X_{2j}+...+X_{nj}) AVGi=n1(X1j+X2j+...+Xnj)
STDi=1n(∣X1j−AVGj∣+∣X2j−AVGj∣+...+∣Xnj−AVGj∣)STD_i = \frac{1}{n}(|X_{1j}-AVG_j|+|X_{2j}-AVG_j|+...+|X_{nj}-AVG_j|) STDi=n1(∣X1j−AVGj∣+∣X2j−AVGj∣+...+∣Xnj−AVGj∣)
其中,AVG为平均值,STAD为平均绝对偏差,如果AVG等于0,则X’=0;如果STD等于0,则X’=0。
核心代码如下所示,这里建议读者直接使用我的数据集或测试数据集测试,否则花费巨大时间。
注意:将np.mean和np.std以及后面的np.max、np.min计算提出来赋值变量,否则会非常耗时。之前速度慢的原因就是这个细节没有注意,大家写代码一定要避免不必要的运算,尤其是多层循环计算过程中,尽量写优美的代码!
#coding:utf-8import numpy as npimport pandas as pdimport csv#全局变量global x_mat#数据标准化def ZscoreNormalization(x, n):meanValue = np.mean(x)stdValue = np.std(x)print(len(x))i = 0while i<len(x):x_mat[i][n] = (x[i] - meanValue) / stdValueif x_mat[i][n]>0:print(x_mat[i][n])i = i + 1print("The ", n , "feature is normal.")#-------------------------------------读取文件划分数据集-----------------------------------------fr = open("test-normal.csv")data_file = open("test-normal-result.csv",'wb+',newline='')lines = fr.readlines()line_nums = len(lines)print(line_nums)#创建line_nums行 para_num列的矩阵x_mat = np.zeros((line_nums, 42))#划分数据集for i in range(line_nums):line = lines[i].strip()item_mat = line.split(',')x_mat[i, :] = item_mat[0:42] #获取42个特征fr.close()print(x_mat.shape)#--------------------------------获取某列特征并依次标准化并赋值-----------------------------print(len(x_mat[:, 0])) #获取某列数据 494021print(len(x_mat[0, :])) #获取某行数据 42#标准化处理 ZscoreNormalization(x_mat[:, 0], 0) #durationZscoreNormalization(x_mat[:, 4], 4) #src_bytesZscoreNormalization(x_mat[:, 5], 5) #dst_bytesZscoreNormalization(x_mat[:, 7], 7) #wrong_fragmentZscoreNormalization(x_mat[:, 8], 8) #urgentZscoreNormalization(x_mat[:, 9], 9) #hotZscoreNormalization(x_mat[:, 10], 10) #num_failed_loginsZscoreNormalization(x_mat[:, 12], 12) #num_compromisedZscoreNormalization(x_mat[:, 14], 14) #su_attempteZscoreNormalization(x_mat[:, 15], 15) #num_rootZscoreNormalization(x_mat[:, 16], 16) #num_file_creationsZscoreNormalization(x_mat[:, 17], 17) #num_shellsZscoreNormalization(x_mat[:, 18], 18) #num_access_filesZscoreNormalization(x_mat[:, 19], 19) #num_outbound_cmdsZscoreNormalization(x_mat[:, 22], 22) #countZscoreNormalization(x_mat[:, 23], 23) #srv_countZscoreNormalization(x_mat[:, 24], 24) #serror_rateZscoreNormalization(x_mat[:, 25], 25) #srv_serror_rateZscoreNormalization(x_mat[:, 26], 26) #rerror_rateZscoreNormalization(x_mat[:, 27], 27) #srv_rerror_rateZscoreNormalization(x_mat[:, 28], 28) #same_srv_rateZscoreNormalization(x_mat[:, 29], 29) #diff_srv_rateZscoreNormalization(x_mat[:, 30], 30) #srv_diff_host_rateZscoreNormalization(x_mat[:, 31], 31) #dst_host_countZscoreNormalization(x_mat[:, 32], 32) #dst_host_srv_countZscoreNormalization(x_mat[:, 33], 33) #dst_host_same_srv_rateZscoreNormalization(x_mat[:, 34], 34) #dst_host_diff_srv_rate ZscoreNormalization(x_mat[:, 35], 35) #dst_host_same_src_port_rateZscoreNormalization(x_mat[:, 36], 36) #dst_host_srv_diff_host_rateZscoreNormalization(x_mat[:, 37], 37) #dst_host_serror_rateZscoreNormalization(x_mat[:, 38], 38) #dst_host_srv_serror_rateZscoreNormalization(x_mat[:, 39], 39) #dst_host_rerror_rateZscoreNormalization(x_mat[:, 40], 40) #dst_host_srv_rerror_rate#文件写入操作csv_writer = csv.writer(data_file)i = 0while i<len(x_mat[:, 0]):csv_writer.writerow(x_mat[i, :])i = i + 1data_file.close()标准化之前的数据显示如下图所示:
0,1,47,9,105,146,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0.00,0.00,0.00,0.00,1.00,0.00,0.00,255,254,1.00,0.01,0.00,0.00,0.00,0.00,0.00,0.00,0
经常处理后的数据如下所示:
-0.024411893497851576,1.0,47.0,9.0,-0.030455897580918892,-0.030455897580918892,0.0,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,0.0,-0.030455897580918892,0.0,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,0.0,0.0,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,-0.030455897580918892,0
数据标准化(归一化)处理是数据挖掘的一项基础工作,不同评价指标往往具有不同的量纲和量纲单位,这样的情况会影响到数据分析的结果,为了消除指标之间的量纲影响,需要进行数据标准化处理,以解决数据指标之间的可比性。原始数据经过数据标准化处理后,各指标处于同一数量级,适合进行综合对比评价。以下是常用的归一化方法:
min-max标准化(Min-Max Normalization)
也称为离差标准化,是对原始数据的线性变换,使结果值映射到[0 , 1]之间。转换函数如下:
x′=x−minmax−minx' = \frac{x-min}{max-min} x′=max−minx−min
其中max为样本数据的最大值,min为样本数据的最小值。这种方法有个缺陷就是当有新数据加入时,可能导致max和min的变化,需要重新定义。min-max标准化python代码如下:
import numpy as nparr = np.asarray([0, 10, 50, 80, 100])for x in arr:x = float(x - np.min(arr))/(np.max(arr)- np.min(arr))print x# output# 0.0# 0.1# 0.5# 0.8# 1.0归一化核心代码如下所示:
#coding:utf-8import numpy as npimport pandas as pdimport csv#全局变量global x_mat#数据归一化def MinmaxNormalization(x, n):minValue = np.min(x)maxValue = np.max(x)print(minValue, maxValue)print(len(x))i = 0while i<len(x):x_mat[i][n] = (x[i] - minValue) / (maxValue - minValue)#if x_mat[i][n]>0:# print(x_mat[i][n])i = i + 1print("The ", n , "feature is normal.")#-------------------------------------读取文件划分数据集-----------------------------------------fr = open("test-normal-result.csv")data_file = open("test-normal-result-minmax.csv",'wb+',newline='')lines = fr.readlines()line_nums = len(lines)print(line_nums)#创建line_nums行 para_num列的矩阵x_mat = np.zeros((line_nums, 42))#划分数据集for i in range(line_nums):line = lines[i].strip()item_mat = line.split(',')x_mat[i, :] = item_mat[0:42] #获取42个特征fr.close()print(x_mat.shape)#--------------------------------获取某列特征并依次标准化并赋值-----------------------------print(len(x_mat[:, 0])) #获取某列数据 494021print(len(x_mat[0, :])) #获取某行数据 42#归一化处理 MinmaxNormalization(x_mat[:, 0], 0) #durationMinmaxNormalization(x_mat[:, 4], 4) #src_bytesMinmaxNormalization(x_mat[:, 5], 5) #dst_bytesMinmaxNormalization(x_mat[:, 7], 7) #wrong_fragmentMinmaxNormalization(x_mat[:, 8], 8) #urgentMinmaxNormalization(x_mat[:, 9], 9) #hotMinmaxNormalization(x_mat[:, 10], 10) #num_failed_loginsMinmaxNormalization(x_mat[:, 12], 12) #num_compromisedMinmaxNormalization(x_mat[:, 14], 14) #su_attempteMinmaxNormalization(x_mat[:, 15], 15) #num_rootMinmaxNormalization(x_mat[:, 16], 16) #num_file_creationsMinmaxNormalization(x_mat[:, 17], 17) #num_shellsMinmaxNormalization(x_mat[:, 18], 18) #num_access_filesMinmaxNormalization(x_mat[:, 19], 19) #num_outbound_cmdsMinmaxNormalization(x_mat[:, 22], 22) #countMinmaxNormalization(x_mat[:, 23], 23) #srv_countMinmaxNormalization(x_mat[:, 24], 24) #serror_rateMinmaxNormalization(x_mat[:, 25], 25) #srv_serror_rateMinmaxNormalization(x_mat[:, 26], 26) #rerror_rateMinmaxNormalization(x_mat[:, 27], 27) #srv_rerror_rateMinmaxNormalization(x_mat[:, 28], 28) #same_srv_rateMinmaxNormalization(x_mat[:, 29], 29) #diff_srv_rateMinmaxNormalization(x_mat[:, 30], 30) #srv_diff_host_rateMinmaxNormalization(x_mat[:, 31], 31) #dst_host_countMinmaxNormalization(x_mat[:, 32], 32) #dst_host_srv_countMinmaxNormalization(x_mat[:, 33], 33) #dst_host_same_srv_rateMinmaxNormalization(x_mat[:, 34], 34) #dst_host_diff_srv_rate MinmaxNormalization(x_mat[:, 35], 35) #dst_host_same_src_port_rateMinmaxNormalization(x_mat[:, 36], 36) #dst_host_srv_diff_host_rateMinmaxNormalization(x_mat[:, 37], 37) #dst_host_serror_rateMinmaxNormalization(x_mat[:, 38], 38) #dst_host_srv_serror_rateMinmaxNormalization(x_mat[:, 39], 39) #dst_host_rerror_rateMinmaxNormalization(x_mat[:, 40], 40) #dst_host_srv_rerror_rate#文件写入操作csv_writer = csv.writer(data_file)i = 0while i<len(x_mat[:, 0]):csv_writer.writerow(x_mat[i, :])i = i + 1data_file.close()输出结果如下图所示:
5.1346198410647435e-05,1.0,47.0,9.0,5.1346198410647435e-05,5.1346198410647435e-05,0.0,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,0.0,5.1346198410647435e-05,0.0,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,0.0,0.0,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,5.1346198410647435e-05,0
最后代码如下所示,主要包括以下功能:
但实验效果非常不理想,不知道什么具体原因,哎,心累~博友们使用的时候帮忙检测下前面的标准化和归一化代码是否正确。
# -*- coding: utf-8 -*- import osimport csvimport numpy as npfrom sklearn.svm import SVC from sklearn import metricsimport matplotlib.pyplot as pltfrom matplotlib.colors import ListedColormapfrom sklearn.model_selection import train_test_splitfrom sklearn.decomposition import PCAfrom sklearn import neighbors#-----------------------------------------第一步 加载数据集-----------------------------------------fr= open("kddcup.data_10_yxz-result-minmax.csv")lines = fr.readlines()line_nums = len(lines)print(line_nums)#创建line_nums行 para_num列的矩阵x_mat = np.zeros((line_nums, 31))y_label = []#划分数据集for i in range(line_nums):line = lines[i].strip()item_mat = line.split(',')x_mat[i, :] = item_mat[0:31] #前41个特征y_label.append(item_mat[-1]) #类标fr.close()print(x_mat.shape)print(len(y_label))#-----------------------------------------第二步 划分数据集-----------------------------------------y = []for n in y_label: y.append(int(float(n)))y = np.array(y, dtype = int) #list转换数组#划分数据集 测试集40%train_data, test_data, train_target, test_target = train_test_split(x_mat, y, test_size=0.4, random_state=42)print(train_data.shape, train_target.shape)print(test_data.shape, test_target.shape)#-----------------------------------------第三步 KNN训练-----------------------------------------def classify(input_vct, data_set):data_set_size = data_set.shape[0]#扩充input_vct到与data_set同型并相减diff_mat = np.tile(input_vct, (data_set_size, 1)) - data_set sq_diff_mat = diff_mat**2 #矩阵中每个元素都平方distance = sq_diff_mat.sum(axis=1)**0.5 #每行相加求和并开平方根return distance.min(axis=0) #返回最小距离test_size = len(test_target)result = np.zeros((test_size, 3))for i in range(test_size):#序号 最小欧氏距离 测试集数据类别result[i] = i + 1, classify(test_data[i], train_data), test_target[i]#矩阵转置result = np.transpose(result) #-----------------------------------------第四步 评价及可视化-----------------------------------------def roc(data_set):normal = 0data_set_size = data_set.shape[1]roc_rate = np.zeros((2, data_set_size)) #输出ROC曲线 二维矩阵#计算正常请求数量for i in range(data_set_size):if data_set[2][i] == 1:normal += 1abnormal = data_set_size - normalmax_dis = data_set[1].max() #欧式距离最大值for j in range(1000):threshold = max_dis / 1000 * jnormal1 = 0abnormal1 = 0for k in range(data_set_size):if data_set[1][k] > threshold and data_set[2][k] == 1:normal1 += 1if data_set[1][k] > threshold and data_set[2][k] != 1:abnormal1 += 1roc_rate[0][j] = normal1 / normal # 阈值以上正常点/全体正常的点roc_rate[1][j] = abnormal1 / abnormal # 阈值以上异常点/全体异常点return roc_rate#图1 散点图#横轴为序号 纵轴为最小欧氏距离#点中心颜色根据测试集数据类别而定 点外围无颜色 点大小为最小1 灰度为最大1plt.figure(1)plt.scatter(result[0], result[1], c=result[2], edgecolors='None', s=2, alpha=1)#图2 ROC曲线#横轴误报率:即阈值以上正常点/全体正常的点#纵轴检测率:即阈值以上异常点/全体异常点roc_rate = roc(result)plt.figure(2)plt.scatter(roc_rate[0], roc_rate[1], edgecolors='None', s=1, alpha=1) plt.show()最后提供Github的代码,希望对读者有所帮助,参考龚炎大神的文章和代码。
https://blog.gongyan.me/2017/04/kdd-cup99/
https://github.com/gongyanc/kddcup99
运行结果如下图所示,本篇文章所有资源参考我的Github。
横坐标序号,纵坐标最小欧式距离,散点颜色类标(正常、攻击)。
ROC曲线:
写到这里,这篇基于机器学习的入侵检测和攻击识别分享完毕。严格意义上来说,这篇文章是数据分析,它有几个亮点:
这篇文章中也有几个不足之处:
总之,希望基础性文章对您有所帮助,如果文章中有错误或不足之处,还请提出和海涵,希望与您共同进步。天行健,君子以自强不息。地势坤,君子以厚德载物。祝大家1024程序员节快乐,祝CSDN越来越好。
(By:Eastmount 2021-10-24 周末写于武大 早上11点 http://blog.csdn.net/eastmount/ )
该篇文章参考了以下文献,非常推荐大家阅读这些大牛的文章: