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 ForestX_k_normal = X[y_pred == 1]X_k_abnormal = X[y_pred == -1]# Correctly and incorrectly predicted points by Isolation Forestcorrectly_predicted_k = y_pred == true_labelsincorrectly_predicted_k = ~correctly_predicted_kaccuracy_k_simple = accuracy_score(true_labels, y_pred)print(accuracy_k_simple)plt.figure(figsize=(15, 5))# Original data plotplt.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.mzph.cn/news/219744.shtml

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

相关文章

WPF-一个简单登录界面

一个简单登录界面 文章目录 一个简单登录界面一、效果展示二、准备代码 一、效果展示 二、准备代码 创建一个WPF工程&#xff0c;创建名为 Login5 的WPF项目。 添加Nuget包 MaterialDesignThemes 界面的整体布局和样式代码 <Window x:Class"Login5.MainWindow&quo…

Java - 异常(三)- 声明异常(throws)和手动抛出异常throw

目录 6.3 方式2&#xff1a;声明异常&#xff08;throws&#xff09; 6.4 手动抛出异常throw 6.4.1 概述 6.4.2 使用格式&#xff1a; 6.4.3 实例代码 6.4.4 为什么要手动抛出异常对象&#xff1f; 6.4.5 如何理解“自动”和“手动” 抛出异常对象 6.4.6 注意点 ❓面试…

数字化赋能实体经济,凌雄科技发挥DaaS模式提质增效价值

11月中旬&#xff0c;市场监管总局发布了2023年前三季度经营主体数据。其中&#xff0c;前三季度全国新设民营企业总计706.5万户&#xff0c;截至9月底&#xff0c;全国登记在册的民营企业数量超过5200万户&#xff0c;在企业总量中占比高达92.3%。如何帮助民营企业实现高质量发…

【数学建模美赛M奖速成系列】报名流程与论文的基本格式

数学建模美赛M奖速成系列 写在前面报名方式1.官网直接报名2.赛氪软件辅助报名 论文的基本格式摘要模型建立模型求解结果分析与检验模型评价 竞赛的基本注意事项1. 选题后查找资料2. 写作能力和编程能力 历年优秀论文标题与摘要简明扼要善用图表 最后 写在前面 最近&#xff0c…

Vue 3 开发中遇到的问题及解决方案(fix bug)

开发环境&#xff1a;mac系统&#xff0c;node版本&#xff1a; 16.15.0 版本兼容问题 vite v3.2.4 building for development... hasInjectionContext is not exported by node_modules/pinia/node_modules/vue-demi/lib/index.mjs, imported by node_modules/pinia/dist/pini…

深圳移动与大富科技助力深圳人工智能教育高质量发展

12月12日&#xff0c;中国移动通信集团广东有限公司深圳分公司(以下简称“深圳移动”) 与大富科技&#xff08;安徽&#xff09;股份有限公司&#xff08;以下简称“大富科技”&#xff09;在中国移动深圳信息大厦签署“战略合作框架协议”&#xff0c;共同推进人工智能教育、I…

【大数据】详解 AVRO 格式

详解 AVRO 格式 1.Avro 介绍2.schema2.1 原始类型2.2 复杂类型2.2.1 Records2.2.2 Enums2.2.3 Arrays2.2.4 Maps2.2.5 Unions2.2.6 Fixed 3.Avro 的文件存储格式3.1 数据编码3.1.1 原始类型3.1.2 复杂类型 3.2 存储格式3.3 存储格式 4.小结 1.Avro 介绍 Apache Avro 是 Hadoop…

three.js(一)

文章目录 three.js环境搭建正文补充 示例效果知识点补充1:一个标准的html知识点补充2:原生的前端框架和Vue框架的区别原生的前端框架Vue框架声明式编程和响应式编程 three.js环境搭建 正文 搭建 Three.js 的环境通常包括以下几个步骤&#xff1a; 1.创建项目目录&#xff1a…

初级数据结构(三)——栈

文中代码源文件已上传&#xff1a;数据结构源码 <-上一篇 初级数据结构&#xff08;二&#xff09;——链表 | 初级数据结构&#xff08;四&#xff09;——队列 下一篇-> 1、栈的特性 1.1、函数栈帧简述 即使是刚入门几天的小白&#xff0c;对栈这个字…

基于YOLOv8深度学习的吸烟/抽烟行为检测系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

基于SSM实现的精品课程网站

一、系统架构 前端&#xff1a;jsp | js | css | jquery | bootstrap 后端&#xff1a;spring | springmvc | mybatis 环境&#xff1a;jdk1.7 | mysql | maven | tomcat 二、代码及数据库 三、功能介绍 01. 登录页 02. web端-首页 03. web端-视频教程 04. web端-资料…

RK3568全国产化多网口板卡带poe供电,支持鸿蒙麒麟系统

信迈XM-3568-01主板采用瑞芯微RK3568四核Cortex-A55 处理器&#xff0c;主频最高可达2.0GHz&#xff0c;效能有大幅提升最高可配8GB内存容量&#xff0c;频率高达1600MHz&#xff1b;支持全链路ECC&#xff0c;让数据更安全可靠配置双千兆自适应RJ45以太网口&#xff0c;并扩展…

stm32---串口使用

### 串口数据发送 #include <string.h> //先引用这个字符串操作库。char str[]" HALLO WORD "&#xff1b; //定义这个数组字符串。HAL_UART_Transmit(&huart2, str, strlen(str), 100); //&huart2,这里他是一个指针&#xff0c;所以要用取地址符…

在WPF窗口中增加水印效果

** 原理&#xff1a; ** 以Canvas作为水印显示载体&#xff0c;在Canvas中创建若干个TextBlock控件用来显示水印文案&#xff0c;如下图所示 然后以每一个TextBlock的左上角为中心旋转-30&#xff0c;最终效果会是如图红线所示&#xff1a; 为了达到第一行旋转后刚好与窗口…

App防止恶意截屏功能的方法:iOS、Android和鸿蒙系统的实现方案

防止应用被截图是一个比较常见的需求&#xff0c;主要是出于安全考虑。下面将分别为iOS&#xff08;苹果系统&#xff09;、Android&#xff08;安卓系统&#xff09;及HarmonyOS&#xff08;鸿蒙系统&#xff09;提供防止截屏的方法和示例代码。 在企业内部使用的应用中&…

深入解析Freemarker模板引擎及其在Spring Boot中的高级整合

目录 引言1. Freemarker1.1.什么是Freemarker1.2 Freemarker模板组成部分1.3.优点 2. Spring Boot整合Freemarker2.1 配置2.2 数据类型 3. 案例总结 引言 Freemarker作为一款强大的模板引擎&#xff0c;与Spring Boot的整合能够极大地提升Web应用的开发效率和灵活性。本篇博客…

探索 Vim:一个强大的文本编辑器

引言&#xff1a; Vim&#xff08;Vi IMproved&#xff09;是一款备受推崇的文本编辑器&#xff0c;拥有强大的功能和高度可定制性&#xff0c;提供丰富的编辑和编程体验。本文将探讨 Vim 的基本概念、使用技巧以及为用户带来的独特优势。 简介和发展 1. Vim 的简介和历史 V…

发布jar包到maven中央仓库

1. 环境 在网上找的很多文章中写得都有很多问题&#xff0c;这里记录一下最近一次成功地发布jar包到maven中央仓库的过程。并附带上每一个步骤官方的指导链接。 系统&#xff1a;mac&#xff08;windows系统在下载辅助工具时不太一样&#xff0c;在配置上和mac系统没有区别&…

docker部署go gin框架 Linux环境

目录 文章目的是什么 环境介绍 Linux 环境下 docker 部署 go gin 详细步骤 部署 gin 文章目的是什么 假设我们学习了 go 语言&#xff0c;在 Linux 上安装了 go 相关的程序&#xff0c;也能直接运行&#xff0c;使用以下命令&#xff1a; go run main.go 假如代码是这样的…

算法中的最优化方法课程复习

算法中的最优化方法课程复习 单模函数、拟凸函数、凸函数证明证明一个线性函数与一个凸函数的和也是凸的 梯度线性规划标准形式以及如何标准化标准形式常见标准化方法线性化技巧 单纯形法二次规划无约束优化Nelder-Mead线搜索FR共轭梯度法例题 优化算法的选择、停止准则算法选择…