python一维时间序列平滑:移动平均、指数平滑、开尔曼滤波等

记录处理时间序列时需要用到的数据平滑方式
参考博客:
移动平均、指数平滑
三阶指数平滑
一阶指数平滑

1. 移动平均

import numpy as np
import pandas as pd
from pykalman import KalmanFilter

df = pd.DataFrame()
df["data"] = np.random.rand(20)
# 数据也可以是series格式

# 简单移动平均
simp_moving_avg = df["data"].rolling(window=window, min_periods=1).mean()
# 加权移动平均
weighted_moving_avg = df["data"].rolling(window=window, min_periods=1, win_type="cosine").mean()
# 指数加权移动平均
ewma = df["data"].ewm(alpha=alpha, min_periods=1).mean()

2. 指数平滑

一阶指数平滑

def exponential_smoothing(alpha, s):
    '''
    一次指数平滑
    :param alpha:  平滑系数
    :param s:      数据序列, list
    :return:       返回一次指数平滑模型参数, list
    '''
    s_temp = []
    s_temp.append(s[0])
    print(s_temp)
    for i in range(1, len(s), 1):
        s_temp.append(alpha * s[i-1] + (1 - alpha) * s_temp[i-1])
    return s_temp

二阶指数平滑

def double_exponential_smoothing(series, alpha, beta):
    """
        series - dataset with timeseries
        alpha - float [0.0, 1.0], smoothing parameter for level
        beta - float [0.0, 1.0], smoothing parameter for trend
    """
    # first value is same as series
    result = [series[0]]
    for n in range(1, len(series)+1):
        if n == 1:
            level, trend = series[0], series[1] - series[0]
        if n >= len(series): # forecasting
            value = result[-1]
        else:
            value = series[n]
        last_level, level = level, alpha*value + (1-alpha)*(level+trend)
        trend = beta*(level-last_level) + (1-beta)*trend
        result.append(level+trend)
    return result

三阶指数平滑(Holt-Winters):

def exponential_smoothing_3(alpha, s):
     '''
    三次指数平滑
    :param alpha:  平滑系数
    :param s:      数据序列, list
    :return:       返回三次指数平滑模型参数a, b, c, list
    '''
    s_single = exponential_smoothing(alpha, s)
    s_double = exponential_smoothing(alpha, s_single)
    s_triple = exponential_smoothing(alpha, s_double)
    
    a_triple = [0 for i in range(len(s))]
    b_triple = [0 for i in range(len(s))]
    c_triple = [0 for i in range(len(s))] 
    for i in range(len(s)):
        a_triple[i] = 3 * s_single[i] - 3 * s_double[i] + s_triple[i]
        b_triple[i] = (alpha / (2 * ((1 - alpha) ** 2))) * ((6 - 5 * alpha) * s_single[i] - 2 * ((5 - 4 * alpha) * s_double[i]) + (4 - 3 * alpha) * s_triple[i])
        c_triple[i] = ((alpha ** 2) / (2 * ((1 - alpha) ** 2))) * (s_single[i] - 2 * s_double[i] + s_triple[i])
    return a_triple, b_triple, c_triple
  

def predict_value_with_exp_smoothing_3(alpha,s):
      a,b,c=exponential_smoothing_3(alpha,s)
      s_temp=[]
      s_temp.append(a[0])
      for i in range(len(a)):
         s_temp.append(a[i]+b[i]+c[i])
     return s_temp
dataset=predict_value_with_exp_smoothing_3(alpha=0.2,s=dataset) 

3. 开尔曼滤波

def Kalman1D(x, damping=1):
    """
    卡尔曼滤波,缺点:耗时较长
    :param x 时间序列
    :damping 协方差,控制参数
    :return x_hat 平滑后的时间序列
    """
    # To return the smoothed time series data
    observation_covariance = damping
    initial_value_guess = x[0]
    transition_matrix = 1
    transition_covariance = 0.1
    kf = KalmanFilter(
        initial_state_mean=initial_value_guess,
        initial_state_covariance=observation_covariance,
        observation_covariance=observation_covariance,
        transition_covariance=transition_covariance,
        transition_matrices=transition_matrix
    )
    x_hat, state_cov = kf.smooth(x)
    return x_hat
  • 5
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值