Nel dataset presentato possiamo trovare questi tipi di variabili:
Cities : Variabile Qualitativa Nominale
Year: Variabile Qualitativa Ordinale (continua);
Months: Variabile Qualitativa Nominale;
Sales: Variabile Quantitativa Discreta;
Volume: Variabile Quantitativa Continua;
Median price: Variabile Quantitativa Continua;
Listings: Variabile Quantitativa Discreta;
Months Inventory: Variabile Quantitativa Continua.
Abbiamo come variabili del tempo: year, month, e months_inventory, che possiamo utilizzare per avere una rappresentazione più specifica nel tempo delle azioni immobiliari delle varie città.
Parto dal creare un summary delle variabili un pò più generali, quindi year, month e sales, a mio avviso.
Qui creo delle funzioni che possono essere utili:
library(ggplot2)
library(dplyr)
##
## Caricamento pacchetto: 'dplyr'
## I seguenti oggetti sono mascherati da 'package:stats':
##
## filter, lag
## I seguenti oggetti sono mascherati da 'package:base':
##
## intersect, setdiff, setequal, union
library(knitr)
library(moments)
df = read.csv("realestate_texas.csv", stringsAsFactors = T)
cv = function(x){
return(sd(x)/mean(x)*100)
}
gini.idx = function(x){
ni = table(x)
fi = ni / length(x)
fi2 = fi ** 2
J = length(ni)
gini = 1 - sum(fi2)
gini.norm = gini / ((J - 1) / J)
return(gini.norm)
}
Qui ho calcolato per ogni variabile quei valori che possono risultare utili secondo me per capire meglio la loro distribuzione e la loro varianza.
str(df)
## 'data.frame': 240 obs. of 8 variables:
## $ city : Factor w/ 4 levels "Beaumont","Bryan-College Station",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ year : int 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 ...
## $ month : int 1 2 3 4 5 6 7 8 9 10 ...
## $ sales : int 83 108 182 200 202 189 164 174 124 150 ...
## $ volume : num 14.2 17.7 28.7 26.8 28.8 ...
## $ median_price : num 163800 138200 122400 123200 123100 ...
## $ listings : int 1533 1586 1689 1708 1771 1803 1857 1830 1829 1779 ...
## $ months_inventory: num 9.5 10 10.6 10.6 10.9 11.1 11.7 11.6 11.7 11.5 ...
# Year
table(df$year)
##
## 2010 2011 2012 2013 2014
## 48 48 48 48 48
summary(df$year)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 2010 2011 2012 2012 2013 2014
IQR(df$year)
## [1] 2
cv_year = cv(df$year)
skew_year = skewness(df$year)
kurt_year = kurtosis(df$year) -3
# City
table(df$city)
##
## Beaumont Bryan-College Station Tyler
## 60 60 60
## Wichita Falls
## 60
# month
table(df$month)
##
## 1 2 3 4 5 6 7 8 9 10 11 12
## 20 20 20 20 20 20 20 20 20 20 20 20
# Volume, sales, median_price, listings, months_inventory
variables = c("sales", "volume", "median_price", "listings", "months_inventory")
idx = sapply(df[, variables], function(x){
c(mean = mean(x),
var = var(x),
cv = cv(x),
iqr = IQR(x),
skew = skewness(x),
kurt = kurtosis(x) - 3
)
})
idx = as.data.frame(t(idx))
kable(idx)
| mean | var | cv | iqr | skew | kurt | |
|---|---|---|---|---|---|---|
| sales | 192.29167 | 6.344300e+03 | 41.42203 | 120.0000 | 0.7181040 | -0.3131764 |
| volume | 31.00519 | 2.772707e+02 | 53.70536 | 23.2335 | 0.8847420 | 0.1769870 |
| median_price | 132665.41667 | 5.135730e+08 | 17.08218 | 32750.0000 | -0.3645529 | -0.6229618 |
| listings | 1738.02083 | 5.665690e+05 | 43.30833 | 1029.5000 | 0.6494982 | -0.7917900 |
| months_inventory | 9.19250 | 5.306889e+00 | 25.06031 | 3.1500 | 0.0409753 | -0.1744475 |
Possiamo notare come la skewness e la kurtosis, possiamo notare che l’unica variabile che porta ad una distribuzione asimmetrica negativa è la mediana dei prezzi, questo porterà la sua distribuzione ad avere una coda più lunga verso la sinistra. Così come la variabile volume che è l’unica con la kurtosi leptocurtica, ovvero ha distribuzione con il picco più alto e stretta ai lati rispetto ad una distribuzione normale.
Ora cerchiamo di capire quale sia la variabile con la più alta variabilità. Per farlo, ho creato un piccolo data frame da utilizzare in ggplot, così da avere una rappresentazione grafica delle variabilità calcolate sopra.
df_cv = data.frame(variabile = c("sales", "volume", "median_price", "listings", "months_inventory"), cvs = idx[, "cv"])
ggplot(data = df_cv)+
geom_bar(aes(x = variabile, y = cvs, fill = variabile), stat = "identity")+
theme_minimal()+
labs(
title = "Variabilità delle variabili",
x = "Variabili",
y = "CV",
fill = "Variabili"
)
Notiamo quindi che, come avevamo potuto intuire dai risultati stampati precedentemente, la variabile con variabilità più alta è la variabile “Volume”, con a secondo posto listings.
Per questo punto, ho deciso di fare una distribuzione di classi utilizzando la variabile sales
df$sales_classes = cut(df$sales, breaks = 5)
sales_classes_table = table(df$sales_classes)
kable(sales_classes_table)
| Var1 | Freq |
|---|---|
| (78.7,148] | 84 |
| (148,217] | 77 |
| (217,285] | 41 |
| (285,354] | 27 |
| (354,423] | 11 |
ggplot(data = df)+
geom_bar(aes(x = sales_classes, fill = city),
col = "black")+
theme_minimal()+
labs(
title = "Valore delle classi di vendita",
x = "Classi",
y = "Conteggio",
fill = "Città"
)
gini_sales = gini.idx(df$sales_classes)
kable(gini_sales)
| x |
|---|
| 0.9132812 |
Dal grafico notiamo come la variabile delle vendite della classe più bassa è molto più alta delle altre, sopratutto per la città di Beaumont mentre nelle ultime due classi, per le zone con più vendita, il range di città è diminuito a solamente Bryan-College Station e Tyler.
Possiamo notare finalmente che l’indice di gini della variabilità sales porta a pensare che ci sia un indice di eterogeneità quasi massima e quindi equidistribuzione.
Per fare questo calcolo abbiamo bisogno di solamente una formula, ovvero il numero del numero di osservazioni per città ed il numero totale di osservazioni, quindi la length del dataset.
Ottenuti questi due dobbiamo semplicemente dividerli, così possiamo ottenere i nostri risultati. L’unica differenza sta nel calcolo del mese di dicembre nell’anno del 2012, in cui alla fine dopo aver ottenuto le probabilità per l’anno e mese singolarmente, dobbiamo moltiplicarli tra loro.
get_probs = function(x){
sample = sample(x, 1000000, replace = TRUE)
table = table(x)
n = length(x)
probs = table[1] / n
return(probs)
}
prob_city = get_probs(df$city)
prob_month = get_probs(df$month)
prob_year = get_probs(df$year)
prob_year_month = prob_month * prob_year
kable(prob_city)
| x | |
|---|---|
| Beaumont | 0.25 |
kable(prob_month)
| x |
|---|
| 0.0833333 |
kable(prob_year_month)
| x |
|---|
| 0.0166667 |
Per il calcolo del prezzo medio possiamo semplicemente moltiplicare la colonna del volume per l’unità di misura della variabile delle vendite, che per noi è in milioni. Una volta ottenuto il volume in milioni possiamo dividerlo alla variabile sales ed ottenere la media.
Per ottenere l’efficienza degli annunci invece basta dividere il numero degli immobili venduti con successo quindi sales, al listings degli immobili, poi moltiplicarlo per 100 così da ottenere la percentuale.
Di seguito possiamo vedere il grafico della densità di questi, dove possiamo notare una buona differenza tra tutte le città.
df$mean_price = (df$volume * 1000000) / df$sales
df$effectiveness = (df$sales / df$listings) * 100
ggplot(data = df)+
geom_density(aes(x = effectiveness, col = city), size = 1)+
theme_minimal()+
xlab("Effectiveness in %")+
ylab("Density")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Per fare delle analisi variate basate sull’anno, città e mese, ho deciso di rendere la funzione group by di dyplir in una funzione, dove poter customizzare a seconda dei casi i vari raggruppamenti per sales e volume. In seguito, ho creato due raggruppamenti diversi, in base all’anno e città e poi in base all’anno e mese.
group.by = function(x, group, group2){
group = x %>%
group_by({{group}},{{group2}}) %>%
summarise(mean_sales = mean(sales),
mean_volume = mean(volume))
return(group)
}
year_city = group.by(df, city, year)
## `summarise()` has grouped output by 'city'. You can override using the
## `.groups` argument.
month_year = group.by(df, month, year)
## `summarise()` has grouped output by 'month'. You can override using the
## `.groups` argument.
ggplot(year_city, aes(x = city, y = mean_sales, fill = mean_sales))+
geom_bar(stat = "identity", position = "dodge")+
facet_wrap(~ year)+
theme_minimal()+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
labs(
title = "Media Vendite ogni anno per ogni città",
x = "Città",
y = "Media Vendite"
)
ggplot(year_city, aes(x = city, y = mean_volume, fill = mean_volume))+
geom_bar(stat = "identity", position = "dodge")+
facet_wrap(~ year)+
theme_minimal()+
labs(
title = "Media del volume ogni anno per ogni città",
x = "Città",
y = "Media Volume"
)+
theme(axis.text.x = element_text(angle = 45, hjust = 1))
ggplot(month_year, aes(x = month, y = mean_volume, fill = mean_volume, group = year, color = year))+
geom_line(stat = "identity", size = 1)+
theme_minimal()+
labs(
title = "Media Volume ogni mese",
x = "Mese",
y = "Media Volume"
)+
scale_x_continuous(breaks = seq(1, 12))
ggplot(month_year, aes(x = month, y = mean_sales, fill = mean_sales, group = year, color = year))+
geom_line(stat = "identity", size = 1)+
theme_minimal()+
labs(
title = "Media Vendite ogni mese",
x = "Mese",
y = "Media Vendite"
)+
scale_x_continuous(breaks = seq(1, 12))
kable(summary(year_city))
| city | year | mean_sales | mean_volume | |
|---|---|---|---|---|
| Beaumont :5 | Min. :2010 | Min. :106.2 | Min. :12.05 | |
| Bryan-College Station:5 | 1st Qu.:2011 | 1st Qu.:138.9 | 1st Qu.:19.56 | |
| Tyler :5 | Median :2012 | Median :184.3 | Median :29.62 | |
| Wichita Falls :5 | Mean :2012 | Mean :192.3 | Mean :31.01 | |
| NA | 3rd Qu.:2013 | 3rd Qu.:238.1 | 3rd Qu.:39.92 | |
| NA | Max. :2014 | Max. :331.5 | Max. :59.60 |
kable(summary(month_year))
| month | year | mean_sales | mean_volume | |
|---|---|---|---|---|
| Min. : 1.00 | Min. :2010 | Min. :105.2 | Min. :15.16 | |
| 1st Qu.: 3.75 | 1st Qu.:2011 | 1st Qu.:155.3 | 1st Qu.:23.39 | |
| Median : 6.50 | Median :2012 | Median :185.9 | Median :29.37 | |
| Mean : 6.50 | Mean :2012 | Mean :192.3 | Mean :31.01 | |
| 3rd Qu.: 9.25 | 3rd Qu.:2013 | 3rd Qu.:224.6 | 3rd Qu.:36.98 | |
| Max. :12.00 | Max. :2014 | Max. :294.2 | Max. :53.81 |
Possiamo notare come nei mesi centrali dell’anno la quantità di vendite e di volume aumentano in maniera abbastanza simile, e che l’anno in cui c’è stato il maggior numero di vendite, oltre che volume, è il 2014, con la città di Tyler che ha i valori più alti.
Per il passaggio 8 ho deciso di esplorare semplicemente un paio di grafici in maniera che potessi confrontare bene le parti più importanti del dataset. Ad esempio nel primo e nel secondo ho voluto riproporre i grafici ottenuti nel passaggio 7, poichè sono ottimi per dimostrare l’oscillazione delle vendite e del volume nel corso del tempo tra le città.
Nel terzo e quarto grafico, abbiamo la visualizzazione della variabile sales tra le città, con il quarto grafico in versione normalizzato. Notiamo che le città hanno delle differenze molto accentuate tra loro.
Nell’ultimo grafico, ho voluto esplorare come si comporta il prezzo mediano con le sue distribuzioni dei valori, notiamo che nel corso degli anni non cambiano troppo, e che nonostante tutto, la città di Beaumont sembra essere quella con circa la stessa grandezza, mentre Wichita Falls, che è la città con minore prezzo mediano, comprende anche un range più alto dello stesso.
df_aggregato <- df %>%
group_by(year, month) %>%
summarise(
sales = sum(sales, na.rm = TRUE),
volume = sum(volume, na.rm = TRUE)
) %>%
ungroup() %>%
arrange(year, month)
## `summarise()` has grouped output by 'year'. You can override using the
## `.groups` argument.
ggplot(data = df_aggregato)+
geom_line(aes(x = month, y = sales, group = year, color = year), size = 1) +
theme_minimal()+
labs(
title = "Vendite negli anni",
x = "Mesi",
y = "Vendite"
)+
scale_x_continuous(breaks = seq(1, 12))
ggplot(data = df_aggregato)+
geom_line(aes(x = month, y = volume, group = year, color = year), size = 1) +
theme_minimal()+
labs(
title = "Volume negli anni",
x = "Mesi",
y = "Volume"
)+
scale_x_continuous(breaks = seq(1, 12))
ggplot(data = df)+
geom_bar(aes(x = month, y = sales, fill = city),
stat = "identity", position = "stack")+
scale_x_continuous(breaks = seq(1, 12, 1))+
ylab("Volume")+
xlab("Month")+
facet_wrap(~ year)+
theme_minimal()+
labs(
title = "Totale vendite ogni mese per città nel corso degli anni",
x = "Mesi",
y = "Valore totale vendite",
fill = "Città"
)
ggplot(data = df)+
geom_bar(aes(x = month, y = sales, fill = city),
stat = "identity", position = "fill")+
scale_x_continuous(breaks = seq(1, 12, 1))+
ylab("Volume")+
xlab("Month")+
facet_wrap(~ year)+
theme_minimal()+
labs(
title = "Totale vendite ogni mese per città nel corso degli anni, normalizzato",
x = "Mesi",
y = "Valore totale vendite",
fill = "Città"
)
ggplot(data = df)+
geom_boxplot(aes(x = median_price, fill = city))+
theme_minimal()+
facet_wrap(~ df$year)+
labs(
title = "Prezzo mediano degli immobili nelle città ogni anno",
x = "Prezzo mediano",
y = "Distribuzione del Valore"
)
Per concludere, in questa analisi del dataset, abbiamo scoperto che in media, le persone hanno preferito comprare immobili più grandi, nonostante il prezzo, nei periodi centrali dell’anno, ovvero tra Maggio e Luglio, e specificatamente che siano nelle città di Beaumont e Bryan College Station.
Abbiamo scoperto che gli annunci che hanno portato a più vendite si possono ritrovare nelle città di Tyler e Whichita Falls, che riportano la percentuale più alta di vendite effettuate nel totale.
Infine, scopriamo con i dati in questo dataset che se dovessimo cercare un immobile in un periodo randomico dell’anno, avremmo una distribuzione di possibilità molto equilibrata in generale, per ogni città.