Načítanie dát a knižníc

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(stringr)
library(car)
## Loading required package: carData
## 
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
## 
##     recode
data <- read.csv("index.csv", check.names = FALSE)
fg_col   <- "IndexFG"
vek_col  <- "AkýjeVášvek"
prijem_col <- "AkýjeVášmesačnýpríjem"
seba_col <- "AkobysteohodnotilisvojeznalostivoblastifinančnejgramotnostiNaš"
# kontrola, že stĺpce existujú
fg_col   %in% names(data)
## [1] TRUE
vek_col  %in% names(data)
## [1] TRUE
prijem_col %in% names(data)
## [1] TRUE
seba_col %in% names(data)
## [1] TRUE
head(data[[fg_col]])
## [1] 10  9 10  4  1  9
head(data[[vek_col]])
## [1] 21 18 22 18 20 20
head(data[[prijem_col]])
## [1] "1600€ a viac" "401 - 800€"   "1600€ a viac" "401 - 800€"   "401 - 800€"  
## [6] "401 - 800€"
head(data[[seba_col]])
## [1] 10  7  8  5  6  7
# funkcia na stred príjmového pásma
income_mid <- function(x) {
  x <- as.character(x)
  x <- stringr::str_squish(x)

  dplyr::case_when(
    x == "0 - 400€"       ~ 200,
    x == "401 - 800€"     ~ 600.5,
    x == "801 - 1000€"    ~ 900.5,
    x == "1001 - 1200€"   ~ 1100.5,
    x == "1201 - 1600€"   ~ 1400.5,
    x == "1600€ a viac"   ~ 1800,
    TRUE ~ NA_real_
  )
}
reg_df <- data %>%
  mutate(
    FG_index   = as.numeric(.data[[fg_col]]),
    Vek        = as.numeric(.data[[vek_col]]),
    Seba       = as.numeric(.data[[seba_col]]),
    Prijem_mid = income_mid(.data[[prijem_col]])
  ) %>%
  filter(!is.na(FG_index),
         !is.na(Vek),
         !is.na(Seba),
         !is.na(Prijem_mid))

nrow(data); nrow(reg_df)
## [1] 392
## [1] 392
summary(reg_df[, c("FG_index","Prijem_mid","Vek","Seba")])
##     FG_index        Prijem_mid          Vek             Seba       
##  Min.   : 1.000   Min.   : 200.0   Min.   :17.00   Min.   : 1.000  
##  1st Qu.: 6.000   1st Qu.: 200.0   1st Qu.:19.00   1st Qu.: 6.000  
##  Median : 8.000   Median : 600.5   Median :21.00   Median : 7.000  
##  Mean   : 7.352   Mean   : 729.6   Mean   :23.22   Mean   : 6.885  
##  3rd Qu.: 9.000   3rd Qu.:1100.5   3rd Qu.:24.00   3rd Qu.: 8.000  
##  Max.   :10.000   Max.   :1800.0   Max.   :52.00   Max.   :10.000
# Odhad základného regresného modelu

model <- lm(FG_index ~ Prijem_mid + Vek + Seba, data = reg_df)
summary(model)
## 
## Call:
## lm(formula = FG_index ~ Prijem_mid + Vek + Seba, data = reg_df)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -6.4169 -1.3509  0.4256  1.5578  3.4122 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  5.611e+00  5.307e-01  10.572  < 2e-16 ***
## Prijem_mid  -6.016e-05  2.554e-04  -0.236    0.814    
## Vek         -5.333e-03  2.061e-02  -0.259    0.796    
## Seba         2.772e-01  5.727e-02   4.841 1.87e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.027 on 388 degrees of freedom
## Multiple R-squared:  0.05934,    Adjusted R-squared:  0.05206 
## F-statistic: 8.158 on 3 and 388 DF,  p-value: 2.797e-05

Interpretácia:

Výsledky viacnásobného regresného modelu ukázali, že subjektívne sebahodnotenie finančných znalostí je významným a pozitívnym prediktorom objektívne meraného indexu finančnej gramotnosti. Každé zvýšenie sebahodnotenia o 1 bod je spojené s nárastom objektívneho indexu o približne 0.28 bodu (p < 0.001).

Naopak, ani vek, ani výška mesačného príjmu študentov nevyšli ako štatisticky významné faktory vysvetľujúce úroveň finančnej gramotnosti. Koeficienty pri týchto premenných sú veľmi malé a nepresné, pravdepodobne vplyvom úzkeho vekového rozpätia respondentov a štruktúry príjmov typickej pre študentov FMUK.

Hodnota R² ≈ 0.06 naznačuje, že model zachytáva len malú časť variability indexu FG, čo je pri dotazníkových dátach bežné.

# Korelačná matica

xvars <- reg_df[, c("Prijem_mid", "Vek", "Seba")]
round(cor(xvars), 3)
##            Prijem_mid   Vek  Seba
## Prijem_mid      1.000 0.675 0.303
## Vek             0.675 1.000 0.197
## Seba            0.303 0.197 1.000

Interpretácia

Korelačná matica ukazuje, že:

Prijem a Vek majú stredne silnú pozitívnu koreláciu (0.675). To znamená, že starší respondenti majú vo všeobecnosti vyšší príjem, čo je očakávateľné vzhľadom na väčšiu pracovnú aktivitu.

Prijem a Sebahodnotenie sú v slabom pozitívnom vzťahu (0.303). Respondenti s vyšším príjmom sa mierne hodnotia ako finančne zdatnejší, ale tento vzťah je slabý.

Vek a Sebahodnotenie majú veľmi slabú koreláciu (0.197), čo naznačuje, že sebahodnotenie finančných znalostí sa medzi rôznymi vekovými skupinami zásadne nelíši.

Celkovo sú premenné navzájom len mierne až slabo prepojené a žiadny z párových vzťahov nie je výrazne silný.

pairs(xvars,
      main = "Scatterplotová matica – Prijem_mid, Vek, Seba")

Interpretácia:

Scatterplotová matica vizuálne potvrdzuje len jeden výraznejší vzťah medzi analyzovanými premennými – starší respondenti majú spravidla vyšší príjem. Na druhej strane, sebahodnotenie finančných znalostí sa vyskytuje pomerne rovnomerne naprieč rôznymi príjmovými pásmami aj vekovou skupinou, čo naznačuje, že ide skôr o individuálny subjektívny odhad než o charakteristiku závislú od socioekonomických faktorov. Žiadna z dvojíc premenných nevykazuje extrémne silný alebo jednoznačný lineárny vzťah, čo sa odráža aj v nízkych korelačných koeficientoch.

VIF

VIF vyhodnocuje, o koľko je rozptyl odhadu β_j nafúknutý kvôli kolinearite s ostatnými premennými:

\[ VIF_j = \frac{1}{1 - R_j^2}, \]

kde \(R_j^2\) pochádza z regresie, v ktorej je \(X_j\) vysvetľovaná ostatnými vysvetľujúcimi premennými.

vif(model)
## Prijem_mid        Vek       Seba 
##   1.944711   1.837686   1.101082

Interpretácia:

Na diagnostiku multikolinearity sme vypočítali Variance Inflation Factor (VIF) pre všetky vysvetľujúce premenné v modeli. Hodnoty VIF vyšli nasledovne:

Prijem_mid: 1.94 Vek: 1.84 Sebahodnotenie: 1.10

Hodnoty VIF interpretujeme podľa bežných pravidiel:

VIF < 5 znamená, že multikolinearita medzi premennými nie je problematická, VIF > 5 môže naznačovať zvýšenú kolinearitu, VIF > 10 sa považuje za vážny problém.

V našom prípade má každá premenná VIF hlboko pod hranicou 5, čo znamená, že vysvetľujúce veličiny nie sú navzájom silno lineárne prepojené. Teda žiadna z premenných nespôsobuje významné nafukovanie rozptylu odhadovaných regresných koeficientov.

To znamená, že model netrpí párovou multikolinearitou,odhady koeficientov nie sú nestabilné v dôsledku závislosti medzi premennými, t-testy významnosti jednotlivých regresorov sú spoľahlivé, nie je potrebné odstraňovať alebo transformovať vysvetľujúce premenné z dôvodu multikolinearity.

Na základe hodnot VIF môžeme konštatovať, že v modeli sa nenachádza problematická multikolinearita. Vysvetľujúce premenné sú dostatočne nezávislé a ich spoločné zaradenie v regresnom modeli je z ekonometrického hľadiska vhodné.

Condition Number

VIF vie zachytiť problém jednej premennej voči ostatným, ale môže sa stať, že všetky premenné sú vo vzťahoch, ktoré sa prejavia až na úrovni celej matice \(\mathbf X^T \mathbf X\).

Preto používame Condition Number:

\[ \kappa = \frac{\sqrt{\theta_{\max}}}{\sqrt{\theta_{\min}}} = \sqrt{\frac{\theta_{\max}}{\theta_{\min}}}, \]

kde \(\theta_\cdot\) sú vlastné čísla matice \(\mathbf X^T \mathbf X\).

X  <- model.matrix(model)[, -1]  # bez stĺpca konštanty
XtX <- t(X) %*% X
eig <- eigen(XtX)

condition_number <- sqrt(max(eig$values) / min(eig$values))
condition_number
## [1] 398.0657

Interpretácia:

Hodnota Condition Number dosiahla približne 398, čo podľa bežného interpretačného pravidla predstavuje veľmi vážnu multikolinearitu. Napriek tomu, že VIF pre jednotlivé premenné boli nízke, vysoký Condition Number naznačuje globálnu multikolinearitu spôsobenú rozdielnymi rádom premenných. Premenná príjem je vyjadrená v tisícoch eur, zatiaľ čo vek a sebahodnotenie sú v podstatne menších jednotkách, čo spôsobuje numerickú nestabilitu matice. Dôsledkom môžu byť nestabilné odhady regresných koeficientov a nadhodnotené štandardné odchýlky. Tento problém možno odstrániť škálovaním premenných alebo zmenou jednotiek príjmu, čo výrazne zníži Condition Number a zlepší numerickú stabilitu modelu.

Riešenia multikolinearity

Vynechanie premennej

Vynecháme postupne príjem a sebahodnotenie a porovnáme modely (najmä Adjusted R²):

model_no_income <- lm(FG_index ~ Vek + Seba, data = reg_df)
summary(model_no_income)
## 
## Call:
## lm(formula = FG_index ~ Vek + Seba, data = reg_df)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -6.3854 -1.3811  0.4185  1.5720  3.3942 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  5.66310    0.48176  11.755  < 2e-16 ***
## Vek         -0.00853    0.01549  -0.551    0.582    
## Seba         0.27407    0.05560   4.929 1.23e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.025 on 389 degrees of freedom
## Multiple R-squared:  0.0592, Adjusted R-squared:  0.05437 
## F-statistic: 12.24 on 2 and 389 DF,  p-value: 6.998e-06
model_no_seba <- lm(FG_index ~ Prijem_mid + Vek, data = reg_df)
summary(model_no_seba)
## 
## Call:
## lm(formula = FG_index ~ Prijem_mid + Vek, data = reg_df)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -6.5551 -1.2738  0.6385  1.6571  2.7748 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  7.3325278  0.4051671  18.098   <2e-16 ***
## Prijem_mid   0.0002301  0.0002553   0.901    0.368    
## Vek         -0.0063908  0.0211920  -0.302    0.763    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.085 on 389 degrees of freedom
## Multiple R-squared:  0.002528,   Adjusted R-squared:  -0.002601 
## F-statistic: 0.4929 on 2 and 389 DF,  p-value: 0.6112

Interpretácia:

Po vynechaní premennej Prijem_mid sa kvalita regresného modelu zlepšila. Model s premennými Vek a Seba dosiahol vyššie Adjusted R² (≈ 0.054) a jediným štatisticky významným prediktorom ostala premenná Seba (p < 0.001), ktorá pozitívne súvisí s hodnotou IndexFG. Naopak, model bez premennej Seba nedosahuje štatistickú významnosť a žiadna z vysvetľujúcich premenných v ňom nemá významný efekt. Preto je z hľadiska kvality modelu aj odstránenia multikolinearity vhodné vynechať premennú Prijem_mid, ktorá neprispieva k vysvetleniu IndexFG.

Škálovanie premenných

Škálovanie (centrovanie a delenie smerodajnou odchýlkou) zmenší rozdiely v rádoch medzi premennými a výrazne zlepší Condition Number, ale sťaží „intuitívnu“ interpretáciu koeficientov.

reg_df$Prijem_c <- scale(reg_df$Prijem_mid, center = TRUE, scale = TRUE)
reg_df$Vek_c    <- scale(reg_df$Vek,        center = TRUE, scale = TRUE)
reg_df$Seba_c   <- scale(reg_df$Seba,       center = TRUE, scale = TRUE)

model_scaled <- lm(FG_index ~ Prijem_c + Vek_c + Seba_c, data = reg_df)
summary(model_scaled)
## 
## Call:
## lm(formula = FG_index ~ Prijem_c + Vek_c + Seba_c, data = reg_df)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -6.4169 -1.3509  0.4256  1.5578  3.4122 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  7.35204    0.10240  71.798  < 2e-16 ***
## Prijem_c    -0.03368    0.14298  -0.236    0.814    
## Vek_c       -0.03597    0.13899  -0.259    0.796    
## Seba_c       0.52080    0.10759   4.841 1.87e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.027 on 388 degrees of freedom
## Multiple R-squared:  0.05934,    Adjusted R-squared:  0.05206 
## F-statistic: 8.158 on 3 and 388 DF,  p-value: 2.797e-05
vif(model_scaled)
## Prijem_c    Vek_c   Seba_c 
## 1.944711 1.837686 1.101082
X_scaled  <- model.matrix(model_scaled)[, -1]
XtX_scaled <- t(X_scaled) %*% X_scaled
eig_s <- eigen(XtX_scaled)
condition_number_scaled <- sqrt(max(eig_s$values) / min(eig_s$values))
condition_number_scaled
## [1] 2.406549

Interprtácia: Po preškálovaní vysvetľujúcich premenných (Prijem_mid, Vek, Seba) sa výrazne zlepšili numerické vlastnosti modelu, pričom ukazovateľ Condition Number klesol na hodnotu 2.41, čo signalizuje prakticky nulovú multikolinearitu. Hodnoty VIF sú taktiež veľmi nízke (1.10 – 1.94), takže žiadna z premenných nevykazuje problém s kolinearitou.

Výsledky regresie ukazujú, že zo všetkých zahrnutých premenných je štatisticky významnym prediktorom Indexu finančnej gramotnosti iba sebahodnotenie (β = 0.521, p < 0.001). Vyššie subjektívne hodnotenie vlastných finančných znalostí je teda spojené s vyšším objektívnym skóre finančnej gramotnosti.

Premenné Prijem_c a Vek_c nevychádzajú štatisticky významne (p > 0.79), čo naznačuje, že pri kontrole sebahodnotenia nemajú výrazný samostatný efekt na IndexFG. Celková vysvetlená variabilita modelu je nízka (R² = 0.059), čo je pri dotazníkových údajoch bežné.

Celkovo možno konštatovať, že škálovanie účinne odstránilo numerickú multikolinearitu a výsledný model umožňuje spoľahlivú interpretáciu efektov jednotlivých premenných. Zároveň platí, že subjektívna vnímaná úroveň finančnej gramotnosti je najlepším prediktorom objektívneho indexu finančných vedomostí v analyzovanej vzorke.