-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfitter.py
47 lines (39 loc) · 1.61 KB
/
fitter.py
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
from typing import Callable, Dict
import scipy.optimize as optimization
import numpy as np
from sklearn.metrics import r2_score
Data = Dict[int, int]
ModelFn = Callable[[np.array, float, float], np.array]
Prediction = Callable[[float], float]
Fitter = Callable[[Data, ModelFn], Prediction]
class ModelFnPool:
def linear(x: np.array, a: float, b: float):
return a * x + b
class FitterPool:
def fit_leastsq(data: Data, fn: ModelFn) -> Prediction:
ret,_,_,_ = FitterPool.fit_leastsq_verbose(data,fn)
return ret
def fit_leastsq_verbose(data: Data, fn: ModelFn) -> (Prediction, int, int, int):
xs, ys = np.array(list(data.keys())), np.array(list(data.values()))
# print("[xs]", xs)
# print("[ys]", ys)
guess_k = (ys[-1]-ys[-2])/(xs[-1]-xs[-2])
guess_b = ys[0] - guess_k * xs[0]
popt, _ = optimization.curve_fit(ModelFnPool.linear, xs, ys, \
[guess_k, guess_b])
# print(popt)
ret = lambda x: fn(x, *popt)
r2 = r2_score(ys, ret(xs))
return ret,r2,popt[0],popt[1]
def fit_leastsq_verbose_offset(data: Data, fn: ModelFn, offset: int) -> (Prediction, int, int, int):
xs, ys = np.array(list(data.keys())), np.array(list(data.values()))
# print("[xs]", xs)
# print("[ys]", ys)
pys = [y-offset for y in ys]
guess_k = (pys[-1]-pys[-2])/(xs[-1]-xs[-2])
popt, _ = optimization.curve_fit(lambda x,k: k*x, xs, pys, \
[guess_k])
# print(popt)
ret = lambda x: fn(x, popt[0],offset)
r2 = r2_score(ys, ret(xs))
return ret,r2,popt[0],offset