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

案例背景

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

标题的这些机器学习方法基本都可以调包,使用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,自编码器较差。

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java项目学生管理系统六后端补充

班级管理 1 班级列表&#xff1a;后端 编写JavaBean【已有】编写Mapper【已有】编写Service编写controller 编写Service 接口 package com.czxy.service;import com.czxy.domain.Classes;import java.util.List;/*** author 桐叔* email liangtongitcast.cn* description*/ p…

计算机基础

【一】深度学习中常用的Linux命令汇总 1.man&#xff1a;man command&#xff0c;可以查看某个命令的帮助文档&#xff0c;按q退出帮助文档 2.cd&#xff1a;用于切换目录&#xff0c;cd - 可以在最近两次目录之间来回切换 3.touch&#xff1a;touch file创建文件。 4.ls&…

Windows、Linux 和 macOS 操作系统:操作系统大比较

目录 引言 Windows Linux macOS 1. 用户界面 1.1 Windows 1.2 Linux 1.3 macOS 2. 开发者支持 2.1 Windows 2.2 Linux 2.3 macOS 3. 安全性和稳定性 3.1 Windows 3.2 Linux 3.3 macOS 结论 引言 在计算机科学领域&#xff0c;操作系统是计算机系统中的核心软件…

【计算机视觉】SIFT

在边缘提取的时候&#xff0c;用高斯一阶导对信号进行卷积&#xff0c;响应值最大的就是边界如果用高斯二阶导对信号进行卷积&#xff0c;0点就是边界点&#xff08;二阶导等于0的点&#xff0c;对应一阶导的极值点&#xff09; 如果用高斯二阶导在不同的信号上进行卷积&#x…

华为数通---配置基本QinQ示例

QinQ简介 定义 QinQ&#xff08;802.1Q-in-802.1Q&#xff09;技术是一项扩展VLAN空间的技术&#xff0c;通过在802.1Q标签报文的基础上再增加一层802.1Q的Tag来达到扩展VLAN空间的功能&#xff0c;可以使私网VLAN透传公网。由于在骨干网中传递的报文有两层802.1Q Tag&#x…

【JavaWeb学习笔记】7 - Servlet入门开发

零、在线文档 Servlet 3.1 API Documentation - Apache Tomcat 8.0.53 一、Servlet基本介绍 1.为什么出现Servlet 提出需求:请用你现有的html css javascript&#xff0c;开发网站&#xff0c;比如可以让用户留言/购物/支付,你能搞定吗? 不能 这几个不能直接操作数据库 …

Android gradle配置jar包加载顺序及延伸知识

Android gradle配置jar包加载顺序及延伸知识 前言一、直接配置1.APP目录下的build.gradle2.项目级的build.gradle3.其他问题 二、gradle的生命周期及关键方法1.关键方法2.gradle的生命周期 总结 前言 项目涉及到了要加载framework.jar&#xff0c;需要将libs文件夹下的framewo…

SpringBoot对PDF进行模板内容填充、电子签名合并

1. 依赖引入–这里只包含额外引入的包 原有项目包不含括在内 <!-- pdf编辑相关--> <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13.3</version> </dependency><de…

数据结构与算法:选择排序

原理 从当前位置到最后&#xff0c;找出最小(或者最大)值&#xff0c;放在当前位置&#xff0c;位置后移。然后重复此过程。 每次都要在剩余未排序的集合中&#xff0c;找到那个最小(或者最大)的值&#xff0c;放到当前位置。所以叫选择排序。 最小或者最大&#xff0c;影响…

iOS加密CoreML模型

生成模型加密密钥 必须在Xcode的Preferences的Accounts页面登录Apple ID&#xff0c;才能在Xcode中生成模型加密密钥。 在Xcode中打开模型&#xff0c;单击Utilities选项卡&#xff0c;然后单击“Create Encryption Key”按钮。 从下拉菜单中选择当前App的Personal Team&…

Hive命令操作

1.命令行模式 1. 获取帮助 --> hive -H 或-help 2. 运行hive语句 --> hive -e "执行语句" 3. 运行hive文件 --> hive –f "执行文件" 4. 定义变量 --> hive –hivevar keyvalue 5. 引用变量 --> ${varname} 2. 交互模式 1. 进入客户端 -…

Apache Web 服务器监控工具

将Apache Web 服务器监控纳入 IT 基础架构管理策略有助于先发制人地识别性能瓶颈&#xff0c;这种主动监控方法提供必要的数据&#xff0c;以确保 Web 服务器能够胜任任务&#xff0c;并在需要时进行优化。保证客户获得流畅、无忧的用户体验可以大大有助于巩固他们对组织的信任…

STM32的DMA的五大问题

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

【教学类-06-15】20231213 (按比例抽题+乱序or先加后减)X-Y之间“加法减法+-题”

作品展示&#xff1a; 背景需求 1、加减混合题——加法题多&#xff0c;减法题少 大三班一位女孩让我给他批改0-10加减法混合题&#xff0c;我随机从每列题目里面选了2个加法和2个减法题抽查答案正确性。 “347&#xff0c;对&#xff0c;这里819 对” 然后我停顿几秒&…

22.Java程序设计-基于SpringBoot的批发零售业商品管理小程序系统的设计与实现

摘要&#xff1a; 批发零售业商品管理小程序系统的设计旨在提高批发商、零售商和管理员的业务效率&#xff0c;实现商品的高效管理、订单的快速处理以及库存的精准监控。本系统基于Spring Boot框架&#xff0c;利用其强大的特性和生态系统&#xff0c;结合小程序前端&#xff…

R语言对医学中的自然语言(NLP)进行机器学习处理(1)

什么是自然语言(NLP)&#xff0c;就是网络中的一些书面文本。对于医疗方面&#xff0c;例如医疗记录、病人反馈、医生业绩评估和社交媒体评论,可以成为帮助临床决策和提高质量的丰富数据来源。如互联网上有基于文本的数据(例如,对医疗保健提供者的社交媒体评论),这些数据我们可…

AndroidStudio flutter 开发环境 绿色版,绿化方法

这里写自定义目录标题 绿色版下载:绿色版制作过程参考资料1.按照正常方式配置flutter开发环境(不包括桌面开发环境),确认能够正常编译apk2.移动AndroidStudio3.修改 {Android Studio安装路径}\bin\idea.properties4.移动.android5.移动AndroidSdk6.移动gradle 绿色版下载: and…

flink yarn-session 启动失败retrying connect to server 0.0.0.0/0.0.0.0:8032

原因分析&#xff0c;启动yarn-session.sh&#xff0c;会向resourcemanager的端口8032发起请求&#xff1a; 但是一直无法请求到8032端口&#xff0c;触发重试机制会不断尝试 备注&#xff1a;此问题出现时&#xff0c;我的环境ambari部署的HA 高可用hadoop&#xff0c;三个节点…

计算机网络传输层(期末、考研)

计算机网络总复习链接&#x1f517; 目录 传输层的功能端口UDP协议UDP数据报UDP的首部格式UDP校验 TCP协议&#xff08;必考&#xff09;TCP报文段TCP连接的建立TCP连接的释放TCP的可靠传输TCP的流量控制零窗口探测报文段 TCP的拥塞控制慢开始和拥塞控制快重传和快恢复 TCP和U…

低代码 —— 饮食均衡,合理膳食

目录 一、低代码的概念 二、低代码的优缺点 &#xff08;一&#xff09;优点 &#xff08;二&#xff09;缺点 三、低代码的能力 1、场景构建能力 2、数据编排能力 3、连接生态能力 4、业务中台能力 四、你认为低代码会替代传统编程吗&#xff1f; 1、从技术特征来看…