0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于Python在数据流中查找异常值的方法

汽车玩家 来源:未知 作者:闻数起舞 2020-05-03 18:17 次阅读

一种简单的方法,可通过Python实现在数据流中查找异常值

在上一篇文章中,我解释了流算法的概念,并给出了许多如何应用流算法的示例。 其中之一是在不保存数据流元素的情况下计算数据流的滚动平均值。 现在,我想扩展这个示例,并在异常值检测的背景下向您展示另一种流算法的用例。

当我们监视机器的功耗以检测任何异常行为时,可能会出现类似的问题。 如果我们发现异常值有所增加(异常观察),则可能表明这台机器的默认值,可能值得检查。

定义和示例

离群值可以通过多种方式定义。 在本文中,我们将使用以下定义:

如果数字数据流中的元素与到目前为止所见元素的平均值不在3个标准偏差之内,则该元素被视为离群值。

这需要一个小例子。 假设我们按顺序获得数据3、2、4、3、5、3、2、10、2、3、1。 让我们进一步假设,我们从零的均值和方差(以及因此的标准差)开始,即,如果不等于零,则始终将第一个元素视为离群值。

因此,将3视为离群值,因为3> 0 3 * 0。 现在,我们根据到目前为止看到的元素(仅是数字3)更新均值和方差。因此,新均值是3,方差是0。

然后我们看到2。我们有2> 3 3 * 0,所以2也被认为是离群值。 这是有道理的,因为到目前为止我们只看到了3,所以其他任何数字都不适合该模式。 平均值更新为(3 2)/2=2.5,方差更新为((3-2.5)²(2-2.5)²)/2=0.25,这意味着标准偏差为0.5。

现在我们看到4。由于2.5–3 *0.5≤4≤2.53 * 0.5,因此该数字不是异常值(即正常值)。 平均值更新为(3 2 4)/ 3 = 3,方差更新为((3–3)²(2–3)²(4–3)²)/ 3 = 2/3,因此标准偏差为 约0.81。

以下数字3、5、3、2被认为是正常的。 凭直觉,我们将下面的数字10视为离群值。 让我们看看该算法的作用。 此时的平均值约为3.1,标准偏差约为1。由于10> 3.1 3 * 1,因此我们希望将10视为离群值。

如果继续最后三个元素,您将看到它们都是正常的。

问题:要计算平均值和标准偏差,我们必须记住到目前为止看到的所有元素。 如果我们有一个每天输出成千上万个元素的系统,那么这不是一个选择。

救援的流式算法

解决此问题的一种方法是使用流算法,该算法在从数据流中每个被扫描元素之后更新其内部状态。 内部状态由到目前为止在任何点看到的所有元素的均值和方差组成,从看到任何元素之前的均值和方差为零开始。 确切地说,在看到数据流的第n个元素之后,令mₙ为平均值,vₙ为方差,并附加定义m₀=v₀= 0。

计算均值

在我有关流算法的文章中,我们看到了如何仅使用旧的均值,正在扫描的最新元素以及到目前为止看到的元素数量来更新均值。 这意味着我们只需要随时使用这种方法存储两个数字,而不是像幼稚的方法那样存储n。 让我再次显示它,将数据流的第i个传入元素表示为aᵢ:

基于Python在数据流中查找异常值的方法

这个公式不难开发,对吧? 有了它,我们就有了我们期望的元素大小的基线。 现在,我们只需要可以用均值围绕的标准偏差即可将输入的示例分类为离群值和正常数据点。 我们通过计算方差来做到这一点,然后取其平方根即可达到标准偏差。

计算方差

在这种情况下,我们也可以轻松找到递归公式。 首先,看到n个元素后的方差为

基于Python在数据流中查找异常值的方法

让我们尝试再次根据n,vₙ和最新元素来写。 由于方差取决于均值,因此我们也要包含mₙ。 在开始之前,让我们重新安排这个公式,以使事情变得更容易:

基于Python在数据流中查找异常值的方法

现在,目标是使vₙ进入那里。 一种进行方式是从以下简单的重新排列开始,以隔离平方和直到索引n,它也以vₙ中的一项出现:

基于Python在数据流中查找异常值的方法

这相当于

基于Python在数据流中查找异常值的方法

反过来导致

基于Python在数据流中查找异常值的方法

现在,我们有了公式,让我们看看它在Python中是如何工作的!

用Python实现

我们可以通过以下方式实现上述解释:

class StreamingMeanAndVariance:

def __init__(self):

self.mean = 0

self.variance = 0

self.n_elements = 0

def update(self, element):

self.variance = ((self.variance + self.mean ** 2) * self.n_elements + element ** 2) / (self.n_elements + 1)

self.mean = ((self.mean * self.n_elements) + element) / (self.n_elements + 1)

self.variance = self.variance - self.mean ** 2

self.n_elements += 1

关于此的注释:update方法的第一行计算方差,但不减去当前均方根。 在第二行中,计算当前平均值。 在第三行中,然后将其从方差中减去,因为在第一行中仍然缺少此值。

要使用它,我们会

import numpy as np

m = StreamingMeanAndVariance()

n = 10000

for i, s in enumerate(np.random.randn(n)):

if not - 3 <= (s - m.mean) / np.sqrt(m.variance) <= 3:

print(i, s)

m.update(s)

这将扫描数据流,该数据流在此示例中由10000个正态分布的数字组成(我们将其表示为N(0,1)),并在出现异常时打印异常值。

如果将法线的间隔和平均值(以黄色表示)作图,则会得到以下图片:

以蓝色显示,您可以看到测量值。绿色区域包含法线点,其外部的测量值(红色表示)被认为是异常值。以黄色显示您的期望值(平均值)。

讨论区

该算法可以达到我们的期望! 但是,到目前为止,我们还没有看到它如何处理分配的变化,而是始终只有标准的正态分布数。

让我们测试执行以下操作时算法的行为:

结果看起来像这样:

Everything adapts slowly to the new data.

优点

这看起来很有希望! 一切都会自动适应新数据。 当数据的平均值从0变为2时,我们可以看到很多离群值,这是有道理的。 新平均值2越多,观测到的异常值就越少,因为2左右是新的常态。

当将平均值从2更改为-2时,我们可以看到更多的离群值,因为这种变化要严重得多。 到目前为止,一切都很好。

缺点

如果查看图的右半部分,可以看到对新数据的适应非常慢。 如您所见,平均值和标准偏差将在一段时间后再次达到正确的水平,因为黄线(均值)下降并且绿色区域再次变窄。 但是直到稳定为止,没有发现异常值。

为了解决这个问题,我们只能使用最后k个样本来计算均值和标准差,因为


这会破坏第一次测量的影响。 如果将k设置为无穷大,则可以从之前获得算法。

我们将k设置得越低,算法就越快地适应新数据。 但是,将k设置得太小可能会导致丢弃异常值,因为该算法认为新数据就是这样。 在设置k = 1的极端情况下,没有元素被视为离群值,因为仅考虑了最新元素。

根据用例,可能几百或几千个就可以了。

结论

在本文中,我们已经看到了如何为数据流建立一个非常简单的异常检测机制。 我们的算法不需要存储所有测量值,因此非常容易应用,也可以在极其受限制的硬件上使用,并且只需固定存储即可。 该算法甚至可以适应数据更改,因此无需手动更新。

唯一需要调整的是自适应率,我们在本文中没有介绍,但是很容易做到。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据流
    +关注

    关注

    0

    文章

    115

    浏览量

    14240
  • python
    +关注

    关注

    53

    文章

    4705

    浏览量

    83704
收藏 人收藏

    评论

    相关推荐

    ESP32如何在不漏数据的情况下采集数据流

    esp32作为spi从机连接一款AD,该AD芯片上电后就会持续不断地向外发送数据,如果循环调用spi_slave_transmit(),那么两次调用之间就会漏掉一些数据。 请问从机有没有办法在不漏数据的情况下采集这个
    发表于 06-19 08:02

    TSN时间敏感网络QoS数据流传输干扰的三种模式#TSN #时间敏感网络

    数据流TSN
    北汇信息POLELINK
    发布于 :2024年04月24日 12:29:11

    stm32F429串口采用DMA方式发送,数据流使能失败的原因?

    DMA1 时钟稳定 DMA_DeInit(DMA2_Stream7);// 复位初始化DMA数据流 while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE
    发表于 04-17 07:05

    Stm32H7 spi会带来更大的adc噪声,导致小信号异常值的原因?

    [Stm32H7]spi会带来更大的adc噪声,导致小信号异常值
    发表于 03-25 06:10

    fx3进行视频数据流的传输的时候,请问如何修改可以达到同步传输的要求?

    在fx3的固件给出的slavefifo 是通过bulk传输的demo 我想进行视频数据流的传输的时候,请问如何修改可以达到同步传输的要求 我目前在固件里面只看到了bulk的方式,如果有同步传输的demo或者修改教程请不吝赐教 FX3
    发表于 02-28 07:50

    源代码审计怎么做?有哪些常用工具

    时,还可以采用正向追踪数据流和逆向溯源数据流两种方法。正向追踪数据流是指跟踪用户输入参数,来到代码逻辑,最后审计代码逻辑缺陷并尝试构造payload;逆向溯源
    发表于 01-17 09:35

    使用AD7656过程采样值每间隔一段时间会有异常值出现是什么原因?

    我在使用AD7656过程中发现采样值每间隔一段时间(10分钟不等)会有异常值出现(0x4000或0xBFFF),不知什么原因。求分析。
    发表于 12-21 06:20

    AD7656输出数据及时序异常是什么原因?

    目前采用AD7656并行模式。在使用过程中发现AD7656采集一段时间后会有异常值出现(0xFEFF,0x4000等)。观察AD芯片的rd_en(紫色)、convst(黄色,A、B、C时序相同)、busy(蓝色)信号如图所示。busy信号有在读过程拉高的现象,不知是什么
    发表于 12-14 06:02

    查看python安装路径的方法

    Python是一种高级编程语言,常用于开发Web应用、数据分析、人工智能等领域。在使用Python进行开发之前,我们需要先安装Python解释器,并了解
    的头像 发表于 11-29 14:54 1822次阅读

    c语言在数组中查找指定元素

    C语言是一种通用的编程语言,广泛应用于各种领域,包括嵌入式系统、操作系统、游戏开发等。在C语言中,数组是一种非常重要的数据结构,用于存储一系列相同类型的元素。查找指定元素在数组中是否存在是一种常见
    的头像 发表于 11-24 10:07 2196次阅读

    Vulture 可在Python程序中查找未使用的代码

    Vulture 可以在Python程序中查找未使用的代码。这对于清理和查找大型项目(代码库)中的错误非常有用。 不过由于Python的动态特性,像 Vulture 这样的静态代码分析器
    的头像 发表于 10-21 10:28 307次阅读

    怎么找SD卡的特定的数据

    现在想到的是用f_lseek函数从最开始把一段数据存进数组然后再用字符串比较,没有的话再f_lseek下一段数据,直到在数组找到时间,把后面的数据读出来。 请问还有其他的
    发表于 09-25 07:43

    python读取数据数据 python查询数据python数据库连接

    python读取数据数据 python查询数据python
    的头像 发表于 08-28 17:09 1425次阅读

    python数据挖掘与机器学习

    python数据挖掘与机器学习 Python是一个非常流行的编程语言,被广泛用于数据挖掘和机器学习领域。在本篇文章中,我们将探讨Python
    的头像 发表于 08-17 16:29 1023次阅读

    数据填报异常值如何处理?#数据填报 #光点科技

    数据
    光点科技
    发布于 :2023年07月28日 18:20:13