2009-08-31 14 views
10

Szukam nieliniowej procedury dopasowywania krzywych (prawdopodobnie najprawdopodobniej można znaleźć w R lub Pythonie, ale jestem otwarty na inne języki), która wymagałaby danych x, y i dopasować do niego krzywą.Znajdowanie krzywej pasującej do danych

Powinienem być w stanie określić jako ciąg wyrażenie, które chcę dopasować.

Przykłady:

"A+B*x+C*x*x" 
"(A+B*x+C*x*x)/(D*x+E*x*x)" 
"sin(A+B*x)*exp(C+D*x)+E+F*x" 

Co bym wyjść z tego jest co najmniej wartości stałych (A, B, C, itd.) I miejmy nadzieję statystyki o przydatności meczu.

Są to programy komercyjne, ale spodziewałem się, że w dzisiejszej bibliotece będzie można znaleźć coś tak powszechnego, jak pasujące do pożądanego wyrażenia w bibliotece językowej. Podejrzewam, że rzeczy optymalizacyjne SciPy mogą być w stanie to zrobić, ale nie widzę, że pozwala mi to zdefiniować równanie. Podobnie, nie mogę znaleźć dokładnie tego, czego chcę w R.

Czy jest to, czego szukam tam, czy muszę przetrenować własne? Nienawidzę tego robić, jeśli tam jest i mam problem ze znalezieniem go.


Edytuj: Chcę to zrobić, aby uzyskać nieco większą kontrolę nad procesem niż w przypadku LAB Fit. Interfejs LAB Fit jest okropny. Chciałbym też móc podzielić zakres na wiele części i mieć różne krzywe reprezentujące różne części zakresu. Ostatecznie wynik musi być w stanie (z prędkością) pokonać LUT z interpolacją liniową lub nie jestem zainteresowany.

W moim bieżącym zestawie problemów mam funkcje trig lub exp() i muszę wykonać je w czasie rzeczywistym 352 800 razy na sekundę (i używać tylko ułamka procesora). W związku z tym wykreślam krzywą i wykorzystuję dane do sterowania instalatorem krzywej, aby uzyskać tańsze przybliżenia. W dawnych czasach LUT były prawie zawsze rozwiązaniem, ale obecnie pomijanie wyszukiwań pamięci i przybliżanie jest czasami szybsze.

+0

Czy zdajesz sobie sprawę, że jest to naprawdę zły pomysł, statystycznie rzecz biorąc? Jeśli chcesz tylko elastyczne dopasowanie do danych, użyj elastycznego modelu, takiego jak less, splajny lub uogólnione modele addytywne. – hadley

+0

Nawet rozbicie zakresu na mniejsze zakresy jest kosztem, z którym muszę być ostrożny. Mam dostęp do wszelkiego rodzaju doskonałych interpolatorów dla danych audio, ale generalnie są one dla mnie zbyt intensywne obliczeniowo. Ogólnie rzecz biorąc, kiedy muszę zacząć rozbijanie zasięgu na kawałki, lepiej mi będzie z LUT. Aproksymacje krzywych są nadal bardzo przydatne w aplikacjach DSP. – Nosredna

Odpowiedz

8

Aby odpowiedzieć na twoje pytanie w ogólnym sensie (dotyczące estymacji parametrów w R) bez uwzględnienia specyfiki wskazanych równań, myślę, że szukasz nls() lub optymalizacji() ..."nls" to mój pierwszy wybór, ponieważ zapewnia szacunki błędów dla każdego szacowanego parametru, a gdy się nie uda, używam "optymalizacji". Jeśli masz X, zmienne Y:

out <- tryCatch(nls(y ~ A+B*x+C*x*x, data = data.frame(x,y), 
       start = c(A=0,B=1,C=1)) , 
       error=function(e) 
       optim(c(A=0,B=1,C=1), function(p,x,y) 
         sum((y-with(as.list(p),A + B*x + C*x^2))^2), x=x, y=y)) 

aby uzyskać współczynniki, coś

getcoef <- function(x) if(class(x)=="nls") coef(x) else x$par 
getcoef(out) 

Jeśli chcesz standardowe błędy w przypadku 'nls'

summary(out)$parameters 

Pliki pomocy i posty na liście mailingowej r-help zawierają wiele dyskusji na temat konkretnych algorytmów minimalizacji zaimplementowanych przez każdą z nich (domyślna w każdym przypadku powyżej) i ich stosowności dla konkretnego f orm równania w zasięgu ręki. Niektóre algorytmy mogą obsługiwać ograniczenia ramek, a inna funkcja o nazwie constrOptim() będzie obsługiwać zestaw więzów liniowych. Ta strona może pomóc także:

http://cran.r-project.org/web/views/Optimization.html

+0

Czy mogę podawać formułę jako ciągi znaków? – Nosredna

+1

yes - coś takiego jak as.formula (wklej ("y", "A + B * x + C * x^2", sep = "~")) powinno to zrobić. – hatmatrix

+0

który był w przypadku Nls, w optym coś jak eval (parse (text = sprintf ("sum ((y-% s)^2)", "A + B * x + C * x^2"))) powinien działać (pokazana jest konstrukcja sprintf, dzięki czemu można wstawić pożądaną formułę). – hatmatrix

1

Zapoznaj się z GNU Octave - między jego polyfit() i nieliniowym rozwiązaniem ograniczeń powinno być możliwe skonstruowanie czegoś odpowiedniego dla twojego problemu.

+0

Używam czasem Oktawy. Zobaczę, co mogę wymyślić. – Nosredna

8

Twój pierwszy model jest rzeczywiście liniowego w trzech parametrów i może być fit w R stosując

fit <- lm(y ~ x + I(x^2), data=X) 

który będzie Ci swoje trzy parametry.

Drugi model można również dopasować za pomocą nls() w R ze zwykłymi ostrzeżenia o konieczności zapewnienia wartości zaczynające itp statystycznych zagadnienia optymalizacji niekoniecznie są takie same jak liczbowych kwestii - nie można po prostu optymalizuj dowolną formę funkcjonalną, niezależnie od wybranego języka.

+3

Mimo, że lepiej Ci będzie z 'y ~ poly (x, 2)' lub 'y ~ ns (x, 2)' – hadley

1

Prawdopodobnie nie znajdziesz pojedynczej rutyny z elastycznością implikowaną w twoich przykładach (wielomiany i racjonalne funkcje używające tej samej procedury), nie mówiąc już o tym, który przeanalizuje ciąg, aby dowiedzieć się, jaki rodzaj równania pasuje .

Monter wielomianu najmniejszych kwadratów byłby odpowiedni dla pierwszego przykładu. (To od ciebie zależy, jakiego stopnia wielomian użyje - kwadratu, sześcienny, kwartowy itd.). Aby uzyskać racjonalną funkcję, jak na przykład w drugim przykładzie, może być konieczne "przetasowanie", jeśli nie można znaleźć odpowiedniej biblioteki.Należy również pamiętać, że do uzyskania "prawdziwej" funkcji można użyć wystarczająco wielomianu o wysokim stopniu, o ile nie trzeba ekstrapolować poza granice zestawu danych, do którego pasujesz.

Jak zauważyli inni, istnieją inne, bardziej uogólnione algorytmy szacowania parametrów, które mogą okazać się przydatne. Ale te algorytmy nie są całkiem "plug and play": zwykle wymagają napisania pewnych procedur pomocniczych i dostarczenia listy wartości początkowych dla parametrów modelu. Te algorytmy mogą się rozbieżności lub utknąć w lokalnym minimum lub maksimum dla pechowego wyboru wstępnych oszacowań parametrów.

+0

Kiedy używam komercyjnych produktów, zazwyczaj nie mam pojęcia, co będzie najlepsze. LAB Fit wypróbuje kilkaset równań, aby zobaczyć, które dane najlepiej pasują do podanego zakresu. – Nosredna

+0

Nie brałem pod uwagę tego przypadku użycia - jeśli jesteś na wczesnym etapie próby scharakteryzowania zestawu danych, sensowne jest wypróbowanie kilku rodzin funkcji (liniowych, wielomianowych, prawa mocy, okresowych ...) aby zobaczyć, jak może wyglądać dobre dopasowanie. Odpowiednio edytuję swoją odpowiedź. –

+0

"Te algorytmy mogą się różnić ..." Tak, zakładam, że programy komercyjne po prostu wyskakują, kiedy to nastąpi podczas sprawdzania wszystkich opcji. Pozwalają grać z wartościami początkowymi, gdy wybierzesz jedno wyrażenie na raz. – Nosredna

1

W R, to całkiem proste.

Metoda wbudowana nazywa się optim(). Jako argumenty przyjmuje początkowy wektor potencjalnych parametrów, a następnie funkcję. Musisz zbudować własną funkcję błędu, ale to naprawdę proste.

Wtedy nazywają to podoba out = Optim (1), err_fn

gdzie err_fn jest

err_fn = function(A) { 
    diff = 0; 
    for(i in 1:data_length){ 
     x = eckses[i]; 
     y = data[i]; 
     model_y = A*x; 
     diff = diff + (y - model_y)^2 
    } 
    return(diff); 
} 

To właśnie zakłada masz wektor z X i Y wartości w eckses i danych. Zmień linię model_y zgodnie z oczekiwaniami, a nawet dodaj więcej parametrów.

Działa nieliniowo, używam go do czterowymiarowych krzywych e^x i jest bardzo szybki. Dane wyjściowe zawierają wartość błędu na końcu dopasowania, która jest miarą tego, jak dobrze pasuje, podana jako suma kwadratów różnic (w moim err_fn).

EDYTOWANIE: Jeśli musisz wykonać model jako ciąg, możesz pozwolić interfejsowi użytkownika skonstruować cały proces dopasowania modelu jako skrypt R i załadować go w celu uruchomienia. R może pobierać tekst ze STDIN lub z pliku, więc nie powinno być zbyt trudno tworzyć odpowiednik ciągu znaków tej funkcji i automatycznie uruchamiać optymalizację.

+0

Ale dlaczego nie używać nls() w R? –

+0

Nie używam nls z dwóch powodów, po pierwsze, lubię być w stanie ręcznie spreparować funkcję błędu, aby być zoptymalizowany, a po drugie, nie jestem tak naprawdę doświadczony z R. So nls() robi to, co napisałem tam ? Schludny. – Karl

+0

Moim ostatecznym celem jest przekazanie listy strun i sprawdzenie, czy kod wypróbował wszystkie, aby znaleźć najlepsze dopasowanie. – Nosredna

1

jeśli masz ograniczenia co do współczynników i wiesz, że istnieje specyficzny typ funkcji, który chcesz dopasować do danych i ta funkcja jest nieczytelna, gdy wygrywają standardowe metody regresji lub inne metody dopasowywania krzywych ' t pracujesz, czy zastanawiałeś się nad algorytmami genetycznymi?

to nie mój pierwszy wybór, ale jeśli próbujesz znaleźć współczynniki drugiej funkcji, o której wspomniałeś, to być może GA zadziałają - zwłaszcza jeśli używasz niestandardowych danych do oceny najlepszego dopasowania. na przykład, jeśli chcesz znaleźć współczynniki "(A + Bx + Cx^2)/(Dx + Ex^2)" takie, że suma kwadratowych różnic między twoją funkcją a danymi jest minimalna i, pewne ograniczenia na długość kolumny wynikowej funkcji, a zatem algorytm stochastyczny może być dobrym sposobem na zbliżenie się do tego.

Niektóre zastrzeżenia: 1) algorytmy stochastyczne nie będą gwarantować rozwiązania najlepsze, ale często będą bardzo blisko. 2) musisz uważać na stabilność algorytmu.

na dłuższą notatkę, jeśli jesteś na etapie, w którym chcesz znaleźć funkcję z jakiejś przestrzeni funkcji, która najlepiej pasuje do twoich danych (np. Nie będziesz narzucać, powiedzmy, drugiego modelu na twoich danych), mogą też pomóc techniki programowania genetycznego.

+0

To interesujący pomysł. Pomyślę o tym. Oczywiście, byłby powolny. Komercyjne programy przebiegają setki wzorów równań w kilka sekund. – Nosredna

+0

tak, kolejną wadą jest to, że algorytmy stochastyczne mogą być wolne. na plus można jednak uzyskać formularz równania poza zbiorem programów komercyjnych. poprzez zezwolenie programowi genetycznemu na przeszukiwanie * klas * funkcji (z operacjami na tych funkcjach), takich jak funkcje mocy, wykładniki, logarytmy, funkcje trygonometryczne, pdf/cdfs itp. możliwe jest znalezienie rozwiązania, które nie zostało rozwiązane zestaw form równania. ale znowu z drugiej strony, wymaga to rozsądnego wysiłku przy kodowaniu z wyprzedzeniem, który może nie być warty swojej chwili. –

+0

Jestem zawsze gotowy na przygodę z quiksotami. – Nosredna

Powiązane problemy