Dopasowanie regresji wielomianowej w R

. (Możesz zgłosić problem dotyczący treści na tej stronie tutaj)chcesz udostępnić swoje treści na R-bloggers? kliknij tutaj, jeśli masz bloga, lub tutaj, jeśli nie.

zależność liniowa między dwiema zmiennymi x i y jest jednym z najczęstszych, skutecznych i łatwych założeń do podjęcia podczas próby ustalenia ich relacji. Czasami jednak prawdziwa relacja jest bardziej złożona niż to, i to jest, gdy regresja wielomianowa przychodzi, aby pomóc.

zobacz przykład z ekonomii: Załóżmy, że chcesz kupić określoną ilość q określonego produktu. Jeśli cena jednostkowa wynosi p, zapłacisz całkowitą kwotę y. Jest to typowy przykład zależności liniowej. Całkowita cena i ilość są wprost proporcjonalne. Aby to wykreślić, napisalibyśmy coś takiego:

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

fabuła będzie wyglądać tak:
linear-relationship

jest to dobre przybliżenie prawdziwej relacji między y a q, jednak kupując i sprzedając, możemy rozważyć inne istotne informacje, takie jak: Kupując znaczne ilości prawdopodobnie możemy poprosić i uzyskać rabat, lub kupując coraz więcej pewnego dobra, możemy przesuwać cenę w górę.
to może prowadzić do takiego scenariusza, w którym całkowity koszt nie jest już funkcją liniową ilości:

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

Rplot02
dzięki regresji wielomianowej możemy dopasować modele rzędu n > 1 do danych i próbować modelować nieliniowe relacje.

jak dopasować regresję wielomianową

po pierwsze, zawsze pamiętaj o użyciu do set.seed(n) podczas generowania liczb pseudolosowych. W ten sposób generator liczb losowych generuje zawsze te same liczby.

set.seed(20)

Użyj seq do generowania równomiernie rozmieszczonych sekwencji szybko

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

wartość do przewidzenia (y):

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

niektóre szumy są generowane i dodawane do rzeczywistego sygnału (y):

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

Wykres szumu sygnału:

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

to jest wykres naszych symulowanych danych obserwowanych. Symulowane punkty danych są niebieskimi kropkami, podczas gdy czerwona linia jest sygnałem (sygnał jest terminem technicznym, który jest często używany do wskazania ogólnego trendu, który jesteśmy zainteresowani wykryciem).
Rplot03
nasz model powinien wyglądać mniej więcej tak: y = a*q + b*q2 + C*q3 + koszt

dopasujmy go za pomocą R. podczas dopasowywania wielomianów możesz użyć

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

lub

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

jednak zauważ, że q, I(q^2) i I(q^3) będą skorelowane, a skorelowane zmienne mogą powodować problemy. Użycie poly() pozwala uniknąć tego poprzez tworzenie wielomianów ortogonalnych, dlatego użyję pierwszej opcji.

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 

korzystając z funkcji confint() możemy uzyskać przedziały ufności parametrów naszego modelu.
przedziały ufności dla parametrów modelu:

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

działka dopasowane vs pozostałości. Żaden wyraźny wzór nie powinien pokazywać się na pozostałej powierzchni, jeśli model jest dobrze dopasowany

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

Rplot04
ogólnie model wydaje się być dobrze dopasowany, jak wskazuje R kwadrat 0.8. Współczynniki pierwszego i trzeciego rzędu są statystycznie istotne, zgodnie z oczekiwaniami. Teraz możemy użyć funkcji predict(), aby uzyskać dopasowane wartości i przedziały ufności, aby narysować wszystko na podstawie naszych danych.

przewidywane wartości i przedziały ufności:

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

Dodaj linie do istniejącego wykresu:

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

Dodaj legendę:

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

oto fabuła:
Rplot05
widzimy, że nasz model wykonał przyzwoitą pracę przy dopasowywaniu danych i dlatego możemy być z niego zadowoleni.

słowo ostrzeżenia: Wielomiany są potężnymi narzędziami, ale mogą obalić: w tym przypadku wiedzieliśmy, że oryginalny sygnał został wygenerowany przy użyciu wielomianu trzeciego stopnia, jednak podczas analizy rzeczywistych danych zwykle niewiele o tym wiemy i dlatego musimy być ostrożni, ponieważ użycie wielomianów wysokiego rzędu (n > 4) może prowadzić do nadmiernego dopasowania. Nadmierne dopasowanie ma miejsce, gdy twój model odbiera szum zamiast sygnału: nawet jeśli twój model jest coraz lepszy w dopasowywaniu istniejących danych, może to być złe, gdy próbujesz przewidzieć nowe dane i prowadzić do mylących wyników.

gist z pełnym kodem dla tego przykładu można znaleźć tutaj.

dziękuję za przeczytanie tego posta, zostaw komentarz poniżej, jeśli masz jakieś pytanie.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.