Skip to content

Instantly share code, notes, and snippets.

@twolodzko
Last active June 12, 2018 08:53
Show Gist options
  • Select an option

  • Save twolodzko/7fd4d59d75e7a1a120dd9e03f2d7c607 to your computer and use it in GitHub Desktop.

Select an option

Save twolodzko/7fd4d59d75e7a1a120dd9e03f2d7c607 to your computer and use it in GitHub Desktop.
Radial Basis Functions Features for Time-Series Data
from __future__ import print_function
import numpy as np
class RadialBasisFunctions(object):
"""Radial Basis Functions features for time-series data
Parameters
----------
frequency : float
Frequency of the time series, e.g. 12 for monthly, 52 weekly, etc.
period : float
Period of the time series, e.g. 362.25 days for a year with daily data.
alpha : float or None
Scale for the RBF kernels. If None, it defaults to 0.5 * (period/frequency)**2.
centered : bool
Center RBF kernels.
Examples
--------
>>> import numpy as np
>>> rbf = RadialBasisFunctions(frequency=4, period=365.25)
>>> x = np.arange(0, 365.25*4)
>>> rbf.transform(x)
array([[0.60653066, 0.01111272, 0.01111272, 0.60653066],
[0.61981325, 0.01186396, 0.01040417, 0.59324805],
[0.63308293, 0.01266002, 0.00973624, 0.57997802],
...,
[0.56673287, 0.00910696, 0.01350311, 0.64632657],
[0.57997802, 0.00973624, 0.01266002, 0.63308293],
[0.59324805, 0.01040417, 0.01186396, 0.61981325]])
"""
def __init__(self, frequency, period, alpha=None, centered=True):
self.frequency = frequency
self.period = period
self.step = self.period / self.frequency
self.centered = centered
if alpha is None:
self.alpha = 0.5 * self.step*self.step
else:
self.alpha = 2 * alpha
def _kern(self, x, loc):
z = x-loc
return np.exp(-(z*z)/self.alpha)
def transform(self, x):
"""Transform the time-series indexes to Radial Basis Functions
Parameters
----------
X : array (n_samples,)
Time-series indexes.
Returns
-------
array, shape (n_samples, frequency)
RBF features.
"""
if isinstance(x, (list,)):
x = np.array(x)
if x.ndim > 1:
raise TypeError
one_period_earlier = (np.min(x) // self.period - 1) * self.period
if self.centered:
lower = one_period_earlier + self.step/2
else:
lower = one_period_earlier
lower = lower - self.period
upper = np.max(x) + self.period
out = np.zeros((x.shape[0], self.frequency))
for i,m in enumerate(np.arange(lower, upper, self.step)):
out[:, i % self.frequency] += self._kern(x, m)
return out
if __name__ == '__main__':
import doctest
doctest.testmod()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment