Analiza danych - projekt

1. Wprowadzenie i cel projektu

Celem niniejszego projektu jest opracowanie i wdrożenie systemu automatycznej oceny zdolności kredytowej klientów w czasie rzeczywistym. Projekt zakłada stworzenie modelu klasyfikacyjnego, który na podstawie danych podanych przez klienta podczas wypełniania wniosku online będzie w stanie precyzyjnie określić, czy dany klient kwalifikuje się do otrzymania pożyczki.

System ten ma na celu nie tylko przyspieszenie procesu decyzyjnego, ale także zwiększenie jego trafności. Dzięki segmentacji klientów oraz identyfikacji cech charakterystycznych dla osób spełniających kryteria kredytowe, firma będzie mogła dostosować swoje oferty do konkretnych grup odbiorców.

Dane, na których pracujemy obejmują: płeć, stan cywilny,liczba osób na utrzymaniu, wykształcenie, informację czy wnioskodawca prowadzi działalność gospodarczą, jego dochód, dochód współwnioskodawcy, kwotę pożyczki, okres spłaty, historię kredytową, lokalizację nieruchomości i status przyznania pożyczki. Mają 614 wierszy i 13 kolumn.

2. Przygotowanie danych

2.1. Ładowanie pakietów i danych

Naszym pierwszym krokiem będzie załadowanie pakietów, które będą nam potrzebne do analizy danych oraz danych, na których będziemy pracować.

Następnie sprawdzamy strukturę naszych danych.

#sprawdzamy strukturę danych
str(pozyczki)
## 'data.frame':    614 obs. of  13 variables:
##  $ Loan_ID          : chr  "LP001002" "LP001003" "LP001005" "LP001006" ...
##  $ Gender           : chr  "Male" "Male" "Male" "Male" ...
##  $ Married          : chr  "No" "Yes" "Yes" "Yes" ...
##  $ Dependents       : chr  "0" "1" "0" "0" ...
##  $ Education        : chr  "Graduate" "Graduate" "Graduate" "Not Graduate" ...
##  $ Self_Employed    : chr  "No" "No" "Yes" "No" ...
##  $ ApplicantIncome  : int  5849 4583 3000 2583 6000 5417 2333 3036 4006 12841 ...
##  $ CoapplicantIncome: num  0 1508 0 2358 0 ...
##  $ LoanAmount       : int  NA 128 66 120 141 267 95 158 168 349 ...
##  $ Loan_Amount_Term : int  360 360 360 360 360 360 360 360 360 360 ...
##  $ Credit_History   : int  1 1 1 1 1 1 1 0 1 1 ...
##  $ Property_Area    : chr  "Urban" "Rural" "Urban" "Urban" ...
##  $ Loan_Status      : chr  "Y" "N" "Y" "Y" ...

2.1. Analiza braków danych

Za pomocą pakietu “naniar” sprawdzamy, czy w naszym zbiorze danych występują braki danych.

#sprawdzamy braki danych
library(naniar)
n_miss(pozyczki)
## [1] 149
#mamy 149 braków danych

#procent braków danych
prop_miss(pozyczki)
## [1] 0.018667
#mamy około 1,9% braków danych w stosunku do całości obserwacji

#tabela podsumowująca
miss_var_summary(pozyczki)
## # A tibble: 13 × 3
##    variable          n_miss pct_miss
##    <chr>              <int>    <num>
##  1 Credit_History        50    8.14 
##  2 Self_Employed         32    5.21 
##  3 LoanAmount            22    3.58 
##  4 Dependents            15    2.44 
##  5 Loan_Amount_Term      14    2.28 
##  6 Gender                13    2.12 
##  7 Married                3    0.489
##  8 Loan_ID                0    0    
##  9 Education              0    0    
## 10 ApplicantIncome        0    0    
## 11 CoapplicantIncome      0    0    
## 12 Property_Area          0    0    
## 13 Loan_Status            0    0
#najwięcej braków mamy w kolumnie "credit_history", ale są też kolumny, w których jest komplet danych

#wizualizacja ogólna
vis_miss(pozyczki)

vis_miss(pozyczki, sort_miss=TRUE) #sortowanie

#mapa
gg_miss_fct(pozyczki, fct = Self_Employed) +
  scale_fill_distiller(direction = 1, palette = "GnBu")
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.

gg_miss_fct(pozyczki, fct = Married) +
  scale_fill_distiller(direction = 1, palette = "GnBu")
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.

gg_miss_fct(pozyczki, fct = Education) +
  scale_fill_distiller(direction = 1, palette = "GnBu")
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.

gg_miss_fct(pozyczki, fct = Credit_History) +
  scale_fill_distiller(direction = 1, palette = "GnBu")
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
## Warning: Removed 12 rows containing missing values or values outside the scale range
## (`geom_tile()`).

#Naszym zdaniem zmienna Education prezentuje największe rozbieżności pomiędzy brakami danych.

# Wizualizacja braków danych względem decyzji o przyznaniu pożyczki

# Wizualizacja braków danych względem loan_status
gg_miss_fct(pozyczki, fct = Loan_Status) +
  labs(title = "Procent braków danych według decyzji o udzieleniu pożyczki", x = "Decyzja odnośnie udzielenia pożyczki", y = "% braków danych") +
  scale_fill_distiller(direction = 1, palette = "GnBu")
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.

2.2. Walidacja danych

Kolejnym krokiem jest walidacja danych. Sprawdzamy, czy dane spełniają nasze założenia.Wykorzystujemy do tego pakiet “validate”.

library(validate)
# Podgląd danych
glimpse(pozyczki)
## Rows: 614
## Columns: 13
## $ Loan_ID           <chr> "LP001002", "LP001003", "LP001005", "LP001006", "LP0…
## $ Gender            <chr> "Male", "Male", "Male", "Male", "Male", "Male", "Mal…
## $ Married           <chr> "No", "Yes", "Yes", "Yes", "No", "Yes", "Yes", "Yes"…
## $ Dependents        <chr> "0", "1", "0", "0", "0", "2", "0", "3+", "2", "1", "…
## $ Education         <chr> "Graduate", "Graduate", "Graduate", "Not Graduate", …
## $ Self_Employed     <chr> "No", "No", "Yes", "No", "No", "Yes", "No", "No", "N…
## $ ApplicantIncome   <int> 5849, 4583, 3000, 2583, 6000, 5417, 2333, 3036, 4006…
## $ CoapplicantIncome <dbl> 0, 1508, 0, 2358, 0, 4196, 1516, 2504, 1526, 10968, …
## $ LoanAmount        <int> NA, 128, 66, 120, 141, 267, 95, 158, 168, 349, 70, 1…
## $ Loan_Amount_Term  <int> 360, 360, 360, 360, 360, 360, 360, 360, 360, 360, 36…
## $ Credit_History    <int> 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, NA, …
## $ Property_Area     <chr> "Urban", "Rural", "Urban", "Urban", "Urban", "Urban"…
## $ Loan_Status       <chr> "Y", "N", "Y", "Y", "Y", "Y", "Y", "N", "Y", "N", "Y…
rules <- validator(
  Gender %in% c("Male", "Female"),
  Married %in% c("Yes", "No"),
  Dependents >= 0,
  Education %in% c("Graduate", "Not Graduate"),
  Self_Employed %in% c("Yes", "No"),
  ApplicantIncome >= 0,
  CoapplicantIncome >= 0,
  LoanAmount > 0,
  Loan_Amount_Term > 0,
  Credit_History %in% c("0", "1"),
  Property_Area %in% c("Urban", "Semiurban", "Rural"),
  Loan_Status %in% c("Y", "N")
)

# Zastosowanie reguł walidacyjnych
wyniki <- confront(pozyczki, rules)

# Raport z walidacji
summary(wyniki)
##    name items passes fails nNA error warning
## 1   V01   614    601     0  13 FALSE   FALSE
## 2   V02   614    611     0   3 FALSE   FALSE
## 3   V03   614    599     0  15 FALSE   FALSE
## 4   V04   614    614     0   0 FALSE   FALSE
## 5   V05   614    582     0  32 FALSE   FALSE
## 6   V06   614    614     0   0 FALSE   FALSE
## 7   V07   614    614     0   0 FALSE   FALSE
## 8   V08   614    592     0  22 FALSE   FALSE
## 9   V09   614    600     0  14 FALSE   FALSE
## 10  V10   614    564     0  50 FALSE   FALSE
## 11  V11   614    614     0   0 FALSE   FALSE
## 12  V12   614    614     0   0 FALSE   FALSE
##                                              expression
## 1                      Gender %vin% c("Male", "Female")
## 2                          Married %vin% c("Yes", "No")
## 3                                       Dependents >= 0
## 4         Education %vin% c("Graduate", "Not Graduate")
## 5                    Self_Employed %vin% c("Yes", "No")
## 6                         ApplicantIncome - 0 >= -1e-08
## 7                       CoapplicantIncome - 0 >= -1e-08
## 8                                        LoanAmount > 0
## 9                                  Loan_Amount_Term > 0
## 10                     Credit_History %vin% c("0", "1")
## 11 Property_Area %vin% c("Urban", "Semiurban", "Rural")
## 12                        Loan_Status %vin% c("Y", "N")
# Wiersze, które nie spełniają reguł
niespelnione <- as.data.frame(summary(wyniki))
View(niespelnione)

Wizualizujemy wyniki walidacji.

cf <- confront(pozyczki, rules, key="Loan_ID")
summary(cf)
##    name items passes fails nNA error warning
## 1   V01   614    601     0  13 FALSE   FALSE
## 2   V02   614    611     0   3 FALSE   FALSE
## 3   V03   614    599     0  15 FALSE   FALSE
## 4   V04   614    614     0   0 FALSE   FALSE
## 5   V05   614    582     0  32 FALSE   FALSE
## 6   V06   614    614     0   0 FALSE   FALSE
## 7   V07   614    614     0   0 FALSE   FALSE
## 8   V08   614    592     0  22 FALSE   FALSE
## 9   V09   614    600     0  14 FALSE   FALSE
## 10  V10   614    564     0  50 FALSE   FALSE
## 11  V11   614    614     0   0 FALSE   FALSE
## 12  V12   614    614     0   0 FALSE   FALSE
##                                              expression
## 1                      Gender %vin% c("Male", "Female")
## 2                          Married %vin% c("Yes", "No")
## 3                                       Dependents >= 0
## 4         Education %vin% c("Graduate", "Not Graduate")
## 5                    Self_Employed %vin% c("Yes", "No")
## 6                         ApplicantIncome - 0 >= -1e-08
## 7                       CoapplicantIncome - 0 >= -1e-08
## 8                                        LoanAmount > 0
## 9                                  Loan_Amount_Term > 0
## 10                     Credit_History %vin% c("0", "1")
## 11 Property_Area %vin% c("Urban", "Semiurban", "Rural")
## 12                        Loan_Status %vin% c("Y", "N")
barplot(cf, main="Wizualizacja błędów i braków danych")

Żadna z reguł walidacyjnych nie została złamana. Wszystkie dane spełniają określone kryteria. W naszym zbiorze znajdują się natomiast brakujące dane, które nie mogły być ocenione.

W przypadku zmiennej “Gender” znajduje się 13 braków danych, zmiennej “Married” - 3, zmiennej “Dependents” - 15, zmiennej “Self_Employed” - 32, zmiennej “LoanAmount” - 22, zmiennej “Loan_Amount_Term” - 14, a w przypadku zmiennej “Credit_History” znajduje się 50 braków danych.

2.3. Imputacja braków danych

W celu uzupełnienia braków danych wykorzystujemy metodę imputacji. Dla zmiennych “Gender” i “Married” zastosujemy metodę imputacji dominantą.

Na początku przystępujemy do zdefiniowania funkcji dominanty.

Mode <- function(x, na.rm = FALSE) {
  uniqx <- unique(x)
  uniqx[which.max(tabulate(match(x, uniqx)))]
}

Następnie przechodzimy do imputacji braków danych.

# imputacja dominantą
pozyczki$Gender <- ifelse(is.na(pozyczki$Gender), 
                          Mode(pozyczki$Gender, na.rm = TRUE), 
                          pozyczki$Gender)

pozyczki$Married <- ifelse(is.na(pozyczki$Married), 
                           Mode(pozyczki$Married, na.rm = TRUE), 
                           pozyczki$Married)

Dla zmiennych “Dependents”, “Self_Employed” i “Credit_History” wykorzystamy metodę hot-deck, która umożliwia imputację na podstawie podobnych obserwacji w zbiorze danych.

Liczba osób na utrzymaniu może być powiązana ze zmienną dotyczącą stanu cywilnego, informacja o prowadzeniu działalności gospodarczej z dochodem, zaś historia kredytowa od wartości pożyczki

# imputacja metodą hot-deck
pozyczki$Dependents <- hotdeck(pozyczki, variable = "Dependents")$Dependents

pozyczki$Self_Employed <- hotdeck(pozyczki, variable = "Self_Employed", ord_var = "ApplicantIncome")$Self_Employed

pozyczki$Credit_History <- hotdeck(pozyczki, variable = "Credit_History", ord_var = "LoanAmount")$Credit_History

Dla zmiennych numerycznych wykorzystujemy metodę imputacji medianą, ponieważ jest ona bardziej odporna na wartości odstające niż średnia.

# imputacja medianą zmiennych numerycznych
kwota_pozyczki <- pozyczki$LoanAmount <- imputate_na(pozyczki, LoanAmount, method = "median")
okres_pozyczki <- pozyczki$Loan_Amount_Term <- imputate_na(pozyczki, Loan_Amount_Term, method = "median")

# wizualizacja zamiany braków danych metodą mediany
plot(kwota_pozyczki)

plot(okres_pozyczki)

3.Wizualizacje

3.1. Dochód wnioskodawcy a kwota pożyczki

Dodajemy nową kolumnę sumującą dochód wnioskodawcy i współwnioskodawcy w celu zbadania zależności między dochodem wnioskodawców a kwotą pożyczki.

pozyczki$TotalIncome <- pozyczki$ApplicantIncome + pozyczki$CoapplicantIncome

Poniższy wykres ukazuje zależność między dochodem wnioskodawcy a kwotą pożyczki.

ggplot(pozyczki, aes(x = TotalIncome, y = LoanAmount)) +
  geom_point(aes(color = Credit_History)) +
  geom_smooth(method = 'loess', se = FALSE) +
  theme_minimal() +
  labs(title = 'Dochód vs Kwota pożyczki', x = 'Całkowity dochód wnioskodawców', y = 'Kwota pożyczki') +
  theme(legend.position = c(0.8, 0.2))
## Warning: A numeric `legend.position` argument in `theme()` was deprecated in ggplot2
## 3.5.0.
## ℹ Please use the `legend.position.inside` argument of `theme()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `geom_smooth()` using formula = 'y ~ x'

Na podstawie powyższej wizualizacji można zaobserwować, że generalnie im wyższy dochód wnioskodawcy, tym wyższa kwota pożyczki.Punkty są dość rozproszone wokół linii trendu, co oznacza, że dochód nie jest jedynym czynnikiem wpływającym na wysokość pożyczki.

Można również zauważyć, że osoby z lepszą historią kredytową (ciemniejsze punkty) mają tendencję do zaciągania wyższych pożyczek przy tym samym poziomie dochodu.

3.2. Stan cywilny a liczba osób w gospodarstwie domowym

W kolejnym kroku sprawdzamy zależność między stanem cywilnym a liczbą osób w gospodarstwie domowym.

pozyczki %>%
  filter(!is.na(Dependents)) %>%  # Usuwamy brakujące dane dla Dependents
  ggplot(aes(x = Married, y = Dependents)) +
  geom_jitter(aes(color = Dependents), width = 0.2, size = 3, alpha = 0.6) +
  theme_minimal() +
  scale_color_brewer(palette = 'Set1') +  # Paleta kolorów
  labs(title = 'Stan cywilny a liczba osób w gospodarstwie domowym',
       x = 'Stan cywilny',
       y = 'Liczba osób w gospodarstwie domowym') +
  theme(legend.position = 'right')  # Ustawienie legendy

Osoby pozostające w związku mają średnio więcej osób na utrzymaniu niż osoby nie będące w związku.

3.3. Kwota pożyczki a obszar zamieszkania

Następnie przeanalizowałyśmy zależność pomiędzy kwotą pożyczki a dochodem wnioskodawców w zależności od statusu pożyczki.

if(!require('ggrepel')) install.packages('ggrepel')
## Ładowanie wymaganego pakietu: ggrepel
library(ggrepel)

ggplot(pozyczki, aes(x = TotalIncome, y = LoanAmount, size = TotalIncome, color = Loan_Status)) +
  geom_point(alpha = 0.6) +
  scale_color_manual(values = c('green', 'red')) +
  theme_minimal() +
  labs(title = 'Dochód a kwota pożyczki', x = 'Dochód wnioskodawcy', y = 'Kwota pożyczki') +
  theme(legend.position = 'right')

Generalnie im wyższy dochód wnioskodawców, tym większa kwota pożyczki. Innymi słowy, im wyższy dochód, tym większa szansa na uzyskanie większej kwoty.

3.4. Macierz korelacji

Następnie sprawdzamy zależności między zmiennymi w naszym zbiorze danych za pomocą macierzy korelacji.

library(corrplot)

pozyczki_korelacja <- pozyczki %>%
  mutate(across(where(is.character), as.factor)) %>%
  mutate(across(where(is.factor), as.numeric))

# Macierz korelacji
cor_matrix <- cor(pozyczki_korelacja, use = "complete.obs")

# Wizualizacja
corrplot(cor_matrix, method = "color", type = "upper", order = "hclust",
         tl.col = "black", tl.srt = 45)

Najsilniejsza korelacja występuje między TotalIncome a ApplicantIncome oraz CoapplicantIncome, co jest naturalne, ponieważ TotalIncome to ich suma.LoanAmount jest dodatnio skorelowany z dochodami, co sugeruje, że wyższe dochody przekładają się na wyższe kwoty pożyczki.

Zmienna Credit_History wykazuje istotną korelację z innymi zmiennymi, co wskazuje, że historia kredytowa ma znaczenie w procesie przyznawania pożyczek.

Zmienne, takie jak Married, Education czy Self_Employed, nie wykazują silnych korelacji z innymi zmiennymi, co sugeruje, że nie mają one bezpośredniego wpływu na kwotę pożyczki lub jej status.Podobnie w przypadku zmiennej Loan_Amount_Term.

4.Analiza opisowa

Poniższy wykres przedstawia rozkład kwot pożyczek udzielanych w zależności od tego, czy dana nieruchomość znajduje się na obszarze wiejskim, podmiejskim czy miejskim.

# Wykres gęstości
density.p <- ggdensity(pozyczki, x = "LoanAmount", 
                       fill = "Property_Area", palette = "jco")+
  stat_overlay_normal_density(color = "red", linetype = "dashed")

# Liczymy statystyki wg liczby osób w gospodarstwie:
stable <- desc_statby(pozyczki, measure.var = "LoanAmount",
                      grps = "Property_Area")
stable <- stable[, c("Property_Area", "length", "mean", "sd")]
# Wykres, szablon "medium orange":
stable.p <- ggtexttable(stable, rows = NULL, 
                        theme = ttheme("mOrange"))
# Podpisujemy wykres:
text <- paste("Kwota pożyczki wg obszaru zamieszkania.",
               sep = " ")
text.p <- ggparagraph(text = text, face = "italic", size = 11, color = "black")
# Aranżujemy wykresy na tym samym panelu:
ggarrange(density.p, stable.p, text.p, 
          ncol = 1, nrow = 3,
          heights = c(1, 0.5, 0.3))

Widzimy, że rozkłady kwot pożyczek dla wszystkich trzech obszarów mają zbliżony so siebie kształt. Osoby mieszkające na obszarach wiejskich zaciągają średnio nieco wyższe pożyczki niż mieszkańcy obszarów podmiejskich i miejskich. Najwyższym odchyleniem standardowym charakteryzują się pożyczki udzielane na obszarach miejskich.

Kolejny wykres przedstawia rozkład kwot pożyczek w zależności od płci wnioskodawcy.

ggplot(pozyczki, aes(x = Gender, y = LoanAmount)) +
  geom_boxplot(aes(fill = Gender), outlier.alpha = 0.25) +
  stat_summary(
    fun = median,
    geom = "text",
    aes(label = after_stat(y)),
    vjust = -0.5,
    color = "blue",
    size = 3 
  ) +
  scale_fill_brewer(palette = "Set3") +
  theme_minimal() +
  labs(
    title = "Kwota pożyczki a płeć wnioskodawcy",
    x = "Płeć",
    y = "Kwota pożyczki"
  ) +
  theme(legend.position = "none")

Mężczyźni zaciągają przeciętnie wyższe pożyczki niż kobiety, o czym świadczy wyższa wartość górnej krawędzi pudełka i dłuższy “wąs” wykresu. W obu grupach występują pojedyncze przypadki bardzo wysokich kwot pożyczek, które odbiegają od większości danych.

5.Testowanie statystyczne

W tej części skupiłyśmy się na testowaniu statystycznym zależności między zmiennymi w naszym zbiorze danych. Wykorzystujemy do tego pakiet “ggstatsplot”.

Poniższy wykres kołowy przedstawia zależność między statusem edukacyjnym a decyzją o przyznaniu kredytu.

#install.packages("ggstatsplot", repos = "https://cran.r-project.org")
library(ggstatsplot) #ładowanie potrzebnego pakietu
## You can cite this package as:
##      Patil, I. (2021). Visualizations with statistical details: The 'ggstatsplot' approach.
##      Journal of Open Source Software, 6(61), 3167, doi:10.21105/joss.03167
ggpiestats(
  data = pozyczki,
  x = Loan_Status,
  y = Education
)

Sformułowałyśmy następujące hipotezy:

Hipoteza zerowa (H0): Brak zależności między wykształceniem a otrzymaniem pożyczki. Hipoteza alternatywna (H1): Istnieje zależność między wykształceniem a otrzymaniem pożyczki.

Wyniki testu: wartość p dla testu chi-kwadrat wynosi 6.93e-20.

Interpretacja:

Ze względu na niską wartość p-value odrzucamy hipotezę zerową i przyjmujemy hipotezę alternatywną. Oznacza to, że istnieje statystycznie istotny związek między poziomem wykształcenia a prawdopodobieństwem otrzymania pożyczki.Absolwenci (Graduate) częściej otrzymują kredyt (71%) niż nieabsolwenci (61%). Różnica jest istotna statystycznie, ale jej siła jest niewielka (V-Cramer = 0.08).

W kolejnym kroku sprawdzamy zależność między płcią a decyzją o przyznaniu pożyczki.

ggpiestats(
  data = pozyczki,
  x = Loan_Status,
  y = Gender
)

Podstawione hipotezy:

Hipoteza zerowa (H0): Nie ma istotnej różnicy w prawdopodobieństwie otrzymania pożyczki między kobietami a mężczyznami. Hipoteza alternatywna (H1): Istnieje istotna różnica w prawdopodobieństwie otrzymania pożyczki między kobietami a mężczyznami.

Wyniki: wartość p wynosi 0.20, współczynnik V Cramera wynosi 0.00.

Interpretacja:

Wartość p-value wskazuje na przyjęcie hipotezy zerowej. Stwierdzamy, że nie ma statystycznie istotnej różnicy w prawdopodobieństwie otrzymania pożyczki między kobietami a mężczyznami.

wspolczynnik Cramera = 0.00 - wskazuje, że siła zależności jest zerowa

#malzenstwo a kwota pozyczki
ggbetweenstats(
data=pozyczki,
y=LoanAmount,
x=Married
)

Wykres pokazuje różnicę w wysokości kwoty kredytu w zależności od statusu małżeńskiego. No (n = 213): Osoby niezamężne/nieżonate. Yes (n = 401): Osoby zamężne/żonate Średnia kwota kredytu dla grupy “No”: 128.85. Średnia kwota kredytu dla grupy “Yes”: 154.73.

Wynik p < 0.05 wskazuje, że różnica między grupami jest istotna statystycznie. Osoby zamężne/żonate biorą wyższe kwoty kredytu średnio niż osoby niezamężne/nieżonate. Rozkład kwot jest bardziej rozproszony w grupie zamężnych/żonatych.

Wnioski: Status małżeński wpływa na wysokość zaciąganej kwoty kredytu, choć różnica ma niewielką siłę efektu.

#status pozyczki a kwota pozyczki
ggbetweenstats(
data=pozyczki,
y=LoanAmount,
x=Loan_Status
)

Na wykresie porównano kwoty pożyczek (“LoanAmount”) między zaakceptowanymi (Y) i odrzuconymi (N) wnioskami. Średnie są podobne: 151,22 dla N i 144,29 dla Y. Test t-Studenta wykazał brak istotnej różnicy (p =0.37). Rozkłady w obu grupach są zbliżone, co wskazuje, że status pożyczki nie zależy istotnie od kwoty.

#anova
wyniki <-aov(LoanAmount~Married, data=pozyczki)
summary(wyniki)
##              Df  Sum Sq Mean Sq F value   Pr(>F)    
## Married       1   93127   93127   13.43 0.000269 ***
## Residuals   612 4243252    6933                     
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

ANOVA pokazuje, że status małżeński (“Married”) ma istotny wpływ na zmienną zależną (np. kwotę pożyczki), z bardzo wysokim poziomem istotności (F=14.45, p=0.000268). To oznacza, że różnice między grupami (żonaci vs nieżonaci) są statystycznie znaczące.

6. Narzędzie pomagające w podejmowaniu decyzji odnośnie przyznania pożyczki

Po przeprowadzeniu analizy danych pochodzących z naszego zbioru przeszłyśmy do budowy narzędzia, które pozwoli firmie zautomatyzować proces przyznawania decyzji o udzieleniu pożyczki na podstawie danych klienta.

W ramach tego etapu zbudowano model logitowy, który na podstawie dostępnych danych o płci, stanie cywilnym, wykształceniu, wysokości dochodu, liczby osób na utrzymaniu, samozatrudnieniu, historii kredytowej, wysokości pożyczki i jej okresu spłaty pozwala oszacować prawdopodobieństwo przyznania pożyczki.

library(mfx)
library(margins)
library(lmtest)

pozyczki$LoanAmount <- as.numeric(pozyczki$LoanAmount)
pozyczki$Loan_Amount_Term <- as.numeric(pozyczki$Loan_Amount_Term)
# Zamiana zmiennej Loan_Status na zmienną binarną
pozyczki$Loan_Status <- ifelse(pozyczki$Loan_Status == "Y", 1, 0)

# Przekodowanie zmiennych objaśniających
pozyczki$Gender <- ifelse(pozyczki$Gender == "Male", 1, 0)
pozyczki$Married <- ifelse(pozyczki$Married == "Yes", 1, 0)
pozyczki$Education <- ifelse(pozyczki$Education == "Graduate", 1, 0)
pozyczki$Self_Employed <- ifelse(pozyczki$Self_Employed == "Yes", 1, 0)
pozyczki$Property_Area <- ifelse(pozyczki$Property_Area == "Urban", 1,
                                 ifelse(pozyczki$Property_Area == "Semiurban", 2, 3))
pozyczki$Dependents <- ifelse(pozyczki$Dependents == "0", 0,
                              ifelse(pozyczki$Dependents == "1", 1,
                                     ifelse(pozyczki$Dependents == "2", 2, 3)))


# Tworzenie modelu logitowego
model <- glm(Loan_Status ~ Gender + Married + Dependents + Education + Self_Employed + Credit_History + TotalIncome + LoanAmount + Loan_Amount_Term + Property_Area, data = pozyczki, family = binomial)

 # Obliczanie prawdopodobieństwa przyznania pożyczki dla wybranego klienta
 x_individual <- data.frame(Gender = 1, Married = 0, Dependents = 2, Education = 1,
                            Self_Employed = 1, Credit_History = 0, TotalIncome = 7000,
                            Property_Area = 2,LoanAmount = 400, Loan_Amount_Term = 360)

 # Przewidywane prawdopodobieństwo przyznania pożyczki
 pred_prob <- predict(model, newdata = x_individual, type = "response")
 pred_prob
##          1 
## 0.07347233

Dla przykładowego klienta z podanymi charakterystykami (mężczyzna, kawaler, jedna osoba na utrzymaniu, wykształcenie wyższe, samozatrudnienie, brak historii kredytowej, dochód: 7000, kwota pożyczki: 400, okres kredytowania 360 miesięcy, nieruchomość podmiejska) model oszacował prawdopodobieństwo otrzymania pożyczki na poziomie około 7,4%.

7.Podsumowanie i wnioski

7.1.Podsumowanie wyników

Wprowadzenie i analiza danych W projekcie przeanalizowano dane dotyczące wniosków kredytowych, obejmujące 614 obserwacji i 13 zmiennych. Dane zawierały informacje o płci, stanie cywilnym, liczbie osób na utrzymaniu, wykształceniu, działalności gospodarczej, dochodach, kwotach pożyczek, okresie spłaty oraz historii kredytowej. W wyniku analizy braków danych wykryto około 1,9% braków, które zostały uzupełnione za pomocą metod imputacji (dominanta, hot-deck, mediana).

7.1.1.Wizualizacje i zależności w danych

Dochód vs. Kwota pożyczki Zaobserwowano, że wyższy całkowity dochód wnioskodawców jest związany z wyższymi kwotami pożyczek, jednak zależność ta nie jest idealna (duże rozproszenie punktów). Lepsza historia kredytowa sprzyja przyznawaniu wyższych pożyczek.

Stan cywilny a liczba osób w gospodarstwie domowym Osoby w związku małżeńskim częściej mają większą liczbę osób na utrzymaniu.

Kwota pożyczki a obszar zamieszkania Mieszkańcy obszarów wiejskich zaciągają średnio wyższe pożyczki niż osoby z miast i terenów podmiejskich, przy czym największe odchylenia występują w miastach.

Kwota pożyczki a płeć wnioskodawcy Mężczyźni zaciągają przeciętnie wyższe pożyczki niż kobiety, co odzwierciedlają wartości wykresów pudełkowych.

Status edukacyjny i płeć a decyzje kredytowe Absolwenci mają większe szanse na pozytywną decyzję kredytową (71%) niż osoby bez wykształcenia wyższego (61%). Płeć nie wpływa istotnie na decyzję o przyznaniu kredytu (różnice statystycznie nieistotne).

7.1.2.Testowanie statystyczne

Zależność między wykształceniem a decyzją kredytową jest istotna statystycznie (p = 0,03), ale siła zależności jest niewielka (V-Cramer = 0,08). Płeć nie wykazuje statystycznie istotnego wpływu na decyzję kredytową (p = 0,63, V-Cramer = 0,00).

7.2. Wnioski Zwiększenie trafności modelu klasyfikacyjnego

Lepsza historia kredytowa i wyższy dochód wnioskodawców mają pozytywny wpływ na decyzje o przyznaniu kredytu. Warto uwzględnić te czynniki jako kluczowe zmienne w budowie modelu. Wykształcenie również wpływa na decyzję kredytową, choć jego znaczenie jest relatywnie niewielkie. Optymalizacja procesów decyzyjnych

Wprowadzenie dodatkowych kryteriów, takich jak analiza obszaru zamieszkania i profilu klienta (np. historia kredytowa i liczba osób w gospodarstwie), może poprawić trafność decyzji kredytowych. Należy monitorować wpływ czynników nieistotnych (np. płeć) na wyniki modelu, aby uniknąć potencjalnej dyskryminacji. Rekomendacje dotyczące braków danych

Należy wdrożyć procesy ograniczające powstawanie braków danych w systemach wprowadzania informacji (np. wymuszenie wypełniania pól kluczowych). Imputacja metodą hot-deck okazała się skuteczna w uzupełnianiu braków danych związanych z cechami kategorialnymi. Rozważenie dalszej segmentacji klientów

Segmentacja klientów na podstawie dochodów, historii kredytowej i obszaru zamieszkania pozwoli na bardziej precyzyjne dostosowanie oferty kredytowej do potrzeb różnych grup klientów.