Projekt Grupa E
Raport projektu “Analityka HR”
Celem niniejszego projektu jest zrozumienie i przewidywanie czynników wpływających na decyzję pracowników o odejściu z pracy. Odejście kwalifikowanych pracowników może być kosztowne dla organizacji, powodując straty zarówno wiedzy, jak i doświadczenia, a także pociągając za sobą konieczność ponoszenia dodatkowych kosztów związanych z rekrutacją i szkoleniem nowych osób. Przez dogłębne zbadanie różnorodnych danych, takich jak wiek pracowników, ich miesięczny dochód, zawód, stan cywilny, poziom satysfakcji z obowiązków zawodowych oraz innych istotnych informacji, można wyszukać wzorców i korelacji, które mogą przyczyniać się do rotacji pracowniczej. Przyjrzenie się tym danym i przeanalizowanie występujących zależności między nimi pomoże nam w odpowiedzi na postawione pytanie.
Czyszczenie danych
Pracę nad projektem rozpoczynamy od przyjrzenia się naszemu zbiorowi danych.
## Age Attrition BusinessTravel DailyRate
## Min. :18.00 Length:1470 Length:1470 Min. : 102.0
## 1st Qu.:30.00 Class :character Class :character 1st Qu.: 465.0
## Median :36.00 Mode :character Mode :character Median : 802.0
## Mean :36.92 Mean : 802.5
## 3rd Qu.:43.00 3rd Qu.:1157.0
## Max. :60.00 Max. :1499.0
## Department DistanceFromHome Education EducationField
## Length:1470 Min. : 1.000 Min. :1.000 Length:1470
## Class :character 1st Qu.: 2.000 1st Qu.:2.000 Class :character
## Mode :character Median : 7.000 Median :3.000 Mode :character
## Mean : 9.193 Mean :2.913
## 3rd Qu.:14.000 3rd Qu.:4.000
## Max. :29.000 Max. :5.000
## EmployeeCount EmployeeNumber EnvironmentSatisfaction Gender
## Min. :1 Min. : 1.0 Min. :1.000 Length:1470
## 1st Qu.:1 1st Qu.: 491.2 1st Qu.:2.000 Class :character
## Median :1 Median :1020.5 Median :3.000 Mode :character
## Mean :1 Mean :1024.9 Mean :2.722
## 3rd Qu.:1 3rd Qu.:1555.8 3rd Qu.:4.000
## Max. :1 Max. :2068.0 Max. :4.000
## HourlyRate JobInvolvement JobLevel JobRole
## Min. : 30.00 Min. :1.00 Min. :1.000 Length:1470
## 1st Qu.: 48.00 1st Qu.:2.00 1st Qu.:1.000 Class :character
## Median : 66.00 Median :3.00 Median :2.000 Mode :character
## Mean : 65.89 Mean :2.73 Mean :2.064
## 3rd Qu.: 83.75 3rd Qu.:3.00 3rd Qu.:3.000
## Max. :100.00 Max. :4.00 Max. :5.000
## JobSatisfaction MaritalStatus MonthlyIncome MonthlyRate
## Min. :1.000 Length:1470 Min. : 1009 Min. : 2094
## 1st Qu.:2.000 Class :character 1st Qu.: 2911 1st Qu.: 8047
## Median :3.000 Mode :character Median : 4919 Median :14236
## Mean :2.729 Mean : 6503 Mean :14313
## 3rd Qu.:4.000 3rd Qu.: 8379 3rd Qu.:20462
## Max. :4.000 Max. :19999 Max. :26999
## NumCompaniesWorked Over18 OverTime PercentSalaryHike
## Min. :0.000 Length:1470 Length:1470 Min. :11.00
## 1st Qu.:1.000 Class :character Class :character 1st Qu.:12.00
## Median :2.000 Mode :character Mode :character Median :14.00
## Mean :2.693 Mean :15.21
## 3rd Qu.:4.000 3rd Qu.:18.00
## Max. :9.000 Max. :25.00
## PerformanceRating RelationshipSatisfaction StandardHours StockOptionLevel
## Min. :3.000 Min. :1.000 Min. :80 Min. :0.0000
## 1st Qu.:3.000 1st Qu.:2.000 1st Qu.:80 1st Qu.:0.0000
## Median :3.000 Median :3.000 Median :80 Median :1.0000
## Mean :3.154 Mean :2.712 Mean :80 Mean :0.7939
## 3rd Qu.:3.000 3rd Qu.:4.000 3rd Qu.:80 3rd Qu.:1.0000
## Max. :4.000 Max. :4.000 Max. :80 Max. :3.0000
## TotalWorkingYears TrainingTimesLastYear WorkLifeBalance YearsAtCompany
## Min. : 0.00 Min. :0.000 Min. :1.000 Min. : 0.000
## 1st Qu.: 6.00 1st Qu.:2.000 1st Qu.:2.000 1st Qu.: 3.000
## Median :10.00 Median :3.000 Median :3.000 Median : 5.000
## Mean :11.28 Mean :2.799 Mean :2.761 Mean : 7.008
## 3rd Qu.:15.00 3rd Qu.:3.000 3rd Qu.:3.000 3rd Qu.: 9.000
## Max. :40.00 Max. :6.000 Max. :4.000 Max. :40.000
## YearsInCurrentRole YearsSinceLastPromotion YearsWithCurrManager
## Min. : 0.000 Min. : 0.000 Min. : 0.000
## 1st Qu.: 2.000 1st Qu.: 0.000 1st Qu.: 2.000
## Median : 3.000 Median : 1.000 Median : 3.000
## Mean : 4.229 Mean : 2.188 Mean : 4.123
## 3rd Qu.: 7.000 3rd Qu.: 3.000 3rd Qu.: 7.000
## Max. :18.000 Max. :15.000 Max. :17.000
## tibble [1,470 × 35] (S3: tbl_df/tbl/data.frame)
## $ Age : num [1:1470] 41 49 37 33 27 32 59 30 38 36 ...
## $ Attrition : chr [1:1470] "Yes" "No" "Yes" "No" ...
## $ BusinessTravel : chr [1:1470] "Travel_Rarely" "Travel_Frequently" "Travel_Rarely" "Travel_Frequently" ...
## $ DailyRate : num [1:1470] 1102 279 1373 1392 591 ...
## $ Department : chr [1:1470] "Sales" "Research & Development" "Research & Development" "Research & Development" ...
## $ DistanceFromHome : num [1:1470] 1 8 2 3 2 2 3 24 23 27 ...
## $ Education : num [1:1470] 2 1 2 4 1 2 3 1 3 3 ...
## $ EducationField : chr [1:1470] "Life Sciences" "Life Sciences" "Other" "Life Sciences" ...
## $ EmployeeCount : num [1:1470] 1 1 1 1 1 1 1 1 1 1 ...
## $ EmployeeNumber : num [1:1470] 1 2 4 5 7 8 10 11 12 13 ...
## $ EnvironmentSatisfaction : num [1:1470] 2 3 4 4 1 4 3 4 4 3 ...
## $ Gender : chr [1:1470] "Female" "Male" "Male" "Female" ...
## $ HourlyRate : num [1:1470] 94 61 92 56 40 79 81 67 44 94 ...
## $ JobInvolvement : num [1:1470] 3 2 2 3 3 3 4 3 2 3 ...
## $ JobLevel : num [1:1470] 2 2 1 1 1 1 1 1 3 2 ...
## $ JobRole : chr [1:1470] "Sales Executive" "Research Scientist" "Laboratory Technician" "Research Scientist" ...
## $ JobSatisfaction : num [1:1470] 4 2 3 3 2 4 1 3 3 3 ...
## $ MaritalStatus : chr [1:1470] "Single" "Married" "Single" "Married" ...
## $ MonthlyIncome : num [1:1470] 5993 5130 2090 2909 3468 ...
## $ MonthlyRate : num [1:1470] 19479 24907 2396 23159 16632 ...
## $ NumCompaniesWorked : num [1:1470] 8 1 6 1 9 0 4 1 0 6 ...
## $ Over18 : chr [1:1470] "Y" "Y" "Y" "Y" ...
## $ OverTime : chr [1:1470] "Yes" "No" "Yes" "Yes" ...
## $ PercentSalaryHike : num [1:1470] 11 23 15 11 12 13 20 22 21 13 ...
## $ PerformanceRating : num [1:1470] 3 4 3 3 3 3 4 4 4 3 ...
## $ RelationshipSatisfaction: num [1:1470] 1 4 2 3 4 3 1 2 2 2 ...
## $ StandardHours : num [1:1470] 80 80 80 80 80 80 80 80 80 80 ...
## $ StockOptionLevel : num [1:1470] 0 1 0 0 1 0 3 1 0 2 ...
## $ TotalWorkingYears : num [1:1470] 8 10 7 8 6 8 12 1 10 17 ...
## $ TrainingTimesLastYear : num [1:1470] 0 3 3 3 3 2 3 2 2 3 ...
## $ WorkLifeBalance : num [1:1470] 1 3 3 3 3 2 2 3 3 2 ...
## $ YearsAtCompany : num [1:1470] 6 10 0 8 2 7 1 1 9 7 ...
## $ YearsInCurrentRole : num [1:1470] 4 7 0 7 2 7 0 0 7 7 ...
## $ YearsSinceLastPromotion : num [1:1470] 0 1 0 3 2 3 0 0 1 7 ...
## $ YearsWithCurrManager : num [1:1470] 5 7 0 0 2 6 0 0 8 7 ...
## class
## Age numeric
## Attrition character
## BusinessTravel character
## DailyRate numeric
## Department character
## DistanceFromHome numeric
## Education numeric
## EducationField character
## EmployeeCount numeric
## EmployeeNumber numeric
## EnvironmentSatisfaction numeric
## Gender character
## HourlyRate numeric
## JobInvolvement numeric
## JobLevel numeric
## JobRole character
## JobSatisfaction numeric
## MaritalStatus character
## MonthlyIncome numeric
## MonthlyRate numeric
## NumCompaniesWorked numeric
## Over18 character
## OverTime character
## PercentSalaryHike numeric
## PerformanceRating numeric
## RelationshipSatisfaction numeric
## StandardHours numeric
## StockOptionLevel numeric
## TotalWorkingYears numeric
## TrainingTimesLastYear numeric
## WorkLifeBalance numeric
## YearsAtCompany numeric
## YearsInCurrentRole numeric
## YearsSinceLastPromotion numeric
## YearsWithCurrManager numeric
Nie wszystkie zmienne w naszym zbiorze danych przydadzą się do niniejszej analizy. Usunięcie zbędnych kolumn nie jest jednak konieczne. W przyszłości możemy chcieć przeprowadzić bardziej złożone analizy, które wymagają wielowymiarowego podejścia. Zmienne, które obecnie wydają się zbędne, mogą okazać się kluczowe w dalszych analizach wieloczynnikowych.
Puste wartości
W pierwszej kolejności sprawdzamy czy w zbiorze danych występują puste wartości.
## [1] FALSE
## # A tibble: 35 × 3
## variable n_miss pct_miss
## <chr> <int> <dbl>
## 1 Age 0 0
## 2 Attrition 0 0
## 3 BusinessTravel 0 0
## 4 DailyRate 0 0
## 5 Department 0 0
## 6 DistanceFromHome 0 0
## 7 Education 0 0
## 8 EducationField 0 0
## 9 EmployeeCount 0 0
## 10 EmployeeNumber 0 0
## # ℹ 25 more rows
## [1] 0
W naszej bazie danych nie występują żadne puste wartości.
Wartości mniejsze od zera
W następnym kroku sprawdzamy czy w naszych danych ilościowych są jakieś wartości ujemne (oczekujemy, że takich nie będzie, ponieważ, przykładowo, ujemny dystans od domu do miejsca pracy byłby nielogiczny).
rules <- validator(HR$DailyRate >= 0
, HR$DistanceFromHome >= 0
, HR$Education >= 0
, HR$EmployeeCount >= 0
, HR$EmployeeNumber >= 0
, HR$HourlyRate >0
, HR$JobInvolvement >= 0
, HR$JobLevel >= 0
, HR$JobSatisfaction >= 0
, HR$MonthlyIncome >= 0
, HR$MonthlyRate >= 0
, HR$NumCompaniesWorked >= 0
, HR$PercentSalaryHike >= 0
, HR$PerformanceRating >= 0
, HR$RelationshipSatisfaction >= 0
, HR$StandardHours >= 0
, HR$StockOptionLevel >= 0
, HR$TotalWorkingYears >= 0
, HR$TrainingTimesLastYear >=0
, HR$WorkLifeBalance >= 0
, HR$YearsAtCompany >= 0
, HR$YearsInCurrentRole >= 0
, HR$YearsSinceLastPromotion >= 0
, HR$YearsWithCurrManager >= 0
)
cf <- confront(HR, rules)
summary(cf)
## name items passes fails nNA error warning
## 1 V01 1470 1470 0 0 FALSE FALSE
## 2 V02 1470 1470 0 0 FALSE FALSE
## 3 V03 1470 1470 0 0 FALSE FALSE
## 4 V04 1470 1470 0 0 FALSE FALSE
## 5 V05 1470 1470 0 0 FALSE FALSE
## 6 V06 1470 1470 0 0 FALSE FALSE
## 7 V07 1470 1470 0 0 FALSE FALSE
## 8 V08 1470 1470 0 0 FALSE FALSE
## 9 V09 1470 1470 0 0 FALSE FALSE
## 10 V10 1470 1470 0 0 FALSE FALSE
## 11 V11 1470 1470 0 0 FALSE FALSE
## 12 V12 1470 1470 0 0 FALSE FALSE
## 13 V13 1470 1470 0 0 FALSE FALSE
## 14 V14 1470 1470 0 0 FALSE FALSE
## 15 V15 1470 1470 0 0 FALSE FALSE
## 16 V16 1470 1470 0 0 FALSE FALSE
## 17 V17 1470 1470 0 0 FALSE FALSE
## 18 V18 1470 1470 0 0 FALSE FALSE
## 19 V19 1470 1470 0 0 FALSE FALSE
## 20 V20 1470 1470 0 0 FALSE FALSE
## 21 V21 1470 1470 0 0 FALSE FALSE
## 22 V22 1470 1470 0 0 FALSE FALSE
## 23 V23 1470 1470 0 0 FALSE FALSE
## 24 V24 1470 1470 0 0 FALSE FALSE
## expression
## 1 HR[["DailyRate"]] >= 0
## 2 HR[["DistanceFromHome"]] >= 0
## 3 HR[["Education"]] >= 0
## 4 HR[["EmployeeCount"]] >= 0
## 5 HR[["EmployeeNumber"]] >= 0
## 6 HR[["HourlyRate"]] > 0
## 7 HR[["JobInvolvement"]] >= 0
## 8 HR[["JobLevel"]] >= 0
## 9 HR[["JobSatisfaction"]] >= 0
## 10 HR[["MonthlyIncome"]] >= 0
## 11 HR[["MonthlyRate"]] >= 0
## 12 HR[["NumCompaniesWorked"]] >= 0
## 13 HR[["PercentSalaryHike"]] >= 0
## 14 HR[["PerformanceRating"]] >= 0
## 15 HR[["RelationshipSatisfaction"]] >= 0
## 16 HR[["StandardHours"]] >= 0
## 17 HR[["StockOptionLevel"]] >= 0
## 18 HR[["TotalWorkingYears"]] >= 0
## 19 HR[["TrainingTimesLastYear"]] >= 0
## 20 HR[["WorkLifeBalance"]] >= 0
## 21 HR[["YearsAtCompany"]] >= 0
## 22 HR[["YearsInCurrentRole"]] >= 0
## 23 HR[["YearsSinceLastPromotion"]] >= 0
## 24 HR[["YearsWithCurrManager"]] >= 0
Nie ma wartości mniejszych od zera, zatem nie musimy poprawiać ich wartości w tym zakresie.
Wartości odstające
Następnie spojrzymy na dane pod względem wartości odstających.
Jak możemy zauważyć, wartości odstające zaczynają się pojawiać w miesięcznych dochodach pracowników.
Aby pozbyć się obserwacji odstających, posłużymy się powszechną metodą wykorzystującą rozstęp międzykwartylowy (IQR). Za wartość odstającą często uważa się dowolną wartość, która jest większa niż 1,5 * IQR powyżej trzeciego kwartyla lub poniżej pierwszego kwartyla.
replace_outliers <- function(x) {
Q1 <- quantile(x, 0.25)
Q3 <- quantile(x, 0.75)
IQR <- Q3 - Q1
x[x < (Q1 - 1.5 * IQR) | x > (Q3 + 1.5 * IQR)] <- median(x, na.rm = TRUE)
return(x)
}
HR <- HR %>%
mutate_if(is.numeric, replace_outliers)
head(HR)
## # A tibble: 6 × 35
## Age Attrition BusinessTravel DailyRate Department DistanceFromHome Education
## <dbl> <chr> <chr> <dbl> <chr> <dbl> <dbl>
## 1 41 Yes Travel_Rarely 1102 Sales 1 2
## 2 49 No Travel_Freque… 279 Research … 8 1
## 3 37 Yes Travel_Rarely 1373 Research … 2 2
## 4 33 No Travel_Freque… 1392 Research … 3 4
## 5 27 No Travel_Rarely 591 Research … 2 1
## 6 32 No Travel_Freque… 1005 Research … 2 2
## # ℹ 28 more variables: EducationField <chr>, EmployeeCount <dbl>,
## # EmployeeNumber <dbl>, EnvironmentSatisfaction <dbl>, Gender <chr>,
## # HourlyRate <dbl>, JobInvolvement <dbl>, JobLevel <dbl>, JobRole <chr>,
## # JobSatisfaction <dbl>, MaritalStatus <chr>, MonthlyIncome <dbl>,
## # MonthlyRate <dbl>, NumCompaniesWorked <dbl>, Over18 <chr>, OverTime <chr>,
## # PercentSalaryHike <dbl>, PerformanceRating <dbl>,
## # RelationshipSatisfaction <dbl>, StandardHours <dbl>, …
Podsumowując pierwszy etap, posłużymy się wykresem, który upewni nas, że nie mamy żadnych wartości brakujących.
Możemy zatem przejść do kolejnego etapu projektu.
Wizualizacja danych
ggplot(HR, aes(y=Age,x=Attrition)) +
geom_boxplot() +
coord_flip()+
labs(x = "Rezygnacja z pracy", y = "Wiek", title="Rezygnacja z pracy ze względu na wiek")
Na powyższym wykresie możemy zauważyć, że z pracy częściej rezygnują młodsi pracownicy.
ggplot(HR, aes(x=MonthlyIncome,size=Attrition,y=Age,color=Gender)) +
geom_point() +
labs(x="Miesięczny dochód", y="Wiek", color="Płeć", size="Rezygnacja z pracy", title="Rezygnacja z pracy ze względu na wiek, płeć i miesięczne dochody")
## Warning: Using size for a discrete variable is not advised.
Możemy zaobserwować, że na rezygnację z pracy częściej decydują się młodsze osoby z niższymi dochodami.
HR %>%
filter(Attrition=="Yes") %>%
ggplot(aes(x = YearsAtCompany)) +
geom_histogram(
aes(fill = OverTime)
,bins = 10
,color = 'black'
) +
labs(x="Liczba przepracowanych lat w firmie", fill="Nadgodziny", y="Liczba pracowników", filter="Rezygnacja z pracy",title = 'Staż pracy i nadgodziny pracowników, którzy opuścili firmę')
Duża część pracowników decyduje się na odejście z pracy w początkowych latach pracy w firmie,a wśród nich spora część pracowników pracuje ponad wymiar godzin.
HR %>%
ggplot(aes(x = PercentSalaryHike)) +
geom_histogram(
aes(fill = Attrition)
,bins = 50
,color = 'black'
) + labs(x="Procentowa podwyżka wynagrodzeń", fill="Rezygnacja z pracy",
y="Liczba pracowników", title="Rezygnacja z pracy ze względu na procentową podwyżkę wynagrodzeń")
Osoby z niższą procentową podwyżką wynagrodzeń są bardziej skłonne do odejścia z pracy.
ggplot(HR, aes(y=DailyRate,x=Attrition)) +
geom_boxplot() +
coord_flip() +
labs(y="Dzienna stawka", x="Rezygnacja z pracy", title="Rezygnacja z pracy ze względu na dzienną stawkę")
Osoby z niższą dzienną stawką częściej rezygnują z pracy.
ggplot(HR, aes(y=DistanceFromHome,x=Attrition)) +
geom_boxplot() +
coord_flip() +
labs(y="Odległość od domu", x="Rezygnacja z pracy", title="Rezygnacja z pracy ze względu na odległość miejsca pracy od domu")
Jak możemy zauważyć, odległość między miejscem pracy a domem ma również znaczenie. Pracownicy, którzy muszą pokonać więcej kilometrów w drodze do pracy, częściej decydują się na odejście z pracy.
HR %>%
ggplot(aes(x = JobLevel)) +
geom_bar(aes(fill = Attrition), color = 'black') +
scale_x_discrete(breaks = 1:5, labels = c("b.niski", "niski", "średni", "wysoki", "b.wysoki")) +
labs(x = "Stopień stanowiska", y = "Liczba pracowników", fill="Rezygnacja z pracy")
Im niższy poziom pracy, tym pracownicy coraz częściej decydują się na rezygnację z pracy.
HR %>%
ggplot(aes(x = BusinessTravel)) +
geom_bar(
aes(fill = Attrition),
color = 'black'
) +
labs(x="Podróże służbowe",fill="Odejście z pracy", y="Liczba pracowników") +
scale_x_discrete(labels = c("Non-Travel" = "Nie podróżuje",
"Travel_Frequently" = "Często podróżuje",
"Travel_Rarely" = "Rzadko podróżuje"))
Pracownicy, którzy rzadko podróżują, najczęściej decydują się na odejście z pracy.
HR %>%
ggplot(aes(x = EducationField)) +
geom_bar(
aes(fill = Attrition),
color = 'black'
) +
labs(x="Dziedzina edukacji", fill="Rezygnacja z pracy", y="Liczba pracowników") +
scale_x_discrete(labels = c("Human Resources" = "Zasoby ludzkie(HR)",
"Life Sciences" = "Nauki przyrodnicze",
"Marketing" = "Marketing",
"Medical" = "Medycyna",
"Other"="Inne",
"Technical Degree"="Techniczny stopień naukowy"))
Analizując dziedzinę edukacji pracowników, na rezygnację z pracy najczęściej decydują się pracownicy z dziedziny nauk przyrodniczych i medycznych.
HR %>%
ggplot(aes(x = MaritalStatus)) +
geom_bar(
aes(fill = Attrition),
color = 'black'
) + labs(x="Stan cywilny", fill="Rezygnacja z pracy") +
scale_x_discrete(labels = c("Divorced" = "Rozwiedziony",
"Married" = "Żonaty",
"Single" = "Wolny"
))
Biorąc pod uwagę życie prywatne pracowników, osoby niebędące w związku małżeńskim częściej odchodzą z pracy.
Podsumowując, na decyzję o odejściu z pracy wpływają różne czynniki. Na podstawie dokonanej analizy w niniejszym etapie, możemy powiedzieć, że najczęściej rezygnują młodsi pracownicy, zwłaszcza ci z niższymi zarobkami. Wysoka rotacja jest obserwowana w początkowych latach pracy, zwłaszcza wśród osób pracujących ponad normę godzinową. Niższa procentowa podwyżka wynagrodzeń i niższa dzienna stawka również sprzyjają odejściu z pracy. To pokazuje, że pracownicy nie czują się docenieni przez swoich przełożonych i nie widzą przyszłości w tej firmie. Długa droga do pracy, niższy stopień stanowiska, rzadkie podróże służbowe, specjalizacja w dziedzinie nauk przyrodniczych i medycznych, a także brak związku małżeńskiego to determinanty sprzyjające rezygnacji z pracy.
Statystyki opisowe
Przed rozpoczęciem tego etapu, należy w pierwszej kolejności dobrać właściwe formaty zmiennych.
HR$Attrition<-as.factor(HR$Attrition)
HR$JobLevel<-factor(HR$JobLevel)
HR$JobInvolvement<-factor(HR$JobInvolvement)
Poniżej utworzono tabelę przedstawiającą statystyki opisowe miesięcznych dochodów pracowników w zależności od ich zaangażowania w pracę, które jest podzielone na cztery kategorie: “bardzo małe”, “małe”, “duże” i “bardzo duże”.
HR %>%
select(MonthlyIncome, JobInvolvement) %>%
mutate(JobInvolvement = factor(JobInvolvement,
levels = c(1, 2, 3, 4),
labels = c("bardzo małe", "małe", "duże", "bardzo duże")),
Zaangażowanie_w_pracy = JobInvolvement) %>%
select(-JobInvolvement) %>%
group_by(Zaangażowanie_w_pracy) %>%
dplyr::summarize(Min=min(MonthlyIncome),
Max=max(MonthlyIncome),
średnia=mean(MonthlyIncome),
odchylenie=sd(MonthlyIncome),
mediana=median(MonthlyIncome),
Q1=quantile(MonthlyIncome, 0.25),
Q3=quantile(MonthlyIncome, 0.75),
Skośność=skewness(MonthlyIncome),
Kurtoza=kurtosis(MonthlyIncome)) %>%
kbl() %>%
kable_paper("striped", full_width = F) %>%
column_spec(1:2, bold = T) %>%
row_spec(c(1,3), bold = T, color = "white", background = "#C8A2C8") %>%
kable_styling(bootstrap_options = c("striped", "hover"),
full_width = F,
position = "center",
fixed_thead = T) %>%
add_header_above(c(" " = 1, "Miesięczne dochody pracowników ze względu na zaangażowanie w pracy" = 9))
Miesięczne dochody pracowników ze względu na zaangażowanie w pracy
|
|||||||||
---|---|---|---|---|---|---|---|---|---|
Zaangażowanie_w_pracy | Min | Max | średnia | odchylenie | mediana | Q1 | Q3 | Skośność | Kurtoza |
bardzo małe | 1118 | 14411 | 5394.892 | 2935.034 | 4919.0 | 2877.50 | 6407.0 | 0.9939833 | 0.6018108 |
małe | 1102 | 16124 | 5673.024 | 3285.346 | 4919.0 | 2905.00 | 7101.0 | 1.0303064 | 0.3045292 |
duże | 1009 | 16555 | 5375.486 | 3160.500 | 4815.5 | 2929.75 | 6500.5 | 1.3705526 | 1.5908040 |
bardzo duże | 1091 | 16184 | 5426.604 | 3284.560 | 4888.0 | 2910.00 | 6380.0 | 1.4873744 | 1.7236479 |
Na podstawie tej tabeli możemy zauważyć, że:
- Kategoria z “bardzo małym” zaangażowaniem ma największy zakres dochodów (Min-Max), a także najwyższą wartość średnich dochodów.
- Skośność w każdej kategorii jest dodatnia, co wskazuje na to, że rozkład dochodów jest prawostronnie skośny - większość pracowników zarabia mniej niż średnia, a mniejsza liczba pracowników zarabia znacznie więcej.
- Kurtoza w każdej kategorii jest dodatnia, co sugeruje, że rozkład dochodów ma bardziej wyostrzony szczyt niż rozkład normalny, wskazując na większą koncentrację wartości wokół średniej.
W ostatniej części tego etapu utworzono macierz korelacji między (prawie) wszystkimi zmiennymi. W celu jej wykonania zakodowano zmienne jakościowe na zmienne ilościowe, przypisując im etykiety liczbowe.
qualitative_columns <- HR %>% select_if(is.character)
qualitative_columns <- qualitative_columns %>%
select(-Over18)
qualitative_columns <- qualitative_columns %>%
mutate(BusinessTravel = case_when(
BusinessTravel == "Non-Travel" ~ 0,
BusinessTravel == "Travel_Rarely" ~ 1,
BusinessTravel == "Travel_Frequently" ~ 2)
)
qualitative_columns <- qualitative_columns %>%
mutate(Department = case_when(
Department == "Human Resources" ~ 0,
Department == "Sales" ~ 1,
Department == "Research & Development" ~ 2)
)
qualitative_columns <- qualitative_columns %>%
mutate(EducationField = case_when(
EducationField == "Human Resources" ~ 0,
EducationField == "Marketing" ~ 1,
EducationField == "Life Sciences" ~ 2,
EducationField == "Technical Degree" ~ 3,
EducationField == "Medical" ~ 4,
EducationField == "Other" ~ 5)
)
qualitative_columns <- qualitative_columns %>%
mutate(Gender = case_when(
Gender == "Male" ~ 0,
Gender == "Female" ~ 1)
)
qualitative_columns <- qualitative_columns %>%
mutate(JobRole = case_when(
JobRole == "Human Resources" ~ 0,
JobRole == "Healthcare Representative" ~ 1,
JobRole == "Research Scientist" ~ 2,
JobRole == "Research Director" ~ 3,
JobRole == "Laboratory Technician" ~ 4,
JobRole == "Manager" ~ 5,
JobRole == "Manufacturing Director" ~ 6,
JobRole == "Sales Representative" ~ 7,
JobRole == "Sales Executive" ~ 8)
)
qualitative_columns <- qualitative_columns %>%
mutate(MaritalStatus = case_when(
MaritalStatus == "Single" ~ 0,
MaritalStatus == "Married" ~ 1,
MaritalStatus == "Divorced" ~ 2)
)
qualitative_columns <- qualitative_columns %>%
mutate(OverTime = case_when(
OverTime == "No" ~ 0,
OverTime == "Yes" ~ 1)
)
factor_columns <- factor_columns %>%
mutate(Attrition = case_when(
Attrition == "No" ~ 0,
Attrition == "Yes" ~ 1)
)
factor_columns$JobInvolvement <- as.numeric(factor_columns$JobInvolvement)
factor_columns$JobLevel <- as.numeric(factor_columns$JobLevel)
combined_data <- bind_cols(factor_columns, qualitative_columns, numeric_data)
combined_data <- combined_data %>%
select(-EmployeeCount) %>%
select(-StandardHours) %>%
select(-PerformanceRating)
cor_matrix <- cor(combined_data, use="complete.obs")
corrplot(cor_matrix, method="color", title="Macierz korelacji")
Z powyższej macierzy korelacji możemy odczytać, że występuje silny związek między miesięcznym dochodem i stopniem stanowiska oraz między łączną liczbą przepracowanych lat a stopniem stanowiska. Możemy również zauważyć występującą zależność pomiędzy oceną wydajności pracownika a podwyżką wynagrodzeń za wyniki pracy.Performance Rating ~ Performance Salary Hike Całkiem mocne korelacje obserwujemy w prawym dolnym rogu macierzy, czyli m.in. między liczbą przepracowanych lat na obecnym stanowisku a liczbą przepracowanych lat w firmie, czy też między liczbą lat od ostatniego awansu a liczbą przepracowanych lat w firmie.
Wnioskowanie statystyczne
Czy miesięczny dochód pracownika zależy od tego jak często pracownik wyjeżdża służbowo?
W wyniku wcześniejszej wizualizacji, można było zauważyć, że najwięcej pracowników, którzy rzadko podróżują, najczęściej decydują się na odejście z pracy, w porównaniu do osób często podróżujących służbowo i niepodróżujących. Podróże służbowe mogą być postrzegane jako przywilej lub obciążenie, w zależności od kontekstu pracy i preferencji indywidualnych. Zrozumienie, jak podróże służbowe wpływają na dochód, może pomóc w ocenie, czy są one motywującym czynnikiem dla pracowników. W celu sprawdzenia założonej hipotezy, utworzono wykres zawierających szczegóły z testów statystycznych, przedstawiający analizę dochodów pracowników w zależności od ich częstotliwości podróży służbowych.
ggbetweenstats(HR, BusinessTravel, MonthlyIncome)+ggtitle("Miesięczny dochód pracownika w zależności od częstotliwości wyjazdów służbowych")+labs(x="Podróże służbowe", y="Miesięczny dochód")
Na podstawie uzyskanego p-value odrzucamy założoną hipotezę. Obserwujemy brak statystycznie istotnych różnic w miesięcznym dochodzie ze względu na częstotliwość wyjazdów służbowych.
Czy procentowa podwyżka wynagrodzenia pracownika zależy od odejścia z pracy (job level)?
Wcześniej obserwowaliśmy również zależność, że osoby z niższą procentową podwyżką wynagrodzenia częściej odchodzą z pracy. Poznając zależność między poziomem stanowiska a podwyżkami wynagrodzenia, firma może lepiej zrozumieć, jakie czynniki wpływają na decyzje pracowników o pozostaniu w firmie lub odejściu. To z kolei może pomóc w opracowaniu strategii zatrzymywania kluczowych talentów. Aby sprawdzić założoną hipotezę, tworzymy poniższy wykres przedstawiający analizę statystyczną związków między odejściem z pracy a procentową podwyżką wynagrodzenia.
ggbetweenstats(HR, Attrition, PercentSalaryHike)+ggtitle("Procentowa podwyżka wynagrodzeń a odejście z pracy")+labs(x="Rezygnacja z pracy", y="Procentowa podwyżka wynagrodzeń")
Wyniki testu wskazują, że nie ma statystycznie istotnej różnicy w procentowych podwyżkach wynagrodzenia między pracownikami, którzy odeszli, a tymi, którzy pozostali w pracy.
Czy odejście z firmy zależy od wykonywanego zawodu w firmie?
Z uwagi na sporą ilość wariantów zmiennej JobRole, we wcześniejszym etapie nie analizowano zawodów firmy. Jest to dobry moment, aby sprawdzić, czy wykonywanie danego zawodu w firmie wpływa na decyzję o odejściu z pracy. Poznanie wzorców rotacji w kontekście różnych zawodów może pomóc firmie zidentyfikować specyficzne role lub działania, które mają wysoki wskaźnik odejść. To z kolei może skłonić do bliższego przyjrzenia się warunkom pracy lub satysfakcji pracowniczej w tych obszarach.
ggbarstats(HR, Attrition, JobRole)+ggtitle("Odejście z pracy w zależności od wykonywanego zawodu")+labs(x="Zawód", y="Odsetek", fill="Rezygnacja z pracy")
Wykres ilustruje, że istnieje różnica w odsetku odejść z pracy między różnymi zawodami w firmie. Przyjmując poziom istotności na poziomie 0.10, obserwujemy, że Przedstawiciele handlowi (ang. Sales Representative) najczęściej decydują się na rezygnację z pracy, a najmniej osób na stanowisku Dyrektora badań odchodzi z firmy.
Czy rezygnacja z pracy zależy od miesięcznego dochodu?
W poprzednim etapie wizualizacji można było zauważyć, że na rezygnację z pracy częściej decydują się młodsze osoby z niższymi zarobkami. Wynagrodzenie jest podstawowym motywatorem dla wielu pracowników. Zrozumienie, jak poziom wynagrodzenia wpływa na decyzje pracowników o pozostaniu w firmie lub odejściu, może dostarczyć cennych informacji do tworzenia polityk wynagradzania.
ggbetweenstats(HR, Attrition, MonthlyIncome)+ggtitle("Miesięczne dochody pracowników a odejście z pracy")+labs(x="Rezygnacja z pracy", y="Miesięczny dochód")
Rozkłady wynagrodzeń pracowników, którzy odeszli, są węższe i skoncentrowane wokół niższych dochodów w porównaniu do tych, którzy pozostali w pracy. Wyniki testów pokazują, że wynagrodzenie ma istotny wpływ na decyzję o odejściu z pracy.
Podsumowanie
Przeprowadzone wnioskowanie statystyczne wskazuje na kilka kluczowych wniosków dotyczących wpływu różnych czynników na decyzje o odejściu z pracy. Przede wszystkim, na podstawie uzyskanego p-value, odrzuciliśmy założoną hipotezę o wpływie częstotliwości wyjazdów służbowych na miesięczny dochód pracownika. To oznacza, że podróżowanie służbowe nie miało znaczącego wpływu na dochody pracowników.
Po drugie, analiza wykazała, że nie istnieje statystycznie istotna różnica w procentowych podwyżkach wynagrodzenia między pracownikami, którzy zdecydowali się odejść, a tymi, którzy pozostali w firmie. Ta obserwacja sugeruje, że podwyżki wynagrodzenia nie były kluczowym czynnikiem wpływającym na decyzję o odejściu.
Jednakże, analiza wykresów wykazała wyraźne różnice w odsetku odejść z pracy między różnymi grupami zawodowymi w firmie. Zauważono, że Przedstawiciele handlowi najczęściej decydowali się na rezygnację z pracy, podczas gdy najmniej osób na stanowisku Dyrektora badań opuszczało firmę. Ten trend był wyraźny przy założonym poziomie istotności na poziomie 0.10.
Dodatkowo, rozkłady wynagrodzeń pracowników, którzy odeszli z pracy, były bardziej skoncentrowane wokół niższych dochodów i charakteryzowały się mniejszą zmiennością w porównaniu do tych, którzy pozostali. To sugeruje, że pracownicy o niższych dochodach byli bardziej skłonni do rezygnacji z pracy, co podkreśla znaczenie wynagrodzenia jako czynnika wpływającego na decyzje o odejściu.
Na podstawie analizy można przedstawić następujące rekomendacje dla firmy, aby zmniejszyć rotację pracowników:
Rewizja Polityki Wynagrodzeń: Z uwagi na istotność wynagrodzenia w decyzjach o odejściu, firma powinna przeprowadzić analizę rynku, aby upewnić się, że wynagrodzenia są konkurencyjne, szczególnie dla stanowisk o najwyższej rotacji. Może to obejmować wprowadzenie elastycznych pakietów wynagrodzeń lub premii dla stanowisk o wysokiej rotacji.
Programy Rozwoju Zawodowego: Rozwój zawodowy może zwiększyć zaangażowanie pracowników i zmniejszyć rotację. Firma powinna oferować szkolenia, warsztaty i możliwości awansu, szczególnie dla grup zawodowych o wyższym odsetku odejść.
Zrównoważone Wyjazdy Służbowe: Chociaż częstotliwość podróży służbowych nie wykazała bezpośredniego wpływu na dochody, warto rozważyć wprowadzenie bardziej zrównoważonych polityk dotyczących podróży służbowych, aby uniknąć wypalenia zawodowego.
Ankiety Satysfakcji Pracowników: Regularne ankiety i spotkania z pracownikami mogą pomóc w identyfikacji i adresowaniu indywidualnych niepokojów i oczekiwań, zanim przerodzą się one w decyzję o odejściu.
Zarządzanie Przez Cele: Ustalenie jasnych, osiągalnych celów dla pracowników może zwiększyć ich motywację i zaangażowanie w pracę.
Implementacja tych rekomendacji może pomóc firmie w zmniejszeniu rotacji pracowników, zwiększeniu ich satysfakcji oraz poprawie ogólnej wydajności i atmosfery w miejscu pracy.