Tilpasning af Polynomregression i R

. (Du kan rapportere problem om indholdet på denne side her) vil du dele dit indhold på R-bloggere? Klik her, hvis du har en blog, eller her, hvis du ikke har det.

et lineært forhold mellem to variabler x og y er en af de mest almindelige, effektive og lette antagelser at tage, når man prøver at finde ud af deres forhold. Nogle gange dog, det sande underliggende forhold er mere komplekst end det, og det er når polynomisk regression kommer ind for at hjælpe.

lad se et eksempel fra økonomi: Antag at du gerne vil købe en bestemt mængde q af et bestemt produkt. Hvis enhedsprisen er p, betaler du et samlet beløb y. Dette er et typisk eksempel på et lineært forhold. Den samlede pris og mængde er direkte proportional. For at plotte det ville vi skrive noget som dette:

p <- 0.5q <- seq(0,100,1)y <- p*qplot(q,y,type='l',col='red',main='Linear relationship')

grunden vil se sådan ud:
linear-relationship

nu er dette en god tilnærmelse af det sande forhold mellem y og q , men når vi køber og sælger, vil vi måske overveje nogle andre relevante oplysninger, som: Købe betydelige mængder det er sandsynligt, at vi kan spørge og få en rabat, eller købe mere og mere af en bestemt vare, vi kan skubbe prisen op.
dette kan føre til et scenario som dette, hvor de samlede omkostninger ikke længere er en lineær funktion af mængden:

y <- 450 + p*(q-10)^3plot(q,y,type='l',col='navy',main='Nonlinear relationship',lwd=3)

Rplot02
med polynomisk regression kan vi passe modeller af orden n > 1 til dataene og forsøge at modellere ikke-lineære relationer.

Sådan passer du til en polynomregression

husk altid brug til set.seed(n) ved generering af pseudo tilfældige tal. Ved at gøre dette genererer random number generator altid de samme tal.

set.seed(20)

Predictor (k). Brug sekv til at generere lige adskilte sekvenser hurtigt

q <- seq(from=0, to=20, by=0.1)

værdi at forudsige (y):

y <- 500 + 0.4 * (q-10)^3

noget støj genereres og tilføjes til det virkelige signal (y):

noise <- rnorm(length(q), mean=10, sd=80)noisy.y <- y + noise

Plot af det støjende signal:

plot(q,noisy.y,col='deepskyblue4',xlab='q',main='Observed data')lines(q,y,col='firebrick1',lwd=3)

dette er plottet af vores simulerede observerede data. De simulerede datapunkter er de blå prikker, mens den røde linje er signalet (signal er et teknisk udtryk, der ofte bruges til at indikere den generelle tendens, vi er interesseret i at opdage).
Rplot03
vores model skal være noget som dette: y = a*spørgsmål + b*2 gange + c*3 gange + omkostninger

lad os passe det ved hjælp af R. ved montering af polynomer kan du enten bruge

model <- lm(noisy.y ~ poly(q,3))

eller

model <- lm(noisy.y ~ x + I(X^2) + I(X^3))

Bemærk dog, at q, I(q^2) og I(q^3) vil blive korreleret og korrelerede variabler kan forårsage problemer. Brugen af poly() lader dig undgå dette ved at producere ortogonale polynomer, derfor vil jeg bruge den første mulighed.

summary(model)Call:lm(formula = noisy.y ~ poly(q, 3))Residuals: Min 1Q Median 3Q Max -212.326 -51.186 4.276 61.485 165.960 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 513.615 5.602 91.69 <2e-16 ***poly(q, 3)1 2075.899 79.422 26.14 <2e-16 ***poly(q, 3)2 -108.004 79.422 -1.36 0.175 poly(q, 3)3 864.025 79.422 10.88 <2e-16 ***---Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1Residual standard error: 79.42 on 197 degrees of freedomMultiple R-squared: 0.8031,Adjusted R-squared: 0.8001 F-statistic: 267.8 on 3 and 197 DF, p-value: 0 

ved at bruge funktionen confint() kan vi opnå konfidensintervaller for parametrene i vores model.
konfidensintervaller for modelparametre:

confint(model, level=0.95) 2.5 % 97.5 %(Intercept) 502.5676 524.66261poly(q, 3)1 1919.2739 2232.52494poly(q, 3)2 -264.6292 48.62188poly(q, 3)3 707.3999 1020.65097

Plot af monteret vs rester. Intet klart mønster skal vises i det resterende plot, hvis modellen passer godt

plot(fitted(model),residuals(model))

Rplot04
samlet set ser modellen ud til at være en god pasform, da R-kvadratet på 0,8 indikerer. Koefficienterne for første og tredje ordens vilkår er statistisk signifikante, som vi forventede. Nu kan vi bruge predict() – funktionen til at få de monterede værdier og konfidensintervaller for at plotte alt mod vores data.

forudsagte værdier og konfidensintervaller:

predicted.intervals <- predict(model,data.frame(x=q),interval='confidence', level=0.99)

tilføj linjer til det eksisterende plot:

lines(q,predicted.intervals,col='green',lwd=3)lines(q,predicted.intervals,col='black',lwd=1)lines(q,predicted.intervals,col='black',lwd=1)

Tilføj en forklaring:

legend("bottomright",c("Observ.","Signal","Predicted"), col=c("deepskyblue4","red","green"), lwd=3)

her er plottet:
Rplot05
vi kan se, at vores model gjorde et anstændigt stykke arbejde med at montere dataene, og derfor kan vi være tilfredse med det.

et ord af forsigtighed: polynomier er kraftfulde værktøjer, men kan slå tilbage: i dette tilfælde vidste vi, at det originale signal blev genereret ved hjælp af et tredje graders polynom, men når vi analyserer reelle data, ved vi normalt lidt om det, og derfor er vi nødt til at være forsigtige, fordi brugen af højordens polynomer (n > 4) kan føre til overmontering. Overmontering sker, når din model optager støj i stedet for signalet: selvom din model bliver bedre og bedre til at montere de eksisterende data, kan dette være dårligt, når du prøver at forudsige nye data og føre til vildledende resultater.

en kerne med den fulde kode til dette eksempel kan findes her.

Tak fordi du læste dette indlæg, Efterlad en kommentar nedenfor, hvis du har spørgsmål.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.