library(zoo)
library(tseries)
library(lmtest)
library(sandwich)
library(car)
rm(list = ls())
Pokračujeme v predchádzajúcich úlohách, kde s pomocou regresie skúmame, nakoľko je počet obyvateľov v obci na konci roka 2024 (stav v decembri 2024) ovplyvnený počtom obyvateľov:
Pracujeme teda s prierezovými dátami za obce Slovenska, pričom za každú obec máme stav obyvateľov v jednotlivých mesiacoch roka 2024. Výsledok základnej regresie je uvedený nižšie.
#######################################################################
# PRÍPRAVA ÚDAJOV
#######################################################################
# načítame databázu (tvoj súbor Databaza.csv)
# check.names = FALSE zabezpečí, že stĺpce zostanú pomenované 2024M12, 2024M01 atď.
udaje_raw <- read.csv("Databaza.csv", dec = ".", sep = ";", header = TRUE,
check.names = FALSE)
# skontrolujeme štruktúru
str(udaje_raw)
'data.frame': 200 obs. of 14 variables:
$ Okres : chr "Okres Bratislava I" "Okres Bratislava II" "Okres Bratislava II" "Okres Bratislava II" ...
$ Obec : chr "Bratislava - mestská časť Staré Mesto" "Bratislava - m. č. Podunajské Biskupice" "Bratislava - mestská časť Ružinov" "Bratislava - mestská časť Vrakuňa" ...
$ 2024M12: int 47634 23095 83365 20172 45539 26481 6050 17065 35538 34815 ...
$ 2024M11: int 47632 23110 83251 20161 45480 26466 6052 17071 35575 34831 ...
$ 2024M10: int 47565 23130 83192 20159 45444 26429 6045 17040 35579 34816 ...
$ 2024M09: int 47564 23132 83163 20162 45455 26432 6049 17036 35636 34788 ...
$ 2024M08: int 47525 23137 83137 20161 45442 26430 6040 17027 35649 34748 ...
$ 2024M07: int 47488 23147 83056 20190 45442 26394 6036 17021 35627 34782 ...
$ 2024M06: int 47503 23162 82867 20216 45411 26376 6030 16999 35633 34812 ...
$ 2024M05: int 47484 23178 82789 20211 45376 26346 6024 17005 35624 34843 ...
$ 2024M04: int 47411 23179 82641 20227 45414 26291 6031 17027 35600 34854 ...
$ 2024M03: int 47408 23201 82612 20209 45439 26245 6034 17007 35575 34899 ...
$ 2024M02: int 47391 23226 82553 20196 45410 26231 6037 17030 35570 34924 ...
$ 2024M01: int 47375 23276 82483 20221 45342 26214 6038 17067 35572 34942 ...
head(udaje_raw)
# Vytvoríme si premenné pre jednotlivé mesiace, s ktorými budeme pracovať v modeli:
# obyv_12 – počet obyvateľov v decembri 2024 (vysvetľovaná premenná)
# obyv_01 – počet obyvateľov v januári 2024
# obyv_06 – počet obyvateľov v júni 2024
# obyv_09 – počet obyvateľov v septembri 2024
udaje <- within(udaje_raw, {
obyv_12 <- `2024M12`
obyv_01 <- `2024M01`
obyv_06 <- `2024M06`
obyv_09 <- `2024M09`
})
# vyberieme len premenné, ktoré idú do modelu
udaje_model <- udaje[, c("obyv_12", "obyv_01", "obyv_06", "obyv_09")]
# (prípadná) imputácia chýbajúcich hodnôt – v našej databáze zrejme chýbajúce údaje nie sú,
# ale pre ukážku ponecháme postup s doplnením mediánov
column_medians <- sapply(udaje_model, median, na.rm = TRUE)
udaje_imputed <- udaje_model
for (col in names(udaje_model)) {
udaje_imputed[[col]][is.na(udaje_imputed[[col]])] <- column_medians[col]
}
udaje <- udaje_imputed
str(udaje)
'data.frame': 200 obs. of 4 variables:
$ obyv_12: num 47634 23095 83365 20172 45539 ...
$ obyv_01: num 47375 23276 82483 20221 45342 ...
$ obyv_06: num 47503 23162 82867 20216 45411 ...
$ obyv_09: num 47564 23132 83163 20162 45455 ...
V základnom modeli predpokladáme, že počet obyvateľov v obci v decembri 2024 je lineárne vysvetlený počtom obyvateľov v januári, júni a septembri:
\[ \text{obyv\_12}_i = \beta_0 + \beta_1 \text{obyv\_01}_i + \beta_2 \text{obyv\_06}_i + \beta_3 \text{obyv\_09}_i + u_i \]
kde index \(i\) označuje obec.
#######################################################################
# ZÁKLADNÁ REGRESIA
#######################################################################
attach(udaje)
model <- lm(obyv_12 ~ 1 + obyv_01 + obyv_06 + obyv_09, data = udaje)
summary(model)
Call:
lm(formula = obyv_12 ~ 1 + obyv_01 + obyv_06 + obyv_09, data = udaje)
Residuals:
Min 1Q Median 3Q Max
-118.937 -4.211 0.368 5.820 41.782
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.34570 1.10739 -0.312 0.755242
obyv_01 -0.11970 0.03708 -3.228 0.001459 **
obyv_06 -0.34533 0.09994 -3.455 0.000673 ***
obyv_09 1.46539 0.06681 21.934 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 14.26 on 196 degrees of freedom
Multiple R-squared: 1, Adjusted R-squared: 1
F-statistic: 4.588e+07 on 3 and 196 DF, p-value: < 2.2e-16
Interpretácia: koeficienty pri premenných obyv_01,
obyv_06 a obyv_09 hovoria, o koľko sa v
priemere zmení počet obyvateľov v decembri, ak sa daná vysvetľujúca
premenná zvýši o jednu osobu (pri ostatných premenných nezmenených).
Chceme otestovať, či je lineárna špecifikácia vhodná, t. j. či medzi premennými nie je výraznejší nelineárny vzťah, ktorý by sme mali zachytiť pomocou transformácií (napr. kvadratické členy, logaritmy).
Základný model:
\[ y_i = \beta_0 + \beta_1 x_{1i} + \dots + \beta_k x_{ki} + u_i \]
Ak je model správne špecifikovaný, pridaním mocnín vyrovnaných hodnôt (napr. \(\hat{y}_i^2\), \(\hat{y}_i^3\)) by sa model nemal štatisticky významne zlepšiť. RESET test formálne testuje:
#######################################################################
# RESET TEST
#######################################################################
library(lmtest)
resettest(model)
RESET test
data: model
RESET = 8.0852, df1 = 2, df2 = 194, p-value = 0.000424
Interpretácia:
Ak p-hodnota < 0,05, zamietame \(H_0\) a usudzujeme, že lineárny model môže
byť nesprávne špecifikovaný – buď chýbajú niektoré vysvetľujúce
premenné, alebo je potrebná nelineárna transformácia premenných.
Ak p-hodnota ≥ 0,05, nemáme dôvod tvrdiť, že je špecifikácia modelu
nevhodná.
Graf rezíduí voči vyrovnaným hodnotám nám pomáha odhaliť nelinearity, heteroskedasticitu či iné systematické vzory v rezíduách.
plot(model, which = 1)
Ak rezíduá vykazujú nenáhodný vzor (napr. zakrivenie), lineárna špecifikácia môže byť nevhodná a má zmysel uvažovať o transformácii niektorej premennej alebo o zaradení ďalšej premennej.
Tieto grafy nám pomáhajú odhadnúť, pri ktorej vysvetľujúcej premennej by mohol byť vzťah s vysvetľovanou premennou nelineárny.
car::crPlots(model)
Vertikálna os zobrazuje hodnoty typu \(\hat{\beta}_i x_{i} + e_i\), horizontálna os zobrazuje hodnotu príslušnej vysvetľujúcej premennej.
Ak sa hladká krivka (lokálna aproximácia) výrazne odchyľuje od
priamky, zvážime transformáciu danej premennej (napr. kvadratický člen,
logaritmus a pod.). V našom prípade nás môžu zaujímať najmä premené
obyv_06 (počet obyvateľov v júni) a obyv_09
(počet obyvateľov v septembri), ak sa pri nich objavuje výraznejšie
zakrivenie.
Často môžeme nelineárne vzťahy približovať pomocou polynómov. V prípade kvadratických členov má model tvar:
\[ y_i = \beta_0 + \beta_1 x_{1i} + \dots + \beta_k x_{ki} + \gamma_i x_{ki}^2 + u_i \]
V našom príklade môžeme zaradiť kvadrát niektorých mesačných stavov
obyvateľov, napríklad obyv_06 (jún) a obyv_09
(september).
Predpokladajme, že podľa C+R grafov sa rozhodneme pridať kvadrát
premenných obyv_06 a obyv_09. Náš rozšírený
model bude:
#######################################################################
# MODELY S KVADRATICKÝMI ČLENMI
#######################################################################
model_linear <- lm(obyv_12 ~ 1 + obyv_01 + obyv_06 + obyv_09)
model_kvadr <- lm(obyv_12 ~ 1 + obyv_01 + obyv_06 + obyv_09 +
I(obyv_06^2) + I(obyv_09^2))
summary(model_kvadr)
Call:
lm(formula = obyv_12 ~ 1 + obyv_01 + obyv_06 + obyv_09 + I(obyv_06^2) +
I(obyv_09^2))
Residuals:
Min 1Q Median 3Q Max
-108.896 -4.359 -0.382 5.112 57.656
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.075e+00 1.189e+00 0.904 0.366992
obyv_01 -1.471e-01 3.627e-02 -4.056 7.21e-05 ***
obyv_06 -4.099e-01 1.127e-01 -3.637 0.000353 ***
obyv_09 1.557e+00 8.553e-02 18.201 < 2e-16 ***
I(obyv_06^2) 9.685e-07 4.695e-07 2.063 0.040454 *
I(obyv_09^2) -9.601e-07 4.699e-07 -2.043 0.042392 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 13.62 on 194 degrees of freedom
Multiple R-squared: 1, Adjusted R-squared: 1
F-statistic: 3.017e+07 on 5 and 194 DF, p-value: < 2.2e-16
anova(model_linear, model_kvadr)
Analysis of Variance Table
Model 1: obyv_12 ~ 1 + obyv_01 + obyv_06 + obyv_09
Model 2: obyv_12 ~ 1 + obyv_01 + obyv_06 + obyv_09 + I(obyv_06^2) + I(obyv_09^2)
Res.Df RSS Df Sum of Sq F Pr(>F)
1 196 39873
2 194 36013 2 3859.6 10.396 5.142e-05 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
resettest(model_kvadr)
RESET test
data: model_kvadr
RESET = 12.357, df1 = 2, df2 = 192, p-value = 8.949e-06
Porovnávame:
Ak rozšírený model vykazuje vyšší \(R^2_{adj}\), ANOVA test je významný a RESET test poukazuje na lepšiu špecifikáciu, môžeme kvadratické členy považovať za vhodné.
Ak by napríklad kvadrát jednej premennej vyšiel štatisticky nevýznamný, môžeme model zjednodušiť a ponechať len tie kvadratické členy, ktoré zlepšujú štatistické vlastnosti modelu.
# Príklad zjednodušenia – ponechajme len kvadrát obyv_06
model_kvadr_simple <- lm(obyv_12 ~ 1 + obyv_01 + obyv_06 + obyv_09 +
I(obyv_06^2))
summary(model_kvadr_simple)
Call:
lm(formula = obyv_12 ~ 1 + obyv_01 + obyv_06 + obyv_09 + I(obyv_06^2))
Residuals:
Min 1Q Median 3Q Max
-108.106 -4.552 -0.013 5.115 57.819
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.604e+00 1.170e+00 1.370 0.17217
obyv_01 -1.508e-01 3.652e-02 -4.128 5.42e-05 ***
obyv_06 -2.906e-01 9.719e-02 -2.990 0.00315 **
obyv_09 1.441e+00 6.462e-02 22.300 < 2e-16 ***
I(obyv_06^2) 9.292e-09 2.298e-09 4.044 7.58e-05 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 13.74 on 195 degrees of freedom
Multiple R-squared: 1, Adjusted R-squared: 1
F-statistic: 3.711e+07 on 4 and 195 DF, p-value: < 2.2e-16
Môžeme ešte skúsiť systematickejšiu rozšírenú špecifikáciu, kde pridáme kvadratické členy ku všetkým vysvetľujúcim premenným:
#######################################################################
# ROZŠÍRENÝ MODEL S VIACERÝMI KVADRATICKÝMI ČLENMI
#######################################################################
model_rozsireny <- lm(obyv_12 ~ obyv_01 + obyv_06 + obyv_09 +
I(obyv_01^2) + I(obyv_06^2) + I(obyv_09^2))
summary(model_rozsireny)
Call:
lm(formula = obyv_12 ~ obyv_01 + obyv_06 + obyv_09 + I(obyv_01^2) +
I(obyv_06^2) + I(obyv_09^2))
Residuals:
Min 1Q Median 3Q Max
-93.720 -4.850 0.383 5.847 56.068
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.625e-02 1.183e+00 0.014 0.989049
obyv_01 -3.015e-01 5.350e-02 -5.636 6.09e-08 ***
obyv_06 -3.479e-02 1.466e-01 -0.237 0.812710
obyv_09 1.336e+00 1.008e-01 13.258 < 2e-16 ***
I(obyv_01^2) 5.639e-06 1.476e-06 3.821 0.000179 ***
I(obyv_06^2) -1.306e-05 3.699e-06 -3.530 0.000519 ***
I(obyv_09^2) 7.418e-06 2.239e-06 3.313 0.001102 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 13.17 on 193 degrees of freedom
Multiple R-squared: 1, Adjusted R-squared: 1
F-statistic: 2.69e+07 on 6 and 193 DF, p-value: < 2.2e-16
anova(model_linear, model_rozsireny)
Analysis of Variance Table
Model 1: obyv_12 ~ 1 + obyv_01 + obyv_06 + obyv_09
Model 2: obyv_12 ~ obyv_01 + obyv_06 + obyv_09 + I(obyv_01^2) + I(obyv_06^2) +
I(obyv_09^2)
Res.Df RSS Df Sum of Sq F Pr(>F)
1 196 39873
2 193 33480 3 6392.6 12.284 2.172e-07 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
resettest(model_rozsireny)
RESET test
data: model_rozsireny
RESET = 15.208, df1 = 2, df2 = 191, p-value = 7.436e-07
Tu sledujeme, či kvadratické členy vychádzajú štatisticky významné a či ANOVA test ukáže štatisticky významné zlepšenie oproti pôvodnému lineárnemu modelu. Výsledok RESET testu nám zároveň napovie, či aj po týchto úpravách zostáva problém nesprávnej špecifikácie.
Predpokladajme, že podľa C+R grafu pri premennej obyv_06
(počet obyvateľov v júni) vidíme, že pre menšie obce a
väčšie obce môže byť vzťah odlišný – teda pre určité
„kritické“ veľkosti obcí sa mení sklon.
Zaveďme dummy premennú:
\[ DUM_i = \begin{cases} 1, & \text{ak obec má v júni viac ako 10\,000 obyvateľov}, \\ 0, & \text{inak}. \end{cases} \]
Pomocou tejto premennej môžeme modelovať:
#######################################################################
# DUMMY PREMENNÁ A LOMENÁ FUNKCIA
#######################################################################
# definujeme dummy podľa júnového stavu – hranica 10 000 obyvateľov je ilustračná
DUM <- ifelse(obyv_06 > 10000, 1, 0)
udaje$DUM <- DUM
# Model so zlomom v autonómnom člene
modelD_auto <- lm(obyv_12 ~ 1 + DUM + obyv_01 + obyv_06 + obyv_09, data = udaje)
summary(modelD_auto)
Call:
lm(formula = obyv_12 ~ 1 + DUM + obyv_01 + obyv_06 + obyv_09,
data = udaje)
Residuals:
Min 1Q Median 3Q Max
-115.108 -4.408 0.171 5.410 46.743
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -0.24123 1.08877 -0.222 0.824885
DUM -13.85798 4.90100 -2.828 0.005180 **
obyv_01 -0.12770 0.03654 -3.495 0.000588 ***
obyv_06 -0.31432 0.09881 -3.181 0.001708 **
obyv_09 1.44264 0.06614 21.812 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 14.02 on 195 degrees of freedom
Multiple R-squared: 1, Adjusted R-squared: 1
F-statistic: 3.564e+07 on 4 and 195 DF, p-value: < 2.2e-16
# Model so zlomom v sklone (interakcia DUM * obyv_06)
modelD_sklon <- lm(obyv_12 ~ 1 + obyv_01 + obyv_06 + I(DUM * obyv_06) + obyv_09,
data = udaje)
summary(modelD_sklon)
Call:
lm(formula = obyv_12 ~ 1 + obyv_01 + obyv_06 + I(DUM * obyv_06) +
obyv_09, data = udaje)
Residuals:
Min 1Q Median 3Q Max
-119.941 -3.962 0.428 5.884 41.831
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.6221606 1.5304139 0.407 0.684798
obyv_01 -0.1257484 0.0376748 -3.338 0.001012 **
obyv_06 -0.3363435 0.1004595 -3.348 0.000977 ***
I(DUM * obyv_06) 0.0005266 0.0005745 0.917 0.360462
obyv_09 1.4619095 0.0669453 21.837 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 14.27 on 195 degrees of freedom
Multiple R-squared: 1, Adjusted R-squared: 1
F-statistic: 3.438e+07 on 4 and 195 DF, p-value: < 2.2e-16
anova(model_linear, modelD_sklon)
Analysis of Variance Table
Model 1: obyv_12 ~ 1 + obyv_01 + obyv_06 + obyv_09
Model 2: obyv_12 ~ 1 + obyv_01 + obyv_06 + I(DUM * obyv_06) + obyv_09
Res.Df RSS Df Sum of Sq F Pr(>F)
1 196 39873
2 195 39702 1 171.07 0.8402 0.3605
resettest(modelD_sklon)
RESET test
data: modelD_sklon
RESET = 7.9324, df1 = 2, df2 = 193, p-value = 0.000489
Interpretácia:
modelD_auto skúmame, či sa líši
úroveň počtu obyvateľov v decembri (autonómny člen)
medzi menšími a väčšími obcami,modelD_sklon skúmame, či sa líši
sklon pri premennej obyv_06 (t. j. či
nárast počtu obyvateľov v júni o jednu osobu zvyšuje počet obyvateľov v
decembri rovnakým spôsobom v malých aj veľkých obciach).Ak ANOVA test medzi model_linear a
modelD_sklon vyjde štatisticky významný a interakčný člen
je významný, môžeme usúdiť, že zavedenie zlomu v sklone zlepšilo
model.
Box–Coxov test nám pomáha rozhodnúť, či je vhodné transformovať
vysvetľovanú premennú (u nás obyv_12),
napríklad pomocou logaritmu, odmocniny alebo reciproka.
#######################################################################
# BOX–COXOVA TRANSFORMÁCIA
#######################################################################
library(MASS)
boxcox(model_linear)
Interpretácia:
Predpokladajme, že Box–Coxov test naznačí nejakú hodnotu \(\lambda\); ilustračné nastavenie:
# Ilustračná transformácia s lambda = 0.5 (odmocnina), ak by nám to Box–Cox odporučil
model_lambda <- lm(I((obyv_12^0.5 - 1) / 0.5) ~ 1 + obyv_01 + obyv_06 + obyv_09,
data = udaje)
summary(model_lambda)
Call:
lm(formula = I((obyv_12^0.5 - 1)/0.5) ~ 1 + obyv_01 + obyv_06 +
obyv_09, data = udaje)
Residuals:
Min 1Q Median 3Q Max
-175.16 -21.13 -4.00 16.55 98.26
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 69.71777 2.51086 27.766 < 2e-16 ***
obyv_01 -0.26908 0.08407 -3.201 0.00160 **
obyv_06 0.60113 0.22660 2.653 0.00864 **
obyv_09 -0.32490 0.15148 -2.145 0.03320 *
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 32.34 on 196 degrees of freedom
Multiple R-squared: 0.8732, Adjusted R-squared: 0.8712
F-statistic: 449.7 on 3 and 196 DF, p-value: < 2.2e-16
resettest(model_lambda)
RESET test
data: model_lambda
RESET = 857.29, df1 = 2, df2 = 194, p-value < 2.2e-16
Pri porovnávaní s pôvodným modelom sledujeme zmenu \(R^2_{adj}\) a výsledok RESET testu. Ak síce dôjde k malej zmene \(R^2_{adj}\), ale výrazne sa skomplikuje interpretácia (už nepracujeme priamo s počtom obyvateľov, ale s transformáciou), v praktických aplikáciách sa často preferuje jednoduchší model, pokiaľ štatisticky „stačí“.