CustomDateFeatureSet returns summed array from dates

This commit is contained in:
Dr. Kashif Rasul
2020-06-16 18:38:53 +02:00
parent 9ac375a89d
commit e063a64ccc
3 changed files with 82 additions and 48 deletions
+8 -1
View File
@@ -1,4 +1,11 @@
from .holiday import SPECIAL_DATE_FEATURES, SpecialDateFeatureSet, CustomDateFeatureSet, CustomHolidayFeatureSet
from .holiday import (
SPECIAL_DATE_FEATURES,
SpecialDateFeatureSet,
CustomDateFeatureSet,
CustomHolidayFeatureSet,
squared_exponential_kernel,
exponential_kernel,
)
from .lag import get_lags_for_frequency, get_fourier_lags_for_frequency
from .time_feature import (
DayOfMonth,
+43 -33
View File
@@ -63,10 +63,7 @@ BlackFriday = Holiday(
"Black Friday", month=11, day=1, offset=[pd.DateOffset(weekday=TH(4)), Day(1)]
)
CyberMonday = Holiday(
"Cyber Monday",
month=11,
day=1,
offset=[pd.DateOffset(weekday=TH(4)), Day(4)],
"Cyber Monday", month=11, day=1, offset=[pd.DateOffset(weekday=TH(4)), Day(4)],
)
@@ -151,7 +148,7 @@ class SpecialDateFeatureSet:
Example use:
>>> from gluonts.time_feature.holiday import (
>>> from pts.features import (
... squared_exponential_kernel,
... SpecialDateFeatureSet,
... CHRISTMAS_DAY,
@@ -219,13 +216,13 @@ class SpecialDateFeatureSet:
for feat_name in self.feature_names
]
)
class CustomDateFeatureSet:
"""
Implements calculation of holiday features. The CustomDateFeatureSet is
applied on a pandas Series with Datetimeindex and returns a 2D array of
the shape (len(dates), num_features), where num_features are the number
of holidays.
Implements calculation of date features. The CustomDateFeatureSet is
applied on a pandas Series with Datetimeindex and returns a 1D array of
the shape (1, len(date_indices)).
Note that for lower than daily granularity the distance to the holiday is
still computed on a per-day basis.
@@ -233,26 +230,34 @@ class CustomDateFeatureSet:
Example use:
>>> import pandas as pd
>>> cfs = CustomDateFeatureSet([pd.to_datetime('20191129', format='%Y%m%d'), pd.to_datetime('20200101', format='%Y%m%d')], kernel)
>>> cfs = CustomDateFeatureSet([pd.to_datetime('20191129', format='%Y%m%d'),
... pd.to_datetime('20200101', format='%Y%m%d')])
>>> date_indices = pd.date_range(
... start="2019-11-24",
... end="2019-12-31",
... freq='D'
... )
>>> cfs(date_indices)
array([[1., 0., 0., 0., 0., 0., 0., 0.],
[0., 1., 0., 0., 0., 0., 0., 0.]])
array([[0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
0., 0., 0., 0., 0., 0.]])
Example use for using a squared exponential kernel:
>>> kernel = squared_exponential_kernel(alpha=1.0)
>>> cfs = CustomDateFeatureSet([pd.to_datetime('20191129', format='%Y%m%d'), pd.to_datetime('20200101', format='%Y%m%d')], kernel)
>>> kernel = squared_exponential_kernel(alpha=0.5)
>>> cfs = CustomDateFeatureSet([pd.to_datetime('20191129', format='%Y%m%d'),
... pd.to_datetime('20200101', format='%Y%m%d')], kernel)
>>> cfs(date_indices)
array([[1.00000000e+00, 3.67879441e-01, 1.83156389e-02, 1.23409804e-04,
1.12535175e-07, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[3.67879441e-01, 1.00000000e+00, 3.67879441e-01, 1.83156389e-02,
1.23409804e-04, 1.12535175e-07, 0.00000000e+00, 0.00000000e+00]])
array([[3.72665317e-06, 3.35462628e-04, 1.11089965e-02, 1.35335283e-01,
6.06530660e-01, 1.00000000e+00, 6.06530660e-01, 1.35335283e-01,
1.11089965e-02, 3.35462628e-04, 3.72665317e-06, 1.52299797e-08,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
1.52299797e-08, 3.72665317e-06, 3.35462628e-04, 1.11089965e-02,
1.35335283e-01, 6.06530660e-01]])
"""
def __init__(
@@ -282,18 +287,22 @@ class CustomDateFeatureSet:
dates
Pandas series with Datetimeindex timestamps.
"""
return np.vstack(
[
np.hstack(
[
self.kernel_function((index - ref_date).days)
for index in dates
]
)
for ref_date in self.reference_dates
]
return (
np.vstack(
[
np.hstack(
[
self.kernel_function((index - ref_date).days)
for index in dates
]
)
for ref_date in self.reference_dates
]
)
.sum(0, keepdims=True)
)
class CustomHolidayFeatureSet:
"""
Implements calculation of holiday features. The CustomHolidayFeatureSet is
@@ -306,7 +315,7 @@ class CustomHolidayFeatureSet:
Example use:
>>> from gluonts.time_feature.holiday import (
>>> from pts.features import (
... squared_exponential_kernel,
... SpecialDateFeatureSet,
... CHRISTMAS_DAY,
@@ -373,4 +382,5 @@ class CustomHolidayFeatureSet:
)
for custom_holiday in self.custom_holidays
]
)
)
+31 -14
View File
@@ -43,7 +43,7 @@ from pts.feature.holiday import (
squared_exponential_kernel,
exponential_kernel,
CustomDateFeatureSet,
CustomHolidayFeatureSet
CustomHolidayFeatureSet,
)
test_dates = {
@@ -105,7 +105,13 @@ test_dates = {
CHRISTMAS_EVE: ["2016-12-24", "2017-12-24", "2018-12-24", "2019-12-24"],
CHRISTMAS_DAY: ["2016-12-25", "2017-12-25", "2018-12-25", "2019-12-25"],
NEW_YEARS_EVE: ["2016-12-31", "2017-12-31", "2018-12-31", "2019-12-31"],
BLACK_FRIDAY: ["2016-11-25", "2017-11-24", "2018-11-23", "2019-11-29", "2020-11-27"],
BLACK_FRIDAY: [
"2016-11-25",
"2017-11-24",
"2018-11-23",
"2019-11-29",
"2020-11-27",
],
CYBER_MONDAY: ["2016-11-28", "2017-11-27", "2018-11-26", "2019-12-2", "2020-11-30"],
}
@@ -258,10 +264,14 @@ def test_special_date_feature_set_daily_squared_exponential():
sfs = SpecialDateFeatureSet([CHRISTMAS_EVE, CHRISTMAS_DAY], squared_exp_kernel)
computed_features = sfs(date_indices)
np.testing.assert_almost_equal(computed_features, reference_features, decimal=6)
def test_custom_date_feature_set():
ref_dates = [pd.to_datetime('20191129', format='%Y%m%d'), pd.to_datetime('20200101', format='%Y%m%d')]
ref_dates = [
pd.to_datetime("20191129", format="%Y%m%d"),
pd.to_datetime("20200101", format="%Y%m%d"),
]
kernel = exponential_kernel(alpha=1.0)
@@ -269,16 +279,22 @@ def test_custom_date_feature_set():
sfs = SpecialDateFeatureSet([BLACK_FRIDAY, NEW_YEARS_DAY], kernel)
date_indices = pd.date_range(
start=pd.to_datetime('20191101', format='%Y%m%d'),
end=pd.to_datetime('20200131', format='%Y%m%d'),
freq='D')
start=pd.to_datetime("20191101", format="%Y%m%d"),
end=pd.to_datetime("20200131", format="%Y%m%d"),
freq="D",
)
assert (
np.sum(cfs(date_indices) - sfs(date_indices).sum(0, keepdims=True)) == 0
), "Features don't match"
assert(np.sum(cfs(date_indices) - sfs(date_indices)) == 0), "Features don't match"
def test_custom_holiday_feature_set():
custom_holidays = [Holiday("New Years Day", month=1, day=1), Holiday("Christmas Day", month=12, day=25)]
custom_holidays = [
Holiday("New Years Day", month=1, day=1),
Holiday("Christmas Day", month=12, day=25),
]
kernel = exponential_kernel(alpha=1.0)
@@ -286,8 +302,9 @@ def test_custom_holiday_feature_set():
sfs = SpecialDateFeatureSet([NEW_YEARS_DAY, CHRISTMAS_DAY], kernel)
date_indices = pd.date_range(
start=pd.to_datetime('20191101', format='%Y%m%d'),
end=pd.to_datetime('20200131', format='%Y%m%d'),
freq='D')
start=pd.to_datetime("20191101", format="%Y%m%d"),
end=pd.to_datetime("20200131", format="%Y%m%d"),
freq="D",
)
assert(np.sum(cfs(date_indices) - sfs(date_indices)) == 0), "Features don't match"
assert np.sum(cfs(date_indices) - sfs(date_indices)) == 0, "Features don't match"