时间序列异常值处理方法

ops/2024/12/22 19:22:13/

文章目录

  • 一、删除法
  • 二、替换法
  • 三、插值法
  • 四、滑动窗口
  • 五、基于模型的替换

时间序列相关参考文章:
时间序列预测算法—ARIMA
时间序列预测算法—Prophet
时间序列分类任务—tsfresh
python时间序列处理
有季节效应的非平稳序列分析
时间序列异常值检测方法
时间序列异常值处理方法

一、删除法

python">import pandas as pd
from scipy.stats import zscore
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 黑体
plt.rcParams['axes.unicode_minus'] = False    # 负号正常显示data = pd.read_excel('data.xlsx')
data['ZScore'] = zscore(data['电量'])outliers_removed = data[data['ZScore'].abs() <= 3]
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(15, 6))axes[0].plot(data['date'],data['电量'], color='blue', alpha=0.6)
axes[0].set_title('Original Data')
axes[0].set_xlabel('date')
axes[0].set_ylabel('电量')
axes[0].grid(True)axes[1].plot(outliers_removed['date'],outliers_removed['电量'], color='green', alpha=0.6)
axes[1].set_title('Cleaned Data')
axes[1].set_xlabel('date')
axes[1].set_ylabel('电量')
axes[1].grid(True)
plt.show()

在这里插入图片描述

二、替换法

  替换法中包括均值中位数众数等。下图只展示中位数可视化方法,均值,众数修改计算条件同中位数。

python">import pandas as pd
from scipy.stats import zscore
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 黑体
plt.rcParams['axes.unicode_minus'] = False    # 负号正常显示# 读取数据
data = pd.read_excel('data.xlsx')# 计算 Z-score
data['ZScore'] = zscore(data['电量'])# 设置阈值来识别异常值,Z-score 大于 3 的被认为是异常值
threshold = 3# 计算中位数
median_value = data['电量'].median()  #26659.4476
#mean_value = data['电量'].mean()  #26533.86 均值# 将异常值替换为中位数,生成新的数据集
cleaned_data = data.copy()  # 创建数据的副本
cleaned_data['电量'] = cleaned_data.apply(lambda row: median_value if abs(row['ZScore']) > threshold else row['电量'], axis=1
)# 重新计算 Z-score 以确认替换后的数据
cleaned_data['ZScore'] = zscore(cleaned_data['电量'])# 绘图
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(15, 6))# 原始数据图
axes[0].plot(data['date'], data['电量'], color='blue', alpha=0.7)
axes[0].set_title('Original Data with Outliers')
axes[0].set_xlabel('Date')
axes[0].set_ylabel('电量')
axes[0].grid(True)# 清理后的数据图
axes[1].plot(cleaned_data['date'], cleaned_data['电量'], color='green', alpha=0.7)
axes[1].set_title('Cleaned Data (Outliers Replaced)')
axes[1].set_xlabel('Date')
axes[1].set_ylabel('电量')
axes[1].grid(True)
plt.show()

在这里插入图片描述

三、插值法

  线性插值:使用邻近的正常值进行插值。通常适用于时间序列数据,替换方法就是在异常值前后点之间进行线性插值。方法:value = (time_series[i-1] + time_series[i+1]) / 2 或者使用更复杂的插值函数。
  多项式插值:适用于时间序列变化呈非线性趋势时,可以使用低次多项式进行插值。
  前向/后向填充:对于短期的突发异常,可以选择用前一个或后一个正常值来填充,特别是对于电力、金融等行业的数据。方法:value = previous_value 或 value = next_value

  • 线性插值
python">import pandas as pd
from scipy.stats import zscore
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 黑体
plt.rcParams['axes.unicode_minus'] = False    # 负号正常显示data = pd.read_excel('data.xlsx')
data['ZScore'] = zscore(data['电量']) # 计算 Z-scorethreshold = 3 # 设置阈值来识别异常值,Z-score 大于 3 的被认为是异常值
outliers = abs(data['ZScore']) > threshold # 标记异常值位置replaced_data = data.copy()
# 将异常值标记为 NaN(缺失值),以便进行插值
replaced_data['电量'] = replaced_data['电量'].where(~outliers, other=None)
replaced_data['电量'] = replaced_data['电量'].interpolate(method='linear') # 使用线性插值替换异常值fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(15, 6))
# 原始数据图
axes[0].plot(data['date'], data['电量'], color='blue', alpha=0.7)
axes[0].set_title('Original Data with Outliers')
axes[0].set_xlabel('Date')
axes[0].set_ylabel('电量')
axes[0].grid(True)
# 清理后的数据图
axes[1].plot(replaced_data['date'], replaced_data['电量'], color='green', alpha=0.7)
axes[1].set_title('Cleaned Data (Outliers Replaced with Linear Interpolation)')
axes[1].set_xlabel('Date')
axes[1].set_ylabel('电量')
axes[1].grid(True)
plt.show()

在这里插入图片描述

  • 前后项填充
python">import pandas as pd
from scipy.stats import zscore
import matplotlib.pyplot as plt
# 设置中文显示和负号显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 黑体
plt.rcParams['axes.unicode_minus'] = False    # 负号正常显示data = pd.read_excel('data.xlsx')
data['ZScore'] = zscore(data['电量']) # 计算 Z-scorethreshold = 3 # 设置阈值来识别异常值,Z-score 大于 3 的被认为是异常值
outliers = abs(data['ZScore']) > threshold # 标记异常值位置replaced_data = data.copy()
replaced_data['电量'] = replaced_data['电量'].where(~outliers, other=None) # 将异常值标记为 NaN(缺失值)# 使用前向填充法(前后值插值)
# replaced_data['电量'] = replaced_data['电量'].ffill() # 前向填充
replaced_data['电量'] = replaced_data['电量'].bfill()  # 后向填充(若前向无值)fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(15, 6))
# 原始数据图
axes[0].plot(data['date'], data['电量'], color='blue', alpha=0.7)
axes[0].set_title('Original Data with Outliers')
axes[0].set_xlabel('Date')
axes[0].set_ylabel('电量')
axes[0].grid(True)# 清理后的数据图
axes[1].plot(replaced_data['date'], replaced_data['电量'], color='green', alpha=0.7)
axes[1].set_title('Cleaned Data (Outliers Replaced with Forward/Backward Fill)')
axes[1].set_xlabel('Date')
axes[1].set_ylabel('电量')
axes[1].grid(True)
plt.show()

在这里插入图片描述

四、滑动窗口

  使用滑动窗口方法计算异常值的周围均值、中值或其他统计量,将异常值替换为滑动窗口内的均值或中值。例如,使用一个固定大小的窗口,在窗口内计算统计量,并用窗口中心的统计值替换异常点。

python">import pandas as pd
from scipy.stats import zscore
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']  # 黑体
plt.rcParams['axes.unicode_minus'] = False    # 负号正常显示data = pd.read_excel('data.xlsx')# 计算 Z-score
data['ZScore'] = zscore(data['电量'])# 设置阈值来识别异常值,Z-score 大于 3 的被认为是异常值
threshold = 3# 设置异常值前后的窗口大小
window_size = 3# # 用附近的平均值替换异常值
# for i in range(window_size, len(data) - window_size):  # 遍历数据,跳过前后 window_size 天
#     # 检查当前点是否是异常值
#     if abs(data['ZScore'][i]) > threshold:
#         # 获取当前点的前后窗口数据,计算窗口内的平均值
#         window_values = data['电量'][i - window_size:i + window_size + 1]
#         mean_value = window_values.mean()#         # 替换异常值为附近的平均值
#         replaced_data.loc[i, '电量'] = mean_value # 使用 rolling() 函数计算窗口内的均值 (如:前后 3 天,即 7 天窗口)
rolling_mean = data['电量'].rolling(window=2*window_size + 1, min_periods=1).mean()# 创建数据副本以保存清理后的数据
replaced_data = data.copy()# 替换异常值为附近的平均值
for i in range(window_size, len(data) - window_size):  # 遍历数据,跳过前后 window_size 天if abs(data['ZScore'][i]) > threshold:  # 如果是异常值replaced_data.loc[i, '电量'] = rolling_mean[i]  # 用滚动窗口均值替换异常值# 重新计算 Z-score 以确认替换后的数据
replaced_data['ZScore'] = zscore(replaced_data['电量'])# 绘图
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(15, 6))# 原始数据图
axes[0].plot(data['date'], data['电量'], color='blue', alpha=0.7)
axes[0].set_title('Original Data with Outliers')
axes[0].set_xlabel('Date')
axes[0].set_ylabel('电量')
axes[0].grid(True)# 替换后的数据图
axes[1].plot(replaced_data['date'], replaced_data['电量'], color='green', alpha=0.7)
axes[1].set_title('Data with Outliers Replaced by Nearby Mean')
axes[1].set_xlabel('Date')
axes[1].set_ylabel('电量')
axes[1].grid(True)# 显示图表
plt.show()

在这里插入图片描述

五、基于模型的替换

  如果时间序列的数据模式较为复杂,简单的替换方法可能无法较好地处理异常。此时可以使用基于模型的方法来替代异常值:
  ARIMA 模型:使用时间序列建模的方法(如 ARIMA)来预测每个时刻的值,异常值可以通过模型的预测值进行替代。可参考时间序列ARIMA
  LSTM 或其他深度学习方法:对于具有长时间依赖性的序列数据,可以训练 LSTM 等神经网络模型来预测序列值,并用模型预测值替换异常值。
  在某些情况下,数据的异常值与其他特征存在一定的关系,可以使用回归模型(如线性回归、决策树回归)根据其他变量预测异常值的合理范围。
  线性回归法:可以利用时间序列的历史数据和其他相关变量来预测异常值的合理值。


http://www.ppmy.cn/ops/144101.html

相关文章

前端图表与数据可视化 - 2024 年实战与面试重点

前端图表与数据可视化 - 2024 年实战与面试重点 目录 前言前端数据可视化概述常用数据可视化库对比 3.1 D3.js3.2 ECharts3.3 Chart.js3.4 AntV 数据可视化中的实战技巧 4.1 如何选择合适的图表类型4.2 数据清洗与格式化4.3 响应式图表布局与交互 实战&#xff1a;构建实时数据…

6_HTML5 SVG (2) --[HTML5 API 学习之旅]

SVG 矩形 SVG&#xff08;Scalable Vector Graphics&#xff0c;可缩放矢量图形&#xff09;是一种基于 XML 的标记语言&#xff0c;用于描述二维图形。<rect> 是 SVG 中的一个基本形状元素&#xff0c;用来绘制矩形。下面我将提供四个不同场景下的 <rect> 示例&a…

网络安全——对称加密与非对称加密

对称加密与非对称加密是两种基本的加密技术&#xff0c;它们在保护数据安全方面起着重要作用。以下是对这两种加密技术的详细解释&#xff1a; 一、对称加密 定义&#xff1a;对称加密指的是加密和解密使用同一个密钥&#xff0c;也称为私钥加密或共享密钥加密。 原理&#x…

【Linux】socket编程1

socket编程1 1. 网络字节序2. ip地址转换函数3. sockaddr数据结构 1. 网络字节序 多字节数据有大端和小端之分&#xff0c;网络数据流采用大端字节序&#xff0c;如果主机采用的是小端字节序&#xff0c;那么需要转换。 大端&#xff1a;低地址存高字节&#xff0c;高地址存低…

Roblox踩坑1——动画无法完整播放

在做一款挂机类游戏的时候&#xff0c;打算给地图怪物做一个被击败动画&#xff0c;我就在击败怪物的回调里面加了一个动画&#xff0c;但是无论如何都没办法正常的播放。 if humanoid then-- 创建一个 Animation 实例并设置动画 IDlocal animation Instance.new("Anima…

simsCheckbox无序列表转换jquery插件

simsCheckbox是一款可以将普通的html无序列表转换为bootstrap样式的checkbox列表的jquery插件。 在线演示 下载 使用方法 在页面中引入bootstrap样式文件&#xff0c;jquery和simsCheckbox.css&#xff0c;以及simsCheckbox.js文件。 <link rel"stylesheet" hre…

【论文阅读】Deep Neural Network Pruning Using Persistent Homology

摘要和介绍 PHPM按照神经元之间的组合效应的大小的升序对DNN进行删减&#xff0c;以防止精度的下降&#xff0c;其中神经元之间的组合效应是利用一维PH计算的。 已经表明PH有利于分析DNN中知识的内部表示[6]&#xff0c;[23]。 [6] C. Corneanu, M. Madadi, S. Escalera, and…

基于SpringBoot的“家具销售电商平台”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“家具销售电商平台”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 管理员登录界面 管理员功能界面 家具分类管理…