2017-02-10 37 views
2

Я пытаюсь соответствовать синусоиде волны этого распределение данных, но по какой-то причине, подгонка неправилен:Python - кривой подходят производить неправильное прилегание

import matplotlib.pyplot as plt 
import numpy as np 
import scipy as sp 
from scipy.optimize import curve_fit 





#======================= 
#====== Analysis ======= 
#======================= 

# sine curve fit 
def fit_Sin(t, A, b, C): 
    return A* np.sin(t*b) + C 

## The Data extraciton 
t,y,y1 = np.loadtxt("new10_CoCore_5to20_BL.txt", unpack=True) 

xdata = t 
popt, pcov = curve_fit(fit_Sin, t, y) 
print "A = %s , b = %s, C = %s" % (popt[0], popt[1], popt[2]) 



#======================= 
#====== Plotting ======= 
#======================= 

fig1 = plt.figure() 
ax1 = fig1.add_subplot(111) 

ax1.plot(t, y, ".") 
ax1.plot(t, fit_Sin(t, *popt)) 


plt.show() 

enter image description here

В которой это подходит делает чрезмерную недооценку данных. Любые идеи, почему это так?

Вот при условии, что данные здесь: https://www.dropbox.com/sh/72jnpkkk0jf3sjg/AAAb17JSPbqhQOWnI68xK7sMa?dl=0

Любая идея, почему это производит это?

ответ

3

Синусоидальные волны чрезвычайно сложны, если угасание частоты отключено. Это связано с тем, что при достаточном количестве циклов в данных предположение будет не в фазе с половиной данных и в фазе с половиной из них даже при небольшой ошибке частоты. В этот момент прямая линия лучше подходит, чем синусоидальная волна разной частоты. Вот как кстати работают преобразования Фурье.

я могу думать о трех способов оценки частоты достаточно хорошо, чтобы линейный алгоритм наименьших квадратов не взять на себя:

  1. Eyeball его. Вычтите значения x двух пиков в графическом интерфейсе или даже в командной строке. Если у вас очень низкий уровень шума, вы можете легко автоматизировать этот процесс.
  2. Использование дискретного преобразования Фурье. Если ваши данные являются синусоидальной волной одного компонента, первый непостоянный пик даст вам частоту. Я нашел, что это требует некоторой дополнительной настройки, поскольку частота выборки часто не кратная синусоидальной частоте. Параболический подход к трем точкам вокруг пика (три, включая пик) может помочь в этой ситуации.
  3. Найти, где ваши данные пересекают вертикальное смещение. Это похоже на # 1, но легче автоматизировать относительно относительно нешуточные данные. Длина волны вдвое превышает расстояние между двумя пересечениями.

Использование # 1, я могу ясно видеть, что ваша длина волны равна 50. Таким образом, первоначальное предположение для b должно быть 2*np.pi/50. Кроме того, не забудьте добавить параметр фазового сдвига, чтобы позволить посадке скользить по горизонтали: A*sin(b*t + d) + C.

Вам необходимо передать первоначальное предположение через параметр p0 в curve_fit. Хорошая оценка глазного яблока - p0=(0.55, np.pi/25, 0.0, -np.pi/25*12.5). Фазовый сдвиг в ваших данных, по-видимому, составляет четверть периода справа, следовательно, 12,5.

Я сейчас в процессе написания алгоритма для установки шумных синусоидальных волн с одним частотным компонентом, который я отправлю в SciPy. Будет обновляться, когда я закончу.

+0

У меня был некоторый успех с использованием генетического алгоритма, чтобы обеспечить начальные оценки параметров, но мой опыт в том, что ваше предложение # 1, кажется, работает лучше всего. Обратите внимание, что начальная оценка параметра для «C» здесь - это просто среднее значение данных. –

+0

@JamesPhillips. Для достаточно винтовых данных (на самом деле я видел примеры) лучше сначала оценить амплитуду, затем взять половину расстояния между пиками. Но, честно говоря, помимо частоты, фазовый сдвиг является единственным параметром, который изредка занимает более 2 или 3 итераций 'curve_fit', чтобы пригнуться. –

+0

Мой план состоял в том, чтобы сделать Dumbed KDE, чтобы получить более надежную частоту, чем FFT –