Vraag Een curve vinden om overeen te komen met gegevens


Ik ben op zoek naar een niet-lineaire curve-aanpassingsroutine (waarschijnlijk waarschijnlijk te vinden in R of Python, maar ik sta open voor andere talen) waarvoor x, y-gegevens nodig zijn en er een curve naar passen.

Ik zou in staat moeten zijn om als een string het type expressie te specificeren dat ik wil passen.

Voorbeelden:

"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"

Wat ik eruit zou halen is tenminste de waarden voor de constanten (A, B, C, etc.) En hopelijk statistieken over de fitheid van de wedstrijd.

Er zijn commerciële programma's om dit te doen, maar ik verwachtte dat ik iets zo gebruikelijk zou kunnen vinden als passend bij een gewenste uitdrukking in een taalbibliotheek tegenwoordig. Ik vermoed dat SciPy's optimalisatiemateriaal dit misschien kan doen, maar ik kan niet zien dat het me een vergelijking laat definiëren. Evenzo kan ik niet lijken te vinden precies wat ik wil in R.

Is dat waar ik naar op zoek ben, of moet ik het zelf maken? Ik haat het om het te doen als het er is en ik heb gewoon problemen om het te vinden.


Bewerken: ik wil dit doen voor een beetje meer controle over het proces dan ik krijg van LAB Fit. De LAB Fit UI is vreselijk. Ik zou ook graag in staat zijn om het bereik in meerdere stukken te breken en verschillende curves hebben voor de verschillende delen van het bereik. Uiteindelijk moet het resultaat in staat zijn om (snel) een LUT te verslaan met lineaire interpolatie of ik ben niet geïnteresseerd.

In mijn huidige reeks problemen, heb ik trig functies of exp () en ik moet ze 352.800 keer per seconde in real time uitvoeren (en gebruik slechts een fractie van de CPU). Dus ik plot de curve en gebruik de gegevens om de curve-installateur aan te zetten om minder dure benaderingen te krijgen. In de oude dagen waren LUT's bijna altijd de oplossing, maar tegenwoordig worden de geheugenzoekfuncties overgeslagen en is een benadering soms sneller.


10
2017-08-31 16:35


oorsprong


antwoorden:


Om je vraag in algemene zin (met betrekking tot parameter schatting in R) te beantwoorden zonder de details van de vergelijkingen in aanmerking te nemen die je hebt aangegeven, denk ik dat je op zoek bent naar nls () of optim () ... 'nls' is mijn eerste keuze als het geeft foutramingen voor elke geschatte parameter en wanneer het mislukt, gebruik ik 'optim'. Als je je x, y variabelen hebt:

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) )

om de coëfficiënten te krijgen, zoiets

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

Als u de standaardfouten wilt in het geval van 'nls',

summary(out)$parameters

De helpbestanden en r-help-mailinglijstberichten bevatten vele discussies met betrekking tot specifieke minimaliseringsalgoritmen die door elk zijn geïmplementeerd (de standaard die in elk voorbeeld hierboven wordt gebruikt) en hun geschiktheid voor de specifieke vorm van de vergelijking bij de hand. Bepaalde algoritmen kunnen boxbeperkingen aan, en een andere functie met de naam constrOptim () zal een reeks lineaire beperkingen afhandelen. Deze website kan ook helpen:

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


8
2017-09-03 11:04



Je eerste model is eigenlijk lineair in de drie parameters en kan passen in R met

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

waarmee je je drie parameters krijgt.

Het tweede model kan ook geschikt zijn om te gebruiken nls() in R met de gebruikelijke voorbehouden voor het verstrekken van startwaarden enz statistischproblemen met optimalisatie zijn niet noodzakelijk hetzelfde als de numeriek problemen - u kunt niet elke functionele vorm optimaliseren, ongeacht de taal die u kiest.


8
2017-08-31 17:03



Uitchecken GNU Octave - tussen zijn polyfit () en de niet-lineaire beperkende oplosser moet het mogelijk zijn om iets te construeren dat geschikt is voor uw probleem.


1
2017-08-31 16:59



In R is dit vrij eenvoudig.

De ingebouwde methode heet optim (). Het neemt als argumenten een startvector van potentiële parameters, dan een functie. Je moet je eigen foutfunctie gaan bouwen, maar dat is heel eenvoudig.

Dan noem je het als out = optim (1, err_fn)

waar err_fn is

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);
}

Dit veronderstelt gewoon dat je een vector van x- en y-waarden hebt in eckses en data. Wijzig de regel model_y zoals u wilt, voeg zelfs meer parameters toe.

Het werkt prima op niet-lineair, ik gebruik het voor vier dimensionale e ^ x-curves en het is erg snel. De uitvoergegevens bevatten de foutwaarde aan het einde van de aanpassing, die een maat is voor hoe goed deze past, gegeven als een som van kwadratische verschillen (in mijn err_fn).

BEWERK: Als u het model als een string moet binnenhalen, kunt u uw gebruikersinterface dit hele aanpassingsproces voor modellen laten maken als een R-script en het laden om uit te voeren. R kan tekst meenemen uit STDIN of uit een bestand, dus het zou niet te moeilijk moeten zijn om het string-equivalent van deze functie te maken en het automatisch optimaal te laten werken.


1
2017-08-31 17:21



Je zult waarschijnlijk geen enkele routine vinden met de flexibiliteit die in je voorbeelden wordt geïmpliceerd (polynomen en rationale functies met dezelfde routine), laat staan ​​een routine die een reeks analyseert om erachter te komen wat voor soort vergelijking past.

Een klein-vierkantige polynomiale fitter zou geschikt zijn voor uw eerste voorbeeld. (Het is aan u in welke mate polynoom te gebruiken - quadradic, cubic, quartic, etc.). Voor een rationele functie zoals uw tweede voorbeeld, moet u mogelijk "zelf rollen" als u geen geschikte bibliotheek kunt vinden. Houd er ook rekening mee dat een voldoende hoge graad polynoom kan worden gebruikt om uw "echte" functie te benaderen, zolang u niet extrapoleert buiten de grenzen van de gegevensset waar u aan voldoet.

Zoals anderen hebben opgemerkt, zijn er andere, meer algemene parameterschattingsalgoritmen die ook nuttig kunnen zijn. Maar die algoritmen zijn niet echt "plug and play": ze vereisen meestal dat je een aantal helperroutines schrijft en een lijst met beginwaarden voor de modelparameters opgeeft. Het is mogelijk dat dit soort algoritmen afwijken, of vastlopen in een lokaal minimum of maximum voor een ongelukkige keuze van initiële parameterschattingen.


1
2017-08-31 17:04



als u beperkingen hebt op uw coëfficiënten en u weet dat er een specifiek type functie is dat u in uw gegevens zou willen passen en die functie is een rommelige situatie waarbij standaardregressiemethoden of andere methoden voor curve-aanpassing niet werken, hebben je overwoog genetische algoritmen?

ze zijn niet mijn eerste keuze, maar als je de coëfficiënten van de tweede functie probeert te vinden die je hebt genoemd, dan werken GA's misschien wel --- vooral als je niet-standaard statistieken gebruikt om de beste pasvorm te evalueren. bijvoorbeeld, als u de coëfficiënten van "(A + Bx + Cx ^ 2) / (Dx + Ex ^ 2)" zo wilt vinden dat de som van de vierkantsverschillen tussen uw functie en gegevens minimaal is en dat er enige beperking is aan de lengte van de resulterende functie, dan is een stochastisch algoritme een goede manier om dit te benaderen.

enkele kanttekeningen: 1) stochastische algoritmen kunnen de het beste oplossing, maar ze zullen vaak heel dichtbij zijn. 2) je moet voorzichtig zijn met de stabiliteit van het algoritme.

in een langere noot, als je in een stadium bent waar je een functie wilt vinden uit een aantal functies die het beste bij je gegevens passen (je gaat bijvoorbeeld niet het tweede model opleggen aan je gegevens), dan programmeertechnieken kunnen ook helpen.


1
2017-09-01 01:52