一、实验目的
通过本学期的课程学习,学生已经掌握基本的数据挖掘相关概念、原理和技术。通过使用Python实现不平衡网络入侵数据的挖掘和实验报告的完成,检验学生理解和应用数据挖掘理念理解问题、分析问题和解决问题的能力等课程目标。
二、实验要求
学习掌握综合运用数据挖掘相关技术,理解问题、分析问题和解决问题的能力。
三、实验内容
针对不平衡网络入侵数据集,不平衡指的是整个入侵数据集中,攻击样本的数量占比整个数据集的比例较小,所以称为少数类(Label:Web Attack),而正常样本的数量占比整个数据集的比例较大,所以称为多数类(Label: BENIGN),请同学们根据本课程所学知识,使用课程所授知识和方法,也可以使用课外拓展的最新技术和方法,设计一个欠采样方法,使用分类模型,基于AUC、F1-Score和G-mean三个评价指标,采用十折交叉验证方法,得到平均后的分类性能,调整分类模型的参数,尽量得到最优的分类性能。
步骤如下:
(1)给定不平衡网络入侵数据集:WebAttacks,第一步使用欠采样方法,得到欠采样之后的平衡网络入侵数据集,因为过采样方法或生成大量少数类数据,从而增加分类模型训练时间,所以WebAttacks不平衡网络入侵数据集适合欠采样方法。
(2)自行寻找一个合适的分类模型,对欠采样之后的平衡网络入侵流量数据进行训练,分类,并采用十折交叉验证方法,每次随机采用其中的9折作为训练集,1折数据作为测试集进行训练和预测,共进行10次。
(3)对10次结果求平均值得到AUC、F1-Score和G-mean三个评价指标下的最终分类性能,根据具体情况进行分析,调整分类模型的参数,提高分类模型在不平衡网络入侵数据集上的最终分类性能。
四、实验结果及分析
导入函数包,我们采用了支持向量机对数据进行评估分类
import pandas as pd
import numpy as np
from sklearn.svm import SVC
from sklearn.model_selection import cross_val_score
data = pd.read_csv('WebAttacks.csv')
因为数据里面检测到有这种inf类型,这种数据类型没办法放入模型中,所以就给剔除了
data.replace([np.inf, -np.inf], np.nan,inplace=True)
data.dropna(inplace=True)#删除所有inf类型数据
欧式距离函数:
def distance(center,value):
return (np.sum((center-value)**2))**0.5
整理攻击样本与未被攻击样本:
#攻击样本(较少)
less_count = data[' Label'].value_counts().values[-1]
less_name = data[' Label'].value_counts().index.values[-1]
less_data = data[data[' Label']==less_name].copy()
#未被攻击样本(较多)
more_count = data[' Label'].value_counts().values[0]
more_name = data[' Label'].value_counts().index.values[0]
more_data = data[data[' Label']==more_name].copy()
用mean()计算数据中心点即均值:
x = more_data.columns[:78]
center = more_data.mean().values
计算出未被攻击样本中数据与中心点的距离:
more_data['distance'] = [distance(center,value) for value in more_data[x].values]
我们的欠采样思路是:
假设label=0的样本有1000个,label=1的样本有2000个,则需要对label=1的样本进程欠采样,采样数为1000个,与label=0的1000个样本相等。然后采样方法如下:首先计算label=1的所有样本的中心点,然后对于中心点,找到离中心点中间距离的1000个样本,将这1000个样本作为欠采样样本
#取出与攻击样本数量相等的中间部分数据
len_pos = more_count//2#对半长度取整
sample_more_data = more_data.sort_values(by='distance',ascending=False).iloc[len_pos:len_pos+less_count]#对距离进行降序排列
#用concat连接函数合并攻击样本和提取的未被攻击样本
final_data = pd.concat([less_data,sample_more_data])
#x和y的特征名
x = data.columns[:78]
y = ' Label'
将Label列标签化:
final_data.loc[final_data[' Label'] == more_name,' Label'] = 0 #未被攻击样本
final_data.loc[final_data[' Label'] == less_name,' Label'] = 1 #攻击样本
final_data[' Label'] = final_data[' Label'].astype('int') #将其转换为int类型
采用SVM对数据分类:
model = SVC()
通过十折交叉验证得到三个评价指标:
F1-score:
f1 = cross_val_score(model, final_data[x].values, final_data[y].values, cv=10,scoring='f1').mean()
AUC:
auc = cross_val_score(model, final_data[x].values, final_data[y].values, cv=10,scoring='roc_auc').mean()
计算G-mean需要的灵敏度和准确率:
#反馈率,也称灵敏度
recall = cross_val_score(model, final_data[x].values, final_data[y].values, cv=10,scoring='recall').mean()
#精确率
precision = cross_val_score(model, final_data[x].values, final_data[y].values, cv=10,scoring='precision').mean()
运行结果
print('f1 score:',f1)
print('auc score:',auc)
print('g-mean score:',g_mean)
f1 score: 0.956968969057381
auc score: 0.9334210083326321
g-mean score: 0.9580657118678659
Process finished with exit code 0
五、实验总结
欠采样方法抛弃了大部分反例数据,从而弱化了数据集中部分反例的影响,可能会造成偏差很大的模型。当然,如果数据集不平衡并且两个类别基数都很大可能影响不大。但是,数据总是宝贵的,抛弃数据是很奢侈的,因此采用十折交叉验证方法,生成10个新的子样本。每次随机采用其中的9折作为训练集,1折数据作为测试集进行训练和预测,共进行10次并集成结果。这样数据达到了有效利用。