udaje <- read.csv("barc_data.csv", dec=".", sep=";", header = TRUE)
udaje_selected <- udaje[, c("Weekday","Mild_injuries","Serious_injuries","Victims","Vehicles_involved","Weekend")]
numeric_cols <- c("Mild_injuries","Serious_injuries","Victims","Vehicles_involved","Weekend")
column_medians <- sapply(udaje_selected[, numeric_cols], median, na.rm = TRUE)
udaje_imputed <- udaje_selected
for (col in numeric_cols) {
udaje_imputed[[col]][is.na(udaje_imputed[[col]])] <- column_medians[col]
}
udaje <- udaje_imputed
model <- lm(Weekend ~ Victims + Mild_injuries + Serious_injuries + Vehicles_involved,
data = udaje)
summary(model)
##
## Call:
## lm(formula = Weekend ~ Victims + Mild_injuries + Serious_injuries +
## Vehicles_involved, data = udaje)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.4521 -0.1717 -0.1376 -0.1200 0.8624
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.21790 0.19035 1.145 0.257
## Victims 0.31917 0.41166 0.775 0.441
## Mild_injuries -0.30702 0.40069 -0.766 0.447
## Serious_injuries -0.16193 0.39767 -0.407 0.685
## Vehicles_involved -0.04622 0.09868 -0.468 0.641
##
## Residual standard error: 0.3819 on 55 degrees of freedom
## Multiple R-squared: 0.03722, Adjusted R-squared: -0.0328
## F-statistic: 0.5315 on 4 and 55 DF, p-value: 0.7131
Model ukazuje veľké rádové rozdiely medzi koeficientmi – niektoré sú v desatinách, iné len v stotinách – čo znamená, že ich účinky na výsledok sa líšia výraznou mierkou.
xvars <- udaje[, c("Mild_injuries", "Serious_injuries", "Victims", "Vehicles_involved", "Weekend")]
round(cor(xvars), 3)
## Mild_injuries Serious_injuries Victims Vehicles_involved
## Mild_injuries 1.000 0.006 0.895 0.179
## Serious_injuries 0.006 1.000 0.433 0.100
## Victims 0.895 0.433 1.000 0.206
## Vehicles_involved 0.179 0.100 0.206 1.000
## Weekend -0.008 0.152 0.070 -0.044
## Weekend
## Mild_injuries -0.008
## Serious_injuries 0.152
## Victims 0.070
## Vehicles_involved -0.044
## Weekend 1.000
Premenné Mild_injuries a Victims sú silne korelované (r = 0.895), preto je vhodné jednu z nich z modelu vylúčiť.
pairs(xvars,
main = "Scatterplotová matica – premenné Mild_injuries, Serious_injuries, Victims, Vehicles_involved, Weekend")
Graf vizuálne potvrdzuje, že Victims a Mild_injuries sú silne závislé, čo môže spôsobovať multikolinearitu v regresnom modeli. Ostatné vzťahy sú slabé alebo nevýrazné.
library(car)
vif(model)
## Victims Mild_injuries Serious_injuries Vehicles_involved
## 63.718627 51.709617 12.629485 1.044753
Intuitívnym kritériom, ktoré signalizuje prítomnosť multikolinearity, je podmienka VIF > 5 (prísne kritérium), alebo VIF > 10 (menej prísne kritérium). V našom prípade to nespĺňa žiadna z vysvetľujúcich veličín.
Ak Conditional number je
V našom prípade to vypočítame nasledovne
X <- model.matrix(model)[, -1]
XtX <- t(X) %*% X
eig <- eigen(XtX)
condition_number <- sqrt(max(eig$values) / min(eig$values))
condition_number
## [1] 40.68967
Keďže tento indikátor nepresahuje hodnotu 10, signalizuje nízku multikolinearitu.
Pokúsme sa vynechať postupne dve premenné, ktoré majú najvyšší VIF a porovnajme následne upravené koeficienty determinácie oboch nových modelov
model_noSerious_injuries <- lm(Victims ~ Mild_injuries + Vehicles_involved + Weekend, data = udaje)
summary(model_noSerious_injuries)
##
## Call:
## lm(formula = Victims ~ Mild_injuries + Vehicles_involved + Weekend,
## data = udaje)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.33179 -0.12685 -0.12685 -0.03066 1.87315
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.02369 0.21717 -0.109 0.914
## Mild_injuries 0.95816 0.06394 14.986 <2e-16 ***
## Vehicles_involved 0.09619 0.11089 0.867 0.389
## Weekend 0.20493 0.14951 1.371 0.176
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.4312 on 56 degrees of freedom
## Multiple R-squared: 0.8102, Adjusted R-squared: 0.8
## F-statistic: 79.67 on 3 and 56 DF, p-value: < 2.2e-16
model_noVehicles_involved <- lm(Victims ~ Mild_injuries + Serious_injuries + Weekend, data = udaje)
summary(model_noVehicles_involved)
##
## Call:
## lm(formula = Victims ~ Mild_injuries + Serious_injuries + Weekend,
## data = udaje)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.85286 -0.00056 -0.00056 0.03490 0.17677
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.03603 0.02978 1.210 0.232
## Mild_injuries 0.96453 0.01801 53.569 <2e-16 ***
## Serious_injuries 0.92323 0.03658 25.236 <2e-16 ***
## Weekend 0.03311 0.04326 0.765 0.447
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1234 on 56 degrees of freedom
## Multiple R-squared: 0.9845, Adjusted R-squared: 0.9836
## F-statistic: 1182 on 3 and 56 DF, p-value: < 2.2e-16
Premenná Serious_injuries (0,8) je dôležitá a jej vynechanie výrazne zhoršuje model. Naopak, Vehicles_involved (0,9836) má slabý vplyv, takže jeho vynechanie neublíži kvalite modelu.
udaje$Mild_c <- scale(udaje$Mild_injuries, center=TRUE, scale=TRUE)
udaje$Serious_c <- scale(udaje$Serious_injuries, center=TRUE, scale=TRUE)
udaje$Vehicles_c <- scale(udaje$Vehicles_involved, center=TRUE, scale=TRUE)
model_centered <- lm(Victims ~ Mild_c + Serious_c + Vehicles_c,
data = udaje)
summary(model_centered)
##
## Call:
## lm(formula = Victims ~ Mild_c + Serious_c + Vehicles_c, data = udaje)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.86082 -0.00709 -0.00709 0.02934 0.17503
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.450000 0.016006 90.590 <2e-16 ***
## Mild_c 0.859869 0.016407 52.409 <2e-16 ***
## Serious_c 0.411735 0.016224 25.379 <2e-16 ***
## Vehicles_c 0.004139 0.016489 0.251 0.803
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.124 on 56 degrees of freedom
## Multiple R-squared: 0.9843, Adjusted R-squared: 0.9835
## F-statistic: 1171 on 3 and 56 DF, p-value: < 2.2e-16
vif(model_centered)
## Mild_c Serious_c Vehicles_c
## 1.033190 1.010236 1.043579
Conditional Number je
X <- model.matrix(model_centered)[, -1]
XtX <- t(X) %*% X
eig <- eigen(XtX)
condition_number <- sqrt(max(eig$values) / min(eig$values))
condition_number
## [1] 1.23037
Už pred škálovaním boli ukazovatele multikolinearity veľmi dobré, no po škálovaní sa ešte viac zlepšili – VIF sa priblížili k hodnote 1 a Condition number klesol na veľmi nízku hodnotu, čo potvrdzuje numerickú stabilitu modelu.
V niektorých prípadoch môže byť užitočné upraviť mierku vysvetľujúcich premenných tak, aby boli vyjadrené v porovnateľných rádoch. V mojom prípade to však nebolo nevyhnutné, pretože hodnoty premenných boli už od začiatku nízke a dobre interpretovateľné.
Napriek tomu som sa rozhodla upraviť premennú Vehicles_involved jednoduchým delením číslom 10 – nie preto, že by to bolo metodicky nutné, ale aby som v rámci zadania ukázala určitú formu transformácie.
udaje$Vehicles_10 <- udaje$Vehicles_involved/10
head(udaje)
## Weekday Mild_injuries Serious_injuries Victims Vehicles_involved Weekend
## 1 Wednesday 1 0 1 2 1
## 2 Tuesday 1 0 1 1 0
## 3 Tuesday 1 0 1 2 0
## 4 Saturday 0 0 0 1 0
## 5 Tuesday 1 0 1 1 0
## 6 Tuesday 2 0 2 2 0
## Mild_c Serious_c Vehicles_c Vehicles_10
## 1 -0.3548595 -0.3375626 0.2912461 0.2
## 2 -0.3548595 -0.3375626 -1.6503945 0.1
## 3 -0.3548595 -0.3375626 0.2912461 0.2
## 4 -1.4754685 -0.3375626 -1.6503945 0.1
## 5 -0.3548595 -0.3375626 -1.6503945 0.1
## 6 0.7657495 -0.3375626 0.2912461 0.2
Potom lineárny model dosiahne výsledky
model_Vehicles_10 <- lm(Victims ~ Mild_injuries + Serious_injuries + Vehicles_10,
data = udaje)
summary(model_Vehicles_10)
##
## Call:
## lm(formula = Victims ~ Mild_injuries + Serious_injuries + Vehicles_10,
## data = udaje)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.86082 -0.00709 -0.00709 0.02934 0.17503
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.02744 0.06168 0.445 0.658
## Mild_injuries 0.96358 0.01839 52.409 <2e-16 ***
## Serious_injuries 0.92658 0.03651 25.379 <2e-16 ***
## Vehicles_10 0.08037 0.32016 0.251 0.803
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.124 on 56 degrees of freedom
## Multiple R-squared: 0.9843, Adjusted R-squared: 0.9835
## F-statistic: 1171 on 3 and 56 DF, p-value: < 2.2e-16
vif(model_Vehicles_10)
## Mild_injuries Serious_injuries Vehicles_10
## 1.033190 1.010236 1.043579
kde všetky regresné koeficienty majú porovnateľné rády a tiež VIF je akceptovateľný vo všetkých prípadoch. Conditional number potom
X <- model.matrix(model_Vehicles_10)[, -1]
XtX <- t(X) %*% X
eig <- eigen(XtX)
condition_number <- sqrt(max(eig$values) / min(eig$values))
condition_number
## [1] 15.22737
naznačuje miernu multikolinearitu, hoci nejde o vážny problém. Regresné koeficienty si ale zachovali dobrú interpretovateľnosť.
### ocistenie databazy od nadbytocnych - pracovnych stlpcov
library(dplyr)
udaje <- udaje %>%
dplyr::select(-Mild_c, -Serious_c, -Vehicles_c, Vehicles_10)
Modely ukázali, že multikolinearita nie je vážny problém. Najsilnejší vzťah je medzi Victims a Mild_injuries, premenná Serious_injuries je kľúčová, zatiaľ čo Vehicles_involved má slabší vplyv. Premenná Weekend sa neukázala ako významná. Škálovanie aj jednoduché úpravy zlepšili stabilitu a koeficienty zostali dobre interpretovateľné.