Используя numpy, вы можете дифференцировать, используя numpy.diff
, который может дать вам подсказку на основе определенного порога, в котором происходят ваши события. После того, как вы получите эти события, вы можете использовать numpy.correlate
между вашими событиями и входным сигналом, чтобы найти наиболее вероятные места, где происходят события.
корреляция
дифференциация
Последующее наблюдение
Если вы хотите полностью автоматизировать его для любого произвольного сигнала, должно быть какое-то машинное обучение где-то там Я не буду давать вам машинное обучение всем go сразу. Я, однако, дам вам указания относительно того, какие параметры могут рассматриваться как факторы в вашем al go.
Взгляните на следующее
import matplotlib.pyplot as plt
import numpy as np
y = [0, 1, 2,
.3, .4, .4, .6, .5, .4, .3, .4, .5, .6, .7, .6, .5, .4, .3, .5, .7, .8, .6, .3, .4, .5, .6, .5, .4, .3,
.3, .3, .3, .3, .3, 5, 4,
0, 1, 3, 4, 8, 9, 13, 10, 7, 4, 6, 3, 4, 3,
.3, 4, 4.4, 4.3, 3, 3.4, 3.2, 4, 3.8, 4, 6, 6, 5, 4, 1,
.3, .4, .5, .6, .5, .4, .3, .4, .5, .6, .7, .6, .3, .4, .3, .5, .7, .8, .6, .3, .4, .6, .6, .5, .4, .3,
0, 1, 3, 4, 6, 9, 13.5, 9.5, 7, 4, 6, 3, 4, 3,
.3, .4, .5, .4, .5, .4, .3, .4, .5, .6, .7, .6, .5, .4, .3, .5, .7, .8, .6, .3, .4, .5, .6, .5, .4, .3,
0, 1, 3, 4, 8, 9, 14, 10, 7, 4, 6, 3, 4, 3,
.3, 2, 1, 1,
2, 3, 4, 4.5, 4, 3, 2, 3, 4, 4, 4, 3, 2,
1, 2, 2, 1, 1,
2, 3, 4, 4, 4, 3, 2, 3, 4, 5, 4, 3, 2,
1, 2, 3, .2, .1, 0
]
x = 5 #Mean Convolution Window Width
v = np.full(x,1/x) #Convolution vector
y=np.convolve(y,v) #Apply X-Width Convolution on signal to get average between X samples
diff_y = np.abs(np.diff(y))
plt.figure()
plt.plot(diff_y)
plt.show()
diff_y_filtered=diff_y
diff_y_filtered[diff_y < 0.20*np.nanmax(diff_y)] = 0 #Differientiate the signal to look for large variations
plt.figure()
plt.plot(y)
plt.plot(diff_y_filtered)
plt.show()
diff_y_peaks = np.diff(diff_y_filtered) #Second derivative
diff_y_peaks = np.convolve(diff_y_peaks,[-1/8,-1/4,-1/2,1.75,-1/2,-1/4,-1/8]) #You may wanna tweak the filter
plt.figure()
plt.plot(diff_y_peaks)
plt.show()
diff_y_peaks[diff_y_peaks < 0.5] = 0; #This is a parameter that would be tweaked
diff_y_peaks[diff_y_peaks > 0]=np.nanmax(y) #Make things pretty
plt.figure()
plt.stem(diff_y_peaks)
plt.plot(y)
plt.show()
Первое и второе производные приходят на ум, потому что вы будете искать большие вариации, я полагаю, в сигнале. Даже если события сами содержат большие вариации, это не должно быть проблемой из-за фактора, который я укажу позже.
Сначала я сгладил сигнал, чтобы избежать больших вариаций внутри событий. Затем я применил первую производную, чтобы найти большие вариации. Я тогда срезал маленькие пики с порога. Значение этого порога может быть параметром в вашей модели.
Затем я фильтрую второй раз и снова сворачиваюсь. Вы можете настроить этот фильтр, чтобы получить лучшие результаты. Некоторые фильтры находят больше возможных точек отсечки, а некоторые - меньше. Это не имеет большого значения, если вы получаете много точек отсечки рядом друг с другом, потому что вы можете обучить свою модель, чтобы найти слишком малые длины событий, или вы можете напрямую указать, что, скажем, 2 точки отсечки на расстоянии 5 выборок не составляют событие.
Лично я считаю, что вы, возможно, захотите взглянуть на получение большего количества событий, содержащихся в более крупном событии, которое, вероятно, даст вам наилучшие результаты.