Python机器学习19——常用六种机器学习的异常值监测方法(孤立森林,数据支持描述,自编码器,高斯混合,DBSCAN,LOF)

news2024/9/20 15:00:39

案例背景

异常值监测是机器学习的一个重要领域,博主以前做预测多,异常值监测涉及得少,但之后的工作可能需要做异常值方面的工作,所以大致总结了一下常用的机器学习来做异常值监测的方法以及代码。

标题的这些机器学习方法基本都可以调包,使用sklearn库实现。不需要装很多包。

(那些传统统计学的方法就不多介绍了,什么三西格玛(方差)准则,t检验,95%分位点啥的,那太简单了,本文主要介绍机器学习的方法。)

方法思路简介

一般来说最简单的思路就是2分类嘛,有监督学习,把异常值归为一类,正常值归为一类,然后做机器学习分类问题就行。

但是,一般来说,异常值情况都在样本中出现得就很少,去分类的话很容易造成样本不平衡的问题。这种不平衡肯定不是简单做一些数据抽样和数据增强处理能解决的,这是一种极度不平衡的情况。而且大部分情况的数据都是没有标签的,没有响应变量告诉你他是不是正常值,所以做不了分类问题的有监督学习。

所以异常值监测大多数都是无监督学习,从数据本身找异常。

当然也有半监督学习,即告诉他哪些是异常值,哪些不是。或者像自编码器这样使用自监督学习。

但是大体上这些方法都是训练的时候只使用特征变量,只使用X,不需要y,然后给结果的时候类似于预测给出每个样本是1(正常)还是-1(异常)。


代码实现

生成模拟数据

我们先导入包,然后生成一个包含异常值的模拟数据集。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.svm import OneClassSVM
from sklearn.neural_network import MLPRegressor
from sklearn.ensemble import IsolationForest
from sklearn.metrics import accuracy_score
# 生成数据:正常数据和异常数据
np.random.seed(77)
X_normal = 0.3 * np.random.randn(800, 2)
X_abnormal = np.random.uniform(low=-4, high=4, size=(20, 2))
X = np.vstack([X_normal, X_abnormal])
print(X_normal.shape,X_abnormal.shape)

# 标准化数据
scaler = StandardScaler()
scaled = scaler.fit(X_normal)
X_scaled=scaled.transform(X)

X_normal_scaled=scaled.transform(X_normal)
X_abnormal_scaled=scaled.transform(X_abnormal)
print(X_scaled.shape)
true_labels = np.hstack([np.ones(len(X_normal_scaled)), -1 * np.ones(len(X_abnormal_scaled))])
print(true_labels.shape)

可以看到从正态分布中生成了800个点,从均匀分布中生成了20个点作为异常点。然后为了对比模型效果我们记录了数据是不是异常值的标签(真实数据集一般没有)。这个正常和异常的比例差距很大,如下图:

pd.Series(true_labels).value_counts().plot.bar(figsize=(2,2))

 

差不多一般真实数据集也是这种比例,正常值:异常值=40:1。

下面开始异常值监测方法的代码 。


支持向量数据描述

支持向量数据描述(Support Vector Data Description,SVMD)是一种用于异常检测的机器学习方法。它基于支持向量机(SVM)的概念,但专门用于无监督学习,尤其是在数据集主要由正常样本组成时。SVMD 试图找到一个能够包含大部分正常样本的最小球体,而将异常值排除在外。

在 Python 中实现 SVMD 可以通过使用 scikit-learn 库中的 OneClassSVM 类来完成。

svmd = OneClassSVM(nu=0.025, kernel="rbf", gamma=0.1)
# Fit the SVM model only on normal data (X_normal)
svmd.fit(X_scaled)  # Ensure to use scaled normal data
y_pred = svmd.predict(X_scaled)
print(y_pred.shape)

上面已经把标准化的数据进行了训练和预测,下面我们来看准确率:

X_pred_normal = X[y_pred == 1]
X_pred_abnormal = X[y_pred == -1]
# Correctly and incorrectly predicted points
correctly_predicted = y_pred == true_labels
incorrectly_predicted = ~correctly_predicted
# Calculating accuracy using sklearn's accuracy_score function
accuracy_simple = accuracy_score(true_labels,y_pred)
accuracy_simple

 ​​​​​​​

98.9%,准确率还挺高 。

进行了一些筛选准备,我下面画了三张图,一张是原始数据中的正常数据和异常数据对比。一张是预测出来的正常数据和异常数据。还有一张是预测准确的点和预测错误的点。

# Plotting
plt.figure(figsize=(15, 5))
# Original data plot
plt.subplot(1, 3, 1)
plt.scatter(X_normal[:, 0], X_normal[:, 1], color='blue', label='Normal',s=20,marker='x')
plt.scatter(X_abnormal[:, 0], X_abnormal[:, 1], color='red', label='Abnormal',s=20,marker='x')
plt.title("Original Data")
plt.legend()

# Predicted data plot
plt.subplot(1, 3, 2)
plt.scatter(X_pred_normal[:, 0], X_pred_normal[:, 1], color='b', label='Predicted Normal',s=20,marker='x')
plt.scatter(X_pred_abnormal[:, 0], X_pred_abnormal[:, 1], color='r', label='Predicted Abnormal',s=20,marker='x')
plt.title("Predicted Data")
plt.legend()

# Prediction accuracy plot
plt.subplot(1, 3, 3)
plt.scatter(X[correctly_predicted, 0], X[correctly_predicted, 1], color='gold', label='Correctly Predicted',s=20,marker='x')
plt.scatter(X[incorrectly_predicted, 0], X[incorrectly_predicted, 1], color='purple', label='Incorrectly Predicted',s=20,marker='x')
plt.title("Prediction Accuracy")
plt.legend()

plt.show()

真实数据就是中间蓝色那一堆,旁边的红色散点就是异常值。黄色是预测正确,紫色是预测错误。

可以看到SVMD预测错误的点也没啥规律,就是把周围一些异常的点判断为了正常。效果一般。


孤立森林 

孤立森林(Isolation Forest)是一种有效的异常值检测方法,特别适用于高维数据集。它与传统的基于密度或基于距离的异常检测方法有所不同。下面是孤立森林的一些关键特点:

1. 基本原理:

孤立森林的核心思想是随机“孤立”每个数据点。这个方法假设异常点更容易被孤立,因为它们的数量少,且与正常点有较大差异。

  • 孤立树(Isolation Trees):孤立森林由多个孤立树组成。每棵孤立树都是通过随机选择一个特征,然后随机选择该特征的切分值来递归地划分数据,直到每个数据点被孤立,或达到限定的树深度。

  • 路径长度:一个数据点被孤立所需的路径长度被用作异常评分的依据。异常点通常在较短的路径长度下就会被孤立,因为它们通常远离大部分点。

2. 优点:

  • 效率:对于大规模数据集,孤立森林的运行效率较高。
  • 适用性:对于高维数据集也很有效,不像某些基于距离的方法那样受到“维数灾难”的影响。
  • 无需预设分布:不像基于统计的方法,孤立森林不需要事先假定数据遵循特定的分布。

3. 应用场景:

孤立森林适用于各种场景,尤其是那些异常数据稀少且不遵循任何特定分布的情况。它被广泛应用于金融欺诈检测、网络安全、故障检测等领域。

4. 使用注意事项:

  • 参数调整:孤立森林的性能可能受到树的数量和树深度这些参数的影响。
  • 数据规模和类型:虽然它对大型数据集表现良好,但对于包含大量重复值或类别变量的数据集,性能可能会降低。

介绍完了,都能看的出来时某GPT写的。。下面是代码 。

和上面的思路一样的,构建模型,拟合预测,画图,我这里把画图封装为函数了,这样方便下面其他模型使用。免得画图这么一大段代码重复。

值得注意的是孤立森林这个contamination这个参数是异常值在总数据中的占比,真实数据集是不知道的,所以只能给一个大致估计比例。这里是模拟数据就直接给了差不多的值。

from sklearn.ensemble import IsolationForest
# Create and fit the Isolation Forest model
iso_forest = IsolationForest(contamination=float(len(X_abnormal)) / len(X))
iso_forest.fit(X_scaled)  #X_normal_scaled
y_pred_iso = iso_forest.predict(X_scaled)

def plot_result(y_pred,model_name=''):
    # Splitting the data into predicted normal and abnormal by Isolation Forest
    X_k_normal = X[y_pred == 1]
    X_k_abnormal = X[y_pred == -1]

    # Correctly and incorrectly predicted points by Isolation Forest
    correctly_predicted_k = y_pred == true_labels
    incorrectly_predicted_k = ~correctly_predicted_k
    accuracy_k_simple = accuracy_score(true_labels, y_pred)
    print(accuracy_k_simple)

    plt.figure(figsize=(15, 5))
    # Original data plot
    plt.subplot(1, 3, 1)
    plt.scatter(X_normal[:, 0], X_normal[:, 1], color='blue', label='Normal',s=20,marker='x')
    plt.scatter(X_abnormal[:, 0], X_abnormal[:, 1], color='red', label='Abnormal',s=20,marker='x')
    plt.title("Original Data")
    plt.legend()

    # Predicted data plot (Isolation Forest)
    plt.subplot(1, 3, 2)
    plt.scatter(X_k_normal[:, 0], X_k_normal[:, 1], color='b', label='Predicted Normal',s=20,marker='x')
    plt.scatter(X_k_abnormal[:, 0], X_k_abnormal[:, 1], color='r', label='Predicted Abnormal',s=20,marker='x')
    plt.title(f"Predicted Data ({model_name})")
    plt.legend()

    # Prediction accuracy plot (Isolation Forest)
    plt.subplot(1, 3, 3)
    plt.scatter(X[correctly_predicted_k, 0], X[correctly_predicted_k, 1], color='gold', label='Correctly Predicted',s=20,marker='x')
    plt.scatter(X[incorrectly_predicted_k, 0], X[incorrectly_predicted_k, 1], color='purple', label='Incorrectly Predicted',s=20,marker='x')
    plt.title(f"Prediction Accuracy ({model_name})")
    plt.legend()

    plt.show()
    
plot_result(y_pred_iso,model_name='IsolationForest')

 准确率99.7561%,比SVMD高,只有两个点预测错误。这两个异常点....预测错了真不能怪模型,因为他们和正常值确实长得很接近。


自编码器

  • 原理:一种基于神经网络的方法,通过重构输入来检测异常。
  • 应用:特别适用于在高维数据中捕捉复杂模式,如在图像或序列数据中检测异常。

自编码器其实是自监督学习,输入的特征变量和响应变量都是X自己,把数据依靠神经网络进行压缩然后解码重构。可以理解为把一把剑融了重新再融一把剑。。。从这个过程中他会从所有样本的数据中学习这个重构的特征,如果一个数据重构后和原来数据比误差很大,说明可能是异常值。

他的思路导致他重构是回归问题,输出的不是类别。从预测的值怎么转为类别呢?

为了将自编码器的输出转换为类别判断(正常或异常),可以设定一个阈值。这个阈值用于决定重构误差多大时将一个数据点视为异常。设置这个阈值的一个常见方法是选择正常数据的重构误差的某个百分位数(例如95%)。数据点的重构误差高于这个阈值时,它们被标记为异常。

在我们的实现中,阈值是根据正常数据的重构误差分布设定的。具体来说,我们选择了正常数据重构误差的95百分位数作为阈值。然后,我们将所有重构误差高于这个阈值的点标记为异常。这样,我们就可以把自编码器的连续输出(重构误差)转换为二元类别(正常/异常)。

按道理来说自编码器需要神经网络框架,TensorFlow或者pytorch,我这里为了简便就直接sklearn库了,也能实现。

构建了一个128编码,32为压缩维度,然后又128解码还原。按照阈值方法转为了类别,用上面自定义的函数进行画图和测评。

from sklearn.neural_network import MLPRegressor
# Creating the autoencoder model
autoencoder = MLPRegressor(hidden_layer_sizes=(128,32,128),activation='relu', 
                           solver='adam', max_iter=2000, random_state=77)
autoencoder.fit(X_scaled,X_scaled)
X_reconstructed = autoencoder.predict(X_scaled)

# Calculating reconstruction error
reconstruction_error = np.mean((X_scaled - X_reconstructed) ** 2, axis=1)
threshold = np.percentile(reconstruction_error[:100], 95)
predicted_anomalies = reconstruction_error <threshold
predicted_anomalies=np.array([1 if i else -1 for i in predicted_anomalies])

plot_result(predicted_anomalies,model_name='autoencoder')

 准确率95%,不是很高,预测错误的点都是左上方的,也不知道为啥。。。


DBSCAN(基于密度的空间聚类的噪声应用)

  • 原理:基于密度的聚类算法,将稀疏区域中的点标记为异常值。
  • 应用:适用于数据集中的聚类结构不规则或者大小不一的情况。

咋也不太懂这个方法的原理,就直接调包来预测和评价了。

from sklearn.cluster import DBSCAN
dbscan = DBSCAN(eps=0.9, min_samples=5)
dbscan_labels = dbscan.fit_predict(X_scaled)
plot_result(np.where(dbscan_labels == 0, 1, -1),model_name='DBSCAN')

 准确率99.6%,只有三个点预测错误,还是很高。


本地异常因子(Local Outlier Factor, LOF)

  • 原理:通过比较一个点与其邻居的局部密度来检测异常。
  • 应用:适用于检测邻域密度差异显著的异常点
from sklearn.neighbors import LocalOutlierFactor
lof = LocalOutlierFactor(n_neighbors=10, contamination=0.025)
lof_labels = lof.fit_predict(X_scaled)
plot_result(lof_labels,model_name='LOF')

 准确率99.6%,只有三个点预测错误,还是很高。


高斯混合模型(Gaussian Mixture Model, GMM):

  • 原理:使用多个高斯分布的混合来模拟数据,异常值通常不符合这些分布。
  • 应用:适用于数据呈现多模态分布时的异常检测。
from sklearn.mixture import GaussianMixture
gmm = GaussianMixture(n_components=2, random_state=77)
gmm_labels = gmm.fit_predict(X_scaled)
plot_result(np.where(gmm_labels == 0, -1, 1),model_name='GaussianMixture')

  准确率99.87%,只有1个点预测错误,最高!。而且这个点,和正常值太接近了,预测错了完全可以理解。


总结

从这个模拟的数据集效果来看,高斯混合最好,其次是孤立森林,LOF,DBSCAN,自编码器较差。

深度学习的方法为了较差,我猜可能是数据量小了,深度学习在小数据集表现确实一般不如传统的机器学习。

高斯混合为什么这么好,因为他是基于分布的,而我们则模拟数据集就是从不同分布里面生成的,所以正好对上了他的专长,所以效果会比较好吧。

这只是一个初步使用对比的案例,以后还需要用海量的真实的数据再进行测试才能知道哪些模型真的好用。

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

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

相关文章

Github 2023-12-13 开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2023-12-13统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量非开发语言项目5Python项目2TypeScript项目1Jupyter Notebook项目1JavaScript项目1PHP项目1 从零开始构建技术…

matlab操作方法(三)——matlab中的数字图像(读取、显示、保存)

数字图像是二维图像用有限数字数值像素的表示。通常像素在计算机中保存为二维整数数组的光栅图像&#xff0c;这些值经常用压缩格式进行传输和存储。 二值图像&#xff1a;图像中每个像素的亮度值仅可以取自0或1的图像&#xff0c;因此也称为1bit图像 灰度图像&#xff1a;图…

flutter 代码混淆

Flutter 应用混淆&#xff1a; Flutter 应用的混淆非常简单&#xff0c;只需要在构建 release 版应用时结合使用 --obfuscate 和 --split-debug-info 这两个参数即可。 –obfuscate --split-debug-info 用来指定输出调试文件的位置&#xff0c;该命令会生成一个符号映射表。目前…

Axure 9基本元件,表单及表格元件简介,表单案例

目录 一.基本元件 1.元件基本介绍 2.基本元件的使用 二.表单及表格元件 三.表单案例 四.简单简历绘制 一.基本元件 1.元件基本介绍 概述 - 在Axure RP中&#xff0c;元件是**构建原型图的基础模块**。 将元件从元件库里拖拽到画布中&#xff0c;即可添加元件到你的原型…

静态HTTP应用:理解其工作原理与优势

随着互联网的普及和发展&#xff0c;Web应用已经成为人们日常生活和工作中不可或缺的一部分。而静态HTTP应用作为Web应用的一种重要形式&#xff0c;也越来越受到开发者的青睐。本文将带你了解静态HTTP应用的工作原理和优势&#xff0c;让你更好地理解这种应用形式。 一、静态…

【学习笔记】Linux(基础知识)

第1章 Linux概况 1.1 Linux起源 四个重要的支柱: ①Unix操作系统; ②Minix操作系统; ③GNU计划; ④Internet网络。 1. Unix操作系统 UNIX的诞生 1971年,用汇编语言首先开发成功16位UNIX系统 1973年,用C语言重写了UNIX系统 创始人:Ken Thompson & Dennis Ritch…

STM32的DMA的五大问题

1&#xff0c;DMA控制器的内部结构 STM32中的DMA控制器是一种用于在外设和存储器之间传输数据的专用硬件。DMA控制器的内部结构主要包括以下几个关键部分&#xff1a; 通道&#xff1a; DMA控制器可以有多个通道&#xff0c;每个通道独立管理一个数据传输任务。通道的数量取决于…

【解决】Windows 11检测提示电脑不支持 TPM 2.0(注意从DTPM改为PTT)

win11升级&#xff0c;tpm不兼容 写在最前面1. 打开电脑健康状况检查2. 开启tpm3. 微星主板AMD平台开启TPM2.0解决电脑健康状况检查显示可以安装win11&#xff0c;但是系统更新里显示无法更新 写在最前面 我想在台式电脑上用win11的专注模式&#xff0c;但win10不支持 1. 打…

[论文精读] 使用扩散模型生成真实感视频 - 【李飞飞团队新作,文生视频 新基准】

论文导读: 论文背景:2023年12月11日&#xff0c;AI科学家李飞飞团队与谷歌合作&#xff0c;推出了视频生成模型W.A.L.T&#xff08;Window Attention Latent Transformer&#xff09;——一个在共享潜在空间中训练图像和视频生成的、基于Transformer架构的扩散模型。李飞飞是华…

本地 SIEM 与云原生 SIEM:哪一种适合您?

安全信息和事件管理 (SIEM) 解决方案对于各种规模的组织监控其环境中的安全威胁至关重要。 SIEM 解决方案收集并审查来自不同来源&#xff08;例如防火墙、入侵检测系统和 Web 服务器&#xff09;的安全日志。随后可以利用这些数据来检测潜在威胁、检查安全事件并针对网络攻击…

ELADMIN - 免费开源 admin 后台管理系统,基于 Spring Boot 和 Vue ,包含前端和后端源码

一款简单好用、功能强大的 admin 管理系统&#xff0c;包含前端和后端源码&#xff0c;分享给大家。 ELADMIN 是一款基于 Spring Boot、Jpa 或 Mybatis-Plus、 Spring Security、Redis、Vue 的前后端分离的后台管理系统。 ELADMIN 的作者在 Github 和 Gitee 上看了很多的项目&…

什么是FPGA原型验证?

EDA工具的使用主要分为设计、验证和制造三大类。验证工作贯穿整个芯片设计流程&#xff0c;可以说芯片的验证阶段占据了整个芯片开发的大部分时间。从芯片需求定义、功能设计开发到物理实现制造&#xff0c;每个环节都需要进行大量的验证。 现如今验证方法也越来越多&#xff…

链路追踪详解(四):分布式链路追踪的事实标准 OpenTelemetry 概述

目录 OpenTelemetry 是什么&#xff1f; OpenTelemetry 的起源和目标 OpenTelemetry 主要特点和功能 OpenTelemetry 的核心组件 OpenTelemetry 的工作原理 OpenTelemetry 的特点 OpenTelemetry 的应用场景 小结 OpenTelemetry 是什么&#xff1f; OpenTelemetry 是一个…

Java常用注解

文章目录 第一章、Java注解与元数据1.1&#xff09;元数据与注解概念介绍1.2&#xff09;Java注解的作用和使用1.3&#xff09;注解的分类 第二章、Mybatis框架常用注解2.1&#xff09;Mybatis注解概览2.2&#xff09;常用注解MapperScanMapperSelectInsertUpdateDeleteParam结…

mysql的负向条件查询会不会使用索引

mysql的负向条件查询&#xff0c;例如not in&#xff0c;会不会使用索引&#xff1f; 其实&#xff0c;mysql还是会尽量利用索引。如果查询的列上有索引&#xff0c;并且索引能够覆盖查询所需的列&#xff0c;那么mysql可能会使用索引来获取结果&#xff0c;而不是进行全表扫描…

CentOS 7 部署frp穿透内网

本文将介绍如何在CentOS 7.9上部署frp&#xff0c;并通过示例展示如何配置和测试内网穿透。 文章目录 &#xff08;1&#xff09;引言&#xff08;2&#xff09;准备工作&#xff08;4&#xff09;frps服务器端配置&#xff08;5&#xff09;frpc客户端配置&#xff08;6&#…

从零到一:influxdb时序性数据库的基本概念与操作指南

目录 ​编辑 引言 数据库(database) 创建数据库 删除数据库 进入数据库 展示influxdb中所有数据库 测量&#xff08;measurement&#xff09; 写入测量 展示测量 总结 引言 InfluxDB是一个开源的时序数据库&#xff0c;专门设计用于处理时间序列数据。它是由InfluxD…

052:vue重新发布,软件热更新方面的一点经验示例

第052个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

Excel: Python 如何干掉 VBA 系列 乙

以下内容为本人的学习笔记&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/k2XtfXS3GUt4r2QhizMOVg 创建工作表格 创建表格 xlwings 就可以协助创建插入了宏的 excel 表格。 先找到一个心满意足的目录&#xff0c;一般我…

随记-nginx docker + SSL 配置 - 配置等资源挂宿主机

随记-Nginx docker SSL 配置 - 配置等资源挂宿主机等 笔者动手配置&#xff0c;随手写的笔者&#xff0c;保证可操作 话说现在padmon是不是已经有代替docker的趋势了&#xff0c;谁能告诉我一把&#xff1f; 配置前准备 # 拉取nginx镜像 docker pull nginx #启动(暂时) doc…