Skip to content

Commit ff42585

Browse files
committed
add validated LocalSimple feature
1 parent 8f617c4 commit ff42585

4 files changed

Lines changed: 92 additions & 3 deletions

File tree

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,7 @@ __13/07:__ 623 partialed functions, 2673 validated features
1414

1515
__18/07:__ 687 partialed functions, 3277 validated features
1616

17+
__20/07:__ 701 partialed functions, 3403 validated features
18+
1719
# Feature Conversion Progress...
18-
![](https://geps.dev/progress/46)
20+
![](https://geps.dev/progress/48)

pyhctsa/Configurations/basic.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,6 +1488,26 @@ ModelFit:
14881488
hctsa_name: MF_ExpSmoothing
14891489
ordered_args: ["ntrain", "alpha"]
14901490

1491+
LocalSimple:
1492+
base_name: LocalSimple
1493+
labels:
1494+
- models
1495+
- forecasting
1496+
- modelfit
1497+
dependencies:
1498+
configs:
1499+
- forecastMeth: "mean"
1500+
trainLength: [1, 2, 3, 4, 'ac']
1501+
zscore: True
1502+
- forecastMeth: "median"
1503+
trainLength: [3, 5, 7, 'ac']
1504+
zscore: True
1505+
- forecastMeth: "lfit"
1506+
trainLength: [2, 3, 4, 5, 'ac']
1507+
zscore: True
1508+
hctsa_name: FC_LocalSimple
1509+
ordered_args: ["forecastMeth", "trainLength"]
1510+
14911511
Graph:
14921512
VisibilityGraph:
14931513
base_name: VisibilityGraph

pyhctsa/Configurations/modelfit.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,24 @@ ModelFit:
4242
zscore: True
4343
hctsa_name: MF_arfit
4444
ordered_args: ["pmin", "pmax", "selector"]
45+
46+
LocalSimple:
47+
base_name: LocalSimple
48+
labels:
49+
- models
50+
- forecasting
51+
- modelfit
52+
dependencies:
53+
configs:
54+
- forecastMeth: "mean"
55+
trainLength: [1, 2, 3, 4, 'ac']
56+
zscore: True
57+
- forecastMeth: "median"
58+
trainLength: [3, 5, 7, 'ac']
59+
zscore: True
60+
- forecastMeth: "lfit"
61+
trainLength: [2, 3, 4, 5, 'ac']
62+
zscore: True
63+
hctsa_name: FC_LocalSimple
64+
ordered_args: ["forecastMeth", "trainLength"]
4565

pyhctsa/Operations/ModelFit.py

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,61 @@
11
import numpy as np
22
from numpy.typing import ArrayLike
33
from statsmodels.tsa.ar_model import AutoReg, ar_select_order
4+
from statsmodels.stats.diagnostic import acorr_ljungbox
45
from scipy.signal import lfilter
56
from pyhctsa.Operations.Correlation import AutoCorr
67
from scipy.stats import ks_1samp, norm, t
78
import numba
89
from typing import Union
9-
from pyhctsa.Utilities.utils import ZScore
10-
from statsmodels.stats.diagnostic import acorr_ljungbox
10+
from ..Utilities.utils import ZScore
11+
from ..Operations.Stationarity import SlidingWindow
12+
from ..Operations.Correlation import FirstCrossing, AutoCorr
1113

14+
def LocalSimple(y, forecastMeth = 'mean', trainLength = 3):
15+
y = np.asarray(y)
16+
N = len(y)
17+
# % Do the local prediction
18+
if trainLength == 'ac':
19+
lp = FirstCrossing(y, 'ac', 0, 'discrete')
20+
else:
21+
lp = trainLength # the length of the subsegment preceeding to use to predict the subsequent value
22+
evalr = np.arange(lp, N) #range over which to evaluate the forecast
23+
if np.size(evalr) == 0:
24+
print("This time series is too short for forecasting")
25+
return np.nan
26+
res = np.zeros(len(evalr))
27+
if forecastMeth == 'mean':
28+
for i in range(len(evalr)):
29+
res[i] = np.mean(y[evalr[i]-lp:evalr[i]]) - y[evalr[i]] # prediction - value
30+
elif forecastMeth == 'median':
31+
for i in range(len(evalr)):
32+
res[i] = np.median(y[evalr[i]-lp:evalr[i]]) - y[evalr[i]] # prediction - value
33+
elif forecastMeth == 'lfit':
34+
for i in range(len(evalr)):
35+
# Fit linear
36+
p = np.polyfit(np.arange(1, lp+1), y[evalr[i]-lp:evalr[i]], 1)
37+
res[i] = np.polyval(p, lp+1) - y[evalr[i]] # prediction - value
38+
else:
39+
raise ValueError(f"Unknown forecasting method: {forecastMeth}")
40+
41+
#Output statistics on the residuals, res
42+
#% Mean residual (mean error/bias):
43+
out = {}
44+
out['meanerr'] = np.mean(res)
45+
#% Spread of residuals:
46+
out['stderr'] = np.std(res, ddof=1)
47+
out['meanabserr'] = np.mean(np.abs(res))
48+
#% Stationarity of residuals:
49+
out['sws'] = SlidingWindow(res, 'std', 'std', 5, 1) # across five non-overlapping segments
50+
out['swm'] = SlidingWindow(res, 'mean', 'std', 5, 1) # across five non-overlapping segments
51+
#% TODO Normality of residuals:
52+
#% Autocorrelation structure of the residuals:
53+
out['ac1'] = AutoCorr(res, 1, 'Fourier')[0]
54+
out['ac2'] = AutoCorr(res, 2, 'Fourier')[0]
55+
out['taures'] = FirstCrossing(res, 'ac', 0, 'continuous')
56+
out['tauresrat'] = FirstCrossing(res, 'ac', 0, 'continuous')/FirstCrossing(y, 'ac', 0, 'continuous')
57+
58+
return out
1259

1360
def ExpSmoothing(x : ArrayLike, ntrain : Union[None, int, float] = None, alpha : Union[str, float] = 'best') -> dict:
1461
"""

0 commit comments

Comments
 (0)