Python数据分析案例29——自编码器监测异常值

news2024/12/23 23:50:10

与传统的监督学习不一样,这一篇主要是讲述自编码器模型的,是无监督学习,并且用于的任务不是分类或者回归,而是异常值的监测。


案例背景

需要从一堆网络流量特征监控的数据中寻找哪些可能是异常情况。

听着像分类问题对吧,但是和分类问题有很大不同,一是训练方式不一样,二是异常值情况通常是很少的,所以不能做分类模型,要做自监督模型。

自编码器是什么我就不多介绍了,总之原理就是把数据拿来编码压缩然后解码还原,比较重构还原出来的数据和原来的数据的差异,差的多的,误差大的,就可能是异常值。


代码实现

导入包

import pandas as pd
from pandas.plotting import scatter_matrix
import numpy as np
import pickle
import h5py
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats

from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import tensorflow as tf
from tensorflow.keras.models import Model, load_model
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping
from tensorflow.keras import regularizers
from tensorflow.keras.utils import plot_model
%matplotlib inline
sns.set(style='whitegrid', palette='muted', font_scale=1.5)
RANDOM_SEED = 42
LABELS = ['normal.', 'ipsweep.']

 

1.准备数据

1.1读取数据

读取,查看训练集数据

kddCupTrain = pd.read_csv('kddCupTrain.csv',header=None)
kddCupTest = pd.read_csv('kddCupTest.csv',header=None)
print("Shape of kddCupTrain: ",kddCupTrain.shape)
print("There are any missing values: ", kddCupTrain.isnull().values.any())
kddCupTrain.head(3)

 可以看到有40列特征,最后一列是标签。

查看测试集

print("Shape of kddCupTest: ",kddCupTest.shape)
print("There are any missing values: ", kddCupTest.isnull().values.any())
kddCupTest.head(3)


 

查看响应变量y的信息 

#将 kddCupTrain 数据集的第41列重命名为 'Class' 并且应用到原数据集中
kddCupTrain.rename(columns={41:'Class'}, inplace=True)

#使用 pandas.factorize() 函数将 'Class' 列中的值转化为数值编码,并返回编码后的结果和唯一值列表
codes,uniques=pd.factorize(kddCupTrain['Class'])

#打印出唯一的类别标签
print(uniques)
#将 'Class' 列的数值编码更新到原数据集中
kddCupTrain['Class'] = codes

#统计每个类别的样本数量并按数量从大到小排序,然后打印
count_classes = kddCupTrain['Class'].value_counts(sort = True)
print(count_classes)

画个图看看

count_classes.plot.bar(figsize=(5,3))  #画图

 

可以看到是极度不平衡的数据。

取出y

y = kddCupTrain['Class']
kddCupTrain = kddCupTrain.drop(['Class'], axis=1)

 


 1.2删除无用信息列

 #取值唯一的变量删除(如果有一列的值全部一样,也就是取值唯一的特征变量就可以删除了,因为每个样本没啥区别,对模型就没啥用)

for col in kddCupTrain.columns:
    if len(kddCupTrain[col].value_counts())==1:
        print(col)
        kddCupTrain.drop(col,axis=1,inplace=True)

这两列删除了

 测试集也进行删除

kddCupTest=kddCupTest[kddCupTrain.columns]
print(kddCupTrain.shape,kddCupTest.shape)

 


1.3训练集和测试集都进行独立热编码 

kddCupTrain=pd.get_dummies(kddCupTrain)
kddCupTest=pd.get_dummies(kddCupTest)
print(kddCupTrain.shape,kddCupTest.shape)

开通看到数据独立热编码后维度不一样,需要统一一下

统一数据维度

for col in kddCupTrain.columns:
    if col not in kddCupTest.columns:
        kddCupTest[col]=0
kddCupTest=kddCupTest[kddCupTrain.columns]
print(kddCupTrain.shape,kddCupTest.shape)

 查看训练集前三行

kddCupTrain.head(3)

测试集前三行

kddCupTest.head(3)

 

 


1.4数据标准化

#数据标准化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(kddCupTrain)
X_s = scaler.transform(kddCupTrain)
X_test_s = scaler.transform(kddCupTest)

print('训练数据形状:')
print(X_s.shape,y.shape)
print('测试数据形状:')
print(X_test_s.shape)

 查看数据信息(验证是不是标准化了)

print(X_s.mean())
print(X_s.std(ddof=0))


1.5将数据拆分为训练子集和验证子集 

#划分训练集和验证集
from sklearn.model_selection import train_test_split
X_train,X_val,y_train,y_val=train_test_split(X_s,y,test_size=0.2,random_state=RANDOM_SEED)

查看形状

print('Train: shape X',X_train.shape,', shape Y',y_train.shape)
print('Val: shape X',X_val.shape,', shape Y',y_val.shape)


  1.6. 分离“正常”实例

X_trainNorm = X_train[y_train == 0]
X_valNorm = X_val[y_val == 0]
print(X_trainNorm.shape,X_valNorm.shape)


2. 构建模型 

2.1.选择自编码器的架构

自己选择几层几个神经元。我这里是4个隐藏层,编码压缩从83到40到20,然后再解码从20到40到83还原。看这个层的张量形状就能看出来。

input_dim = X_trainNorm.shape[1]
layer1_dim = 40
encoder_dim = 20

input_layer = Input(shape=(input_dim, ))
encoder1 = Dense(layer1_dim, activation="relu")(input_layer)
encoder2 = Dense(encoder_dim, activation="relu")(encoder1)
decoder1 = Dense(layer1_dim, activation='relu')(encoder2)
decoder2 = Dense(input_dim, activation='linear')(decoder1)
print('input_layer: ',input_layer)
print('encoder1',encoder1)
print('encoder2',encoder2)
print('decoder1',decoder1)
print('decoder2',decoder2)

 查看模型信息。

autoencoder = Model(inputs=input_layer, outputs=decoder2)
autoencoder.summary()

 

 对模型进行可视化,画出来

plot_model(autoencoder, to_file='fraud_encoder1.png',show_shapes=True,show_layer_names=True)


2.2. 拟合模型 

批量大小64,训练轮数50.

nb_epoch = 50
batch_size = 64

autoencoder.compile(optimizer='adam', loss='mean_squared_error')

checkpointer = ModelCheckpoint(filepath="model.h5",verbose=0,save_best_only=True)

earlystopping = EarlyStopping(monitor='val_loss', patience=5, verbose=0) # 'patience' number of not improving epochs

history = autoencoder.fit(X_trainNorm, X_trainNorm,epochs=nb_epoch, batch_size=batch_size,shuffle=True,
                    validation_data=(X_valNorm, X_valNorm),
                    verbose=1,callbacks=[checkpointer, #tensorboard, 
                               earlystopping]).history

有早停机制,所以24轮就停下来了。

查看损失图

plt.plot(history['loss'])
plt.plot(history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'val'], loc='upper right');

 


3. 评估  

3.1. 从文件加载安装的自动编码器

autoencoder = load_model('model.h5')

3.2. 重建

对验证集数据进行评价 (下面的图都是验证集的)

重构预测

testPredictions = autoencoder.predict(X_val)
X_val.shape,testPredictions.shape

真实数据和预测重构的数据形状一样,下面计算对比他们的误差。 

 3.3. 评估

testMSE = mean_squared_error(X_val.transpose(), testPredictions.transpose(), multioutput='raw_values')
error_df = pd.DataFrame({'reconstruction_error': testMSE,'true_class': y_val})
error_df.head()

描述性统计一下

error_df.reconstruction_error.describe()

 

画图查看正常的情况重构误差的分布。 

fig = plt.figure(figsize=(5,3),dpi=128)
ax = fig.add_subplot(111)
normal_error_df = error_df[(error_df['true_class']== 0) & (error_df['reconstruction_error'] < 10)]
ax.hist(normal_error_df.reconstruction_error.values, bins=10);

 

 可以看到误差基本都是0附近,说明正常情况下的重构误差都很小。

查看异常值的重构误差分布

fig = plt.figure(figsize=(5,3),dpi=128)
ax = fig.add_subplot(111)
fraud_error_df = error_df[(error_df['true_class']== 1) & (error_df['reconstruction_error'] < 10)]
ax.hist(fraud_error_df.reconstruction_error.values, bins=10);

  可以看到误差分布没那么极端了,有很多样本重构后有较大的误差,说明异常情况下的重构误差都会偏大。

计算AUC值

from sklearn.metrics import (confusion_matrix, auc, roc_curve, cohen_kappa_score, accuracy_score)
fpr, tpr, thresholds = roc_curve(error_df.true_class, error_df.reconstruction_error)
roc_auc = auc(fpr, tpr)

plt.figure(figsize=(7,4),dpi=128)
plt.title('Receiver Operating Characteristic')
plt.plot(fpr, tpr, label='AUC = %0.4f'% roc_auc)
plt.legend(loc='lower right')
plt.plot([0,1],[0,1],'r--')
plt.xlim([-0.001, 1])
plt.ylim([0, 1.001])
plt.ylabel('True Positive Rate')
plt.xlabel('False Positive Rate')
plt.show();

 3.4 预测效果

threshold = normal_error_df.reconstruction_error.quantile(q=0.995)
threshold

 

找到误差5%的分位数水平作为阈值,重构误差大于这个值就认为是异常情况。

筛序一下极端情况,方便画图

error_df=error_df[error_df['reconstruction_error']<3500]
groups = error_df.groupby('true_class')
fig, ax = plt.subplots()
for name, group in groups:
    if name == 1:
        MarkerSize = 7 ; Color = 'orangered' ; Label = 'Fraud' ; Marker = 'd'
    else:
        MarkerSize = 3.5 ; Color = 'b' ; Label = 'Normal' ; Marker = 'o'
        
    ax.plot(group.index, group.reconstruction_error, linestyle='',color=Color,label=Label,ms=MarkerSize,marker=Marker)
    
ax.hlines(threshold, ax.get_xlim()[0], ax.get_xlim()[1], colors="r", zorder=100, label='Threshold')
ax.legend(loc='upper left', bbox_to_anchor=(0.95, 1))
plt.title("Probabilities of fraud for different classes")
plt.ylabel("Reconstruction error")  ;   plt.xlabel("Data point index")
plt.show()

可以看到,大于阈值的情况,有一些事正常的,也有异常的,分类没那么准确。

画混淆矩阵来进一步观察

y_pred = [1 if e > threshold else 0 for e in error_df.reconstruction_error.values]
conf_matrix = confusion_matrix(error_df.true_class, y_pred)
print(conf_matrix)

plt.figure(figsize=(5, 5),dpi=108)
sns.heatmap(conf_matrix, xticklabels=LABELS, yticklabels=LABELS, annot=True, fmt="d");
plt.title("Confusion matrix")
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.show()

 

 计算科恩指标和准确率 

cohen_kappa_score(error_df.true_class, y_pred),accuracy_score(error_df.true_class, y_pred)

准确率还是高达98的,但是由于样本的极度不平衡,科恩指标较小。


4.测试集的预测,创建提交 

预测重构

testPredictions = autoencoder.predict(X_test_s)
X_test_s.shape,testPredictions.shape

计算误差

testMSE = mean_squared_error(X_test_s.transpose(), testPredictions.transpose(), multioutput='raw_values')
result_df = pd.DataFrame({'reconstruction_error': testMSE}) 

画个图看看

result_df.plot.box()

 有很多极大值,说明可能这些误差大的样本就是异常情况。

储存,就可以提交了

result_df.to_csv('result.csv')

(如果需要变成分类的结果(是否为异常值),就按照上面算出阈值,然后加一个判断映射为分类变量就行)

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

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

相关文章

虹科新闻 | 虹科与Skkynet正式建立合作伙伴关系

近日&#xff0c;虹科与Skkynet正式建立合作伙伴关系&#xff0c;双方就工业应用自动化领域进行深入的交流与合作&#xff0c;未来将共同致力于为亚洲市场提供完整的工业物联网通讯解决方案&#xff0c;解决亚洲客户的物联网挑战。 虹科与Skkynet都表示十分期待这次的合作。“虹…

【IMX6ULL驱动开发学习】04.IMX6ULL开发板与虚拟机互传文件

互传文件前提&#xff1a;IMX6ULL开发板和虚拟机能够互相ping通&#xff0c;即在同一网段下且能够互ping 可参考这篇博客&#xff1a;设置IMX6ULL开发板与虚拟机在同一网段 目录 一、使用SCP命令 二、通过SFTP服务传输文件&#xff08;使用Xftp等工具&#xff09; 三、通过N…

程序员错觉之『这个Bug很快搞定!』

博主&#xff1a;爱码叔 个人博客站点&#xff1a; icodebook 公众号&#xff1a;漫话软件设计 微博&#xff1a;程序员涛哥 专注于软件设计与架构、技术管理。擅长用通俗易懂的语言讲解技术。对技术管理工作有自己的一定见解。文章会第一时间首发在个站上&#xff0c;欢迎大家…

Hive中的DML操作

文章目录 Hive中的DML操作一、Load1&#xff09;语法2&#xff09;实操案例&#xff08;0&#xff09;创建一张表&#xff08;1&#xff09;加载本地文件到hive&#xff08;2&#xff09;加载HDFS文件到hive中 二、Insert1. 将查询结果插入表中1&#xff09;语法2&#xff09;案…

美团 551 亿佣金收入,需要“埋葬”多少客单20元的中小商家?

文 | 新熔财经 作者 | 卡夫卡 热度喧嚣尘上的618大促氛围里&#xff0c;中小商家们当了一回主角。 在急需提振消费、复苏经济的2023年&#xff0c;各大电商平台史上第一次&#xff0c;出意料之外但又情理之中地在618&#xff0c;把资源最为丰沛的C位给了中小商家。 但这样和…

【数据结构与算法篇】 二叉树的性质(补充)

​&#x1f47b;内容专栏&#xff1a;《数据结构与算法篇》 &#x1f428;本文概括&#xff1a; 继上一篇深入浅出_二叉树之后遗漏掉了&#xff0c;再次写一篇二叉树的性质博文&#xff0c;对二叉树进行补充总结。 &#x1f43c;本文作者&#xff1a;花 碟 &#x1f438;发布时…

qt 乱码

init() { // 根据配置加载默认语言系统 // 解决中文乱码问题 QTextCodec *codec QTextCodec::codecForName("system"); QTextCodec::setCodecForLocale(codec); } 设置 /execution-charset:utf-8

LVS负载均衡群集部署——NAT模式

LVS负载均衡群集部署——NAT模式 一、群集概述1、群集存在的必要2、解决方法3、根据集群针对的目标差异分类 二、负载均衡群集架构三、负载均衡群集工作模式分析1、NAT模式2、TUN模式3、DR模式4、三种工作模式的区别 四、LVS虚拟服务器1、Linux Virtual Server2、LVS现在已成为…

2核2G轻量应用服务器3M带宽阿里云和腾讯云性能对比

2核2G3M轻量应用服务器选阿里云还是腾讯云&#xff1f;腾讯云2核2G3M轻量应用服务器95元一年&#xff0c;阿里云2核2G3M配置优惠价108元一年&#xff0c;如何选择&#xff1f;阿腾云详细对比阿里云和腾讯云轻量应用服务器2核2G3M配置CPU性能及选择方法&#xff1a; 目录 轻量…

Spring6源码编译、安装

环境准备 名称版本jdk17gradle8.1.1spring源码版本6.0.9 安装JDK 下载并解压 配置环境变量 JAVA_HOME D:\\Develop\\Zulu\\zulu-17 CLASSPATH .;%JAVA_HOME%\lib; PATH %JAVA_HOME%\bin验证 java -version安装Gradle 下载并解压 配置环境变量 GRADLE_HOME D:…

网络安全面试题大全(整理版)500+面试题附答案详解,最全面详细

前言 随着国家政策的扶持&#xff0c;网络安全行业也越来越为大众所熟知&#xff0c;想要进入到网络安全行业的人也越来越多。 为了拿到心仪的Offer之外&#xff0c;除了学好网络安全知识以外&#xff0c;还要应对好企业的面试。 作为一个安全老鸟&#xff0c;工作这么多年&…

使用 YApi 管理 API 文档,测试, mock

随着互联网的发展&#xff0c;API变的至关重要。根据统计&#xff0c;目前市面上有上千万的开发者&#xff0c;互联网项目超过10亿&#xff0c;保守统计涉及的 API 数量大约有 100 亿。这么大基数的API&#xff0c;只要解决某些共有的痛点&#xff0c;将会是非常有意义的事情。…

CISP好考吗?考试大纲有哪些,CISP通过率有多少?

CISP全称&#xff1a;注册信息安全专业人员&#xff0c;发证机构是&#xff1a;中国信息安全测评中心&#xff1b;面向的培训对象是&#xff1a;各信息系统管理、建设、运行维护、督查及从事信息化工作的相关人员&#xff1b; 国测中心对报考CISP也是有学历要求的&#xff1a;硕…

Fmoc-Ser(Ac4Manα1-2Ac3Manα)-OH,一种糖基化氨基酸,化合物CAS号1427205-92-2

Fmoc-Ser(Ac4Manα1-2Ac3Manα)-OH是一种化学品&#xff0c;CAS编号1427205-92-2&#xff0c;分子式C44H51NO22&#xff0c;分子量为945.88。它的纯度标准达到95%以上&#xff0c;供应包装规格有1克、5克和10克&#xff0c;也可进行定制&#xff0c;时间周期可与生产厂家沟通。…

Simulink尝试双脉冲实验验证MOSFET二极管反向恢复实验的特性(附仿真模型)

目录 前言 双脉冲实验 Simulink仿真对比 总结 前言 最近在做交错串联的图腾柱单相PFC的项目&#xff0c;基于模型的开发&#xff0c;想要在仿真上实现过零点尖峰电流产生并通过软启动进行抑制&#xff0c;把整个过程都通过仿真实现出来&#xff0c;在这个过程中尝试了Simul…

WPS:文件输出与输出格式PDF与图片。

WPS的文件输出格式有很多种 点击文件后会出现两种能输出的方式&#xff0c;如果是word则有三种&#xff1a; 图片与PDF word&#xff1a; 点击输出为PDF后会跳出一个对话框&#xff1a; 可以在右边选择输出的范围&#xff1a;第x页 到 第y页 在输出为PDF的右边有一个设置选项…

如何将测绘数据加载到三维地图中,解决海量测绘数据在线管理难题?

《四维轻云》是四川兴域技术团队基于浏览器打造的一款地理空间数据在线管理平台&#xff0c;可实现TB级大规模倾斜摄影三维模型、正射影像、激光点云、数字高程模型等数据在线发布、管理及分享&#xff0c;并支持私有化部署和高阶功能定制化开发&#xff0c;解决了海量测绘数据…

企业国际物流信息化解决方案_箱讯科技

随着全球化的加速和国际贸易的不断扩大&#xff0c;物流行业的重要性日益凸显。企业国际物流信息化解决方案成为了提高企业物流效率和降低成本的重要手段。本文将从信息化对物流行业的影响、企业国际物流信息化解决方案的构成和实施步骤三个方面进行探讨。 一、信息化对物流行业…

nodejs+vue+elementui校园车辆校车管理系统

开发语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode 本界面为学生用车信息的添加界面 本界面是校园车辆的使用记录信息&#xff0c;包括校车的编号&#xff0c;校车的名称&#xff0…

指针 和 数组 习题总结

这里看着脑袋晕了可以休息一下的。 目录 1. 数组 1.1 一维数组&#xff1a; 1.2 字符数组 1.3 字符串 1.4 二维数组 2. 指针 开始之前我们简单复习一下数组与指针的相关知识 数组 - 能够存放一组相同类型的元素&#xff0c;数组的大小取决于数组的元素个数和元素类型 指…