-
Notifications
You must be signed in to change notification settings - Fork 18
/
series_fit_sine.csl
73 lines (68 loc) · 2.7 KB
/
series_fit_sine.csl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//
// series_fit_sine_sf() - Fit the best sine wave to a series using scipy.optimize.curve_fit
//
// The function appends the fitted series column to the original input table\n'
// The last input parameter is the expected seasonality which is used as a prior to the fitting process
//
.create function with (folder = "Packages\\Series", docstring = "Fit a sine wave to a series")
series_fit_sine_sf(tbl:(*), in_series:string, out_series:string, seasonality:long)
{
let kwargs = pack('in_series', in_series, 'out_series', out_series, 'seasonality', seasonality);
let code=
'\n'
'in_series = kargs["in_series"]\n'
'out_series = kargs["out_series"]\n'
'seasonality = kargs["seasonality"]\n'
'\n'
'from scipy.optimize import curve_fit\n'
'def fit(y, x, s):\n'
' def fit_func(t, gain, level, T, phase):\n'
' return gain * np.sin(t*2*np.pi/T-phase) + level\n'
' soft_min, med, soft_max = pd.Series(y).quantile([0.05, 0.5, 0.95])\n'
' popt, pcov = curve_fit(fit_func, x, y, p0=[(soft_min+soft_max)/2, med, s, 0])\n'
' return fit_func(x, *popt)\n'
'\n'
'x = np.arange(len(df[in_series][0]))\n'
'result = df\n'
'result[out_series] = df[in_series].apply(fit, args=(x, seasonality))\n'
;
tbl
| evaluate python(typeof(*), code, kwargs)
}
#connect cluster('demo11.westus.kusto.windows.net').database('ML')
//
// lambda - for debugging
//
let series_fit_sine_sf=(tbl:(*), in_series:string, out_series:string, seasonality:long)
{
let kwargs = pack('in_series', in_series, 'out_series', out_series, 'seasonality', seasonality);
let code=
'\n'
'in_series = kargs["in_series"]\n'
'out_series = kargs["out_series"]\n'
'seasonality = kargs["seasonality"]\n'
'\n'
'from scipy.optimize import curve_fit\n'
'def fit(y, x, s):\n'
' def fit_func(t, gain, level, T, phase):\n'
' return gain * np.sin(t*2*np.pi/T-phase) + level\n'
' soft_min, med, soft_max = pd.Series(y).quantile([0.05, 0.5, 0.95])\n'
' popt, pcov = curve_fit(fit_func, x, y, p0=[(soft_min+soft_max)/2, med, s, 0])\n'
' return fit_func(x, *popt)\n'
'\n'
'x = np.arange(len(df[in_series][0]))\n'
'result = df\n'
'result[out_series] = df[in_series].apply(fit, args=(x, seasonality))\n'
;
tbl
| evaluate python(typeof(*), code, kwargs)
};
//
// Test
//
let max_t = datetime(2016-09-03);
demo_make_series1
| make-series num=count() on TimeStamp from max_t-5d to max_t step 1h by OsVer
| extend fnum = dynamic(null)
| invoke series_fit_sine_sf('num', 'fnum', 24)
| render timechart