Как указать лучший сплайн для этих данных - PullRequest
0 голосов
/ 11 декабря 2018
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import UnivariateSpline
x = [0,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]
y = [31031.4,35241.7,42320.8,38146.7,38345.9,42320.8,33649.2,42883.3,35459,36371.6,23259.8,53740.6,36971.6,29518.3,45773,51421.43,56303.5,38786,31956.4,42717,43026.88,58479.4,50628.24,33375.19,40332.36,52731.29,48409.99,62328.65,48409.99,53941.38,52736.68,55794.38,48180.88,42949.35,48234.66,49505.83,50629.87,25361.3,57403.21,46805.93,55834.61,24978.13,51037.43,46727.27,31766.46,21553.01,34017.05,31533.17]
plt.plot(x, y, 'ro', ms=5)
spl = UnivariateSpline(x, y)
print(spl.get_knots())
xs = np.linspace(0, 47, 1000)
plt.plot(xs, spl(xs), 'g', lw=3)
#spl.set_smoothing_factor(1000000000)
#plt.plot(xs, spl(xs), 'b', lw=3)
plt.show()

У меня есть график, где сплайн проходит через все точки (экран 1), но мне нужно изображение, как на экране 2.
Экран 1:

Экран 2:

1 Ответ

0 голосов
/ 11 декабря 2018

UnivariateSpline имеет параметр сглаживания s, см. здесь .

Положительный коэффициент сглаживания, используемый для выбора количества узлов.Количество узлов будет увеличиваться до тех пор, пока не будет выполнено условие сглаживания:

sum((w[i] * (y[i]-spl(x[i])))**2, axis=0) <= s

Поскольку ваши значения y достаточно велики, коэффициент сглаживания также должен быть большим (или вы могли бынормализуйте ваши данные, см. ниже).

spl = UnivariateSpline(x, y, s=1e9)

Выглядит так:

enter image description here

Нормализация:

spl = UnivariateSpline(x, y/np.max(y))
xs = np.linspace(0, 47, 1000)
plt.plot(xs, spl(xs)*np.max(y), 'g', lw=3)

Здесь s = len(w) (см. Ссылку, w - веса), что является значением по умолчанию.Участок:

enter image description here

spl = UnivariateSpline(x, y/np.max(y), s=float(len(y))*0.017)
xs = np.linspace(0, 47, 1000)
plt.plot(xs, spl(xs)*np.max(y), 'g', lw=3)

выглядит аналогично вашему участку:

enter image description here

...