Spotreba cukru a výskyt cukrovky

Lineárna regresia

Autor

Ema Šimkovicová

Publikované

29. októbra 2026

1 Predmet výskumu

Pri nasledujúcom zadaní vychádzam z otázky, ktorú som si položila už pri opise údajov:

  • Súvisí vyššia spotreba cukru na obyvateľa s vyšším výskytom cukrovky?

2 Údaje

Pracujem so súborom sugar_consumption_dataset.csv, ktorý som vyčistila v minulom zadaní. Jeden riadok je jeden záznam (krajina + rok). Na jednu dvojicu krajina + rok pripadá viac záznamov s odlišnými hodnotami, preto nevyberám jeden rok ako vo vzore. Všetkých 10000 záznamov beriem ako samostatné pozorovania, teda ako združené prierezové údaje (pooled cross-section). `r if (pocet_na == 0)

Premenné použité v modeloch
Premenná Význam Jednotka
diabetes Výskyt cukrovky v populácii; vysvetľovaná premenná. %
spotreba_na_obyv Ročná spotreba cukru na obyvateľa. kg / osoba / rok
obezita Miera obezity. %
hdp_tis HDP na obyvateľa v tisícoch USD. tis. USD
urbanizacia Miera urbanizácie. %
Opisná štatistika premenných modelu
Premenná Minimum Medián Priemer Maximum
diabetes 2.14 9.33 9.35 16.55
spotreba_na_obyv 5.02 37.88 37.63 69.99
obezita 5.00 22.26 22.36 40.00
hdp_tis 0.50 25.16 25.24 50.00
urbanizacia 10.02 50.20 49.97 90.00

3 Graf

Hypotéza: Očakávam, že záznamy s vyššou spotrebou cukru majú spravidla aj vyšší

graf_cukor <- ggplot(udaje.model,
                     aes(x = spotreba_na_obyv, y = diabetes)) +
  geom_point(color = farba, size = 1, alpha = 0.15) +
  labs(x = "Spotreba cukru (kg na osobu za rok)",
       y = "Výskyt cukrovky (%)") +
  theme_minimal(base_size = 13)

graf_cukor
Obrázok 1: Spotreba cukru a výskyt cukrovky. Každý bod predstavuje jeden záznam (krajina + rok).

Odpovede na otázky zo vzoru:

  • Je závislosť rastúca, alebo klesajúca? Korelačný koeficient je 0,122, takže závislosť je rastúca a slabá. Body pokrývajú takmer celú plochu grafu, takže sklon voľným okom takmer nevidno.
  • Majú všetky záznamy s podobnou spotrebou aj rovnaký výskyt cukrovky? Nie. Napríklad pri spotrebe 35 až 40 kg ročne (763 záznamov) sa výskyt cukrovky pohybuje od 2,9 % do 15,9 %.

4 Jednoduchá lineárna regresia

4.1 Zápis modelu

Najprv použijem iba jednu vysvetľujúcu premennú:

\[ Diabetes_i = \beta_0 + \beta_1 Spotreba_i + u_i. \]

  • \(i\) označuje záznam (krajina + rok).
  • \(\beta_0\) je konštanta, teda priesečník regresnej priamky s osou Y.
  • \(\beta_1\) je smernica priamky: vyjadruje rozdiel predikovaného výskytu cukrovky pri rozdiele spotreby o 1 kg ročne.
  • \(u_i\) zachytáva tú časť výskytu cukrovky, ktorú tento jednoduchý model nevysvetľuje.

Regresná priamka nemusí prechádzať všetkými bodmi. Metóda najmenších štvorcov vyberie takú priamku, ktorá minimalizuje súčet štvorcov vertikálnych rozdielov medzi bodmi a priamkou.

4.2 Odhad pomocou lm()

model1 <- lm(diabetes ~ spotreba_na_obyv, data = udaje.model)
vysledky1 <- tidy(model1)
vysledky1 |>
  mutate(odhad = sapply(estimate, koef)) |>   # desatinná čiarka
  select(term, odhad) |>
  kable(format = "html", row.names = FALSE, align = c("l", "r"),
        col.names = c("Člen modelu", "Odhad koeficienta"),
        caption = "Jednoduchá regresia: výskyt cukrovky a spotreba cukru") |>
  styl()
Jednoduchá regresia: výskyt cukrovky a spotreba cukru
Člen modelu Odhad koeficienta
(Intercept) 8,419
spotreba_na_obyv 0,0247
b0 <- coef(model1)["(Intercept)"]
b1 <- coef(model1)["spotreba_na_obyv"]

Funkcia tidy(model1) z balíka broom prevedie výsledky modelu na tabuľku: jeden riadok zodpovedá jednému koeficientu. Stĺpec term obsahuje názov člena modelu a estimate jeho odhad. Označenie (Intercept) znamená konštantu. Zobrazujem iba tieto dva stĺpce.

Znak ~ čítam ako „vysvetľujem pomocou“. Vľavo je vysvetľovaná premenná a vpravo vysvetľujúca premenná. Konštantu R zahrnie automaticky.

Odhadnutá regresná priamka:

\[ \widehat{Diabetes}_i = 8{,}419 + 0{,}0247\,Spotreba_i. \]

Interpretácia smernice: Výskyt cukrovky je v percentách, preto rozdiely vyjadrujem v percentuálnych bodoch (p. b.), nie v percentách. Rozdiel 1 kg v ročnej spotrebe cukru na obyvateľa sa v tomto modeli spája s približne o 0,0247 p. b. vyšším predikovaným výskytom cukrovky. Pri rozdiele 10 kg (asi 27 g cukru denne) je to približne 0,25 p. b.

Interpretácia konštanty: Pri nulovej spotrebe cukru by priamka predikovala výskyt cukrovky približne 8,42 %. Najnižšia spotreba v údajoch je však 5,0 kg, takže nula leží mimo pozorovaného rozsahu. Konštantu preto chápem predovšetkým ako parameter polohy priamky.

Poznámka

Súvis medzi záznamami sám osebe nedokazuje, že ak niekto zje o 10 kg cukru ročne viac, jeho riziko cukrovky stúpne o 0,25 p. b. Krajiny a roky sa líšia aj v mnohých ďalších charakteristikách a údaje sú navyše pravdepodobne simulované.

4.3 Regresná priamka v grafe

K bodovému grafu pridám priamku pomocou geom_abline(). Jej konštantu (intercept) a smernicu (slope) prevezmem priamo z odhadnutého modelu model1.

graf_cukor +
  geom_abline(intercept = coef(model1)["(Intercept)"],
              slope = coef(model1)["spotreba_na_obyv"],
              color = "firebrick", linewidth = 1)
Obrázok 2: Odhadnutá regresná priamka pre spotrebu cukru a výskyt cukrovky.

5 Viacnásobná lineárna regresia

Výskyt cukrovky môže súvisieť s viacerými charakteristikami súčasne. Model rozšírim o tri premenné:

  • obezita je jeden z hlavných rizikových faktorov cukrovky 2. typu,
  • HDP na obyvateľa zachytáva rozdiely v životnej úrovni, strave aj v tom, ako často sa cukrovka diagnostikuje,
  • urbanizácia súvisí s menším pohybom a vyššou spotrebou spracovaných potravín.

\[ Diabetes_i = \beta_0 + \beta_1 Spotreba_i + \beta_2 Obezita_i + \beta_3 HDP_i + \beta_4 Urbanizacia_i + u_i. \]

Do modelu nezaraďujem denný príjem cukru (denny_prijem). V minulom zadaní som overila, že je len prepočtom spotreby (g za deň = kg × 1000 / 365). Obe premenné teda nesú tú istú informáciu a R by nevedel oddeliť ich vplyv (dokonalá multikolinearita).

model <- lm(diabetes ~ spotreba_na_obyv + obezita + hdp_tis + urbanizacia,
            data = udaje.model)
vysledky <- tidy(model)
vysledky |>
  mutate(odhad = sapply(estimate, koef)) |>
  select(term, odhad) |>
  kable(format = "html", row.names = FALSE, align = c("l", "r"),
        col.names = c("Člen modelu", "Odhad koeficienta"),
        caption = "Viacnásobná regresia: spotreba cukru, obezita, HDP a urbanizácia") |>
  styl()
Viacnásobná regresia: spotreba cukru, obezita, HDP a urbanizácia
Člen modelu Odhad koeficienta
(Intercept) 8,459
spotreba_na_obyv 0,0247
obezita -0,00165
hdp_tis -0,00230
urbanizacia 0,00111
b <- coef(model)

Vo vzore bolo potrebných osem desatinných miest, aby sa malý koeficient pri GDP nezaokrúhlil na nulu. Tu tento problém nemám, lebo HDP som už v minulom zadaní prepočítala na tisíce USD (hdp_tis). Počet desatinných miest sa navyše nastavuje automaticky podľa veľkosti koeficienta. Odhadnutá rovnica:

\[ \widehat{Diabetes}_i = 8{,}459 + 0{,}0247\,Spotreba_i - 0{,}00165\,Obezita_i - 0{,}00230\,HDP_i + 0{,}00111\,Urbanizacia_i. \]

Každý koeficient sa teraz interpretuje pri rovnakých hodnotách ostatných premenných v modeli:

  • Spotreba cukru: rozdiel 1 kg ročne sa pri rovnakej obezite, HDP a urbanizácii spája s približne o 0,0247 p. b. vyšším predikovaným výskytom cukrovky.
  • Obezita: rozdiel 1 p. b. v miere obezity sa spája s približne o 0,00165 p. b. nižším predikovaným výskytom cukrovky.
  • HDP: rozdiel 1 000 USD v HDP na obyvateľa sa spája s približne o 0,00230 p. b. nižším predikovaným výskytom cukrovky. Vďaka jednotke „tisíc USD“ netreba koeficient násobiť tisícom ako vo vzore.
  • Urbanizácia: rozdiel 1 p. b. v miere urbanizácie sa spája s približne o 0,00111 p. b. vyšším predikovaným výskytom cukrovky.

5.1 Zmenil sa koeficient spotreby cukru?

Vo vzore sa koeficient Schooling po pridaní ďalších premenných zmenšil (z 2,23 na 1,92). Vzdelanie totiž súvisí s HDP, a tak časť súvisu, ktorú jednoduchý model pripisoval vzdelaniu, prevzalo HDP. Pozriem sa preto, ako spolu súvisia moje vysvetľujúce premenné:

vysvetlujuce <- c("spotreba_na_obyv", "obezita", "hdp_tis", "urbanizacia")
korelacie <- cor(udaje.model[vysvetlujuce])
korelacie |>
  kable(format = "html", digits = 3,
        caption = "Korelácie medzi vysvetľujúcimi premennými") |>
  styl()
Korelácie medzi vysvetľujúcimi premennými
spotreba_na_obyv obezita hdp_tis urbanizacia
spotreba_na_obyv 1.000 0.002 -0.002 0.012
obezita 0.002 1.000 0.008 0.008
hdp_tis -0.002 0.008 1.000 -0.008
urbanizacia 0.012 0.008 -0.008 1.000
max_kor <- max(abs(korelacie[upper.tri(korelacie)]))
zmena <- (b["spotreba_na_obyv"] - b1) / b1

Koeficient spotreby cukru je v jednoduchom modeli 0,0247 a vo viacnásobnom 0,0247, takže sa takmer nezmenil (zmena o -0,1 %). Dôvod vidno v tabuľke korelácií: najväčšia korelácia medzi vysvetľujúcimi premennými (v absolútnej hodnote) je iba 0,012. Keď pridaná premenná so spotrebou cukru nesúvisí, nemôže od nej „prevziať“ časť súvisu a odhad sa takmer nezmení. Aj toto zodpovedá tomu, že údaje sú simulované a premenné boli generované nezávisle.

Jednoduchý a viacnásobný model aj tak odpovedajú na odlišné otázky: druhý porovnáva záznamy s rovnakou obezitou, HDP a urbanizáciou.

6 Stručný súhrn modelu pomocou glance()

Zatiaľ čo tidy() poskytuje riadok pre každý koeficient, glance() poskytuje jeden riadok so súhrnnými charakteristikami celého modelu. Vyberám počet pozorovaní, \(R^2\) a odhad štandardnej odchýlky chyby. Pre porovnanie uvádzam oba modely.

suhrn1 <- glance(model1)
suhrn  <- glance(model)
suhrny <- data.frame(
  Model = c("jednoduchý", "viacnásobný"),
  rbind(suhrn1[c("nobs", "r.squared", "sigma")],
        suhrn[c("nobs", "r.squared", "sigma")])
)
suhrny |>
  kable(format = "html", digits = c(0, 0, 4, 3), row.names = FALSE,
        col.names = c("Model", "Počet záznamov", "R²", "Odhad SD chyby (p. b.)"),
        caption = "Základné charakteristiky modelov") |>
  styl()
Základné charakteristiky modelov
Model Počet záznamov R² Odhad SD chyby (p. b.)
jednoduchý 10000 0.0149 3.767
viacnásobný 10000 0.0150 3.767
r2 <- suhrn$r.squared
  • nobs je počet záznamov použitých pri odhade.
  • r.squared je podiel výberovej variability výskytu cukrovky zachytený modelom.
  • sigma je odhad štandardnej odchýlky modelovej chyby, tu vyjadrený v percentuálnych bodoch.

Hodnota \(R^2\) je vo viacnásobnom modeli 0,0150. Model teda zachytáva približne 1,5 % výberovej variability výskytu cukrovky. To je veľmi málo: takmer všetky rozdiely vo výskyte cukrovky medzi záznamami zostávajú nevysvetlené. Zodpovedá to zisteniu z minulého zadania, že premenné v týchto (pravdepodobne simulovaných) údajoch spolu takmer nesúvisia. Pridanie troch premenných zvýšilo \(R^2\) z 0,0149 na 0,0150.

Nízke \(R^2\) neznamená, že odhady koeficientov sú „zlé“. Znamená len, že výskyt cukrovky ovplyvňuje najmä niečo, čo v modeli nie je (alebo náhoda). Hodnota \(R^2\) tiež neznamená podiel správnych predikcií a nedokazuje kauzalitu.

Úplný textový súhrn je dostupný príkazom summary(model). tidy(model) okrem odhadov obsahuje aj std.error, statistic a p.value. Ich vysvetlenie patrí na hodinu venovanú štatistickému testovaniu, preto ich tu nezobrazujem.

7 Skutočná hodnota, predikcia a rezíduum

Pre každý záznam môžem porovnať skutočný výskyt cukrovky s hodnotou na regresnej ploche:

\[ e_i = y_i - \widehat y_i. \]

Tento rozdiel sa nazýva rezíduum. Kladné rezíduum znamená, že skutočná hodnota je vyššia než predikcia, záporné znamená opak. Rezíduum viem vypočítať, zatiaľ čo skutočnú modelovú chybu \(u_i\) nepoznám.

porovnanie <- data.frame(
  Krajina    = udaje.model$country,
  Rok        = udaje.model$year,
  Skutocnost = udaje.model$diabetes,
  Predikcia  = fitted(model),
  Reziduum   = residuals(model)
)
head(porovnanie, 8) |>
  kable(format = "html", digits = 2, row.names = FALSE,
        col.names = c("Krajina", "Rok", "Skutočnosť", "Predikcia", "Rezíduum"),
        caption = "Skutočný a predikovaný výskyt cukrovky (%)") |>
  styl()
Skutočný a predikovaný výskyt cukrovky (%)
Krajina Rok Skutočnosť Predikcia Rezíduum
France 1972 11.50 8.74 2.76
Australia 2003 6.52 8.98 -2.46
Germany 1963 8.25 9.23 -0.98
France 1965 11.00 9.65 1.34
Germany 2010 14.89 8.93 5.96
South Africa 1997 14.89 10.07 4.82
India 1965 11.99 8.98 3.01
Mexico 1970 8.88 9.84 -0.96
prvy <- porovnanie[1, ]

Úloha zo vzoru (ručné overenie): V prvom riadku (France, 1972) je skutočný výskyt cukrovky 11,4951 % a predikcia 8,7378 %. Ich rozdiel 11,4951 − 8,7378 = 2,7573 sa rovná rezíduu 2,7573.

Funkcia coef(model) vracia koeficienty, fitted(model) vyrovnané hodnoty a residuals(model) rezíduá. Maticu vysvetľujúcich premenných by som získala príkazom model.matrix(model).

8 Predikcia pre zadanú hodnotu

Na ukážku predikcie sa vrátim k jednoduchému modelu. Vypočítam, aký výskyt cukrovky priamka predikuje pre tri hodnoty spotreby. Prvá zodpovedá hornej hranici odporúčania WHO (50 g denne × 365 dní = 18,25 kg ročne), ktorú som používala v minulom zadaní:

nove_udaje <- data.frame(spotreba_na_obyv = c(18.25, 40, 60))
nove_udaje$Predikcia <- predict(model1, newdata = nove_udaje)
nove_udaje |>
  kable(format = "html", digits = 2, row.names = FALSE,
        col.names = c("Spotreba cukru (kg/rok)", "Predikcia výskytu cukrovky (%)"),
        caption = "Predikcie jednoduchého regresného modelu") |>
  styl()
Predikcie jednoduchého regresného modelu
Spotreba cukru (kg/rok) Predikcia výskytu cukrovky (%)
18.25 8.87
40.00 9.41
60.00 9.90

Rozdiel medzi spotrebou 18,25 kg a 60 kg ročne sa v modeli spája s rozdielom 1,03 p. b. vo výskyte cukrovky. Ide o bodové predikcie, nie o isté výsledky. Skutočný záznam môže mať iný výskyt cukrovky. Neistotu predikcie (predikčné intervaly) preberieme neskôr.

9 Malé cvičenia

9.1 Vysvetľovaná a vysvetľujúce premenné

Vysvetľovaná premenná je výskyt cukrovky (diabetes). V jednoduchom modeli je vysvetľujúcou premennou spotreba cukru na obyvateľa (spotreba_na_obyv). Vo viacnásobnom modeli k nej pribudli obezita, HDP na obyvateľa a urbanizácia.

9.2 Jednoduchý model s obezitou

Namiesto modelu s GDP zo vzoru odhadnem model s obezitou, lebo pri cukrovke dáva väčší zmysel.

model_ob <- lm(diabetes ~ obezita, data = udaje.model)
tidy(model_ob) |>
  mutate(odhad = sapply(estimate, koef)) |>
  select(term, odhad) |>
  kable(format = "html", row.names = FALSE, align = c("l", "r"),
        col.names = c("Člen modelu", "Odhad koeficienta"),
        caption = "Jednoduchá regresia: výskyt cukrovky a obezita") |>
  styl()
Jednoduchá regresia: výskyt cukrovky a obezita
Člen modelu Odhad koeficienta
(Intercept) 9,384
obezita -0,00157
ggplot(udaje.model, aes(x = obezita, y = diabetes)) +
  geom_point(color = farba, size = 1, alpha = 0.15) +
  geom_abline(intercept = coef(model_ob)["(Intercept)"],
              slope = coef(model_ob)["obezita"],
              color = "firebrick", linewidth = 1) +
  labs(x = "Miera obezity (%)", y = "Výskyt cukrovky (%)") +
  theme_minimal(base_size = 13)
Obrázok 3: Obezita a výskyt cukrovky s odhadnutou regresnou priamkou.

Rozdiel 1 p. b. v miere obezity sa spája s približne o 0,00157 p. b. nižším predikovaným výskytom cukrovky.

9.3 Koeficient spotreby v oboch modeloch

V jednoduchom modeli koeficient 0,0247 porovnáva záznamy, ktoré sa líšia spotrebou cukru, bez ohľadu na ostatné charakteristiky. Vo viacnásobnom modeli koeficient 0,0247 porovnáva záznamy, ktoré sa líšia spotrebou, ale majú rovnakú obezitu, HDP a urbanizáciu. Preto dopĺňam „pri rovnakých ostatných premenných“: bez toho by sa súvis spotreby mohol miešať so súvisom premenných, ktoré sa so spotrebou menia spolu.

9.4 Predikcia pre spotrebu 30 kg

predikcia_30 <- predict(model1, newdata = data.frame(spotreba_na_obyv = 30))
rucne_30 <- coef(model1)["(Intercept)"] + coef(model1)["spotreba_na_obyv"] * 30
c(predict = unname(predikcia_30), rucne = unname(rucne_30))
predict   rucne 
9.16056 9.16056 

Ručne: 8,419 + 0,0247 × 30 = 9,161 %, čo sa zhoduje s výsledkom funkcie predict() (9,161 %).

9.5 Kladné a záporné rezíduum

kladne  <- porovnanie[porovnanie$Reziduum > 0, ][1, ]
zaporne <- porovnanie[porovnanie$Reziduum < 0, ][1, ]
rbind(kladne, zaporne) |>
  kable(format = "html", digits = 2, row.names = FALSE,
        col.names = c("Krajina", "Rok", "Skutočnosť", "Predikcia", "Rezíduum"),
        caption = "Príklad kladného a záporného rezídua") |>
  styl()
Príklad kladného a záporného rezídua
Krajina Rok Skutočnosť Predikcia Rezíduum
France 1972 11.50 8.74 2.76
Australia 2003 6.52 8.98 -2.46
  • France (1972) má kladné rezíduum 2,76: skutočný výskyt cukrovky je vyšší, než predikuje model.
  • Australia (2003) má záporné rezíduum -2,46: skutočný výskyt cukrovky je nižší, než predikuje model.

9.6 Prečo koeficient neznamená kauzálny účinok

Koeficient opisuje, ako sa v údajoch spolu menia spotreba cukru a výskyt cukrovky. Nehovorí, čo by sa stalo, keby sme spotrebu cukru zmenili. Súvis môžu spôsobovať iné faktory, ktoré v modeli nie sú (strava, vek populácie, pohyb, zdravotníctvo), alebo môže ísť o náhodu. Na kauzálny záver by bol potrebný experiment alebo špeciálne metódy. Pri simulovaných údajoch navyše nejde o skutočné správanie ľudí.