• 时序预测 02


    同比环比的区别 百度百科

    同比,就是跟去年同期比,英文名 on year-on-year basis。
    环比,就是跟上一个周期比,就是相邻时间段的对比,一般是指报告期水平与前一时期水平之比.
    例如,去年3月的价格指数是100,今年3月的价格指数是105,那么今年3月价格同比增长5%.
    例如,今年2月的价格指数是105,今年3月的价格指数是105,那么今年3月价格环比增长为0.
    
    因此, Chain算法更像是环比,去历史最近一个周期的最大值和最小值进行评估异常点.
    

    参考链接

    一点调参总结

    • window: 同期比较的滑动窗口大小, 建议乘上周期数,再乘上一定的倍数; 如周期为7天,可以设置为7*4,适当扩大参考范围.

    • max_threshold: 最大值的倍数阈值, 高于该阈值判定为异常点

    • min_threshold: 最小值的倍数阈值, 低于该阈值判定为异常点

    • influence : 异常点的折算值, 避免异常值之后的所有的点都无法再判断为异常点 (借鉴了z-score的算法, 看上一篇)

    • output_multiples: 放大异常值结果的倍数, 默认为1

    复制粘贴下来就可以运行的Python程序

    # -*- coding: utf-8 -*-
    
    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    import math
    import datetime
    
    
    def paint_array(dfs=[], labels=[], title='输出字典测试'):
        assert len(dfs) == len(labels)
        plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文标签
        plt.rcParams['axes.unicode_minus'] = False
    
        plt.figure(figsize=(16, 8))
        for i in range(0, len(dfs)):
            plt.plot(dfs[i], label=labels[i])
        plt.legend(loc='best')
        plt.title(title + str(datetime.datetime.now()))
        plt.show()
    
    
    def chain_amplitude_algo(data):
        input_ids = [157]
        output_ids = [161]
        output_multiples = [1]
    
        for input_id, output_id, output_multiple in zip(input_ids, output_ids, output_multiples):
    
            # 设置chain各种参数 ,window为同期相比的滑动窗口大小, window乘上回归周期 * 4*7
            window, max_threshold, min_threshold, influence = 8 * 2, 1.5, 0.5, 0.5
    
            y = data[input_id]['data_value']
    
            signals = np.zeros(len(y))
            filteredY = np.array(y)
            maxFilter = [0] * len(y)
            minFilter = [0] * len(y)
            maxFilter[window - 1] = np.max(y[0:window])
            minFilter[window - 1] = np.min(y[0:window])
            for i in range(window, len(y)):
                if filteredY[i] > maxFilter[i - 1] * max_threshold:
                    signals[i] = 1
                    filteredY[i] = filteredY[i] * influence + filteredY[i - 1] * (1.0 - influence)
                elif filteredY[i] < minFilter[i - 1] * min_threshold:
                    signals[i] = -1
                    filteredY[i] = filteredY[i] * influence + filteredY[i - 1] * (1.0 - influence)
    
                maxFilter[i] = np.max(y[i - window: i])
                minFilter[i] = np.min(y[i - window: i])
    
            series_dict = dict(signals=np.asarray(signals * output_multiple),
                               maxFilters=np.asarray(maxFilter),
                               minFilters=np.asarray(minFilter)
                               )
    
            data[output_id] = data[input_id].copy()
            data[output_id]['data_value'] = np.asarray(series_dict['signals'])
    
            # 绘图
            paint_array(dfs=[signals, maxFilter, minFilter, np.asarray(y)],
                        labels=['signals', 'maxFilter', 'minFilter', 'y'])
    
    
    def paint(dfs=[], labels=[], title='暂无'):
        assert len(dfs) == len(labels)
        plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文标签
        plt.rcParams['axes.unicode_minus'] = False
    
        plt.figure(figsize=(16, 8))
        for i in range(0, len(dfs)):
            plt.plot(dfs[i]['data_value'], label=labels[i])
        plt.legend(loc='best')
        plt.title(title + str(datetime.datetime.now()))
        plt.show()
    
    
    if __name__ == '__main__':
        idx = pd.date_range('2020-01-01', periods=190, freq='D')
        # 构造一个周期为8*2的余弦函数
        cos_arr = np.arange(len(idx)) * np.pi / 8
        for i in range(0, len(cos_arr)):
            # 这里加一, 将余弦函数整体上移1个单位, 避免出现负值, 出现负值,会导致大量误判,
            cos_arr[i] = math.cos(cos_arr[i]) + 1
        # 人为制造4个异常点
        cos_arr[32] += 4
        cos_arr[44] -= 1
        # cos_arr[45] -= 2
        cos_arr[132] += 4
        cos_arr[182] += 4
        data_value = pd.Series(cos_arr, index=idx)
    
        df = pd.DataFrame({
            'data_time': idx,  # 时间列
            'data_value': data_value  # 数据列
        })
    
        data = {}
        data[157] = df
        data[161] = pd.DataFrame()
        chain_amplitude_algo(data)
    
        # paint(dfs=[data[157], data[161]], labels=['origin', 'signal'], title='origin模拟以天为周期的业务数据,signal模拟脉冲信号')
    
        """
        以上涉及的场景数据暂无负值,如有负值请改造min_threshold,特判最小值小于0时改为乘于一个大于1的数值
        """
    
    

    输出示例

    实际拟合

    注意点

    • 以上涉及的场景数据暂无负值,如有负值请改造min_threshold,特判最小值小于0时改为乘于一个大于1的数值, influence : 异常点的折算值,也要对应进行改造.
    你不逼自己一把,你永远都不知道自己有多优秀!只有经历了一些事,你才会懂得好好珍惜眼前的时光!
  • 相关阅读:
    Android:在eclipse中快速多行注释的方法
    DB2中若何除去SELECT输入的头信息
    哄骗DB2look重新设立建立优化器访谒操持(1)
    利用DB2look 从头创建优化器访问经营(2)
    运用DB2look重新建立优化器会晤企图(5)
    运用DB2look重新建立优化器访问摒挡(9)
    实例理睬IBM DB2的数据复制、迁移设置装备摆设
    DB2数据库优化的几条根底战略
    使用DB2look从头树立优化器拜候经营(6)
    哄骗DB2look重新创立优化器访谒企图(7)
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/13571223.html
Copyright © 2020-2023  润新知