【Python】学习时序模型没有数据怎么办?自己造!

授人以鱼,不如授人以渔! 云朵君今天给大家分享一个时间序列数据生成方法!简单好用!云朵君致力于知识分享,希望能够在大家奋斗的路上出一份薄力,文末给大家带来了由清华大学出版社出版的《Python机器学习》免费送书给大家!

云朵君之前分享过不少时间序列相关文章,有时间序列基本概念介绍、有基本模型介绍、也有时间序列分析与预测实战案例。我发现,很多小伙伴私信云朵君,说的最多的就是需要案例数据。其实云朵君分享的文章,重点是介绍基本方法的使用,演示所用数据仅仅是用来演示,很多情况下并没有实际意义。这个时候,我们就不必纠结于数据本身。

为此,云朵君教大家自动动手,生成学习时间序列分析和预测过程中,缺少练手数据的问题。当然,大家也可以举一反三,用这样的方法去生成更多适用于其他应用场景的实验数据。

时序数据生成原理

一般而言,数据是由函数生成的,而周期性时间序列数据可以使用由余弦函数来生成。

余弦型函数是实践中广泛应用的一类重要函数,指函数ωφ(其中,ω,φ均为常数,且,ω)。这里A称为振幅,ω 称为圆频率或角频率,φ 称为初相位或初相角,正弦型函数ωφ是周期函数,其周期为πω。

但由于正常的余弦型函数是单调周期性函数,生成的函数图像如下图所示:

ea41a02bdb66fdb61e17c20d200f2c46.png

这样的数据太过理想,与现实相差很大。现实中的时序数据具有大量的噪声,因此此时我们只需要加上随机振幅和随机偏移就能生存具有噪声的时间序列数据。

接下来我们一步一步实现具有真实场景的随机时间序列数据。

生成时间序列索引

def get_init_df():
    # 生成时间序列索引
    date_rng = pd.date_range(start="2015-01-01", end="2020-01-01", freq="D")
    dataframe = pd.DataFrame(date_rng, columns=["timestamp"])
    dataframe["index"] = range(dataframe.shape[0])
    dataframe["article"] = uuid4().hex 
    # UUID 为 32 个字符的十六进制字符串
    return dataframe
  
get_init_df().head()
ea24c23ed176fe99e07e317b529cba96.png

设置振幅

生成随机振幅的函数,我们选用

其中:

  • 为最大振幅,(0.1, 1)之间的随机数

  • 为最大步幅,(90, 365) 中的随机整数

  • 为偏移,(-1, 1)之间的随机数

最后为了增加随机性,每次生成,都有50%的机会正序或倒序排列。

def set_amplitude(dataframe):

    max_step = random.randint(90, 365)
    max_amplitude = random.uniform(0.1, 1)
    offset = random.uniform(-1, 1)

    phase = random.randint(-1000, 1000)

    amplitude = (
        dataframe["index"]
        .apply(lambda x: max_amplitude * (x % max_step + phase) / max_step + offset)
        .values
    )
    
    # 每次生成,都有50%的机会正序或倒序排列
    if random.random() < 0.5:
        amplitude = amplitude[::-1]

    dataframe["amplitude"] = amplitude

    return dataframe
5a48201465f1dc1efb6c673833412644.png

设置偏移

生成随机偏移的函数,我们选用

其中

  • 为最大偏移,(-1, 1)之间的随机数

  • 为基础偏移,(-1, 1)之间的随机数

  • 为最大步幅,(15, 45) 中的随机整数

同样为了增加随机性,每次生成,都有50%的机会正序或倒序排列。

def set_offset(dataframe):
    max_step = random.randint(15, 45)
    max_offset = random.uniform(-1, 1)
    base_offset = random.uniform(-1, 1)

    phase = random.randint(-1000, 1000)

    offset = (
        dataframe["index"]
        .apply(
            lambda x: max_offset * np.cos(x * 2 * np.pi / max_step + phase)
            + base_offset
        )
        .values
    )

    if random.random() < 0.5:
        offset = offset[::-1]

    dataframe["offset"] = offset

    return dataframe
3fdb46fdd99373220a00b42f8a02b552.png

生成具有噪声的时序数据

生成随机时序数据的函数,我们选用余弦型函数

其中

  • 为生成的随机振幅:set_amplitude

  • 为生成的随机偏移:set_offset

  • 为周期:在 [7, 14, 28, 30] 中随机选择

  • 为初相位:(-1000, 1000)中的随机整数

为了增加随机性,这里有两个细节:

一是设置余弦函数的最大最小值范围,在(0.3, 1)中的随机数。而是在整个函数上加上一系列常数,使得每次生成的数据有一定的差别。该系列常数分布满足是从0到最大振幅之间生成的正态分布。

def generate_time_series(dataframe):
  periods = [7, 14, 28, 30]
    clip_val = random.uniform(0.3, 1)
    period = random.choice(periods)
    phase = random.randint(-1000, 1000)

    dataframe["views"] = dataframe.apply(
        lambda x: np.clip(
            np.cos(x["index"] * 2 * np.pi / period + phase), -clip_val, clip_val
        )
        * x["amplitude"]
        + x["offset"],
        axis=1,
    ) + np.random.normal(
        0, dataframe["amplitude"].abs().max() / 10, size=(dataframe.shape[0],)
    )

    return dataframe
33d9da4da627fb97666728f901c71804.png

多次生成的数据样式是不同的:

0969128319e878f076198b665525981d.png

最后我们多次生成,并合并数据:

dataframes = []
for _ in tqdm(range(20)):
  df = generate_df()
  # 简单绘图步骤
  # fig = plt.figure()
  # plt.plot(df[-120:]["index"], df[-120:]["views"])
  # plt.show()

  dataframes.append(df)
  all_data = pd.concat(dataframes, ignore_index=True)

得到如下形状的时间序列数据。

d8d35f51ed7ebed90ca9a353580706ce.png

季节性分解

最后,我们使用时间序列季节性分解,看下分解结果。从结果看,基本符合我们日常学习使用。

from statsmodels.tsa.seasonal import seasonal_decompose
df = generate_df()
df = df.set_index(['timestamp'])
result_mul = seasonal_decompose(df['views'], 
             model='additive', 
             extrapolate_trend='freq')

plt.rcParams.update({'figure.figsize': (10, 10)})
result_mul.plot().suptitle('Additive Decompose')
plt.show()
2c6ddf69b346c84ea0094e8b56ab1722.png

写在最后

以上就是本次所有内容,本次介绍的所有生成函数中的参数,均可以根据实际需要修改,如最大振幅,最大步长等。

 
 
 
 
 
 
 
 
 
 
往期精彩回顾




适合初学者入门人工智能的路线及资料下载(图文+视频)机器学习入门系列下载中国大学慕课《机器学习》(黄海广主讲)机器学习及深度学习笔记等资料打印《统计学习方法》的代码复现专辑机器学习交流qq群955171419,加入微信群请扫码:

0adf3d2bf044884d4f7ffc18f0789b56.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值