nom <- c("Region", "District_ad", "Address", "Metro", "No_agents", "Building", "Lift", "Furnished", "Bath", "Refurbished", "Balcony", "", "")
col <- c("Date", "Dist_metro_ad", "Rooms", "Price", "Minimum_duration", "Area_total", "Area_living", "Area_kitchen", "Floor" ,"NFloor", "Latitude", "Longitude", "Year_construction")
mc = data.frame(nom,col)
formattable(mc, col.names = c("Номинальные", "Количественные"), align = "l")| Номинальные | Количественные |
|---|---|
| Region | Date |
| District_ad | Dist_metro_ad |
| Address | Rooms |
| Metro | Price |
| No_agents | Minimum_duration |
| Building | Area_total |
| Lift | Area_living |
| Furnished | Area_kitchen |
| Bath | Floor |
| Refurbished | NFloor |
| Balcony | Latitude |
| Longitude | |
| Year_construction |
Y$Date_entry = ymd(Y$Date_entry) # С помощью пакета 'lubridate' преобразуем данные в дату.Y$Lift = case_when(Y$Furnished == "Est'" ~ "Est'",
TRUE ~ Y$Lift)
Y$Furnished = case_when(Y$Furnished == "Est'" ~ NA_character_,
TRUE ~ Y$Furnished)
Y$Lift = case_when(Y$Lift == "Est'" ~ TRUE,
TRUE ~ FALSE)Y$NFloor = case_when(str_detect(Y$NFloor, "kv.m.") == TRUE ~ NA_character_,
TRUE ~ Y$NFloor)Y$No_agents = case_when( Y$No_agents == "Da" ~ TRUE,
TRUE ~ FALSE)Y$Rooms = case_when(Y$Rooms == "1 (studiya)" ~ "1 (studiya)",
TRUE ~ Y$Rooms)Y$Price = as.numeric(Y$Price)
Y$Price = case_when(Y$Price == 2 ~ 2000,
TRUE ~ Y$Price)Y$Dist_metro_ad = as.numeric(Y$Dist_metro_ad)
Y$Dist_metro_ad[Y$Dist_metro_ad == 0] <- NAY$Bath = case_when(Y$Refurbished == "Dush" ~ "Dush",
Y$Refurbished == "Poperechnaya" ~ "Poperechnaya",
Y$Refurbished == "Sovmeshchennaya" ~ "Sovmeshchennaya",
Y$Refurbished == "Otdel'naya" ~ "Otdel'naya",
TRUE ~ Y$Bath)
Y$Refurbished = case_when(Y$Refurbished == "Dush" ~ NA_character_,
Y$Refurbished == "Poperechnaya" ~ NA_character_,
Y$Refurbished == "Sovmeshchennaya" ~ NA_character_,
Y$Refurbished == "Otdel'naya" ~ NA_character_,
TRUE ~ Y$Refurbished)Y$Area_total = case_when(Y$Area_total == 70000 ~ 85,
TRUE ~ Y$Area_total)Y$Area_living[Y$Area_living=="1"]<-15
Y$Area_kitchen[Y$Area_kitchen=="1"]<-5Z_Region = as.data.frame(table(Y$Region))
formattable(Z_Region, col.names = c("Название" , "Частота"), align = "l")| Название | Частота |
|---|---|
| gorod Sankt-Peterburg | 2870 |
| Leningradskaya oblast’ | 130 |
Z_District_ad = as.data.frame(table(Y$District_ad))
# Дальше код, который нужен, чтобы вывести таблицу в 4 столбца, а не в два, так как она получилась довольно большая.
one = arrange(filter(Z_District_ad, Z_District_ad$Freq < 127), by = Freq)
two = arrange(filter(Z_District_ad, Z_District_ad$Freq > 127), by = Freq)
df<-data.frame("","")
names(df)<-c("Var1","Freq")
one <- rbind(one, df)
Z_District_ad = bind_cols(one,two)
formattable(Z_District_ad, col.names = c("Район", "Частота", "Район", "Частота"), align = "l")| Район | Частота | Район | Частота |
|---|---|---|---|
| Кронштадтский | 1 | Адмиралтейский | 134 |
| Ломоносовский | 1 | Кировский | 136 |
| Колпинский | 4 | Красносельский | 144 |
| Гатчинский | 7 | Василеостровский | 180 |
| Курортный | 8 | Невский | 209 |
| Петродворцовый | 10 | Калининский | 232 |
| Пушкинский | 36 | Петроградский | 247 |
| Всеволожский | 117 | Выборгский | 278 |
| Красногвардейский | 119 | Приморский | 310 |
| Фрунзенский | 126 | Московский | 316 |
| Центральный | 385 |
U_Address = unique(Y$Address)
cat("Количество уникальных значений: ", length(U_Address), "\n") # = 2421Количество уникальных значений: 2421
# Скорее всего, не имеет смысла строить таблицу саму по себе - 2421 из 3000 значений уникальные
# Попробуем, это несложно:
Z_Address = as.data.frame(table(Y$Address))
cat("Наибольшая частота одного значения: ", max(Z_Address$Freq), "\n") # = 10 - наибольшая частота одного значенияНаибольшая частота одного значения: 10
Здесь таблица с частотой малосодержательна: получим 2421 строки, в большинстве которых частота значения 1 (адрес встречается один раз).
Y$Metro[Y$Metro==""]<-NA
Z_Metro = as.data.frame(table(Y$Metro))
# formattable(Z_Metro, align = "l")
# Как-то очень много строчек, все станции метро, полезна ли эта информация? Я думаю, что нет, поэтому решила вывести таблицу с 5 наименьшими и 5 наибольшими частотами.
Z_Metro = bind_cols(filter(Z_Metro, Freq == 1), rbind(rbind(filter(Z_Metro, Freq > 100), df), df))
formattable(Z_Metro, align = "l", col.names = c("Станция метро", "Частота", "Станция метро", "Частота")) | Станция метро | Частота | Станция метро | Частота |
|---|---|---|---|
| Antropshino | 1 | Chernyshevskaya | 116 |
| Gatchina-Varsh. | 1 | Komendantskii pr. | 116 |
| Kuz’molovo | 1 | Moskovskaya | 104 |
| Repino | 1 | Primorskaya | 119 |
| Sestroreck | 1 | Veteranov pr. | 118 |
| Spasskaya | 1 | ||
| Suida | 1 |
Z_No_agents = as.data.frame(table(Y$No_agents))
Z_No_agents$Var1 = ifelse(Z_No_agents$Var1 == TRUE, "Да", "Нет") # Замена TRUE и FALSE на "Да", "Нет"
Z_No_agents = arrange(Z_No_agents, by = Freq) # Ранжировка по частоте
formattable(Z_No_agents, align = "l", col.names = c("Aгентам не звонить", "Частота"))| Aгентам не звонить | Частота |
|---|---|
| Да | 407 |
| Нет | 2593 |
Y$Building[Y$Building==""]<-NA
Z_Building = as.data.frame(table(Y$Building))
one = arrange(filter(Z_Building, Freq < 30), by = Freq)
one <- rbind(one, df)
two = arrange(filter(Z_Building, Freq > 30), by=Freq)
Z_Building = bind_cols(one,two)
formattable(Z_Building, col.names = c("Тип здания", "Частота", "Тип здания", "Частота"), align = "l")| Тип здания | Частота | Тип здания | Частота |
|---|---|---|---|
| 504D seriya | 4 | 137 seriya | 39 |
| Besshovnaya tehnologiya | 4 | Staryi fond s KR | 39 |
| Rekonstrukciya | 4 | Individual’nyi proekt | 40 |
| 121(Gatchinskaya) | 6 | Stalinskii | 52 |
| 600.11 seriya | 12 | Staryi fond | 82 |
| 504 seriya | 16 | Monol.Panel’nyi | 87 |
| 606 seriya | 16 | Blochnyi | 102 |
| Korabl’ | 16 | Panel’nyi | 204 |
| Brejnevka | 21 | Monolit | 321 |
| Hrushchevka | 26 | Kirp.Monolit | 555 |
| Kirpichnyi | 1034 |
Z_Lift = as.data.frame(table(Y$Lift))
Z_Lift$Var1 = ifelse(Z_Lift$Var1 == TRUE, "Да", "Нет")
# Замена TRUE и FALSE на "Да", "Нет"
formattable(Z_Lift, col.names = c("Наличие лифта", "Частота"), align = "l")| Наличие лифта | Частота |
|---|---|
| Нет | 1278 |
| Да | 1722 |
Y$Furnished[Y$Furnished==""]<-NA
Y$Furnished[Y$Furnished=="Net"]<-"Нет"
Z_Furnished = as.data.frame(table(Y$Furnished))
Z_Furnished = arrange(Z_Furnished, by = Freq)
formattable(Z_Furnished, col.names = c("Меблировка", "Частота"), align = "l")| Меблировка | Частота |
|---|---|
| Garnitur 70-80 | 6 |
| Tol’ko kuhnya | 34 |
| Sbornaya 70-80 | 35 |
| Garnit+kuh.nab. | 72 |
| Minimum | 80 |
| Нет | 118 |
| Garnitur Sovr. | 315 |
| Sbor.+kuh.garn. | 596 |
| Sbornaya Sovr. | 821 |
Y$Bath[Y$Bath==""]<-NA
Z_Bath = as.data.frame(table(Y$Bath))
Z_Bath = arrange(Z_Bath, by = Freq)
formattable(Z_Bath, col.names = c("Тип ванной", "Частота"), align = "l")| Тип ванной | Частота |
|---|---|
| Poperechnaya | 9 |
| Prodol’naya | 10 |
| Dush | 52 |
| Est’ | 95 |
| Sovmeshchennaya | 411 |
| Otdel’naya | 843 |
Y$Refurbished[Y$Refurbished==""]<-NA
Z_Refurbished = as.data.frame(table(Y$Refurbished))
Z_Refurbished = arrange(Z_Refurbished, by = Freq)
formattable(Z_Refurbished, col.names = c("Тип ремонта", "Частота"), align = "l")| Тип ремонта | Частота |
|---|---|
| Trebuetsya | 8 |
| Ne trebuetsya | 180 |
| Proizveden | 642 |
| Evrostandart | 869 |
Y$Balcony[Y$Balcony==""]<-NA
Y$Balcony[Y$Balcony=="Net"]<-"Нет"
Y$Balcony[Y$Balcony=="net"]<-"Нет"
Y$Balcony[Y$Balcony=="est'"]<-"Есть"
Z_Balcony = as.data.frame(table(Y$Balcony))
Z_Balcony = arrange(Z_Balcony, by = Freq)
formattable(Z_Balcony, col.names = c("Наличие балкона", "Частота"), align = "l")| Наличие балкона | Частота |
|---|---|
| 3 lodjii | 1 |
| 4 balkona | 2 |
| Erker | 6 |
| Terrasa | 9 |
| Balkon i lodjiya | 11 |
| 2 balkona | 15 |
| 2 lodjii | 17 |
| Zasteklennyi balkon | 86 |
| Есть | 128 |
| Zasteklennaya lodjiya | 233 |
| Нет | 286 |
| Lodjiya | 346 |
| Balkon | 776 |
Создаем функцию, которая считает описательные статистики для числовых переменных: минимум, первый квартиль, медиану, среднюю, моду, третий квартиль, максимум, среднеквадратическое отклонение, размах, коэффициент асимметрии и куртозис.
opis.stat <- function(a, comprendo) {
face = comprendo
face_name = str_replace(deparse(substitute(a)), "name", face)
title = str_extract(face_name, "(?<=\\[\\[).+?(?=\\])")
quantiles = quantile(a, na.rm = TRUE)
min <- unname(quantiles[1]) # но есть функция min
q_0.25 <- unname(quantiles[2])
q_0.75 <- unname(quantiles[4])
max <- unname(quantiles[5])
median <- median(a, na.rm = TRUE) # или c(unname(quantiles[3]))
mean <- mean(a, na.rm = TRUE)
mode <- as.numeric(names(table(a))[table(a)==
max(table(a))])
stdev <- sd(a, na.rm = TRUE)
range <- max(a, na.rm = TRUE)-min(a, na.rm = TRUE)
asym <- skewness(a, na.rm = TRUE)
kurtosis <- kurtosis(a, na.rm = TRUE)
data_name = paste("Z_", title, sep = "")
data = as.name(data_name)
data = data.frame(title, min, q_0.25, median, mean, mode, q_0.75, max,
stdev, range, asym, kurtosis, row.names = NULL)
for (i in names(data )) {
if (is.numeric(data [[i]][1]) == TRUE) {
k = as.numeric(data [[i]][1])
if (k < 1) {
data[[i]][1] <- c(round(k, digits=3))
} else if (k >= 1 &k < 10) {
data[[i]][1] <- c(round(k, digits=2))
} else if (k >= 10 &k < 100) {
data[[i]][1] <- c(round(k, digits=1))
} else if (k >= 100) {
data[[i]][1] <- c(round(k))
} }
}
assign(data_name, data, .GlobalEnv)
return(formattable(data))
}title = "Date_entry"
min = min(Y$Date_entry)
max = max(Y$Date_entry)
median = median(Y$Date_entry)
mean = mean(Y$Date_entry)
mode <- unique(Y$Date_entry)
mode = mode[which.max(tabulate(match(Y$Date_entry, mode)))]
q_0.25 = as.Date(quantile(unclass(Y$Date_entry), 0.25), origin = "1970-01-01")
q_0.75 = as.Date(quantile(unclass(Y$Date_entry), 0.75), origin = "1970-01-01")
stdev = as.numeric(sd(Y$Date_entry))
range = (max - min)/ddays(1)
Y = Y %>% mutate(difference = as.numeric((Y$Date_entry - min(Y$Date_entry))/ddays(1)))
asym <- as.numeric(skewness(Y$difference, na.rm = TRUE))
kurtosis <- as.numeric(kurtosis(Y$difference, na.rm = TRUE))
Z_Date_entry = data.frame(title,min, q_0.25, median, mean, mode, q_0.75, max,
stdev, range, asym, kurtosis, row.names = NULL)
for (i in names(Z_Date_entry)) {
if (is.numeric(Z_Date_entry[[i]][1]) == TRUE) {
k = as.numeric(Z_Date_entry[[i]][1])
if (k < 1) {
Z_Date_entry[[i]][1] <- c(round(k, digits=3))
} else if (k >= 1 &k < 10) {
Z_Date_entry[[i]][1] <- c(round(k, digits=2))
} else if (k >= 10 &k < 100) {
Z_Date_entry[[i]][1] <- c(round(k, digits=1))
} else if (k >= 100) {
Z_Date_entry[[i]][1] <- c(round(k))
} }
}Y$Minimum_duration<-str_remove(Y$Minimum_duration, ' mes.')
for (name in c("Dist_metro_ad", "Rooms", "Price", "Area_total", "Area_living", "Area_kitchen", "NFloor", "Latitude", "Longitude", "Year_construction", "Floor", "Minimum_duration")){
comprendo = name
if (name == "Rooms") {
Y_Rooms = Y
Y_Rooms$Rooms[Y_Rooms$Rooms=='1 (studiya)']<-1
Y_Rooms[[name]] = as.numeric(Y_Rooms[[name]])
opis.stat(Y_Rooms[[name]], comprendo)
}
else {
Y[[name]] = as.numeric(Y[[name]])
opis.stat(Y[[name]], comprendo)
}
}options(scipen = 99999)
Join = bind_rows(Z_Dist_metro_ad, Z_Rooms, Z_Price, Z_Minimum_duration, Z_Area_total, Z_Area_living, Z_Area_kitchen, Z_Floor, Z_NFloor, Z_Latitude, Z_Longitude, Z_Year_construction, id = NULL)
Join = bind_rows(mutate_all(Z_Date_entry, as.character), mutate_all(Join, as.character))
formattable(Join)| title | min | q_0.25 | median | mean | mode | q_0.75 | max | stdev | range | asym | kurtosis |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Date_entry | 2012-08-24 | 2016-06-08 | 2016-12-28 | 2016-11-04 | 2017-04-04 | 2017-04-20 | 2017-07-23 | 228 | 1794 | -2.08 | 11.2 |
| Dist_metro_ad | 10 | 330 | 770 | 1470 | 50 | 1532 | 37390 | 2775 | 37380 | 6.14 | 52.8 |
| Rooms | 1 | 1 | 2 | 1.83 | 1 | 2 | 9 | 0.964 | 8 | 1.21 | 4.86 |
| Price | 1500 | 21500 | 30000 | 44005 | 20000 | 50000 | 700000 | 44603 | 698500 | 4.9 | 42.1 |
| Minimum_duration | 1 | 11 | 11 | 10.4 | 11 | 11 | 31 | 3.17 | 30 | 0.786 | 18.6 |
| Area_total | 18 | 38 | 49.5 | 60.7 | 40 | 70 | 514 | 36.8 | 496 | 3.23 | 22.7 |
| Area_living | 9 | 18 | 30 | 36.8 | 18 | 44 | 333 | 27.8 | 324 | 3.43 | 23.6 |
| Area_kitchen | 2 | 8 | 10 | 13.7 | 10 | 14 | 200 | 12.8 | 198 | 5.67 | 53.2 |
| Floor | 1 | 3 | 5 | 6.7 | 3 | 9 | 31 | 4.91 | 30 | 1.37 | 4.79 |
| NFloor | 1 | 6 | 10 | 12.1 | 5 | 17 | 36 | 6.85 | 35 | 0.649 | 2.35 |
| Latitude | 59.5 | 59.9 | 59.9 | 59.9 | 60 | 60 | 60.1 | 0.068 | 0.561 | -0.179 | 3.09 |
| Longitude | 30.1 | 30.3 | 30.3 | 30.3 | 30.3 | 30.4 | 30.7 | 0.081 | 0.585 | 0.046 | 3.06 |
| Year_construction | 1817 | 2004 | 2012 | 2002 | 2015 | 2015 | 2017 | 26.8 | 200 | -3.858 | 21.1 |
Другой способ наглядно представить некоторые описательные статистики для количественных переменных – построить ящиковые диаграммы:
ggplot(Y, aes(x=Price/1000)) +
geom_boxplot()+theme(axis.text.y = element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(hjust = 0.5))+labs(x="Наёмная цена (тыс. рублей/месяц)", title="Распределение наемных цен квартир")График показывает, что медианная цена съема квартиры - около 30,000 рублей в месяц. При этом 50% всех наблюдений лежат в пределах от 21,500 до 50,000. рублей. Также мы видим, что цена в выбросах доходит до 700,000 рублей.
ggplot(Y, aes(x=Dist_metro_ad/1000)) +
geom_boxplot()+theme(axis.text.y = element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(hjust = 0.5))+labs(x="Расстояние до ближайшей станции метро (км)", title="Распределение расстояния до ближайшей станции метро")График показывает, что медианное расстояние от квартиры до метро составляет около 1 км. При этом 50% всех наблюдений лежат в пределах от чуть менее 1 до 3 километров. Также мы видим, что расстояние в выбросах может превышать 30 км.
ggplot(Y, aes(x=Area_total)) +
geom_boxplot()+theme(axis.text.y = element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(hjust = 0.5))+labs(x="Общая площадь (кв. м)", title="Распределение общей площади квартир")График показывает, что медианный метраж квартиры составляет около 50 квадратных метров. При этом 50% всех наблюдений лежат в пределах от 40 до 70 квадратных метров. Также мы видим, что метраж в выбросах превышает 500 квадратных метров.
ggplot(Y, aes(x=Area_living)) +
geom_boxplot()+theme(axis.text.y = element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(hjust = 0.5))+labs(x="Жилая площадь (кв. м)", title="Распределение жилой площади квартир")Из графика видно, что в основном (в более 75% наблюдений) жилая площадь квартиры не превышает 50 метров квадратных. Тем не менее, некоторые наблюдения (в выбросах) преодолевают отметку в 300 квадратых метров.
ggplot(Y, aes(x=Area_kitchen)) +
geom_boxplot()+theme(axis.text.y = element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(hjust = 0.5))+labs(x="Площадь кухни (кв. м)", title="Распределение площадей кухни квартир")Из графика видно, что в среднем площадь кухни в квартире не превышает 16.5 метров квадратных. Тем не менее, некоторые наблюдения (в выбросах) доходят до отметки в 200 квадратых метров.
ggplot(Y, aes(x=NFloor)) +
geom_boxplot()+theme(axis.text.y = element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(hjust = 0.5))+labs(x="Число этажей в доме", title="Распределение числа этажей в доме")Большинство домов (около 50%) имеют этажность от 6 до 17 этажей. Остальные не превышают 30 этажей, но заметны два выброса -“небоскреба” в 35 и 36 этажей.
ggplot(Y, aes(x=Latitude)) +
geom_boxplot()+theme(axis.text.y = element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(hjust = 0.5))+labs(x="Географическая широта", title="Распределение географической широты")Географические координаты исторического центра Санкт-Петербурга (приблизительно станция метрополитена Гостиный двор) – 59° 57’ северной широты и 30° 19’ восточной долготы. Заметим, что большинство квартир достаточно тесно расположены севернее исторического центра. Однако есть предложения и чуть южнее центра, но их очень мало.
ggplot(Y, aes(x=Longitude)) +
geom_boxplot()+theme(axis.text.y = element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(hjust = 0.5))+labs(x="Географическая долгота", title="Распределение географической долготы")Ящиковый график координат долготы показывает, что квартиры в аренду имеют координаты долготы примерно 30° 33’, при 50% квартир находятся в диапазоне от 30° 28’ до 30° 38’, а подавляющее большинство квартир - 30° 19’ до 30° 5’. Самые дальние выбросы отклоняются на 3’ от значения медианы.
ggplot(Y, aes(x=Year_construction)) +
geom_boxplot()+theme(axis.text.y = element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(hjust = 0.5))+labs(x="Год постройки дома", title="Распределение объявлений по годам постройки домов")Большинство домов в датасете, для которых указан год постройки (заметим, что таких немного, и не стоит распространять результаты рассмотрения графика на все объявления) были построены уже в 21 веке. Тем не менее, есть некоторое количество домов, построенных во второй половине прошлого столетия, а несколько выбросов и подавно в 19 веке.
ggplot(Y, aes(x=Date_entry)) +
geom_boxplot()+theme(axis.text.y = element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(hjust = 0.5))+labs(x="Дата размещения объявления (гггг-мм-дд)", title="Распределение дат размещения объявлений")Объявления были размещены между началом 2015 и серединой 2017 годов. Большинство из них (50% наблюдений) были размещены в период с середины 2016 до первой четверти 2017 включительно. Медианное объявление пришлось на январь 2017 года.
ggplot(Y, aes(x=Floor)) +
geom_boxplot()+theme(axis.text.y = element_blank(), axis.ticks.y=element_blank(), plot.title = element_text(hjust = 0.5))+labs(x="Этаж, на котором расположена квартира", title="Распределение этажей, на которых расположены квартиры")Большинство сдаваемых квартир расположены ниже 10-ого этажа, притом что медианная квартира расположена на 5-ом этаже. В то же время мы можем заметить, что самая высокая из сдаваемых квартир расположена на 32 этаже. Также мы можем отметить, что размах среди квартир по данному показателю составляет около 30 этажей.
ggplot()+geom_bar(Y,mapping=aes(x=Region))+labs(title="Регион расположения квартир",
x="Регион", y = "Количество объявлений")Анализируя данные полученной диаграммы, заметим, что лишь небольшая часть предлагаемых квартир расположена в Ленинградской области, подавляющая часть квартир предлагается в городе Санкт-Петербурге. За последние 10 лет, по данным Росстата, численность населения Санкт-Петербурга увеличилась на полмиллиона человек, например, за счет приезжих, а с ростом некоренного населения города появляется спрос на аренду жилья. При этом в условиях относительно плохого дорожно-транспортного сообщения Санкт-Петербурга с Ленинаградской областью этот спрос приходится в основном на квартиры в черте города. Этим обусловлено более высокое предложение квартир в аренду в Санкт-Петербурге.
ggplot()+geom_bar(Y,mapping=aes(x=District_ad))+labs(title="Район расположения квартир",
x="Район", y = "Количество объявлений")+coord_flip() Заметим, что наибольшее количество объявлений размещено в Центральном и ближайших к центру районах, а наименьшее - в наиболее удаленных от центра (Ломоносовском и Кронштадтском). В Центральном районе находятся не только памятники культурного наследия, но и огромное количество офисных зданий и сооружений. Сопоставив эти данные с данными о минимальном сроке аренды квартиры, можно предположить, что владельцы квартир заинтересованы в длительной сдаче жилой площади людям, которым необходимо быстро добираться до центра города (работа, учеба в вузе).
Y = Y %>% mutate(street = str_extract(Y$Address, "[0-9]*-?[А-Яа-я.\\s-]*"))
qq = data.frame(table(Y$street))
topchik = top_n(x = qq, n =5, wt = Freq)
topchik = topchik[order(topchik$Freq),]
ggplot() + geom_bar(topchik, mapping = aes(x = reorder(Var1, -Freq), y = Freq), stat = "identity")+labs(title="Адреса квартир",
x="Улицы и районы", y = "Количество объявлений")Так как у каждой квартиры уникальный адрес, график со всеми адресами было бы невозможно прочитать, поэтому мы использовали в анализе только те улицы и районы, которые наиболее часто встречаются в адресах квартир. Эти квартиры находятся в поселке Парголово, в двух южных районах г. Санкт-Петербурга (на Ленинском и Московском проспектах) и в двух северных районах (на пр. Просвещения и в р-не Мурино).
ggplot()+geom_bar(Y,mapping=aes(x=Metro))+labs(title="Ближайшая станция метро",
x="Метро", y = "Количество объявлений")+coord_flip()+ theme(axis.text = element_text(size = 5,5))Metro_line = c("Красная", "Синяя", "Зеленая", "Оранжевая", "Фиолетовая")
Red_names = c("Devyatkino","Grajdanskii pr." ,"Akademicheskaya" ,"Politehnicheskaya","Mujestva pl." ,"Lesnaya" ,"Vyborgskaya","Lenina pl.","Chernyshevskaya" ,"Vosstaniya pl.","Vladimirskaya" ,"Pushkinskaya" ,"Tekhnologichesky Institut" ,"Baltiyskaya" ,"Narvskaya" ,"Kirovskii Zavod","Avtovo" ,"Leninskii pr." ,"Veteranov pr.")
Sin_names = c("Parnas","Prosveshcheniya pr.","Ozerki" ,"Udel'naya","Pionerskaya","Chyornaya Rechka","Petrogradskaya" ,"Gor'kovskaya" ,"Nevskii pr.","Sennaya pl.","Tehnologicheskii i-t","Frunzenskaya" ,"Moskovskie vorota" ,"Elektrosila" ,"Park Pobedy" ,"Moskovskaya" ,"Zvezdnaya" ,"Kupchino")
Green_names = c("Begovaya","Novokrestovskaya","Primorskaya","Vasileostrovskaya","Gostinyi Dvor","Mayakovskaya","A.Hevskogo pl.","Yelizarovskaya","Lomonosovskaya","Proletraskaya","Obuhovo","Rybackoe")
Oran_names = c("Spasskaya" ,"Dostoevskaya" ,"Ligovskii pr." ,"A.Hevskogo pl." ,"Novocherkasskaya" ,"Ladozhskaya" ,"Bol'shevikov pr.","Dybenko ul.")
Purp_names = c("Staraya Derevnya" ,"Krestovskii ostrov" ,"Chkalovskaya" ,"Sportivnaya" ,"Admiralteyskaya","Sadovaya" ,"Zvenigorodskaya","Obvodnyi Kanal" ,"Volkovskaya" ,"Bukharestskaya","Mezhdunarodnaya","Slavy pr." ,"Dunayskaya" ,"Shushary","Komendantskii pr.")
countlines<-function(l) {
c = 0
namevar = paste("Count_", deparse(substitute(l)), sep = "")
obj = as.name(namevar)
for (j in l) {
c = c + nrow(filter(Y, Metro == j))
}
obj = c
assign(namevar, obj, .GlobalEnv)
return(obj)
}
#countlines(Red_names)
#countlines(Sin_names)
#countlines(Green_names)
#countlines(Oran_names)
#countlines(Purp_names)
#3000-(826+916+306+233+374)=345
kol_vo = c(countlines(Red_names), countlines(Sin_names), countlines(Green_names), countlines(Oran_names), countlines(Purp_names))
Lines = data.frame(Metro_line, kol_vo)
ggplot() + geom_bar(Lines, mapping = aes(x = Metro_line, y=kol_vo), stat = "identity")+labs(title="Расположение квартир на ветках метрополитена г. Санкт-Петербурга",
x="Количество объявлений", y = "Ветки метро")По первому графику видно, что наибольшее количество объявлений относится к станции метро Приморская, а наименьшее - к станции метро Спасская и к шести железнодорожным станциям пригородных электропоездов. Чтение графика затруднено большим количеством станций метрополитена и ж/д, поэтому агрегируем данные по веткам метро Санкт-Петербурга (в черте города), чтобы сделать более общие выводы.
Если отобрать только данные по квартирам, для которых в объявлениях указаны станции метро, и подсчитать количество объявлений, относящихся к различным веткам метро (см. график “Расположение квартир на ветках метрополитена г. Санкт-Петербурга”), то можно сделать следующие выводы:
Большинство предлагаемых квартир находятся недалеко от станций синей ветки метрополитена.
Наименьшее количество объявлений об аренде относится к квартирам, которые располагаются на оранжевой ветке метро - самой короткой ветке Санкт-Петербургского метрополитена.
345 объявлений не содержат информации о ближайшей станции метро. Можно предположить, что предлагаемые квартиры находятся в тех районах, где нет станций метро (например, в отдаленных районах города и в Ленинградской области).
ggplot()+geom_bar(Y,mapping=aes(x=No_agents))+labs(title="Возможность сдачи квартиры через посредника (агента)", x="Могут ли звонить агенты", y = "Количество объявлений") + scale_x_discrete(labels=c("Могут","Не могут"))Здесь мы видим, что большинство объявлений размещено владельцами, которые не против, чтобы потенциальные покупатели связывались с ними через агентов. Однако, есть владельцы квартир, которые предпочитают связываться с покупателем напрямую (таких объявлений немногим более 400). Заметим, что первая группа, участники которой не возражают против посредничества агента, но и не против непосредственной связи с покупателем (судя по NA в данных, эти люди не выразили конкретных предпочтений), шире второй, участники которой отказываются от помощи агента. Неудивительно, что объявлений в первой категории больше, чем во второй.
ggplot()+geom_bar(Y,mapping=aes(x=Building))+labs(title="Материал здания", x="Материал", y = "Количество объявлений" )+coord_flip()По данным предыдущих диаграмм видно, что большинство объявлений предлагают в аренду квартиры в центре Санкт-Петербурга, где преобладает историческая застройка. Здесь мы видим, что большинство домов изготовлено из кирпича или кирпичного монолита, которые могли применяться при возведении старых зданий. При постройке современных зданий используются другие технологии, но кирпичная застройка тоже входит в их число. Объявления о сдаче квартир в панельных и монолитных домах тоже встречаются достаточно часто.
ggplot()+geom_bar(Y,mapping=aes(x=Lift))+labs(title="Наличие лифта", x="Лифт", y = "Количество объявлений") + scale_x_discrete(labels=c("Нет","Есть"))По данным столбиковой диаграммы домов с лифтом почти на 500 единиц больше, чем домов без лифта. Несмотря на то, что большинство объявлений относится к центру Санкт-Петербурга, даже в исторических домах сейчас устанавливают лифты. Этим объясняется преобладание домов с лифтом.
ggplot()+geom_bar(Y,mapping=aes(x=Furnished))+labs(title="Меблировка", x="Тип мебели", y = "Количество объявлений")+coord_flip()Чуть меньше 1000 объявлений не содержат никакой информации о мебели в квартире. Есть квартиры, в которых минимальное количество мебели или её нет вовсе. Чаще всего в квартирах сборная современная мебель, реже - различные мебельные гарнитуры. Это может объясняться тем, что сборная мебель дешевле, поэтому владелец может обставлять такой мебелью квартиру, которую он всё равно собирается сдавать.
ggplot()+geom_bar(Y,mapping=aes(x=Bath))+labs(title="Ванная комната", x="Характер ванной комнаты", y = "Количество объявлений")+coord_flip()Более полутора тысяч объявлений, что больше 50% от общего числа, не содержат какой-либо информации о типе ванной комнаты. Владельцы могут указывать любую информацию о характере ванной комнаты. В тех случаях, когда данные о типе ванной комнаты есть, чаще всего ванная комната отдельная. Это может объясняться тем, что раздельный санузел часто встречается в домах старой постройки, которых много в центре города.
ggplot()+geom_bar(Y,mapping=aes(x=Refurbished))+labs(title="Ремонт", x="Состояние квартиры", y = "Количество объявлений")+coord_flip()Заметим, что большинство квартир либо недавно отремонтированы, либо находятся в таком состоянии, что ремонт им на данный момент не требуется. Также заметим, что внушительное количество объявлений не несет никакой информации о состоянии квартиры. Крайне мало квартир, в которых требуется ремонт, вероятно, потому, что меньше шансов быстро сдать в аренду такую квартиру.
ggplot()+geom_bar(Y,mapping=aes(x=Balcony))+labs(title="Наличие балкона", x="Типы балконов", y = "Количество объявлений")+coord_flip()Более тысячи объявлений не содержат информации о наличии балкона. Чуть больше 250 квартир не имеют балконов. Скорее всего, это маленькие квартиры, студии, однокомнатные квартиры. Остальные квартиры имеют достаточно разные типы балконов (до четырёх!), среди объявлений встречаются даже террасы, что может говорить о том, что среди предлагаемых квартир есть квартиры от застройщиков элитного жилья.
ggplot()+geom_histogram(Y,mapping=aes(x=Date_entry))+labs(title="Дата размещения объявления", x="Год", y = "Количество объявлений")Первое объявление было размещено в 2012 году. Начиная с 2012 года, заметна тенденция увеличения числа объявлений о сдаче квартир в аренду. Данный график показывает ситуацию на конец 2017 года, поэтому очевидно, что на сайте на момент получения данных больше всего объявлений именно за последний период. Со временем уменьшается количество старых объявлений. Этому можно найти два объяснения:
Владельцы наконец получают отклик на свои предложения и сдают квартиры.
Владельцы квартир убирают объявления, теряя надежду привлечь арендаторов.
ggplot(data = Y, aes(Date_entry))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения дат размещения объявлений", x="Год", y = "") + theme_bw()В данном случае график эмпирической функции плотности даёт ненамного больше информации, так что выводы по этому графику в целом совпадают с полученными при анализе гистограммы.
New1 = data.frame(tit = "Меньше 1 километра", ct = count(filter(Y, Y$Dist_metro_ad <= 1000)))
New2 = data.frame(tit = "От 1 до 10 километров", ct = count(filter(Y, Y$Dist_metro_ad > 1000 & Y$Dist_metro_ad < 10000)))
New3 = data.frame(tit = "Больше 10 километров", ct = count(filter(Y, Y$Dist_metro_ad > 10000)))
New4 = bind_rows(New1,New2,New3)
ggplot()+geom_histogram(New4,mapping=aes(x=tit, y = n), stat="identity")+labs(title="Расстояние до ближайшего метро", x="Расстояние в километрах", y = "Количество объявлений")Заметим, что большинство квартир расположены на расстоянии менее одного километра от ближайшей к ним станции метро. Таких квартир 1688. На расстоянии более 10 километров от ближайшей станции метро расположены 57 квартир. Вероятно, такие квартиры относятся к отдаленным районам города, но возможность сдачи таких квартир существует. При рассмотрении таких вариантов будущие арендаторы должны учитывать, что до метро нужно искать какой-либо вид общественного транспорта или пользоваться услугами такси или каршеринга. Самая далеко расположенная от метро квартира находится на расстоянии почти 38 километров от него: в таком случае вызывает сомнения решение владельца указать станцию метро, но такая ситуация, опять же, возможна.
ggplot(data = Y, aes(Dist_metro_ad/1000))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения расстояния\n от квартиры до метро", x="Расстояние до метро (км)", y = "") + theme_bw()ggplot(data = filter(Y, Dist_metro_ad < 10000), aes(Dist_metro_ad, fill = District_ad))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения\n расстояния от квартиры до метро по районам", x="Расстояние от квартиры до метро (м)", y = "") + theme_bw()Данный график плотности демонстрирует, что большинство квартир находятся в диапазоне двух километров от метро. При этом, самые близкие к метро квартиры располагаются в Адмиралтейском и Центральном районах, а наиболее отдаленные - в Красногвардейском, Курортном и Красносельских районах. Расстояние до метро там может достигать 10 километров.
ggplot()+geom_bar(Y,mapping=aes(x=Rooms))+labs(title="Тип квартиры по количеству комнат", x="Количество комнат", y = "Количество объявлений")В основном представлены квартиры однокомнатные и двухкомнатные. Однако есть в целом есть квартиры в диапазоне от студий до девятикомнатных квартир. В действительности, количество комнат, как и район расположения квартиры и близость к метро, объясняет разброс цен.
Money = data.frame(tit = "Меньше 20", ct = count(filter(Y, Y$Price <= 20000)))
Money1 = data.frame(tit = "От 20 до 40", ct = count(filter(Y, Y$Price > 20000 & Y$Price < 40000)))
Money2 = data.frame(tit = "От 40 до 60", ct = count(filter(Y, Y$Price > 40000 & Y$Price < 60000)))
Money3 = data.frame(tit = "Больше 60", ct = count(filter(Y, Y$Price > 60000)))
Money4 = bind_rows(Money,Money1,Money2,Money3)
ggplot()+geom_histogram(Money4,mapping=aes(x=tit, y = n), stat="identity")+labs(title="Стоимость аренды жилья на месяц", x="Цены за аренду (тыс. руб./мес.)", y = "Количество объявлений")Спектр цен огромен, поэтому для удобства анализа мы объединили цены в некоторые промежутки. Это показывает нам, что чуть более половины предлагаемых квартир оцениваются владельцами между 20 и 40 тысячами рублей за месяц аренды. Около 600 объявлений предлагают квартиры в аренду на месяц менее чем за 20 тысяч рублей. Однако стоит учитывать, что оплата жилищно-коммунальных услуг может не входить в указанную стоимость аренды. Тогда траты на жилье могут увеличиваться в среднем на 3-6 тысяч рублей.
ggplot(data = Y, aes(Price/1000))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения цен", x="Цена (тыс. руб.)", y = "") + theme_bw()ggplot(data = filter(Y, Price < 100000), aes(Price/1000, fill = District_ad))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения цен в зависимости от районов", x="Цена (тыс. руб.)", y = "") + theme_bw()Из графика плотности видно, что значение моды цены сдаваемого жилья по районами находится в диапазоне 20-23 тысяч рублей. Чтобы ближе рассмотреть плотность распределения цен в зависимости от района, мы ограничили цену 100 тыс. руб.: исходя из графика распределения, а также из соответствующей ящиковой диаграммы (см. одноименный раздел), стоимость подавляющего большинства квартир меньше этого значения. Наиболее дорогими для аренды жилья являются Адмиралтейский и Василеостровский районы. Судя по графику, плотность распределения цен довольно близка к нормальному распределению.
Y$min_duration_number <- str_replace(Y$Minimum_duration, " mes.", "")
Y$min_duration_number = as.numeric(Y$min_duration_number)
ggplot()+geom_histogram(Y,mapping=aes(x=min_duration_number), stat="count")+labs(title="Минимальная продолжительность аренды квартиры", x="Количество месяцев", y = "Количество объявлений")Некоторые владельцы хотят обезопасить себя от безответственных арендаторов и устанавливают минимальный срок аренды квартиры, показывая, что они заинтересованы в долгосрочном сотрудничестве. Большинство арендодателей устанавливают минимальный срок 11 месяцев. Таким образом, в основном владельцы не хотят сдавать квартиры туристам или людям, которые снимают квартиры на очень непродолжительный срок. Однако некоторые объявления (чуть более 100) всё-таки содержат информацию об одном месяце как о минимальном сроке аренды квартиры. Около 900 владельцев не указывают никакой информации о минимальном периоде аренды.
ggplot()+geom_histogram(Y,mapping=aes(x=Area_total), breaks = seq(18,514,20))+labs(title="Общая площадь квартиры", x="Общая площадь квартиры (кв.м.)", y = "Количество объявлений")Минимальная общая площадь - 18 кв.м. Максимальная - 514 кв.м. Средняя площадь однокомнатных квартир обычно колеблется от 20 до 40 кв.м. Средняя площадь двухкомнатных квартир - 40-60 кв.м. Средняя площадь трехкомнатных квартир - 60-80 кв.м. Анализируя предыдущие графики, мы пришли к выводу, что большинство объявлений приходится на студии, одно-, двух-, трехкомнатные квартиры. На данном графике мы видим, что так оно и есть: площадь большинства квартир меньше 100 кв.м.
ggplot(data = Y, aes(Area_total))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения метража квартир", x="Метраж квартиры", y = "") + theme_bw()Из графика видно, что значение моды общей площади примерно равняется 40 кв.м, а большинство всех сдаваемых квартир имеют метраж не более 100 метров, затем показатель значительно снижается. Самые большие арендуемые квартиры превышают по площади 500 кв.м., в то время как самые маленькие имеют пространство около 20 кв.м.
ggplot()+geom_histogram(Y,mapping=aes(x=Area_living), breaks = seq(9,263,10))+labs(title="Общая площадь жилой части квартиры", x="Жилая площадь квартиры (кв.м.)", y = "Количество объявлений")На данном графике представлено распределение площади жилой части квартиры. Под жилой частью понимается площадь квартиры без учета сан.узла, лоджии, коридора внутри квартиры, кухни. Максимальное значение жилой площади - 333 кв.м. В остальных объявлениях представлены жилые площади меньше 263 кв.м. Поэтому для четкости графика ограничимся распределением между 9 и 263 кв.м. жилой площади. Большинство объявлений представляют квартиры с жилой площадью менее 30 кв.м. Есть также и такие объявления, где не указана информация о жилой площади квартиры.
ggplot(data = Y, aes(Area_living))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения жилой площади квартир", x="Жилая площадь квартиры (кв.м.)", y = "") + theme_bw()Исходя из графика жилой площади квартиры, наиболее частые предложения аренды имеют около 20 кв.м. жилого пространства, затем показатель вероятности, что жилая площадь квартиры в случайно выбранном объявлении равна заданному числу, довольно резко падает между 20 и 25 кв.м. (то есть квартиры, где жилая площадь равна 25 кв. м., встречаются реже). Однако значения функции на промежутке правее моды не монотонны, на интервале от 25 до 30 кв.м. происходит весьма резкий подъем, а далее плавное снижение. Подавляющее большинство квартир имеют жилую площадь менее 50 кв.м.
ggplot()+geom_histogram(Y,mapping=aes(x=Area_kitchen), breaks = seq(2,130,5))+labs(title="Площадь кухни в квартире", x="Метраж кухни (кв.м.)", y = "Количество объявлений")На данном графике представлено распределение площади кухни. Максимальное значение площади кухни среди всех объявлений - 200 кв.м. В остальных объявлениях представлены площади кухонь меньше 130 кв.м. Поэтому для четкости графика ограничимся распределением между 2 и 130 кв.м. площади кухни. Большинство объявлений предлагают квартиры с площадью кухни менее 15 кв.м. Зачастую кухня - комната площадью меньше любой жилой комнаты. Крайне редко можно встретить планировки, где площадь кухни превышает площадь какой-либо жилой комнаты в рассматриваемой квартире или совпадает с ней. В квартирах старой застройки площадь кухни чаще всего не превышает 10, а то и 8 кв.м.
ggplot(data = Y, aes(Area_kitchen))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения площади кухни", x="Метраж кухни (кв.м.)", y = "") + theme_bw()График показывает, что чаще всего площадь кухни в квартире, сдаваемой в аренду, составляет 10 кв.м. В целом, функция плотности монотонно возрастает до значений 10 кв.м. и вполне гладко снижается после 10 кв.м. Большинство квартир имеют площадь кухни менее 20 кв.м., при этом площадь самых больших кухонь превышает 200 кв.м., а самых маленьких составляет около 3 кв.м.
ggplot()+geom_histogram(Y,mapping=aes(x=Floor), binwidth = 1)+labs(title="Этаж, на котором расположена предлагаемая квартира", x="Номер этажа", y = "Количество объявлений")Заметим, что большинство предлагаемых квартир расположены ниже 10 этажа. Вспомним рассуждения о том, где находятся квартиры, на каких станциях метро и в каких районах: много квартир расположены в центра города. Этот вывод может объяснять наблюдаемый факт. В центре застройка низкая, т.к. раньше был определенный запрет на высоту домов, а сейчас мало застройщиков начинают строительство в центре, так как там практически нет места для новых высотных домов.
ggplot(data = Y, aes(Floor))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения этажей сдаваемых квартир", x="Этаж квартиры", y = "") + theme_bw()ggplot(data = Y, aes(Floor, fill = District_ad))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения этажей сдаваемых квартир", x="Этаж квартиры", y = "") + theme_bw()Большинство квартир, которые сдаются в аренду, находится на 3 этаже, особенно много объявлений о таких квартирах в Адмиралтейском и Московском районах. При этом наибольшее число квартир находятся ниже 10 этажа. Квартиры, расположенные выше всех, находятся выше 30 этажа.
ggplot()+geom_histogram(Y,mapping=aes(x=NFloor), binwidth = 1)+labs(title="Количество этажей в доме", x="Количество этажей", y = "Количество объявлений")Как мы можем заметить, 50% объявлений предлагают квартиры в домах, этажность которых не превышает 10 этажей (возможная причина - низкая застройка в центре Санкт-Петербурга, см. предыдущий график). Однако отметим, что довольно много объявлений - о сдаче квартир в очень высоких домах. Скорее всего, они расположены на окраинах города и прилегающих территориях (удаленные районы Санкт-Петербурга, Ленинградская область), где застройщики проектируют и строят новые высотные дома, удовлетворяя растущий с каждым годом спрос на относительно недорогое жилье в окрестностях Санкт-Петербурга.
ggplot(data = Y, aes(NFloor))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения количества этажей в доме", x="Количество этажей", y = "") + theme_bw()ggplot(data = Y, aes(NFloor, fill = District_ad))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения количества этажей в доме", x="Количество этажей", y = "") + theme_bw()Из графика видно, что чаще всего квартиры сдаются в домах высотой 5 этажей, и значительная часть квартир располагаются в домах этажностью от 4 до 10 этажей. Примечательно, что фукнция имеет несколько пиков, располагающихся в значениях этажности 5, 9, 16 и 24. При этом есть дома высотой как выше 30 этажей, так и в один этаж. Также видно, что здания в наиболее близких к центру районах в среднем имеют меньше этажей, а в более удаленных - больше.
ggplot()+geom_histogram(Y,mapping=aes(x=Latitude), binwidth = 0.01)+labs(title="Географическая широта расположения квартиры", x="Широта (в градусах)", y = "Количество объявлений")На данном графике представленно распределение количества квартир в соответствии с их расположением относительно географической широты. Географические координаты исторического центра Санкт-Петербурга (приблизительно станция метрополитена Гостиный двор) – 59° 57’ северной широты и 30° 19’ восточной долготы. Заметим, что большинство квартир достаточно тесно расположены севернее исторического центра. Однако есть предложения и чуть южнее центра, но их очень мало.
ggplot(data = Y, aes(Latitude))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения координат широты", x="Широта", y = "") + theme_bw()Удивительно, что график плотности распределения координат широты весьма не похож на график нормального распределения. Он имеет три пика, располагающиеся в 59° 93’, 59° 85’ и 60° 03’, при этом наивысший в 59° 85’. Это означает, что самые распространенные предложения находятся в этих координатах широты. Стоит также отметить, что большинство квартир находятся в координатах долготы от 59° 8’ до 60° 1’.
ggplot()+geom_histogram(Y,mapping=aes(x=Longitude), binwidth = 0.01)+labs(title="Географическая долгота расположения квартиры", x="Долгота (в градусах)", y = "Количество объявлений")На данном графике представленно распределение количества квартир в соответствии с их расположением относительно географической долготы. Географические координаты исторического центра Санкт-Петербурга (приблизительно станция метрополитена Гостиный двор) – 59° 57’ северной широты и 30° 19’ восточной долготы. Подавляющее большинство предлагаемых квартир расположены близко к центру, но если посмотреть на карту Санкт-Петербурга, то мы заметим, что город более вытянут вверх и вниз, чем вправо и влево, что и объясняет причину столь незначительного отклонения от координат исторического центра (если рассматривать только долготу).
ggplot(data = Y, aes(Longitude))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения координат долготы", x="Долгота (в градусах)", y = "") + theme_bw()Данный график плотности распределения координат долготы показывает, что зачастую квартиры, предлагаемые в аренду, имеют координаты 30° 33’. При этом показатель долготы большинства квартир находится в диапазоне от 30° 19’ до 30° 5’, а самые крайние варианты отклоняются примерно на 3’ от значения моды.
ggplot()+geom_histogram(Y,mapping=aes(x=Year_construction),, breaks = seq(1817,2017,10))+labs(title="Годы посторойки зданий, в которых расположены квартиры", x="Год", y = "Количество объявлений")Большинство квартир, для которых указан год постройки здания (заметим, что таких относительно немного, и не стоит распространять результаты рассмотрения графика на все объявления) расположено в относительно новых зданиях. Наибольшее количество квартир находится в зданиях, построенных между 2007 и 2017 годами. Примечательно, что предлагаемые квартиры также есть в зданиях, которые были построены в 1817 г.
ggplot(data = Y, aes(Year_construction))+
geom_density(alpha = 0.3) + labs(title="Плотность распределения объявлений по годам постройки домов", x="Год постройки дома", y = "") + theme_bw()Из графика видно, что большинство квартир для аренды располагаются в новых домах, построенных после 2010 года. Примечательно, что присутствуют предложения о квартирах, которые находятся в более чем двухсотлетних зданиях.
ggplot() +
geom_point(data = Y, aes(x = Rooms , y = Price/1000)) +
xlab("Количество комнат") +
ylab("Стоимость аренды (тыс. рублей/месяц)") +
ggtitle("Распределение стоимости аренды квартиры\n в зависимости от количества комнат") +
theme_bw()Из графика видно, что стоимость квартиры положительным образом коррелирует с количеством комнат в ней. В наиболее дорогих квартирах, сдаваемых в аренду, от трех до пяти комнат, а наиболее дешевыми вариантами на рассматриваемом рынке являются студии или однокомнатные квартиры. Такое распределение весьма закономерно, ведь квартиры, имеющие несколько комнат, гораздо удобнее. Они лучше удовлетворяют различные потребности арендаторов, что ведет к повышению их цены.
ggplot() +
geom_point(data = Y, aes(x = Floor , y = Price/1000)) +
xlab('Этаж') +
ylab("Стоимость аренды (тыс. рублей/месяц)") +
ggtitle("Распределение стоимости аренды квартиры\n в зависимости от этажа квартиры") +
theme_bw() Примечательно, что наиболее дорогой сегмент составляют квартиры, расположенные на этажах с первого по девятый, причем особенно выделяются по стоимости четвертый и пятый этажи. Так как в основном предлагаются квартиры с достаточно длительным сроком аренды, владельцы квартир покупают наиболее рентабельные квартиры, чтобы сделать квартиру более востребованной для аренды, а затем удовлетворить большинство желаний будущих арендаторов. Не так много людей предпочитают самые высокие и самые низкие этажи, потому что в первом случае опасаются воздействия определенных погодных условий на состояние квартиры и трудностей с доставкой (например, мебели или детских колясок на нужный этаж), во втором случае арендаторы могут опасаться взломов и краж (по статистике треть краж приходится на квартиры, расположенные на первых этажах). Соответственно, учитывая все пожелания арендаторов, владельцы квартир могут завышать стоимость аренды квартиры на средних этажах относительно самых низких и самых высоких.
Y$NFloor <- as.numeric(Y$NFloor)
Y1 <- Y[(Y$NFloor < 30),]
Y1 <- Y1[order(Y$NFloor),]
ggplot() +
geom_point(data = Y1, aes(x = NFloor , y = Price/1000)) +
xlab('Количество этажей') +
ylab("Стоимость аренды (тыс. рублей/месяц)") +
ggtitle("Распределение стоимости аренды квартиры\n в зависимости от количества этажей в доме") +
theme_bw()Судя по графику, наиболее дорогие квартиры сдаются в домах высотой до 10 этажей. Цена в этом диапазоне значительно превосходит аналогичные показатели в зданиях, имеющих от 10 до 30 этажей. Возможно, это обусловлено историческими особенностями Санкт-Петербурга и распределением более дорогой недвижимости в центре или более старых районах города. Высота таких домов в среднем едва ли превосходит 5-7 этажей, однако из-за развитой рядом инфраструктуры и удобного расположения, цена на квартиры в них остается весьма солидной. В то же время квартиры в спальных районах с многоэтажной застройкой, расположенных на окраинах Санкт-Петербурга, привлекают семьи со средним достатком, что не дает возможности сильно поднимать цену.
Y$min_duration_number <- str_replace(Y$Minimum_duration, " mes.", "")
Y2 <- Y[order(Y$min_duration_number),]
Y2<-Y2[(Y2$min_duration_number <=18),]
ggplot() +
geom_point(data = Y2, aes(x = min_duration_number , y = Price/1000)) +
xlab('Минимальное время прибывания (мес.)') +
ylab("Стоимость аренды (тыс. рублей/месяц)") +
ggtitle("Распределение стоимости аренды квартиры\n в зависимости от длительности проживания") +
theme_bw()Наиболее дорогими и наиболее диверсифицированными являются квартиры, которые сдаются на 11 месяцев. Большое количество предложений о сдаче квартир на данный срок может говорить о нежелании арендодателей рисковать и сдавать жилье на короткий промежуток времени, потому что они заинтересованы в относительно стабильном заработке на год вперед. Заметим также, что квартиры, предназначенные для сдачи на более короткий срок, могут стоить больше тех, которые рассчитаны на длительную аренду. Такое распределение может быть оправдано конкуренцией с отелями в краткосрочной перспективе и получением значительной арендной платы от арендатора заранее, что даёт возможность дополнительного заработка.
ggplot() +
geom_point(data = Y, aes(x = Area_kitchen, y = Price/1000)) +
xlab("Площадь кухни (кв.м.)") +
ylab("Стоимость аренды (тыс. рублей/месяц)") +
ggtitle("График рассеяния стоимости аренды квартиры в \nзависимости от площади кухни") +
theme_bw()Среди представленного списка квартир наиболее дорогими являются те, в которых площадь кухни находится в диапазоне от 20 до 50 кв. м. Наиболее дешевыми являются квартиры, кухни которых не превосходят 10 кв.м. (таких в данной выборке большинство). Очевидно, что вариантов с большими кухнями (более 50 кв.м.) немного - обычно это квартиры с достаточно большой общей площадью. Часть площади кухни в таких квартирах используется как жилая, что объясняет общую стоимость аренды квартиры, так как жилые комнаты ценятся выше, чем “нежилые” метры. Есть слабая положительная взаимосвязь между стоимостью аренды квартиры и площадью кухни.
ggplot() +
geom_point(data = Y, aes(x = Area_living, y = Price/1000)) +
xlab("Жилая площадь (кв.м.)") +
ylab("Стоимость аренды (тыс. рублей/месяц)") +
ggtitle("График рассеяния стоимости аренды в зависимости \nот жилой площади") +
theme_bw()График показывает, что жилая площадь наиболее дешёвых квартир составляет менее 50 кв.м. Жилье большей площади доступно немногим: самые дорогие квартиры - жилой площадью от 70 до 250 кв.м. Ясна следующая закономерность: чем меньше жилая площадь, тем меньше личного пространства, больше неудобств, которые можно компенсировать низкой ценой. В целом, прослеживается положительная корреляция между стоимостью жилья и его жилой площадью - просторные апартаменты всегда более востребованы, а значит и цена на такие квартиры выше.
Dummy <-Y[(Y$Area_total <400),]
ggplot() +
geom_point(data = Dummy, aes(x = Area_total, y = Price/1000)) +
xlab("Общая площадь (кв.м.)") +
ylab("Стоимость аренды (тыс. рублей/месяц)") +
ggtitle("График рассеяния стоимости аренды в зависимости \nот общей площади") +
theme_bw()Данный график рассеяния демонстрирует прямую зависимость между общей площадью и стоимостью аренды квартиры: чем выше общая площадь квартиры, тем она дороже, так как большую часть пространства занимает жилая часть, которая необходима арендаторам для комфортной жизни больше, чем просторный сан.узел или свободная кухня. Площади наибольшего числа предлагаемых квартир располагаются в диапазоне до 100 кв.м., затем предложение значительно снижается, что объясняется дороговизной содержания подобных квартир, а также низким спросом в данном сегменте.
ggplot() +
geom_point(data = Y, aes(x = Dist_metro_ad, y = Price/1000)) +
xlab("Расстояние до метро") +
ylab("Стоимость аренды (тыс. рублей/месяц)") +
ggtitle("График рассеяния стоимости аренды в зависимости \nот расстояния до метро") +
theme_bw()Данный график демонстрирует, как связаны стоимость аренды квартир и расстояние от квартиры до ближайшей станции метро. Самые высокие цены аренды приходятся на квартиры, расположенные достотачно близко к станциям метро (до 3 километров). Прослеживается закономерность: чем ближе метро,тем выше цены, соотвественно, с увеличением расстояния до метро, стоимость снижается. Это явление обусловлено удобством перемещения, сокращением затрат времени на дорогу, что привлекает внимание значительной части арендаторов, а значит, повышает стоимость аренды квартиры. Квартиры, расположенные от метро на расстоянии более, чем 5 километров, стоят меньше, так как потенциальные арендаторы будут вынуждены пользоваться другим транспортом, чтобы добраться до места назначения.
ggplot() +
geom_point(data = Y, aes(x =Longitude, y = Price/1000)) +
xlab("Долгота") +
ylab("Стоимость аренды (тыс. рублей/месяц)") +
ggtitle("График рассеяния стоимости аренды в зависимости \nот географической долготы") +
theme_bw()Вспомним, что координаты центра Санкт-Петербурга - 59° 57’ северной широты и 30° 19’ восточной долготы. Из графика мы видим, что наиболее дорогими являются квартиры в центре и восточнее него. Это объясняется наилучшей развитостью инфраструктуры центральных районов, большими возможностями для заработка, музеями и парками в шаговой доступности.
ggplot() +
geom_point(data = Y, aes(x = Latitude, y = Price/1000)) +
xlab('Широта') +
ylab("Стоимость аренды (тыс. рублей/месяц)") +
ggtitle("Распределение стоимости аренды квартиры \nв зависимости от географической широты") +
theme_bw() Из данного графика мы видим, что квартиры, расположенные недалеко от центра, наиболее дорогие, что закономерно. Такие квартиры находятся в историческом центре Санкт-Петербурга, что располагает к приобщению к культурным ценностям города.
Для большей наглядности построим карту, на которой отметим адреса квартир в соответствии с их координатами широты и долготы.
Создадим датафреймы, в которых будут только станции, принадлежащие определенным веткам метро.
Y = Y %>% mutate(Price_size = case_when(Y$Price <= 20000 ~ 0.1,
Y$Price > 20000 & Y$Price <= 40000 ~ 0.4,
Y$Price > 40000 & Y$Price <= 60000 ~ 0.7,
Y$Price > 60000 ~ 1))
makeadataframe<-function(l) {
dfvar = paste("Lines_", deparse(substitute(l)), sep = "")
df = as.name(dfvar)
df = setNames(data.frame(matrix(ncol = 28, nrow = 0)), c(names(Y)))
for (j in l) {
df<-rbind(df, filter(Y, Metro == j))
}
assign(dfvar, df, .GlobalEnv)
}
makeadataframe(Red_names)
makeadataframe(Sin_names)
makeadataframe(Green_names)
makeadataframe(Oran_names)
makeadataframe(Purp_names)Скачаем карту Санкт-Петербурга и Ленинградской области с сервера Stamen Maps.
map = get_stamenmap(bbox = c(left = 29.9592, bottom = 59.6759, right =
30.5907, top = 60.1800), zoom = 10, maptype = "toner-lite",
crop = FALSE, messaging = FALSE, urlonly = FALSE,
color = c("color", "bw"), force = FALSE, where = tempdir())Построим на ней объявления в соответствии с их координатами долготы и широты.
ggmap(map) +
theme(axis.line = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
plot.margin = unit(c(0, 0, -1, -1), 'lines')) +
xlab('') +
ylab('') + geom_point(aes(x = Longitude, y = Latitude), data = Y, size = 0.8)Большинство сдаваемых в аренду квартир расположены в центре города, но есть “выбросы” на юге и севере. Однако такой анализ неполный, так как квартиры в черте города находятся слишком близко друг к другу.
Для полноты анализа скачаем карту с другим масштабом.
map1 = get_stamenmap(bbox = c(left = 30.1535, bottom = 59.8066, right =
30.5601, top = 60.0856), zoom = 10, maptype = "toner-lite",
crop = TRUE, messaging = FALSE, urlonly = FALSE,
color = c("color", "bw"), force = FALSE, where = tempdir())Расположим на карте объявления, находящиеся в основном в черте города. Раскрасим точки в соответствии с цветами веток метро, на которых находятся квартиры. При этом размер точки будет отражать цену аренды (чем больше точка – тем дороже аренда).
Lines_Sin_names_select1 <- Lines_Sin_names[Lines_Sin_names$Price_size == 1 &
Lines_Sin_names$District_ad != "Центральный" &
Lines_Sin_names$District_ad != "Петроградский" &
Lines_Sin_names$District_ad != "Адмиралтейский" &
Lines_Sin_names$District_ad != "Московский",]
Lines_Sin_names_select2 <- Lines_Sin_names[Lines_Sin_names$Price_size == 1 &
Lines_Sin_names$District_ad == "Московский" &
Lines_Sin_names$Metro != "Frunzenskaya" ,]
Lines_Purp_names_select <- Lines_Purp_names[Lines_Purp_names$Price_size == 1 &
Lines_Purp_names$District_ad == "Приморский" &
Lines_Purp_names$Metro != "Komendantskii pr.",]
ggmap(map1) +
theme(axis.line = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank(),
plot.margin = unit(c(0, 0, -1, -1), 'lines')) +
xlab('') +
ylab('') +
geom_point(aes(x = Longitude, y = Latitude), color = "red", data = Lines_Red_names, size = Lines_Red_names$Price_size) +
geom_point(aes(x = Longitude, y = Latitude), size = Lines_Sin_names$Price_size, color = "blue", data = Lines_Sin_names) +
geom_point(aes(x = Longitude, y = Latitude), size = Lines_Green_names$Price_size, color = "green", data = Lines_Green_names) +
geom_point(aes(x = Longitude, y = Latitude), size = Lines_Purp_names$Price_size, color = "purple", data = Lines_Purp_names) +
geom_point(aes(x = Longitude, y = Latitude), size = Lines_Oran_names$Price_size, color = "chocolate1", data = Lines_Oran_names) +
geom_encircle(aes(x = Longitude, y = Latitude),
data=Lines_Sin_names_select1,
color="black",
size=1,
expand=0.04,
show.legend = NA,
stat = "identity",
s_shape=0.7,
alpha = 0.7)+
geom_encircle(aes(x = Longitude, y = Latitude),
data=Lines_Sin_names_select2,
color="black",
size=1,
expand=0.03,
show.legend = NA,
alpha = 0.7) +
geom_encircle(aes(x = Longitude, y = Latitude),
data=Lines_Purp_names_select,
color="black",
size=1,
expand=0.03,
show.legend = NA,
alpha = 0.7)Неудивительно, что самое крупное скопление больших точек (дорогих квартир), находится в центре Санкт-Петербурга. Однако наблюдаются некоторые районы, в которых, несмотря на отдаленность от центра, довольно много дорогих квартир. Такая тенденция прослеживается в Московском и Приморском районах, которые считаются “элитными”. Стоит отметить, что цены на квартиры на набережной Малой Невки в районе метро Беговой, резко поднялись после постройки там Лахта-Центра, Зенит-Арены и примыкающих к ним объектов инфраструктуры.
# Собираем в датафрейм числовые признаки
Y$Rooms[Y$Rooms=='1 (studiya)']<-1
Y$Rooms = as.numeric(Y$Rooms)
NumY = data.frame(Y$Dist_metro_ad, Y$Rooms, Y$Price, Y$Minimum_duration,
Y$Area_total,Y$Area_living, Y$Area_kitchen, Y$Floor, Y$NFloor,
Y$Latitude, Y$Longitude)
# Считаем корреляционную матрицу
CorMatrix = cor(NumY, use = "complete.obs")
cor.mtest <- function(mat, ...) {
mat <- as.matrix(mat)
n <- ncol(mat)
p.mat<- matrix(NA, n, n)
diag(p.mat) <- 0
for (i in 1:(n - 1)) {
for (j in (i + 1):n) {
tmp <- cor.test(mat[, i], mat[, j], ...)
p.mat[i, j] <- p.mat[j, i] <- tmp$p.value
}
}
colnames(p.mat) <- rownames(p.mat) <- colnames(mat)
p.mat
}
# matrix of the p-value of the correlation
p.mat <- cor.mtest(NumY)
CorMatrix<-round(CorMatrix,2)
col <- colorRampPalette(c("deeppink", "hotpink", "lightpink", "floralwhite", "darkseagreen1", "darkslategray2", "dodgerblue4"))
corrplot(CorMatrix, method="color", col=col(200),
type="full", order="hclust",
addCoef.col = "black", # Add coefficient of correlation
tl.col="black", tl.srt=45, #Text label color and rotation
# Combine with significance
p.mat = p.mat, sig.level = 0.1, insig ="pch",
# hide correlation coefficient on the principal diagonal
diag=FALSE ,number.cex=0.75)Корреляции, не статистически значимые на уровне значимости 0.1, вычеркнуты
Во-первых, общая площадь квартиры довольно сильно положительно коррелирует с общим количеством комнат в квартире (коэффицент корреляции +0.8), жилой площадью (+0.89) и площадью кухни (+0.61). Чем больше общая площадь квартиры, тем больше обычно её жилая площадь, площадь кухни и тем больше в квартире комнат, и наоборот, чем больше комнат, тем больше общая занимаемая площадь, и т.д. Аналогично, жилая площадь напрямую связана с количеством комнат (+0.86) и с площадью кухни (+0.44), и наоборот.
Во-вторых, рассмотрим связи с ценовыми показателями. Цена сильно связана с общей площадью и жилой площадью квартиры, с коэффицентами +0.77 и +0.74. Большие квартиры стоят больше, чем маленькие. Кроме того, квартиры с большим количеством комнат и большой кухней стоят дороже. Коэффиценты корелляции +0.59 и +0.58 соответственно.
Интересна отрицательная корреляция между количеством комнат в квартире и этажностью дома (-0.25), а также между площадью квартиры (-0.17) и этажностью дома. Это может быть вызвано тем, что большие новые многоквартирные дома рассчитаны на большое количество небольших квартир для потребителей со средним доходом, а малоэтажные дома с большим квартирами являются товаром роскоши.
# В этой матрице будут значения хи-квадрат критерия хи-квадрат Пирсона
chi2_tbl = matrix(, nrow = 11, ncol = 11, byrow = TRUE)
# В этой матрице будут значения p-value критерия хи-квадрат Пирсона
p_tbl = matrix(, nrow = 11, ncol = 11, byrow = TRUE)
# В этой матрице будут значения коэффициента сопряженности Пирсона
cont_tbl = matrix(, nrow = 11, ncol = 11, byrow = TRUE)
# В этой матрице будут значения скорректированного коэффициента сопряженности Пирсона
corrected_tbl = matrix(, nrow = 11, ncol = 11, byrow = TRUE)
nominal = c("Region", "District_ad", "Address", "Metro", "No_agents", "Building", "Lift", "Furnished", "Bath", "Refurbished", "Balcony")
dimnames(chi2_tbl) = list(nominal, nominal)
dimnames(p_tbl) = list(nominal, nominal)
dimnames(cont_tbl) = list(nominal, nominal)
dimnames(corrected_tbl) = list(nominal, nominal)Цикл для подсчета результатов:
#install.packages('DescTools')
library('DescTools')
#Y_nom = select(Y, c("Region", "District_ad", "Address", "Metro", "No_agents", "Building", "Lift", "Furnished", "Bath", "Refurbished", "Balcony"))
#Y_nom = na.omit(Y_nom)
for (i in nominal) {
for (j in nominal){
chi2_tbl[i, j] = unname(chisq.test(Y[[i]], Y[[j]])$statistic)
p_tbl[i, j] = chisq.test(Y[[i]], Y[[j]])$p.value
cont_tbl[i, j] = ContCoef(Y[[i]], Y[[j]], correct = FALSE)
corrected_tbl[i, j] = ContCoef(Y[[i]], Y[[j]], correct = TRUE)
}
}formattable(round(as.data.frame(chi2_tbl)))| Region | District_ad | Address | Metro | No_agents | Building | Lift | Furnished | Bath | Refurbished | Balcony | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Region | 2976 | 2884 | 3000 | 2039 | 0 | 83 | 2 | 34 | 27 | 1 | 39 |
| District_ad | 2884 | 60000 | 59645 | 33602 | 43 | 1844 | 129 | 321 | 176 | 101 | 415 |
| Address | 3000 | 59645 | 7260000 | 201109 | 2542 | 48413 | 2645 | 14895 | 6355 | 4649 | 19140 |
| Metro | 2039 | 33602 | 201109 | 209520 | 110 | 3943 | 272 | 740 | 538 | 228 | 1069 |
| No_agents | 0 | 43 | 2542 | 110 | 2991 | 41 | 50 | 76 | 56 | 27 | 69 |
| Building | 83 | 1844 | 48413 | 3943 | 41 | 53600 | 372 | 429 | 231 | 318 | 450 |
| Lift | 2 | 129 | 2645 | 272 | 50 | 372 | 2996 | 131 | 6 | 59 | 157 |
| Furnished | 34 | 321 | 14895 | 740 | 76 | 429 | 131 | 16616 | 602 | 321 | 846 |
| Bath | 27 | 176 | 6355 | 538 | 56 | 231 | 6 | 602 | 7100 | 29 | 860 |
| Refurbished | 1 | 101 | 4649 | 228 | 27 | 318 | 59 | 321 | 29 | 5097 | 64 |
| Balcony | 39 | 415 | 19140 | 1069 | 69 | 450 | 157 | 846 | 860 | 64 | 22992 |
corrplot(p_tbl, method="color", col="white",
type="full", cl.pos = "n", order="hclust",
addCoef.col = "black", # Add coefficient of correlation
tl.col="black", tl.srt=45, #Text label color and rotation
# hide correlation coefficient on the principal diagonal
diag=FALSE ,number.cex=0.75, number.digits = 2)corrplot(cont_tbl, method="color", col=col(200),
type="full",
addCoef.col = "black", # Add coefficient of correlation
tl.col="black", tl.srt=45, #Text label color and rotation
# Combine with significance
p.mat = p_tbl, sig.level = 0.01, insig ="pch",
# hide correlation coefficient on the principal diagonal
diag=FALSE ,number.cex=0.75, number.digits = 2)Корреляции, не статистически значимые на уровне значимости 0.01, вычеркнуты
corrplot(corrected_tbl, method="color", col=col(200),
type="full",
addCoef.col = "black", # Add coefficient of correlation
tl.col="black", tl.srt=45, #Text label color and rotation
# Combine with significance
p.mat = p_tbl, sig.level = 0.01, insig ="pch",
# hide correlation coefficient on the principal diagonal
diag=FALSE ,number.cex=0.75, number.digits = 2)Корреляции, не статистически значимые на уровне значимости 0.01, вычеркнуты
Заметим, что у некоторых коэффициентов (как обычных, так и исправленных) значения - NA (в таблице отмечены “?”). Мы выяснили, что это объясняется нулевыми частотами в таблице сопряженности: если есть нули - в таблице сопряженности для Metro и Address, например, их много (так как много уникальных адресов и, очевидно, для каждого адреса указывается одна станция метро) - расчет невозможен, так как в формуле появляются нули в знаменателе. Остальные коэффициенты, однако, можно интерпретировать так:
Наиболее сильная корреляция (≈+1) наблюдается у довольно очевидно связанных между собой величин — региона, района, адреса квартиры и ближайшей станции метро. Также наличие/отсутствие лифта сильно коррелирует с адресом квартиры (+0.97), что тоже не требует дополнительных разъяснений: в доме с определенным адресом однозначно либо есть лифт, либо его нет.
Более интересной представляется высокая корреляция между типом здания и ближайшей станцией метро (≈+0.79), а также районом (≈+0.65) — возможно, это отражает связь между районом и типами построек, встречающихся в нём. Более высокий коэффициент корреляции между типом здания и станцией метро может объясняться тем, что ближайшая станция метро более узко, нежели район, определяет область, где располагается сдаваемое жильё.
Стоит также отметить высокую корреляцию между наличием в квартире балкона, ванной и тем, является ли квартира меблированной (типом меблировки). Возможно, это показывает, что наиболее часто ванные и балконы встречаются именно в квартирах, уже оборудованных какой-то мебелью, нежели в более аскетичных жилищах.