python库Tsmoothie模块数据平滑化异常点抓取


Posted in Python onJune 10, 2022

前言

在处理数据的时候,我们经常会遇到一些非连续的散点时间序列数据:

python库Tsmoothie模块数据平滑化异常点抓取

有些时候,这样的散点数据是不利于我们进行数据的聚类和预测的。因此我们需要把它们平滑化,如下图所示:

python库Tsmoothie模块数据平滑化异常点抓取

如果我们将散点及其范围区间都去除,平滑后的效果如下:

python库Tsmoothie模块数据平滑化异常点抓取

这样的时序数据是不是看起来舒服多了?此外,使用平滑后的时序数据去做聚类或预测或许有令人惊艳的效果,因为它去除了一些偏差值并细化了数据的分布范围。

如果我们自己开发一个这样的平滑工具,会耗费不少的时间。因为平滑的技术有很多种,你需要一个个地去研究,找到最合适的技术并编写代码,这是一个非常耗时的过程。平滑技术包括但不限于:

  • 指数平滑
  • 具有各种窗口类型(常数、汉宁、汉明、巴特利特、布莱克曼)的卷积平滑
  • 傅立叶变换的频谱平滑
  • 多项式平滑
  • 各种样条平滑(线性、三次、自然三次)
  • 高斯平滑
  • 二进制平滑

所幸,有大佬已经为我们实现好了时间序列的这些平滑技术,并在GitHub上开源了这份模块的代码——它就是 Tsmoothie 模块。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器,它有许多的优点。

请选择以下任一种方式输入命令安装依赖:

  • Windows 环境 打开 Cmd (开始-运行-CMD)。
  • MacOS 环境 打开 Terminal (command+空格输入Terminal)。
  • 如果你用的是 VSCode编辑器 或 Pycharm,可以直接使用界面下方的Terminal.
pip install tsmoothie

(PS) Tsmoothie 仅支持Python 3.6 及以上的版本。

2.Tsmoothie 基本使用

为了尝试Tsmoothie的效果,我们需要生成随机数据:

import numpy as np
import matplotlib.pyplot as plt
from tsmoothie.utils_func import sim_randomwalk
from tsmoothie.smoother import LowessSmoother
# 生成 3 个长度为200的随机数据组
np.random.seed(123)
data = sim_randomwalk(n_series=3, timesteps=200,
                      process_noise=10, measure_noise=30)

然后使用Tsmoothie执行平滑化:

# 平滑
smoother = LowessSmoother(smooth_fraction=0.1, iterations=1)
smoother.smooth(data)

通过 smoother.smooth_data 你就可以获取平滑后的数据:

print(smoother.smooth_data)
# [[ 5.21462928 3.07898076 0.93933646 -1.19847767 -3.32294934
# -5.40678762 -7.42425709 -9.36150892 -11.23591897 -13.05271523
# ....... ....... ....... ....... ....... ]]

绘制效果图:

python库Tsmoothie模块数据平滑化异常点抓取

3.基于Tsmoothie的极端异常值检测

事实上,基于smoother生成的范围区域,我们可以进行异常值的检测:

python库Tsmoothie模块数据平滑化异常点抓取

可以看到,在蓝色范围以外的点,都属于异常值。我们可以轻易地将这些异常值标红或记录,以便后续的处理。

_low, _up = smoother.get_intervals('sigma_interval', n_sigma=2)
series['low'] = np.hstack([series['low'], _low[:,[-1]]])
series['up'] = np.hstack([series['up'], _up[:,[-1]]])
is_anomaly = np.logical_or(
    series['original'][:,-1] > series['up'][:,-1],
    series['original'][:,-1] < series['low'][:,-1]
).reshape(-1,1)

假设蓝色范围interval的最大值为up、最小值为low,如果存在 data > up 或 data < low 则表明此数据是异常点。

使用以下代码通过滚动数据点进行平滑化和异常检测,就能保存得到上方的GIF动图。

上滑查看更多代码

# Origin: https://github.com/cerlymarco/MEDIUM_NoteBook/blob/master/Anomaly_Detection_RealTime/Anomaly_Detection_RealTime.ipynb
import numpy as np
import matplotlib.pyplot as plt
from celluloid import Camera
from collections import defaultdict
from functools import partial
from tqdm import tqdm
from tsmoothie.utils_func import sim_randomwalk, sim_seasonal_data
from tsmoothie.smoother import *
def plot_history(ax, i, is_anomaly, window_len, color='blue', **pltargs):
    posrange = np.arange(0,i)
    ax.fill_between(posrange[window_len:],
                    pltargs['low'][1:], pltargs['up'][1:],
                    color=color, alpha=0.2)
    if is_anomaly:
        ax.scatter(i-1, pltargs['original'][-1], c='red')
    else:
        ax.scatter(i-1, pltargs['original'][-1], c='black')
    ax.scatter(i-1, pltargs['smooth'][-1], c=color)
    ax.plot(posrange, pltargs['original'][1:], '.k')
    ax.plot(posrange[window_len:],
            pltargs['smooth'][1:], color=color, linewidth=3)
    if 'ano_id' in pltargs.keys():
        if pltargs['ano_id'].sum()>0:
            not_zeros = pltargs['ano_id'][pltargs['ano_id']!=0] -1
            ax.scatter(not_zeros, pltargs['original'][1:][not_zeros],
                       c='red', alpha=1.)
np.random.seed(42)
n_series, timesteps = 3, 200
data = sim_randomwalk(n_series=n_series, timesteps=timesteps,
                      process_noise=10, measure_noise=30)
window_len = 20
fig = plt.figure(figsize=(18,10))
camera = Camera(fig)
axes = [plt.subplot(n_series,1,ax+1) for ax in range(n_series)]
series = defaultdict(partial(np.ndarray, shape=(n_series,1), dtype='float32'))
for i in tqdm(range(timesteps+1), total=(timesteps+1)):
    if i>window_len:
        smoother = ConvolutionSmoother(window_len=window_len, window_type='ones')
        smoother.smooth(series['original'][:,-window_len:])
        series['smooth'] = np.hstack([series['smooth'], smoother.smooth_data[:,[-1]]])
        _low, _up = smoother.get_intervals('sigma_interval', n_sigma=2)
        series['low'] = np.hstack([series['low'], _low[:,[-1]]])
        series['up'] = np.hstack([series['up'], _up[:,[-1]]])
        is_anomaly = np.logical_or(
            series['original'][:,-1] > series['up'][:,-1],
            series['original'][:,-1] < series['low'][:,-1]
        ).reshape(-1,1)
        if is_anomaly.any():
            series['ano_id'] = np.hstack([series['ano_id'], is_anomaly*i]).astype(int)
        for s in range(n_series):
            pltargs = {k:v[s,:] for k,v in series.items()}
            plot_history(axes[s], i, is_anomaly[s], window_len,
                         **pltargs)
        camera.snap()
    if i>=timesteps:
        continue
    series['original'] = np.hstack([series['original'], data[:,[i]]])
print('CREATING GIF...') # it may take a few seconds
camera._photos = [camera._photos[-1]] + camera._photos
animation = camera.animate()
animation.save('animation1.gif', codec="gif", writer='imagemagick')
plt.close(fig)
print('DONE')

注意,异常点并非都是负面作用,在不同的应用场景下,它们可能代表了不同的意义。

python库Tsmoothie模块数据平滑化异常点抓取

比如在股票中,它或许可以代表着震荡行情中某种趋势反转的信号。

或者在家庭用电量分析中,它可能代表着某个时刻的用电峰值,根据这个峰值我们可以此时此刻开启了什么样的电器。

所以异常点的作用需要根据不同应用场景进行不同的分析,才能找到它真正的价值。

python库Tsmoothie模块数据平滑化异常点抓取

总而言之,Tsmoothie 不仅可以使用多种平滑技术平滑化我们的时序数据,让我们的模型训练更加有效,还可以根据平滑结果找出数据中的离群点,是我们做数据分析和研究的一个好帮手,非常有价值。

以上就是python库Tsmoothie模块数据平滑化异常点抓取的详细内容,更多关于python Tsmoothie异常点抓取的资料请关注三水点靠木其它相关文章!


Tags in this post...

Python 相关文章推荐
Python的for和break循环结构中使用else语句的技巧
May 24 Python
解决python大批量读写.doc文件的问题
May 08 Python
python web自制框架之接受url传递过来的参数实例
Dec 17 Python
python3 tkinter实现添加图片和文本
Nov 26 Python
Python中itertools的用法详解
Feb 07 Python
Python callable内置函数原理解析
Mar 05 Python
TensorFLow 数学运算的示例代码
Apr 21 Python
Python基于gevent实现高并发代码实例
May 15 Python
Python基于httpx模块实现发送请求
Jul 07 Python
python 装饰器的使用示例
Oct 10 Python
Selenium+BeautifulSoup+json获取Script标签内的json数据
Dec 07 Python
python中对列表的删除和添加方法详解
Feb 24 Python
使用Django框架创建项目
Jun 10 #Python
Python实现信息管理系统
Jun 05 #Python
python实现学员管理系统(面向对象版)
Jun 05 #Python
python实现学生信息管理系统(面向对象)
Jun 05 #Python
Python使用pyecharts控件绘制图表
Jun 05 #Python
Python使用openpyxl模块处理Excel文件
Jun 05 #Python
Python中requests库的用法详解
Jun 05 #Python
You might like
PHP反射类ReflectionClass和ReflectionObject的使用方法
2013/11/13 PHP
微信营销平台系统?刮刮乐的开发
2014/06/10 PHP
php获取YouTube视频信息的方法
2015/02/11 PHP
PHP判断浏览器、判断语言代码分享
2015/03/05 PHP
php通过array_merge()函数合并关联和非关联数组的方法
2015/03/18 PHP
Smarty分页实现方法完整实例
2016/05/11 PHP
微信网页授权(OAuth2.0) PHP 源码简单实现
2016/08/29 PHP
关于jQuery中的end()使用方法
2011/07/10 Javascript
Extjs单独定义各组件的实例代码
2013/06/25 Javascript
javascript表单验证使用示例(javascript验证邮箱)
2014/01/07 Javascript
jqTransform美化表单
2015/10/10 Javascript
jQuery实现从身份证号中获取出生日期和性别的方法分析
2016/02/25 Javascript
基于JavaScript实现表单密码的隐藏和显示出来
2016/03/02 Javascript
深入剖析JavaScript中的函数currying柯里化
2016/04/29 Javascript
解析JavaScript中的字符串类型与字符编码支持
2016/06/24 Javascript
分享一个原生的JavaScript拖动方法
2016/09/25 Javascript
关于AngularJs数据的本地存储详解
2017/01/20 Javascript
jquery easyui DataGrid简单示例
2017/01/23 Javascript
JS实现的简单分页功能示例
2018/08/23 Javascript
纯javascript前端实现base64图片下载(兼容IE10+)
2018/09/14 Javascript
create-react-app使用antd按需加载的样式无效问题的解决
2019/02/26 Javascript
js判断浏览器的环境(pc端,移动端,还是微信浏览器)
2020/12/24 Javascript
Vue如何跨组件传递Slot的实现
2020/12/14 Vue.js
[02:28]DOTA2亚洲邀请赛附加赛 RECAP赛事回顾
2015/01/29 DOTA
关于Python中浮点数精度处理的技巧总结
2017/08/10 Python
Python爬取视频(其实是一篇福利)过程解析
2019/08/01 Python
Python中PyQt5/PySide2的按钮控件使用实例
2019/08/17 Python
python元组和字典的内建函数实例详解
2019/10/22 Python
python3.7.3版本和django2.2.3版本是否可以兼容
2020/09/01 Python
CSS3 RGBA色彩模式使用实例讲解
2016/04/26 HTML / CSS
《长城》教学反思
2014/02/14 职场文书
应聘英语教师求职信
2014/04/24 职场文书
吨的认识教学反思
2014/04/27 职场文书
超市店庆活动方案
2014/08/31 职场文书
综合管理员岗位职责
2015/02/11 职场文书
2016年“世界气象日”广播稿
2015/12/17 职场文书