Generate patterns in time series¶
In [1]:
Copied!
import numpy as np
import matplotlib.pyplot as plt
from badgers.generators.time_series.patterns import add_linear_trend, add_offset, scale, Pattern, RandomlySpacedPatterns, RandomlySpacedLinearPatterns, RandomlySpacedConstantPatterns
import matplotlib.patches as patches
import numpy as np
import matplotlib.pyplot as plt
from badgers.generators.time_series.patterns import add_linear_trend, add_offset, scale, Pattern, RandomlySpacedPatterns, RandomlySpacedLinearPatterns, RandomlySpacedConstantPatterns
import matplotlib.patches as patches
Setup random generator¶
In [2]:
Copied!
from numpy.random import default_rng
seed = 0
rng = default_rng(seed)
from numpy.random import default_rng
seed = 0
rng = default_rng(seed)
Import data (using sktime)¶
In [3]:
Copied!
from sktime.datasets import load_airline
from sktime.datasets import load_airline
In [4]:
Copied!
X = load_airline()
t = X.index.to_timestamp()
X = load_airline()
t = X.index.to_timestamp()
In [5]:
Copied!
plt.plot(t, X.values)
plt.plot(t, X.values)
Out[5]:
[<matplotlib.lines.Line2D at 0x1ef8d8668d0>]
In [6]:
Copied!
p = Pattern(values=np.array([0,0.2,0.1,0.3,0.2,0.4,-0.4,-0.2,-0.3,-0.1,-0.2,-0.0]))
p = Pattern(values=np.array([0,0.2,0.1,0.3,0.2,0.4,-0.4,-0.2,-0.3,-0.1,-0.2,-0.0]))
In [7]:
Copied!
fig, ax = plt.subplots()
ax.plot(np.linspace(0,1,len(p.values)), p.values, 'o', ls='-', color='C0', label='original')
fig, ax = plt.subplots()
ax.plot(np.linspace(0,1,len(p.values)), p.values, 'o', ls='-', color='C0', label='original')
Out[7]:
[<matplotlib.lines.Line2D at 0x1ef8d8c57d0>]
Inject predefined patterns (randomly spaced)¶
In [8]:
Copied!
p = Pattern(values=np.array([0,0.2,0.1,0.3,0.2,0.4,-0.4,-0.2,-0.3,-0.1,-0.2,-0.0]))
generator = RandomlySpacedPatterns(random_generator=rng)
p = Pattern(values=np.array([0,0.2,0.1,0.3,0.2,0.4,-0.4,-0.2,-0.3,-0.1,-0.2,-0.0]))
generator = RandomlySpacedPatterns(random_generator=rng)
In [9]:
Copied!
Xt, _ = generator.generate(X.copy(), y=None, n_patterns=5, min_width_pattern=5, max_width_patterns=15, pattern=p)
Xt, _ = generator.generate(X.copy(), y=None, n_patterns=5, min_width_pattern=5, max_width_patterns=15, pattern=p)
In [10]:
Copied!
fig, axes = plt.subplots(2, sharex=True, sharey=True, figsize=(6,6))
axes[0].plot(t, X.values)
axes[0].set_title('Original data')
axes[1].plot(t, Xt)
axes[1].set_title('Transformed data')
# show where the patterns are located
bottom = np.min(Xt)
height = np.max(Xt) - np.min(Xt)
for start, end in generator.patterns_indices_:
width = t[end]-t[start]
left = t[start]
rect = plt.Rectangle((left, bottom), width, height,
facecolor="red", alpha=0.1)
axes[1].add_patch(rect)
plt.tight_layout();
fig, axes = plt.subplots(2, sharex=True, sharey=True, figsize=(6,6))
axes[0].plot(t, X.values)
axes[0].set_title('Original data')
axes[1].plot(t, Xt)
axes[1].set_title('Transformed data')
# show where the patterns are located
bottom = np.min(Xt)
height = np.max(Xt) - np.min(Xt)
for start, end in generator.patterns_indices_:
width = t[end]-t[start]
left = t[start]
rect = plt.Rectangle((left, bottom), width, height,
facecolor="red", alpha=0.1)
axes[1].add_patch(rect)
plt.tight_layout();
Generate patterns (subsequences) with constant values (randomly spaced)¶
In [11]:
Copied!
generator = RandomlySpacedConstantPatterns(random_generator=rng)
generator = RandomlySpacedConstantPatterns(random_generator=rng)
In [12]:
Copied!
Xt, _ = generator.generate(X.copy(), y=None, n_patterns=5, min_width_pattern=5, max_width_patterns=15, constant_value=0)
Xt, _ = generator.generate(X.copy(), y=None, n_patterns=5, min_width_pattern=5, max_width_patterns=15, constant_value=0)
In [13]:
Copied!
fig, axes = plt.subplots(2, sharex=True, sharey=True, figsize=(6,6))
axes[0].plot(t, X.values)
axes[0].set_title('Original data')
axes[1].plot(t, Xt)
axes[1].set_title('Transformed data')
# show where the patterns are located
bottom = np.min(Xt)
height = np.max(Xt) - np.min(Xt)
for start, end in generator.patterns_indices_:
width = t[end]-t[start]
left = t[start]
rect = plt.Rectangle((left, bottom), width, height,
facecolor="red", alpha=0.1)
axes[1].add_patch(rect)
plt.tight_layout();
fig, axes = plt.subplots(2, sharex=True, sharey=True, figsize=(6,6))
axes[0].plot(t, X.values)
axes[0].set_title('Original data')
axes[1].plot(t, Xt)
axes[1].set_title('Transformed data')
# show where the patterns are located
bottom = np.min(Xt)
height = np.max(Xt) - np.min(Xt)
for start, end in generator.patterns_indices_:
width = t[end]-t[start]
left = t[start]
rect = plt.Rectangle((left, bottom), width, height,
facecolor="red", alpha=0.1)
axes[1].add_patch(rect)
plt.tight_layout();
Generate patterns with constant slope (randomly spaced)¶
In [14]:
Copied!
generator = RandomlySpacedLinearPatterns(random_generator=rng)
generator = RandomlySpacedLinearPatterns(random_generator=rng)
In [15]:
Copied!
Xt, _ = generator.generate(X.copy(), y=None, n_patterns=5, min_width_pattern=5, max_width_patterns=15,)
Xt, _ = generator.generate(X.copy(), y=None, n_patterns=5, min_width_pattern=5, max_width_patterns=15,)
In [16]:
Copied!
fig, axes = plt.subplots(2, sharex=True, sharey=True, figsize=(6,6))
axes[0].plot(t, X.values)
axes[0].set_title('Original data')
axes[1].plot(t, Xt)
axes[1].set_title('Transformed data')
# show where the patterns are located
bottom = np.min(Xt)
height = np.max(Xt) - np.min(Xt)
for start, end in generator.patterns_indices_:
width = t[end]-t[start]
left = t[start]
rect = plt.Rectangle((left, bottom), width, height,
facecolor="red", alpha=0.1)
axes[1].add_patch(rect)
plt.tight_layout();
fig, axes = plt.subplots(2, sharex=True, sharey=True, figsize=(6,6))
axes[0].plot(t, X.values)
axes[0].set_title('Original data')
axes[1].plot(t, Xt)
axes[1].set_title('Transformed data')
# show where the patterns are located
bottom = np.min(Xt)
height = np.max(Xt) - np.min(Xt)
for start, end in generator.patterns_indices_:
width = t[end]-t[start]
left = t[start]
rect = plt.Rectangle((left, bottom), width, height,
facecolor="red", alpha=0.1)
axes[1].add_patch(rect)
plt.tight_layout();
In [17]:
Copied!
p = Pattern(values=np.array([0,0.2,0.1,0.3,0.2,0.4,-0.4,-0.2,-0.3,-0.1,-0.2,-0.0]))
p = Pattern(values=np.array([0,0.2,0.1,0.3,0.2,0.4,-0.4,-0.2,-0.3,-0.1,-0.2,-0.0]))
In [18]:
Copied!
upsampled_pattern = p.resample(nb_point=30)
downsampled_pattern = p.resample(nb_point=5)
fig, ax = plt.subplots()
ax.plot(np.linspace(0,1,len(p.values)), p.values, 'o', ls='-', color='C0', label='original')
ax.plot(np.linspace(0,1,len(upsampled_pattern)), upsampled_pattern, 'o', ls='--', color='C1', label='upsampled')
ax.plot(np.linspace(0,1,len(downsampled_pattern)), downsampled_pattern, 'o', ls='--', color='C2', label='downsampled')
plt.legend()
upsampled_pattern = p.resample(nb_point=30)
downsampled_pattern = p.resample(nb_point=5)
fig, ax = plt.subplots()
ax.plot(np.linspace(0,1,len(p.values)), p.values, 'o', ls='-', color='C0', label='original')
ax.plot(np.linspace(0,1,len(upsampled_pattern)), upsampled_pattern, 'o', ls='--', color='C1', label='upsampled')
ax.plot(np.linspace(0,1,len(downsampled_pattern)), downsampled_pattern, 'o', ls='--', color='C2', label='downsampled')
plt.legend()
Out[18]:
<matplotlib.legend.Legend at 0x1ef8fc4bbd0>
Add a linear trend to the pattern¶
The function add_linear_trend
takes three arguments: the values to be transformed, a start_value (were the new pattern should start) and end_value (where the new pattern should end)
In [19]:
Copied!
fig, ax = plt.subplots()
ax.plot(np.linspace(0,1,len(p.values)), p.values, 'o', ls='-', color='C0', label='original')
for i, (start, end) in enumerate([(0,0.5),(0.5,-0.5)]):
ax.plot(np.linspace(0,1,len(p.values)), add_linear_trend(p.values, start_value=start, end_value=end), 'o', ls='--', color=f'C{i+1}', label=f'trend ({start}, {end})')
plt.legend()
fig, ax = plt.subplots()
ax.plot(np.linspace(0,1,len(p.values)), p.values, 'o', ls='-', color='C0', label='original')
for i, (start, end) in enumerate([(0,0.5),(0.5,-0.5)]):
ax.plot(np.linspace(0,1,len(p.values)), add_linear_trend(p.values, start_value=start, end_value=end), 'o', ls='--', color=f'C{i+1}', label=f'trend ({start}, {end})')
plt.legend()
Out[19]:
<matplotlib.legend.Legend at 0x1ef902bb110>
Add an offset (bias) to the pattern¶
The function add_offset
takes two arguments: the values to be transformed and an offset (float or int)
In [20]:
Copied!
fig, ax = plt.subplots()
ax.plot(np.linspace(0,1,len(p.values)), p.values, 'o', ls='-', color='C0', label='original')
for i, offset in enumerate([0.5,-0.5]):
ax.plot(np.linspace(0,1,len(p.values)), add_offset(p.values, offset), 'o', ls='--', color=f'C{i+1}', label=f'offset ({offset})')
plt.legend()
fig, ax = plt.subplots()
ax.plot(np.linspace(0,1,len(p.values)), p.values, 'o', ls='-', color='C0', label='original')
for i, offset in enumerate([0.5,-0.5]):
ax.plot(np.linspace(0,1,len(p.values)), add_offset(p.values, offset), 'o', ls='--', color=f'C{i+1}', label=f'offset ({offset})')
plt.legend()
Out[20]:
<matplotlib.legend.Legend at 0x1ef8fe56310>
Scale a pattern¶
In [21]:
Copied!
fig, ax = plt.subplots()
ax.plot(np.linspace(0,1,len(p.values)), p.values, 'o', ls='-', color='C0', label='original')
for i, scaling_factor in enumerate([-0.5,2]):
ax.plot(np.linspace(0,1,len(p.values)), scale(p.values, scaling_factor), 'o', ls='--', color=f'C{i+1}', label=f'scale ({scaling_factor})')
plt.legend()
fig, ax = plt.subplots()
ax.plot(np.linspace(0,1,len(p.values)), p.values, 'o', ls='-', color='C0', label='original')
for i, scaling_factor in enumerate([-0.5,2]):
ax.plot(np.linspace(0,1,len(p.values)), scale(p.values, scaling_factor), 'o', ls='--', color=f'C{i+1}', label=f'scale ({scaling_factor})')
plt.legend()
Out[21]:
<matplotlib.legend.Legend at 0x1ef8fe33410>
In [ ]:
Copied!