Feature-based Slow Feature Analysis
Project description
fsfa: feature-based slow feature analysis
About
Feature-based slow feature analysis (f-SFA) is an approach to parameter inference from a non-stationary unknown process (PINUP) comprising sliding-window computation of multivariate time series of canonical time-series features followed by dimension reduction using slow feature analysis.
Given a time series measured from a non-stationary process for which variation in dynamical properties is governed by some time-varying parameter (TVP), f-SFA is an unsupervised method for inferring the TVP directly from the time series.
This package provides a python implementation licensed under an MIT license.
Acknowledgement :
If you use this software, please read and cite this open-access article:
- 📗 Owens et al. Parameter inference from a non-stationary unknown process using statistical feature-based slow feature analysis, arXiv (In Preparation).
For details on the parameter inference from a non-stationary unknown process (PINUP) problem see:
- 📗 Owens et al. Parameter inference from a non-stationary unknown process, Chaos: An Interdisciplinary Journal of Nonlinear Science (2024).
Installation
Using pip for fsfa:
pip install fsfa
Usage
import fsfa
# dataset for analysis
X = np.random.random((10000, 2)) # (or more interesting data)
# option 1: compute a time series of time-series features
df = fsfa.feature_embedding(X, window=1000, stride=100)
# option 2: f-SFA
fsfa1 = fsfa.fSFA(X, window=1000, stride=100, n_components=1)
Example: non-stationary logistic map
Here we use the chaotic logistic map to simulate a non-stationary process:
import fsfa
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
# logistic map function
def logistic_map(x, r):
return r*x*(1-x)
# time varying parameter (tvp)
T = 10**5
time = np.linspace(0, 1, T, endpoint=0)
tvp = np.sin(2*np.pi*5*time) +\
np.sin(2*np.pi*11*time) +\
np.sin(2*np.pi*13*time)
# non-stationary time series with initial condition x=0.6
X = np.zeros((T, 1), 'd')
X[0] = 0.6
for i in range(1,T):
X[i] = logistic_map(X[i-1],3.6+0.13*tvp[i])
Plot the time-varying parameter and non-stationary logistic map process:
# plot tvp and X
fig = plt.figure(layout="constrained", figsize=(8, 4))
mosaic = """
A
B
"""
ax = fig.subplot_mosaic(mosaic)
ax["A"].plot(range(T), tvp, linewidth=1)
ax["A"].set_ylabel('r')
ax["B"].scatter(range(T), X, s=0.01, c='black')
ax["B"].set_ylabel('x')
ax["B"].set_xlabel('Timestep')
for loc in "AB":
ax[loc].spines['top'].set_visible(False)
ax[loc].spines['right'].set_visible(False)
Use f-SFA to infer a time varying parameter directly from the time-series data:
# single-component f-SFA
window, stride = 1000, 100
fsfa1 = fsfa.fSFA(X, window=window, stride=stride, n_components=1)
Compute mean values of the time-varying parameter over the same windows as f-SFA and use linear regression to align the f-SFA and TVP for plotting:
# time points at which to evaluate window features
time_points = np.arange(0, T - window + 1, stride)
window_indices = np.array([np.arange(t, t + window) for t in time_points])
tvp_means = [np.mean(tvp[indices]) for indices in window_indices]
# linear projection to align the time series for plotting
model = LinearRegression().fit(X=fsfa1, y=tvp_means)
projection = model.predict(fsfa1)
# plot the TVP and the f-SFA component
fig, ax = plt.subplots(figsize=(8,2))
ax.plot(tvp_means, c='black', lw=2, label='r')
ax.plot(projection, label='f-SFA', lw=2, linestyle='--', c='#3fadaf')
ax.set_xlabel('Window')
ax.legend(frameon=False)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# compute Pearson R^2 correlation
R2 = round(np.corrcoef(tvp_means, fsfa1.flatten())[0,1]**2, 3)
ax.text(800, -2.3, r'$R^2=$' + f'{R2}')
Usage notes
- The default time-series featureset used in f-SFA is catch24, but there are other keyword options ('mean', 'meanvar', 'quatiles', 'stft', 'catch24'). Alternatively, a list of time-series statistic functions can be passed as a list.
fsfauses thesklearn-sfapackage to perform SFA. Keyword arguments to the underlying SFA function can be passed to fSFA using a dictionary. Important SFA arguments can be found in thesklearn-sfadocumentation, including fill_mode, svd_solver, and robustness_cutoff.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fsfa-0.2.1.tar.gz.
File metadata
- Download URL: fsfa-0.2.1.tar.gz
- Upload date:
- Size: 7.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b97d4b018fe181a70d07c7067546ae4037b6273885c6ef062b2b69fc24efa4d
|
|
| MD5 |
333489777ff25df1cb2e8b08b56ffaaa
|
|
| BLAKE2b-256 |
a2dd7dd567dcaee6343a82bc62e758fc026e1c76d2434c38d87973707743e9cd
|
File details
Details for the file fsfa-0.2.1-py3-none-any.whl.
File metadata
- Download URL: fsfa-0.2.1-py3-none-any.whl
- Upload date:
- Size: 8.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
60b61b39561d6aaf64e92a83d2c3c896be80f2fd4b3126e6a83b65fcc8be8aa1
|
|
| MD5 |
01beeb72bc2c698162b6680d69c4cfa4
|
|
| BLAKE2b-256 |
6e6210ef4b006ebadf7201c8a102329cca57058d35f9411d32a731d926a2780a
|