Opracowanie zbioru

Author

Jakub Braszczok

Zbiór danych Boston

Boston pochodzi z pakietu MASS i zawiera informacje dotyczące różnych aspektów życia, takich jak: przestępczość, zanieczyszczenie powietrza, dostęp do szkół i usług, czy struktura demograficzna, które mają wpływ na ceny mieszkań. Obserwacje pochodzą z lat 70. XX wieku. Jest to zbiór głównie używany do analizy czynników wpływających na cenę nieruchomości. Zbiór zawiera 506 obserwacji.

Boston

Biblioteki
Code
options(repos = c(CRAN = "https://cloud.r-project.org/"))

#install.packages("ggplot2")
#install.packages("ggcorrplot")
#install.packages("gganimate")
#install.packages("gifski")
#install.packages("dplyr")
#install.packages("tidyr")
#install.packages("knitr")
#install.packages("moments")
library(ggplot2)
library(ggcorrplot)
library(gganimate)
library(gifski)
library(dplyr)
library(tidyr)
library(moments)

Załadowanie i wczytanie zbioru

Code
library(MASS)
attach(Boston)
head(Boston[,(1:12)])
     crim zn indus chas   nox    rm  age    dis rad tax ptratio  black
1 0.00632 18  2.31    0 0.538 6.575 65.2 4.0900   1 296    15.3 396.90
2 0.02731  0  7.07    0 0.469 6.421 78.9 4.9671   2 242    17.8 396.90
3 0.02729  0  7.07    0 0.469 7.185 61.1 4.9671   2 242    17.8 392.83
4 0.03237  0  2.18    0 0.458 6.998 45.8 6.0622   3 222    18.7 394.63
5 0.06905  0  2.18    0 0.458 7.147 54.2 6.0622   3 222    18.7 396.90
6 0.02985  0  2.18    0 0.458 6.430 58.7 6.0622   3 222    18.7 394.12

Opis zmiennych

  • crim: wskaźnik przestępczości na 100.000 mieszkańców
  • zn: procent terenów mieszkalnych przeznaczonych na działki
  • indus: procent obszarów przemysłowych w mieście
  • chas: zmienna binarna (0 lub 1), wskazująca, czy dana dzielnica graniczy z rzeką Charles (0 = nie, 1 = tak)
  • nox: stężenie tlenków azotu w powietrzu (w ppm)
  • rm: średnia liczba pokoi w mieszkaniach w danej dzielnicy
  • age: procent budynków zbudowanych przed 1940 rokiem
  • dis: wskaźnik odległości od 5 głównych centrów pracy w Boston
  • rad: wskaźnik dostępu do autostrad w danej dzielnicy
  • tax: stawka podatku od nieruchomości (na 10.000 dolarów)
  • ptratio: stosunek liczby uczniów do nauczycieli w szkołach publicznych
  • black: wskaźnik proporcji osób czarnoskórych w prowincji
  • lstat: procent osób o niskim statusie ekonomicznym
  • medv: medianowa wartość domu w tysiącach dolarów (Medianowa wartość domów to wartość, która dzieli zbiór cen domów na dwie równe części: połowa domów ma wartość mniejszą lub równą tej medianie, a druga połowa większą lub równą)
Code
df <- data.frame(
  Średnia = c(mean(crim), mean(zn), mean(indus), mean(chas), mean(nox), mean(rm), mean(age), mean(dis), mean(rad), mean(tax), mean(ptratio), mean(black), mean(lstat), mean(medv)),
  Q1 = c(quantile(crim, 0.25), quantile(zn, 0.25), quantile(indus, 0.25), quantile(chas, 0.25), quantile(nox, 0.25), quantile(rm, 0.25), quantile(age, 0.25), quantile(dis, 0.25), quantile(rad, 0.25), quantile(tax, 0.25), quantile(ptratio, 0.25), quantile(black, 0.25), quantile(lstat, 0.25), quantile(medv, 0.25)),
  Mediana = c(median(crim), median(zn), median(indus), median(chas), median(nox), median(rm), median(age), median(dis), median(rad), median(tax), median(ptratio), median(black), median(lstat), median(medv)),
  Q3 = c(quantile(crim, 0.75), quantile(zn, 0.75), quantile(indus, 0.75), quantile(chas, 0.75), quantile(nox, 0.75), quantile(rm, 0.75), quantile(age, 0.75), quantile(dis, 0.75), quantile(rad, 0.75), quantile(tax, 0.75), quantile(ptratio, 0.75), quantile(black, 0.75), quantile(lstat, 0.75), quantile(medv, 0.75)),
  Minimum = c(min(crim), min(zn), min(indus), min(chas), min(nox), min(rm), min(age), min(dis), min(rad), min(tax), min(ptratio), min(black), min(lstat), min(medv)),
  Maksimum = c(max(crim), max(zn), max(indus), max(chas), max(nox), max(rm), max(age), max(dis), max(rad), max(tax), max(ptratio), max(black), max(lstat), max(medv)),
  Rozstęp = c(max(crim) - min(crim), max(zn) - min(zn), max(indus) - min(indus), max(chas) - min(chas), max(nox) - min(nox), max(rm) - min(rm), max(age) - min(age), max(dis) - min(dis), max(rad) - min(rad), max(tax) - min(tax), max(ptratio) - min(ptratio), max(black) - min(black), max(lstat) - min(lstat), max(medv) - min(medv)),
  Odchylenie = c(sd(crim), sd(zn), sd(indus), sd(chas), sd(nox), sd(rm), sd(age), sd(dis), sd(rad), sd(tax), sd(ptratio), sd(black), sd(lstat), sd(medv)),
  Skośność = c(skewness(crim), skewness(zn), skewness(indus), skewness(chas), skewness(nox), skewness(rm), skewness(age), skewness(dis), skewness(rad), skewness(tax), skewness(ptratio), skewness(black), skewness(lstat), skewness(medv))
)
df$Średnia <- round(df$Średnia, 2)
df$Q1 <- round(df$Q1, 2)
df$Mediana <- round(df$Mediana, 2)
df$Q3 <- round(df$Q3, 2)
df$Minimum <- round(df$Minimum, 2)
df$Maksimum <- round(df$Maksimum, 2)
df$Rozstęp <- round(df$Rozstęp, 2)
df$Odchylenie <- round(df$Odchylenie, 2)
df$Skośność <- round(df$Skośność, 2)

rownames(df) <- c("crim", "zn", "indus", "chas", "nox", "rm", "age", "dis", "rad", "tax", "ptratio", "black",  "lstat", "medv")

Miary przeciętne

Code
df[, c("Średnia", "Q1", "Mediana", "Q3")]
        Średnia     Q1 Mediana     Q3
crim       3.61   0.08    0.26   3.68
zn        11.36   0.00    0.00  12.50
indus     11.14   5.19    9.69  18.10
chas       0.07   0.00    0.00   0.00
nox        0.55   0.45    0.54   0.62
rm         6.28   5.89    6.21   6.62
age       68.57  45.02   77.50  94.07
dis        3.80   2.10    3.21   5.19
rad        9.55   4.00    5.00  24.00
tax      408.24 279.00  330.00 666.00
ptratio   18.46  17.40   19.05  20.20
black    356.67 375.38  391.44 396.22
lstat     12.65   6.95   11.36  16.96
medv      22.53  17.02   21.20  25.00

Miary zróżnicowania

Code
df[, c("Odchylenie", "Maksimum", "Minimum", "Rozstęp")]
        Odchylenie Maksimum Minimum Rozstęp
crim          8.60    88.98    0.01   88.97
zn           23.32   100.00    0.00  100.00
indus         6.86    27.74    0.46   27.28
chas          0.25     1.00    0.00    1.00
nox           0.12     0.87    0.38    0.49
rm            0.70     8.78    3.56    5.22
age          28.15   100.00    2.90   97.10
dis           2.11    12.13    1.13   11.00
rad           8.71    24.00    1.00   23.00
tax         168.54   711.00  187.00  524.00
ptratio       2.16    22.00   12.60    9.40
black        91.29   396.90    0.32  396.58
lstat         7.14    37.97    1.73   36.24
medv          9.20    50.00    5.00   45.00

Skośność

Code
df["Skośność"]
        Skośność
crim        5.21
zn          2.22
indus       0.29
chas        3.40
nox         0.73
rm          0.40
age        -0.60
dis         1.01
rad         1.00
tax         0.67
ptratio    -0.80
black      -2.88
lstat       0.90
medv        1.10

Analiza graficzna danych

Plot

Wykres przedstawia relację między średnią liczbą pokoi na mieszkanie a medianową wartością nieruchomości (w tysiącach dolarów). Zauważamy trend, który wskazuje na to, że większa liczba pokoi jest związana z wyższą wartością nieruchomości.

Code
plot(rm, medv,
     xlab = "rm - Średnia liczba pokoi w mieszkaniach",
     ylab = "medv - Medianowa wartość domu",
     main = "Zależność między liczbą pokoi, a wartością nieruchomości",
     pch = 19, col = "#6F4E37")
grid()

Boxplot

Wykres przedstawia relację między zaokrągloną liczbą pokoi a wskaźnikiem przestępczości. Zauważalny jest trend wskazujący, że dzielnice z mniejszą liczbą pokoi charakteryzują się wyższym poziomem przestępczości. W miarę wzrostu liczby pokoi wskaźnik przestępczości maleje, co sugeruje, że większe mieszkania znajdują się w bezpieczniejszych dzielnicach.

Zaokrąglenie liczby pokoi do wartości całkowitej.

Code
zaokrąglenie = round(rm)
Code
boxplot(crim ~ zaokrąglenie, 
        data = Boston, 
        main = "Zależność między przestępczością, a liczbą pokoi",
        xlab = "zaokrąglenie - Zaokrąglona liczba pokoi",
        ylab = "crim - wskaźnik przestępczości",
        col = "#6F4E37",
        border = "black")
grid()

Histogram

Histogram przedstawia rozkład procentu osób o niskim statusie ekonomicznym. Większość dzielnic charakteryzuje się udziałem osób o niskim statusie ekonomicznym w przedziale 5%-15%, co wskazuje na względnie dobrą sytuację ekonomiczną mieszkańców. Dzielnice z wyższym udziałem takich osób występują znacznie rzadziej.

Code
ggplot(Boston, aes(x = lstat)) +
  geom_histogram(binwidth = 2, fill = "#6F4E37", color = "black") +
  labs(
    title = "Procent osób o niskim statusie ekonomicznym",
    x = "lstat - Procent osób o niskim statusie ekonomicznym",
    y = "Częstość"
  ) +
  theme_minimal() +
  scale_x_continuous(breaks = seq(0, max(Boston$lstat), by = 5)) +
  scale_y_continuous(breaks = seq(0, 40, by = 5)) +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"))

Inny histogram

Histogram przedstawia rozkład stężenia tlenków azotu w dzielnicach Bostonu. Na podstawie tego wykresu możemy powiedzieć, że najwięcej dzielnic charakteryzuje się stężeniem NOX w przedziale od 0.4 do 0.6 ppm, co wskazuje, no to, że większość dzielnic ma stosunkowo dobrą jakość powietrza. Jest mniej dzielnic z wyższym poziomem zanieczyszczenia.

Code
ggplot(Boston, aes(x = nox)) +
  geom_histogram(binwidth = 0.05, fill = "#6F4E37", color = "black") +
  labs(
    title = "Stężenie tlenków azotu w powietrzu",
    x = "nox - Stężenie tlenków azotu",
    y = "Liczba dzielnic"
  ) +
  theme_minimal() +
  scale_x_continuous(breaks = seq(0.3, 0.9, by = 0.1)) +
  scale_y_continuous(breaks = seq(0, 100, by = 10)) +
  theme(plot.title = element_text(hjust = 0.5, face = "bold"))

Korelacja

Macierz korelacji przedstawia siłę i kierunek zależności między róznymi zmiennymi. Jaśniejsze kolory ukazują silną dodatnią korelację, natomiast ciemniejsze na ujemną, a wartości bliskie 0 oznaczają brak istotnej zależności.

Code
macierz_kor = cor(Boston)

ggcorrplot(macierz_kor,
           method = "square",    
           type = "lower",       
           lab = TRUE,           
           lab_size = 3,         
           colors = c("#6F4E37", "#8B4513", "#D2B48C"), 
           title = 'Macierz korelacji',
           ggtheme = ggplot2::theme_minimal()) +
  ggplot2::theme(
    plot.title = element_text(hjust = 0.5, size = 14),  
    legend.position = "right",                         
    legend.title.align = 0.5                            
  )

Wykres rozrzutu

Wykres rozrzutu przedstawia zależność między średnią liczbą pokoi w mieszkaniach w danej dzielnicy a medianową wartością nieruchomości. Zauważamy, że większa liczba pokoi oznacza wyższą wartość nieruchomości. Czerwona linia regresji wskazuje dodatnią zależność, a szary obszar przedstawia przedział ufności.

Code
ggplot(Boston, aes(x = rm, y = medv)) +
  geom_point(color = "#6F4E37", size = 2) + 
  labs(
    title = "Wykres rozrzutu - Liczba pokoi a Wartość nieruchomości",
    x = "rm - Średnia liczba pokoi w mieszkaniach w danej dzielnicy",
    y = "medv - Medianowa wartość domu"
  ) +
  theme_minimal() +
  geom_smooth(method = "lm", color = "red", linetype = "dashed") +  
  theme(
    plot.title = element_text(hjust = 0.5, size = 14, face = "bold")
  )

Animacja

Animacja przedstawia zależność między średnią liczbą pokoi w mieszkaniach a medianową wartością nieruchomości uwzględniając wpływ stawki podatkowej tax. Dzięki animacji możemy zobaczyć, jak zmienia się relacja między zmiennymi w różnych przedziałach podatków.

Code
ggplot(Boston, aes(x = rm, y = medv, size = tax, color = tax)) +
  geom_point(alpha = 0.7) +
  scale_color_gradient(low = "#56B1F7", high = "#132B43") +
  labs(
    title = "Animacja - Liczba pokoi a Wartość nieruchomości",
    subtitle = "Zmiana w zależności od stawki podatku",
    x = "rm - Średnia liczba pokoi w mieszkaniach w danej dzielnicy",
    y = "medv - Medianowa wartość domu",
    size = "Podatek",
    color = "Podatek"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, size = 16, face = "bold"),
    plot.subtitle = element_text(hjust = 0.5, size = 12)
  ) +
  transition_states(
    states = cut(Boston$tax, breaks = 10),  
    transition_length = 2,
    state_length = 1
  ) +
  ease_aes('linear')

Line plot

Wykres przedstawia zmienność udziału obszarów przemysłowych na podstawie numeru obserwacji. Możemy zauważyć, że obszary przemysłowe mogą zajmować od bardzo małego procentu, do ponad 20% powierzchni. Widoczne są momenty, gdzie udział obszarów znacząco wzrasta, świadczy to o obszarach uprzemysłowionych.

Code
ggplot(Boston, aes(x = 1:nrow(Boston), y = indus)) +
  geom_line(color = "#6F4E37") +
  labs(title = "Zmienność procentu obszarów przemysłowych w mieście",
       x = "Numer obserwacji",
       y = "indus - procent obszarów przemysłowych w mieście") +
  theme_minimal()

Gęstości

Wykres gęstości przedstawia stosunek liczby uczniów do nauczycieli w szkołach publicznych. Na podstawie wykresu możemy powiedzieć, że najwięcej obserwacji występuje w przedziale między 19 a 22, co wskazuje na to, że większość szkół publicznych ma stosunkowo wysoki stosunek liczby uczniów do nauczycieli.

Code
ggplot(Boston, aes(x = ptratio)) +
  geom_density(fill = "#6F4E37", alpha = 0.6) +
  labs(title = "Wykres gęstości: Stosunek liczby uczniów do nauczycieli w szkołach publicznych",
       x = "ptratio - Stosunek liczby uczniów do nauczycieli w szkołach publicznych.",
       y = "Gęstość") +
  theme_minimal()

Wykres punktowy (z gradientem kolorów)

Wykres punktowy ukazuje zależność między liczbą pokoi a wartością nieruchomości, jasnożółty kolor oznacza wysoki procent osób o niskim statusie ekonomiczny, natomiast brązowy wskazuje na niski procent takich osób. Ponadto możemy stwierdzić, że liczby pokoi oraz wartości nieruchomości są wyższe w regionach, gdzie procent osób o niskim statusie społecznym jest mniejszy.

Code
ggplot(Boston, aes(x = rm, y = medv, color = lstat)) +
  geom_point(size = 3, alpha = 0.7) +
  scale_color_gradient(low = "#6F4E37", high = "yellow") +
  labs(title = "Liczba pokoi a wartość nieruchomości (zależność od lstat)",
       x = "rm - Średnia liczba pokoi w mieszkaniach w danej dzielnicy",
       y = "medv - Medianowa wartość nieruchomości",
       color = "lstat - Procent osób o niskim statusie ekonomicznym") +
  theme_minimal()

Wykres skrzypcowy

Poniższy wykres przedstawia,rozklad wartości nieruchomości w zależności od wskaźnika dostępu do autostrad.

Code
ggplot(Boston, aes(x = factor(rad), y = medv, fill = factor(rad))) +
  geom_violin(alpha = 0.7, color = "black") +
  labs(title = "Rozkład wartości nieruchomości w zależności od wskaźnika dostępu do autostrad",
       x = "rad - Wskaźnik dostępu do autostrad w danej dzielnicy",
       y = "medv - Medianowa wartość nieruchomości ",
       fill = "Wskaźnik dostępu") +
  theme_minimal()

Wykres konturowy

Wykres konturowy przedstawia zależność między procentem powierzchni przemysłowej w mieście a stężeniem tlenków azotu w powietrzu. Owe kontury wskazują na gęstość obserwacji w różnych obszarach. Linie konturowe wskazują obszary o większej gęstości obserwacji – im gęściej ułożone linie, tym więcej obserwacji w danym zakresie wartości.

Code
ggplot(Boston, aes(x = indus, y = nox)) +
  geom_density_2d(color = "#6F4E37") +
  labs(title = "Wykres konturowy -  Powierzchnia przemysłowa a Stężenie tlenków azotu",
       x = "indus - procent obszarów przemysłowych w mieście",
       y = "nox - Stężenie tlenków azotu w powietrzu") +
  theme_minimal()

Wykres lizakowy (Lollipop)

Wykres lizakowy przedstawia zależność między odległością od 5 głównych centrów pracy a procentem terenów mieszkalnych przeznaczonych na działki. Możemy zauważyć, że im większy procent terenów mieszkalnych , tym odległość od centrum ma tendencję do wzrostu. Na podstawie tego możemy wysunąc wionski, że tereny o więszej powierzchni (które przeznaczone są na duże działki) mogą znajdować się na obrzeżach miasta.

Code
ggplot(Boston, aes(x = reorder(factor(zn), dis), y = dis)) +
  geom_segment(aes(xend = factor(zn), yend = 0), color = "grey") +
  geom_point(size = 4, color = "#6F4E37") +
  labs(title = "Wykres Lollipop -  Odległość od 5 głównych centrów pracy a procent terenów mieszkalnych przeznaczonych na działki",
       x = "zn - procent terenów mieszkalnych przeznaczonych na działki",
       y = "dis - Wskaźnik odległości od 5 głównych centrów pracy w Boston") +
  theme_minimal()