Cvičenie 4 – Čistenie a analýza údajov v Data Science

Moja vysnívaná kariéra: Dátový vedec

Autor

Martin Bakič

Publikované

19. októbra 2026

Kód
knitr::opts_chunk$set(
  echo = TRUE,
  message = FALSE,
  warning = FALSE
)

Úvod

V tomto cvičení sa venujem čisteniu a analýze údajov v programovacom jazyku R.

Pokračujem vo svojej téme Moja vysnívaná kariéra: Dátový vedec.

Cieľom je naučiť sa pracovať s databázou, upravovať názvy premenných, identifikovať chýbajúce hodnoty, dopĺňať ich a následne vytvárať grafy, tabuľky a jednoduché štatistické modely.

Pri analýze používam svoju databázu Latest Data Science Salaries, ktorá obsahuje údaje o pracovných pozíciách a platoch v oblasti Data Science.

1. Import skutočnej databázy

Databázu mám uloženú v priečinku údaje.

Kód
subor <- "údaje/Latest_Data_Science_Salaries.csv"

file.exists(subor)
[1] TRUE

Databázu načítam pomocou funkcie read.csv().

Pri importe ponechám pôvodné názvy stĺpcov, aby som ich mohol neskôr upraviť.

Kód
udaje <- read.csv(
  subor,
  header = TRUE,
  sep = ",",
  dec = ".",
  stringsAsFactors = FALSE,
  check.names = FALSE
)

head(udaje)
       Job Title Employment Type Experience Level Expertise Level Salary
1  Data Engineer       Full-Time           Senior          Expert 210000
2  Data Engineer       Full-Time           Senior          Expert 165000
3  Data Engineer       Full-Time           Senior          Expert 185900
4  Data Engineer       Full-Time           Senior          Expert 129300
5 Data Scientist       Full-Time           Senior          Expert 140000
6 Data Scientist       Full-Time           Senior          Expert 126000
       Salary Currency Company Location Salary in USD Employee Residence
1 United States Dollar    United States        210000      United States
2 United States Dollar    United States        165000      United States
3 United States Dollar    United States        185900      United States
4 United States Dollar    United States        129300      United States
5 United States Dollar    United States        140000      United States
6 United States Dollar    United States        126000      United States
  Company Size Year
1       Medium 2023
2       Medium 2023
3       Medium 2023
4       Medium 2023
5       Medium 2023
6       Medium 2023

Rozmery databázy

Kód
dim(udaje)
[1] 3300   11

Databáza obsahuje 3300 pozorovaní a 11 premenných.

Názvy premenných

Kód
names(udaje)
 [1] "Job Title"          "Employment Type"    "Experience Level"  
 [4] "Expertise Level"    "Salary"             "Salary Currency"   
 [7] "Company Location"   "Salary in USD"      "Employee Residence"
[10] "Company Size"       "Year"              

Štruktúra databázy

Kód
str(udaje)
'data.frame':   3300 obs. of  11 variables:
 $ Job Title         : chr  "Data Engineer" "Data Engineer" "Data Engineer" "Data Engineer" ...
 $ Employment Type   : chr  "Full-Time" "Full-Time" "Full-Time" "Full-Time" ...
 $ Experience Level  : chr  "Senior" "Senior" "Senior" "Senior" ...
 $ Expertise Level   : chr  "Expert" "Expert" "Expert" "Expert" ...
 $ Salary            : int  210000 165000 185900 129300 140000 126000 170000 130000 85000 75000 ...
 $ Salary Currency   : chr  "United States Dollar" "United States Dollar" "United States Dollar" "United States Dollar" ...
 $ Company Location  : chr  "United States" "United States" "United States" "United States" ...
 $ Salary in USD     : int  210000 165000 185900 129300 140000 126000 170000 130000 104584 92280 ...
 $ Employee Residence: chr  "United States" "United States" "United States" "United States" ...
 $ Company Size      : chr  "Medium" "Medium" "Medium" "Medium" ...
 $ Year              : int  2023 2023 2023 2023 2023 2023 2023 2023 2023 2023 ...

2. Upravovanie názvov premenných

Pôvodné názvy

Najskôr si uložím pôvodné názvy jednotlivých stĺpcov.

Kód
old_names <- names(udaje)

old_names
 [1] "Job Title"          "Employment Type"    "Experience Level"  
 [4] "Expertise Level"    "Salary"             "Salary Currency"   
 [7] "Company Location"   "Salary in USD"      "Employee Residence"
[10] "Company Size"       "Year"              

Úprava názvov

Názvy obsahujú medzery, preto ich upravím pomocou funkcie make.names().

Kód
names(udaje) <- make.names(
  names(udaje),
  unique = TRUE
)

names(udaje)
 [1] "Job.Title"          "Employment.Type"    "Experience.Level"  
 [4] "Expertise.Level"    "Salary"             "Salary.Currency"   
 [7] "Company.Location"   "Salary.in.USD"      "Employee.Residence"
[10] "Company.Size"       "Year"              

Po úprave môžem používať napríklad:

  • Job.Title
  • Experience.Level
  • Salary.in.USD
  • Company.Location
  • Company.Size
  • Year

Porovnanie názvov

Kód
comparison <- data.frame(
  Povodny_nazov = old_names,
  Upraveny_nazov = names(udaje)
)

knitr::kable(
  comparison,
  caption = "Porovnanie pôvodných a upravených názvov"
)
Porovnanie pôvodných a upravených názvov
Povodny_nazov Upraveny_nazov
Job Title Job.Title
Employment Type Employment.Type
Experience Level Experience.Level
Expertise Level Expertise.Level
Salary Salary
Salary Currency Salary.Currency
Company Location Company.Location
Salary in USD Salary.in.USD
Employee Residence Employee.Residence
Company Size Company.Size
Year Year

3. Počiatočná kontrola databázy

Chýbajúce hodnoty

Najskôr skontrolujem počet chýbajúcich hodnôt v jednotlivých premenných.

Kód
colSums(
  is.na(udaje)
)
         Job.Title    Employment.Type   Experience.Level    Expertise.Level 
                 0                  0                  0                  0 
            Salary    Salary.Currency   Company.Location      Salary.in.USD 
                 0                  0                  0                  0 
Employee.Residence       Company.Size               Year 
                 0                  0                  0 

Celkový počet chýbajúcich hodnôt:

Kód
sum(
  is.na(udaje)
)
[1] 0

Úplné záznamy

Kód
sum(
  complete.cases(udaje)
)
[1] 3300

Neúplné záznamy

Kód
sum(
  !complete.cases(udaje)
)
[1] 0

Pôvodná databáza neobsahuje chýbajúce hodnoty.

Kontrola duplicít

Kód
sum(
  duplicated(udaje)
)
[1] 0

Odstránenie úplných duplicít

Pre istotu vytvorím čistú verziu databázy pomocou funkcie unique().

Kód
udaje_ciste <- unique(
  udaje
)

dim(
  udaje_ciste
)
[1] 3300   11

4. Výber pracovnej pozície Data Scientist

Keďže mojou vysnívanou kariérou je pozícia Data Scientist, vyberiem iba tieto záznamy.

Kód
data_scientist <- subset(
  udaje_ciste,
  Job.Title == "Data Scientist"
)

head(
  data_scientist
)
        Job.Title Employment.Type Experience.Level Expertise.Level Salary
5  Data Scientist       Full-Time           Senior          Expert 140000
6  Data Scientist       Full-Time           Senior          Expert 126000
7  Data Scientist       Full-Time           Senior          Expert 170000
8  Data Scientist       Full-Time           Senior          Expert 130000
17 Data Scientist       Full-Time           Senior          Expert 185900
18 Data Scientist       Full-Time           Senior          Expert 129300
        Salary.Currency Company.Location Salary.in.USD Employee.Residence
5  United States Dollar    United States        140000      United States
6  United States Dollar    United States        126000      United States
7  United States Dollar    United States        170000      United States
8  United States Dollar    United States        130000      United States
17 United States Dollar    United States        185900      United States
18 United States Dollar    United States        129300      United States
   Company.Size Year
5        Medium 2023
6        Medium 2023
7        Medium 2023
8        Medium 2023
17       Medium 2023
18       Medium 2023

Počet pozorovaní:

Kód
nrow(
  data_scientist
)
[1] 635

Databáza obsahuje 635 záznamov pracovnej pozície Data Scientist.

5. Vytvorenie časovej databázy

Pre ďalšie čistenie vytvorím databázu, ktorá sumarizuje údaje Data Scientist podľa jednotlivých rokov.

Kód
roky <- sort(
  unique(
    data_scientist$Year
  )
)

Vytvorím priemerný plat, medián platu a počet pozorovaní podľa rokov.

Kód
rocne_udaje <- data.frame(

  Rok = roky,

  Priemerny.plat = sapply(
    roky,
    function(r) {
      mean(
        data_scientist$Salary.in.USD[
          data_scientist$Year == r
        ]
      )
    }
  ),

  Median.platu = sapply(
    roky,
    function(r) {
      median(
        data_scientist$Salary.in.USD[
          data_scientist$Year == r
        ]
      )
    }
  ),

  Pocet.pozorovani = sapply(
    roky,
    function(r) {
      sum(
        data_scientist$Year == r
      )
    }
  )
)

rocne_udaje
   Rok Priemerny.plat Median.platu Pocet.pozorovani
1 2020       85970.52        62726               21
2 2021       79366.23        77684               39
3 2022      127960.07       127750              222
4 2023      160877.95       158677              353

6. Vytvorenie pracovnej databázy s chybami

Keďže pôvodná databáza je kompletná, na precvičenie čistenia vytvorím jej pracovnú kópiu.

Pôvodné údaje týmto nijako nemením.

Kód
udaje1 <- rocne_udaje

Do pracovnej kópie zámerne vložím niekoľko chýbajúcich hodnôt.

Kód
udaje1$Priemerny.plat[
  udaje1$Rok == 2021
] <- NA

udaje1$Median.platu[
  udaje1$Rok == 2022
] <- NA

udaje1$Pocet.pozorovani[
  udaje1$Rok == 2023
] <- NA

udaje1
   Rok Priemerny.plat Median.platu Pocet.pozorovani
1 2020       85970.52        62726               21
2 2021             NA        77684               39
3 2022      127960.07           NA              222
4 2023      160877.95       158677               NA

Tieto chýbajúce hodnoty boli vytvorené iba na účely precvičenia čistenia databázy.

7. Kontrola chýbajúcich údajov

Počet chýbajúcich hodnôt

Kód
print(
  "Počet chýbajúcich údajov podľa premenných"
)
[1] "Počet chýbajúcich údajov podľa premenných"
Kód
colSums(
  is.na(udaje1)
)
             Rok   Priemerny.plat     Median.platu Pocet.pozorovani 
               0                1                1                1 

Celkový počet NA

Kód
sum(
  is.na(udaje1)
)
[1] 3

Počet úplných záznamov

Kód
sum(
  complete.cases(udaje1)
)
[1] 1

Počet neúplných záznamov

Kód
sum(
  !complete.cases(udaje1)
)
[1] 3

Zobrazenie neúplných riadkov

Kód
neuplne_riadky <- udaje1[
  !complete.cases(udaje1),
]

neuplne_riadky
   Rok Priemerny.plat Median.platu Pocet.pozorovani
2 2021             NA        77684               39
3 2022       127960.1           NA              222
4 2023       160877.9       158677               NA

8. Vizualizácia chýbajúcich údajov

Graf počtu chýbajúcich hodnôt

Kód
chybajuce <- colSums(
  is.na(udaje1)
)

barplot(
  chybajuce,
  main = "Počet chýbajúcich údajov",
  xlab = "Premenné",
  ylab = "Počet NA",
  las = 2,
  cex.names = 0.8
)

Mapa chýbajúcich hodnôt

Kód
matica_na <- is.na(
  udaje1
)

image(
  x = seq_len(
    nrow(matica_na)
  ),
  y = seq_len(
    ncol(matica_na)
  ),
  z = matica_na,
  xlab = "Pozorovanie",
  ylab = "Premenná",
  main = "Mapa chýbajúcich hodnôt",
  yaxt = "n"
)

axis(
  2,
  at = seq_len(
    ncol(matica_na)
  ),
  labels = names(
    udaje1
  ),
  las = 2,
  cex.axis = 0.7
)

9. Imputácia chýbajúcich hodnôt

Imputácia znamená nahradenie chýbajúcich hodnôt odhadnutými hodnotami.

Porovnám dve metódy:

  1. nahradenie priemerom,
  2. lineárnu interpoláciu.

Nahradenie priemerom

Najskôr vytvorím kópiu databázy.

Kód
udaje_priemer <- udaje1

Numerické premenné:

Kód
numericke_stlpce <- c(
  "Priemerny.plat",
  "Median.platu",
  "Pocet.pozorovani"
)

Chýbajúce hodnoty nahradím priemerom danej premennej.

Kód
for (
  stlpec in numericke_stlpce
) {

  priemer <- mean(
    udaje_priemer[[stlpec]],
    na.rm = TRUE
  )

  udaje_priemer[[stlpec]][
    is.na(
      udaje_priemer[[stlpec]]
    )
  ] <- priemer
}

udaje_priemer
   Rok Priemerny.plat Median.platu Pocet.pozorovani
1 2020       85970.52     62726.00               21
2 2021      124936.18     77684.00               39
3 2022      127960.07     99695.67              222
4 2023      160877.95    158677.00               94

Kontrola:

Kód
colSums(
  is.na(
    udaje_priemer
  )
)
             Rok   Priemerny.plat     Median.platu Pocet.pozorovani 
               0                0                0                0 

10. Lineárna interpolácia

Keďže databáza obsahuje údaje zoradené podľa rokov, môžeme použiť aj lineárnu interpoláciu.

Kód
udaje_interpolacia <- udaje1

for (
  stlpec in numericke_stlpce
) {

  udaje_interpolacia[[stlpec]] <- approx(
    x = udaje1$Rok,
    y = udaje1[[stlpec]],
    xout = udaje1$Rok,
    rule = 2
  )$y
}

Počet pozorovaní by mal byť celé číslo, preto ho zaokrúhlim.

Kód
udaje_interpolacia$Pocet.pozorovani <- round(
  udaje_interpolacia$Pocet.pozorovani
)

udaje_interpolacia
   Rok Priemerny.plat Median.platu Pocet.pozorovani
1 2020       85970.52      62726.0               21
2 2021      106965.30      77684.0               39
3 2022      127960.07     118180.5              222
4 2023      160877.95     158677.0              222

Kontrola po interpolácii

Kód
colSums(
  is.na(
    udaje_interpolacia
  )
)
             Rok   Priemerny.plat     Median.platu Pocet.pozorovani 
               0                0                0                0 

11. Porovnanie metód

Porovnám pôvodné hodnoty priemerného platu s hodnotami doplnenými priemerom a interpoláciou.

Kód
porovnanie <- data.frame(

  Rok =
    udaje1$Rok,

  Povodna_hodnota =
    udaje1$Priemerny.plat,

  Priemer =
    udaje_priemer$Priemerny.plat,

  Interpolacia =
    udaje_interpolacia$Priemerny.plat
)

knitr::kable(
  porovnanie,
  digits = 2,
  caption = "Porovnanie metód dopĺňania chýbajúcich údajov"
)
Porovnanie metód dopĺňania chýbajúcich údajov
Rok Povodna_hodnota Priemer Interpolacia
2020 85970.52 85970.52 85970.52
2021 NA 124936.18 106965.30
2022 127960.07 127960.07 127960.07
2023 160877.95 160877.95 160877.95

Pri údajoch zoradených v čase môže byť interpolácia vhodnejšia ako jednoduché nahradenie priemerom, pretože zohľadňuje vývoj medzi jednotlivými rokmi.

12. Príprava vyčistenej databázy

Na ďalšiu analýzu použijem databázu s interpolovanými hodnotami.

Kód
rocne_ciste <- udaje_interpolacia

rocne_ciste
   Rok Priemerny.plat Median.platu Pocet.pozorovani
1 2020       85970.52      62726.0               21
2 2021      106965.30      77684.0               39
3 2022      127960.07     118180.5              222
4 2023      160877.95     158677.0              222

Rozdiel priemeru a mediánu

Vytvorím novú premennú, ktorá ukazuje rozdiel medzi priemerným platom a mediánom.

Kód
rocne_ciste$Rozdiel.priemer.median <- round(
  rocne_ciste$Priemerny.plat -
    rocne_ciste$Median.platu,
  2
)

rocne_ciste
   Rok Priemerny.plat Median.platu Pocet.pozorovani Rozdiel.priemer.median
1 2020       85970.52      62726.0               21               23244.52
2 2021      106965.30      77684.0               39               29281.30
3 2022      127960.07     118180.5              222                9779.57
4 2023      160877.95     158677.0              222                2200.95

Medziročná zmena platu

Vypočítam percentuálnu medziročnú zmenu priemerného platu.

Kód
rocne_ciste$Rast.platu.percent <- c(
  NA,
  round(
    diff(
      rocne_ciste$Priemerny.plat
    ) /
      head(
        rocne_ciste$Priemerny.plat,
        -1
      ) *
      100,
    2
  )
)

rocne_ciste
   Rok Priemerny.plat Median.platu Pocet.pozorovani Rozdiel.priemer.median
1 2020       85970.52      62726.0               21               23244.52
2 2021      106965.30      77684.0               39               29281.30
3 2022      127960.07     118180.5              222                9779.57
4 2023      160877.95     158677.0              222                2200.95
  Rast.platu.percent
1                 NA
2              24.42
3              19.63
4              25.73

Výber údajov od roku 2022

Kód
udaje_2022 <- subset(
  rocne_ciste,
  Rok >= 2022
)

udaje_2022
   Rok Priemerny.plat Median.platu Pocet.pozorovani Rozdiel.priemer.median
3 2022       127960.1     118180.5              222                9779.57
4 2023       160877.9     158677.0              222                2200.95
  Rast.platu.percent
3              19.63
4              25.73

Triedenie podľa priemerného platu

Kód
udaje_zoradene <- rocne_ciste[
  order(
    rocne_ciste$Priemerny.plat,
    decreasing = TRUE
  ),
]

udaje_zoradene
   Rok Priemerny.plat Median.platu Pocet.pozorovani Rozdiel.priemer.median
4 2023      160877.95     158677.0              222                2200.95
3 2022      127960.07     118180.5              222                9779.57
2 2021      106965.30      77684.0               39               29281.30
1 2020       85970.52      62726.0               21               23244.52
  Rast.platu.percent
4              25.73
3              19.63
2              24.42
1                 NA

13. Grafické zobrazenie údajov

Vývoj priemerného platu

Kód
plot(
  rocne_ciste$Rok,
  rocne_ciste$Priemerny.plat,
  type = "b",
  pch = 19,
  xlab = "Rok",
  ylab = "Priemerný plat v USD",
  main = "Vývoj priemerného platu Data Scientist"
)

Priemer a medián

Kód
matplot(
  rocne_ciste$Rok,

  rocne_ciste[, c(
    "Priemerny.plat",
    "Median.platu"
  )],

  type = "b",
  pch = c(
    19,
    17
  ),
  lty = 1,

  xlab = "Rok",
  ylab = "Plat v USD",
  main = "Priemerný a mediánový plat Data Scientist"
)

legend(
  "topleft",
  legend = c(
    "Priemer",
    "Medián"
  ),
  lty = 1,
  pch = c(
    19,
    17
  ),
  bty = "n"
)

Vzťah počtu pozorovaní a platu

Kód
plot(
  rocne_ciste$Pocet.pozorovani,
  rocne_ciste$Priemerny.plat,
  pch = 19,
  xlab = "Počet pozorovaní",
  ylab = "Priemerný plat v USD",
  main = "Počet pozorovaní a priemerný plat"
)

14. Boxplot skutočných platov podľa rokov

V ďalších grafoch použijem opäť pôvodnú reálnu databázu.

Kód
boxplot(
  Salary.in.USD ~ factor(Year),
  data = data_scientist,
  xlab = "Rok",
  ylab = "Plat v USD",
  main = "Rozdelenie platov Data Scientist podľa rokov"
)

15. Boxplot podľa skúseností

Kód
boxplot(
  Salary.in.USD ~ Experience.Level,
  data = data_scientist,
  xlab = "Úroveň skúseností",
  ylab = "Plat v USD",
  main = "Platy Data Scientist podľa skúseností"
)

16. Základné štatistiky

Štatistiky podľa rokov

Kód
roky <- sort(
  unique(
    data_scientist$Year
  )
)

statistiky <- data.frame(

  Rok = roky,

  Pocet = sapply(
    roky,
    function(r) {
      sum(
        data_scientist$Year == r
      )
    }
  ),

  Priemer = sapply(
    roky,
    function(r) {
      mean(
        data_scientist$Salary.in.USD[
          data_scientist$Year == r
        ]
      )
    }
  ),

  SD = sapply(
    roky,
    function(r) {
      sd(
        data_scientist$Salary.in.USD[
          data_scientist$Year == r
        ]
      )
    }
  ),

  Minimum = sapply(
    roky,
    function(r) {
      min(
        data_scientist$Salary.in.USD[
          data_scientist$Year == r
        ]
      )
    }
  ),

  Median = sapply(
    roky,
    function(r) {
      median(
        data_scientist$Salary.in.USD[
          data_scientist$Year == r
        ]
      )
    }
  ),

  Maximum = sapply(
    roky,
    function(r) {
      max(
        data_scientist$Salary.in.USD[
          data_scientist$Year == r
        ]
      )
    }
  )
)

knitr::kable(
  statistiky,
  digits = 2,
  caption = "Základné štatistiky platov Data Scientist podľa rokov"
)
Základné štatistiky platov Data Scientist podľa rokov
Rok Pocet Priemer SD Minimum Median Maximum
2020 21 85970.52 81436.65 21669 62726 412000
2021 39 79366.23 41063.36 16904 77684 165000
2022 222 127960.07 57428.99 17684 127750 350000
2023 353 160877.95 65251.37 16000 158677 370000

Kvartily

Kód
quantile(
  data_scientist$Salary.in.USD,
  probs = c(
    0.25,
    0.50,
    0.75
  )
)
   25%    50%    75% 
 93400 140000 184217 

Súhrn platu

Kód
summary(
  data_scientist$Salary.in.USD
)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  16000   93400  140000  141886  184217  412000 

17. Testovanie hypotéz

T-test

Pomocou t-testu porovnám priemerný plat Data Scientist v rokoch 2022 a 2023.

Kód
plat_2022 <- data_scientist$Salary.in.USD[
  data_scientist$Year == 2022
]

plat_2023 <- data_scientist$Salary.in.USD[
  data_scientist$Year == 2023
]

t_test_result <- t.test(
  plat_2022,
  plat_2023
)

print(
  t_test_result
)

    Welch Two Sample t-test

data:  plat_2022 and plat_2023
t = -6.3447, df = 513.16, p-value = 4.9e-10
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -43110.69 -22725.07
sample estimates:
mean of x mean of y 
 127960.1  160877.9 

Nulová hypotéza predpokladá, že priemerný plat Data Scientist v roku 2022 a 2023 je rovnaký.

18. ANOVA

Pomocou analýzy rozptylu porovnám platy medzi jednotlivými úrovňami skúseností.

Kód
data_scientist$Experience.Level <- factor(
  data_scientist$Experience.Level
)

anova_result <- aov(
  Salary.in.USD ~ Experience.Level,
  data = data_scientist
)

summary(
  anova_result
)
                  Df    Sum Sq   Mean Sq F value Pr(>F)    
Experience.Level   3 8.987e+11 2.996e+11   98.75 <2e-16 ***
Residuals        631 1.914e+12 3.033e+09                   
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

ANOVA umožňuje porovnať priemerné platy skupín Entry, Mid, Senior a Executive.

19. Lineárna regresia

Pomocou lineárnej regresie preskúmam, ako plat Data Scientist súvisí s rokom, skúsenosťami a veľkosťou spoločnosti.

Model má tvar:

\[ SALARY_i = \beta_0 + \beta_1 YEAR_i + \beta_2 EXPERIENCE_i + \beta_3 SIZE_i + \varepsilon_i \]

Kód
data_scientist$Company.Size <- factor(
  data_scientist$Company.Size
)

model <- lm(
  Salary.in.USD ~
    Year +
    Experience.Level +
    Company.Size,
  data = data_scientist
)

summary(
  model
)

Call:
lm(formula = Salary.in.USD ~ Year + Experience.Level + Company.Size, 
    data = data_scientist)

Residuals:
    Min      1Q  Median      3Q     Max 
-135659  -35648   -3527   30791  290271 

Coefficients:
                           Estimate Std. Error t value Pr(>|t|)    
(Intercept)               -22784627    6760716  -3.370 0.000797 ***
Year                          11301       3344   3.379 0.000771 ***
Experience.LevelExecutive     94384      14391   6.559 1.13e-10 ***
Experience.LevelMid           16348       8152   2.005 0.045359 *  
Experience.LevelSenior        77673       7751  10.022  < 2e-16 ***
Company.SizeMedium            18894       6692   2.823 0.004906 ** 
Company.SizeSmall            -11859      11557  -1.026 0.305211    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 53430 on 628 degrees of freedom
Multiple R-squared:  0.3627,    Adjusted R-squared:  0.3566 
F-statistic: 59.57 on 6 and 628 DF,  p-value: < 2.2e-16

20. Regresné koeficienty

Kód
koeficienty <- as.data.frame(
  summary(model)$coefficients
)

koeficienty$Premenna <-
  rownames(
    koeficienty
  )

rownames(
  koeficienty
) <- NULL

knitr::kable(
  koeficienty,
  digits = 4,
  caption = "Regresné koeficienty modelu"
)
Regresné koeficienty modelu
Estimate Std. Error t value Pr(>|t|) Premenna
-22784627.24 6760716.497 -3.3701 0.0008 (Intercept)
11301.33 3344.190 3.3794 0.0008 Year
94383.80 14390.562 6.5587 0.0000 Experience.LevelExecutive
16348.02 8152.397 2.0053 0.0454 Experience.LevelMid
77672.94 7750.556 10.0216 0.0000 Experience.LevelSenior
18893.85 6692.387 2.8232 0.0049 Company.SizeMedium
-11859.18 11556.846 -1.0262 0.3052 Company.SizeSmall

21. Skutočné a predikované hodnoty

Pomocou regresného modelu vytvorím predikované platy.

Kód
data_scientist$Predikovany.plat <- predict(
  model
)

Porovnám prvých 20 skutočných a predikovaných hodnôt.

Kód
porovnanie_predikcie <- data.frame(

  Rok =
    data_scientist$Year[1:20],

  Skusenosti =
    data_scientist$Experience.Level[1:20],

  Skutocny_plat =
    data_scientist$Salary.in.USD[1:20],

  Predikovany_plat = round(
    data_scientist$Predikovany.plat[1:20],
    2
  )
)

knitr::kable(
  porovnanie_predikcie,
  digits = 2,
  caption = "Porovnanie skutočných a predikovaných platov"
)
Porovnanie skutočných a predikovaných platov
Rok Skusenosti Skutocny_plat Predikovany_plat
2023 Senior 140000 174526.9
2023 Senior 126000 174526.9
2023 Senior 170000 174526.9
2023 Senior 130000 174526.9
2023 Senior 185900 174526.9
2023 Senior 129300 174526.9
2023 Senior 225000 174526.9
2023 Senior 156400 174526.9
2023 Mid 61520 113202.0
2023 Mid 49216 113202.0
2023 Senior 153600 174526.9
2023 Senior 106800 174526.9
2023 Senior 71259 174526.9
2023 Mid 125000 113202.0
2023 Mid 90000 113202.0
2023 Senior 161000 174526.9
2023 Senior 151000 174526.9
2023 Senior 214500 174526.9
2023 Senior 150000 174526.9
2023 Senior 175000 174526.9

22. Vyhodnotenie regresného modelu

Kód
model_summary <- summary(
  model
)

statistiky_modelu <- data.frame(

  R_squared =
    model_summary$r.squared,

  Adjusted_R_squared =
    model_summary$adj.r.squared,

  Pocet_pozorovani =
    nobs(model)
)

knitr::kable(
  statistiky_modelu,
  digits = 4,
  caption = "Základné štatistiky regresného modelu"
)
Základné štatistiky regresného modelu
R_squared Adjusted_R_squared Pocet_pozorovani
0.3627 0.3566 635

Výsledky regresie predstavujú štatistické vzťahy medzi premennými. Samotná regresia však nedokazuje príčinnú súvislosť.

23. Databáza na ďalšie hodiny

Na ďalších hodinách budem pokračovať s databázou Latest Data Science Salaries.

Moja téma je Moja vysnívaná kariéra: Dátový vedec.

Databáza obsahuje:

  • názov pracovnej pozície,
  • typ pracovného pomeru,
  • úroveň skúseností,
  • úroveň odbornosti,
  • plat,
  • menu platu,
  • plat v USD,
  • lokalitu spoločnosti,
  • miesto bydliska pracovníka,
  • veľkosť spoločnosti,
  • rok pozorovania.

Údaje obsahujú roky 2020 až 2023, preto je možné analyzovať ich aj chronologicky.

Na ďalších hodinách by som chcel sledovať najmä vývoj platov, rozdiely medzi úrovňami skúseností, pracovnými pozíciami, spoločnosťami a krajinami.

Záver

V tomto cvičení som si precvičil čistenie a analýzu databáz v programovacom jazyku R.

Najskôr som importoval svoju skutočnú databázu Latest_Data_Science_Salaries.csv a upravil názvy jej premenných.

Skontroloval som chýbajúce hodnoty a duplicity.

Keďže pôvodná databáza neobsahovala chýbajúce hodnoty, vytvoril som pracovnú časovú databázu odvodenú zo skutočných údajov a zámerne som v nej vytvoril niekoľko chýbajúcich hodnôt na precvičenie čistenia dát.

Chýbajúce hodnoty som následne doplnil pomocou priemeru a lineárnej interpolácie.

V ďalšej časti som analyzoval skutočné údaje pracovnej pozície Data Scientist, vytvoril grafy a základné štatistiky a použil som t-test, ANOVA a lineárnu regresiu.

Tieto postupy predstavujú dôležitú súčasť práce dátového vedca pri spracovaní reálnych databáz.