Robię badania, ale utknąłem na etapie analizy (powinienem był poświęcić więcej uwagi wykładom statystyk).
Zebrałem dwa jednoczesne sygnały: zintegrowane natężenie przepływu dla objętości i zmiany w rozszerzaniu klatki piersiowej. Chciałbym porównać sygnały i ostatecznie mam nadzieję uzyskać głośność na podstawie sygnału rozszerzania klatki piersiowej. Ale najpierw muszę wyrównać / zsynchronizować moje dane.
Ponieważ nagrywanie nie rozpoczyna się dokładnie w tym samym czasie, a ekspansja klatki piersiowej jest rejestrowana przez dłuższy czas, muszę znaleźć dane, które odpowiadają moim danym objętości w zestawie danych ekspansji klatki piersiowej, i mam miarę, w jakim stopniu są one wyrównane. Nie jestem do końca pewien, jak to zrobić, jeśli dwa sygnały nie zaczynają się dokładnie w tym samym czasie lub między danymi w różnych skalach i przy różnych rozdzielczościach.
Dołączyłem przykład dwóch sygnałów ( https://docs.google.com/spreadsheet/ccc?key=0As4oZTKp4RZ3dFRKaktYWEhZLXlFbFVKNmllbGVXNHc ), proszę dać mi znać, jeśli jest coś jeszcze, co mogę podać.
źródło
Odpowiedzi:
Pytanie brzmi, jak znaleźć wielkość, o jaką jeden szereg czasowy („rozszerzenie”) jest opóźniony względem drugiego („objętość”), gdy serie są próbkowane w regularnych, ale różnych odstępach czasu.
W tym przypadku obie serie zachowują się w sposób dość ciągły, jak pokazują liczby. Oznacza to (1), że początkowe wygładzenie może być niewielkie lub wcale (2) ponowne próbkowanie może być tak proste, jak interpolacja liniowa lub kwadratowa. Kwadrat może być nieco lepszy ze względu na gładkość. Po ponownym próbkowaniu opóźnienie znajduje się poprzez maksymalizację korelacji krzyżowej , jak pokazano w wątku: W przypadku dwóch serii danych próbkowanych z przesunięciem, jakie jest najlepsze oszacowanie przesunięcia między nimi? .
Aby to zilustrować , możemy użyć danych dostarczonych w pytaniu, wykorzystując
R
pseudokod. Zacznijmy od podstawowej funkcjonalności, korelacji krzyżowej i ponownego próbkowania:Jest to prosty algorytm: obliczenia oparte na FFT byłyby szybsze. Ale dla tych danych (obejmujących około 4000 wartości) jest wystarczająco dobry.
Pobrałem dane jako plik CSV oddzielony przecinkami i usunąłem jego nagłówek. (Nagłówek spowodował pewne problemy z R, których nie chciałem zdiagnozować).
Uwaga: w tym rozwiązaniu założono, że każda seria danych jest uporządkowana w czasie, bez żadnych przerw w żadnej z nich. Pozwala to na wykorzystanie indeksów do wartości jako przybliżeń czasowych i skalowanie tych indeksów według częstotliwości próbkowania czasowego w celu konwersji ich na czasy.
Okazuje się, że jeden lub oba z tych instrumentów nieco z czasem dryfuje. Przed kontynuowaniem dobrze jest usunąć takie trendy. Ponadto, ponieważ na końcu występuje zwężający się sygnał głośności, powinniśmy go wyciąć.
Ponownie próbkuję rzadziej występującą serię, aby uzyskać jak największą precyzję wyniku.
Teraz można obliczyć korelację krzyżową - dla wydajności szukamy tylko rozsądnego okna opóźnień - i można określić opóźnienie, w którym można znaleźć maksymalną wartość.
Dane wyjściowe mówią nam, że ekspansja opóźnia głośność o 1,85 sekundy. (Jeśli ostatnie 3,5 sekundy danych nie zostały przycięte, wynik wyniósłby 1,84 sekundy.)
Dobrze jest sprawdzić wszystko na kilka sposobów, najlepiej wizualnie. Po pierwsze, funkcja korelacji krzyżowej :
Następnie zarejestrujmy dwie serie w czasie i narysujmy je razem na tych samych osiach .
Wygląda całkiem nieźle! Możemy jednak lepiej zrozumieć jakość rejestracji za pomocą wykresu rozrzutu . Zmieniam kolory według czasu, aby pokazać postęp.
Szukamy punktów do śledzenia tam iz powrotem wzdłuż linii: odmiany, które odzwierciedlają nieliniowości opóźnionej reakcji wzrostu na objętość. Chociaż istnieją pewne odmiany, są one dość małe. Jednak to, jak zmiany te zmieniają się w czasie, może budzić pewne zainteresowanie fizjologiczne. Cudowną cechą statystyki, zwłaszcza jej eksploracji i aspektu wizualnego, jest to, że tworzy dobre pytania i pomysły wraz z przydatnymi odpowiedziami.
źródło
acf
funkcji R.R
, kiedy opublikowałem tę odpowiedź i zapomniałem podać definicję tej funkcji. Oto oryginał:normalize <- function(x) { x.max <- max(x); x.min <- min(x); dx <- x.max - x.min; if (dx==0) dx <- 1; (x-x.min) / dx }