1. Analisi Preliminare Dataset

Obiettivo

L’obiettivo di questa analisi è rendere più efficiente il mercato immobiliare del Texas fornendo insight utili sui dati relativi alle vendite di immobili e verificare se gli annunci pubblicati risultano essere efficaci per finalizzare le vendite. Di seguito, alcune righe del dataset e i tipi di dati delle variabili:

##       city year month sales volume median_price listings months_inventory
## 1 Beaumont 2010     1    83 14.162       163800     1533              9.5
## 2 Beaumont 2010     2   108  17.69       138200     1586               10
## 3 Beaumont 2010     3   182 28.701       122400     1689             10.6
## 4 Beaumont 2010     4   200 26.819       123200     1708             10.6
## 5 Beaumont 2010     5   202 28.833       123100     1771             10.9
## 6 Beaumont 2010     6   189 27.219       122800     1803             11.1
## 'data.frame':    240 obs. of  8 variables:
##  $ city            : chr  "Beaumont" "Beaumont" "Beaumont" "Beaumont" ...
##  $ 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          : chr  "14.162" "17.69" "28.701" "26.819" ...
##  $ median_price    : num  163800 138200 122400 123200 123100 ...
##  $ listings        : int  1533 1586 1689 1708 1771 1803 1857 1830 1829 1779 ...
##  $ months_inventory: chr  "9.5" "10" "10.6" "10.6" ...
  • city = variabile qualitativa nominale
  • year = variabile quantitativa su scala di intervalli
  • month = variabile qualitativa ordinale poichè i numeri corrispondono ai mesi dell’anno codificati in numeri
  • sales = variabile quantitativa discreta
  • volume = variabile quantitativa continua
  • median_price = variabile quantitativa discreta
  • listings = variabile quantitativa discreta
  • months_inventory = variabile quantitativa continua

1.1 Valutazioni Preliminari:

1.2 Funzioni

## Funzione per calcolare l'indice di Gini
gini.index <- function(x) {
  ni=table(x)
  fi=ni/length(x)
  fi2=fi^2
  J = length(table(x))
  gini = 1-sum(fi2)
  gini.normalizzato = gini/((J-1)/J)
  return(gini.normalizzato)
}

# Funzione per calcolare il coefficiente di variazione
CV <- function(x) {
  return(sd(x)/mean(x)*100)
}

# Funzione per calcolare il valore mediano di una determinata classe (E' fuori dallo scope del corso, ma ho approfondito l'argomento e mi è tornata utile nell'analisi)
calcola_mediana_classe <- function(limiti_inferiori, frequenze, totale_frequenze) {
  # Calcolo della posizione della mediana
  posizione_mediana <- totale_frequenze / 2
  
  # Calcolo la frequenza cumulativa
  frequenze_cumulate <- cumsum(frequenze)
  
  # Individuare la classe mediana
  indice_classe_mediana <- which(frequenze_cumulate >= posizione_mediana)[1]
  
  # Limite inferiore della classe mediana
  L <- limiti_inferiori[indice_classe_mediana]
  
  # Frequenza della classe mediana
  f <- frequenze[indice_classe_mediana]
  
  # Frequenza cumulativa della classe precedente
  F <- ifelse(indice_classe_mediana == 1, 0, frequenze_cumulate[indice_classe_mediana - 1])
  
  # Ampiezza della classe
  w <- limiti_inferiori[indice_classe_mediana + 1] - limiti_inferiori[indice_classe_mediana]
  
  # Calcolo della mediana usando la formula di interpolazione
  mediana <- L + ((posizione_mediana - F) / f) * w
  return(mediana)
}

1.3 Analisi Variabili

Analisi variabile city

# studio preliminare variabile city
table(city)
## city
##              Beaumont Bryan-College Station                 Tyler 
##                    60                    60                    60 
##         Wichita Falls 
##                    60
unique(city)
## [1] "Beaumont"              "Bryan-College Station" "Tyler"                
## [4] "Wichita Falls"
gini.index(city)
## [1] 1

Considerazioni

L’ indice di Gini per la variabile city è uguale ad 1 ed indica che city ha eterogeneità massima. Dunque, si può dedurre con questo indice che le frequenze saranno equamente distribuite tra tutti i valori possibili della variabile

Analisi variabile year

# studio preliminare variabile year
# il range degli anni va dal 2010 al 2014, dunque ha ampiezza 4 anni
range(year)
## [1] 2010 2014
gini.index(year)
## [1] 1
n_year_lenght <- length(year)
# l'indice di Gini indicava che la distribuzione è equamente distribuita. Dunque, le frequenze sono uguali per tutte le classi
year_distr_freq <- as.data.frame(
  cbind(
    ni=table(year),
    fi=table(year)/n_year_lenght,
    Ni=cumsum(table(year)),
    Fi=cumsum(table(year))/n_year_lenght
  )
)
print(year_distr_freq)
##      ni  fi  Ni  Fi
## 2010 48 0.2  48 0.2
## 2011 48 0.2  96 0.4
## 2012 48 0.2 144 0.6
## 2013 48 0.2 192 0.8
## 2014 48 0.2 240 1.0

Considerazioni

  • L’ indice di Gini per la variabile year è uguale ad 1 ed indica che year ha eterogeneità massima. Dunque, si può dedurre con questo indice che le frequenze saranno equamente distribuite tra tutti i valori possibili della variabile
  • Il range degli anni è di ampiezza 4 anni e contiene gli anni dal 2010 al 2014

Analisi variabile month

# studio preliminare variabile month
table(month)
## 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
gini.index(month)
## [1] 1
n_month_lenght <- length(month)
month_distr_freq <- as.data.frame(
  cbind(
    ni=table(month),
    fi=table(month)/n_month_lenght,
    Ni=cumsum(table(month)),
    Fi=cumsum(table(month))/n_month_lenght
  )
)
print(month_distr_freq)
##    ni         fi  Ni         Fi
## 1  20 0.08333333  20 0.08333333
## 2  20 0.08333333  40 0.16666667
## 3  20 0.08333333  60 0.25000000
## 4  20 0.08333333  80 0.33333333
## 5  20 0.08333333 100 0.41666667
## 6  20 0.08333333 120 0.50000000
## 7  20 0.08333333 140 0.58333333
## 8  20 0.08333333 160 0.66666667
## 9  20 0.08333333 180 0.75000000
## 10 20 0.08333333 200 0.83333333
## 11 20 0.08333333 220 0.91666667
## 12 20 0.08333333 240 1.00000000

Considerazioni

L’ indice di Gini per la variabile month è uguale ad 1 ed indica che year ha eterogeneità massima. Dunque, si può dedurre con questo indice che le frequenze saranno equamente distribuite tra tutti i valori possibili della variabile

Analisi variabile sales

#studio preliminare variabile sales
range(sales)
## [1]  79 423
mean(sales)
## [1] 192.2917
quantile(sales)
##    0%   25%   50%   75%  100% 
##  79.0 127.0 175.5 247.0 423.0
IQR(sales)
## [1] 120
varianza_sales <- var(sales)
print(varianza_sales)
## [1] 6344.3
deviazione_standard_sales <- sd(sales)
print(deviazione_standard_sales)
## [1] 79.65111
CV(sales)
## [1] 41.42203
n <- length(sales)
sales_length_cl <- cut(sales, breaks = seq(min(sales), max(sales), by = 30), include.lowest = TRUE)
frequenze <- c(table(sales))
# Ottieni i break points
breaks <- seq(min(sales), max(sales), by = 30)
# I limiti inferiori sono i break points tranne l'ultimo
limiti_inferiori <- breaks[-length(breaks)]
totale_frequenze <- sum(frequenze)
# 
#la classe modale è la prima, ovvero quella da [79,129]
table(sales_length_cl)
## sales_length_cl
##  [79,109] (109,139] (139,169] (169,199] (199,229] (229,259] (259,289] (289,319] 
##        33        42        40        32        21        19        20        13 
## (319,349] (349,379] (379,409] 
##         8         8         3
sales_distr_freq <- as.data.frame(
  cbind(
    ni=table(sales_length_cl),
    fi=table(sales_length_cl)/n,
    Ni=cumsum(table(sales_length_cl)),
    Fi=cumsum(table(sales_length_cl))/n
  )
)
#calcolo del valore mediano della classe - utile per verificare se l'indice di asimmetria risulta coerente con media>mediana>moda
mediana <- calcola_mediana_classe(limiti_inferiori, frequenze, totale_frequenze)
print(mediana)
## 175 
##  NA
# calcolo degli indici di forma - assimetria-curtosi
# l'assimetria è maggiore di 0, questo vuol dire che vi è un'asimmetria positiva dove media>moda>mediana (verificato). Sono presenti più modalità basse
skewness(sales)
## [1] 0.718104
#la curtosi negativa indica che vi è una distribuzione platicurtica, ovvero il grafico avrà una forma più appiattita
kurtosis(sales)-3
## [1] -0.3131764

Considerazioni

  • Range = La variabile sales ha un range di valori di ampiezza 344, inteso come una quantità, e quindi un numero intero
  • Mean = 192.2917
  • Median = 175.5
  • IQR = 120 [Questo indica che il corpo centrale dei dati ha un range di ampiezza 120]
  • SD = 79.65111 [questo indica di quanto in media i valori si discostano dalla media]
  • CV = 41.42203 [Questo indica che la deviazione standard è circa il 41% della media]
  • sales_length_cl = ho diviso in classi per un valore coerente, in modo tale da non ottenere classi vuote o disperdere troppe informazioni {Classe modale = (109, 139] }
  • Indice di Asimmetria = 0.718104 [L’indice di assimetria è maggiore di 0, questo vuol dire che vi è un’asimmetria positiva dove medi a> moda >mediana (verificato). Questo indica che sono più frequenti modalità basse]
  • Curtosi = -0.3131764 [la curtosi negativa indica che vi è una distribuzione platicurtica, ovvero che il grafico avrà una forma più appiattita]

Analisi variabile volume

# studio preliminare variabile volume
# si potrebbe rapportare agli anni per evidenziare come è aumentato nel tempo con un line chart
# Questa variabile risulta essere un char anche se contiene solo valori numerici decimali
# Quindi verrà eseguito una conversione in float e saranno individuati eventuali valori nulli o diversi da numeri

# Calcoliamo il numero di valori nulli
num_nulls_volume <- sum(is.na(volume_float))
cat("Numero di valori nulli trovati:", num_nulls_volume, "\n")
## Numero di valori nulli trovati: 0
range(volume_float)
## [1]  8.166 83.547
mean(volume_float)
## [1] 31.00519
quantile(volume_float)
##      0%     25%     50%     75%    100% 
##  8.1660 17.6595 27.0625 40.8930 83.5470
IQR(volume_float)
## [1] 23.2335
varianza_volume <- var(volume_float)
print(varianza_volume)
## [1] 277.2707
deviazione_standard_volume <- sd(volume_float)
print(deviazione_standard_volume)
## [1] 16.65145
CV(volume_float)
## [1] 53.70536
n_volume_float <- length(volume_float)
volume_length_cl <- cut(volume_float, breaks = seq(min(volume_float), max(volume_float), by = 10), include.lowest = TRUE)
frequenze_volume <- c(table(volume_float))
# Ottieni i break points
breaks_volume <- seq(min(volume_float), max(volume_float), by = 10)
# I limiti inferiori sono i break points tranne l'ultimo
limiti_inferiori <- breaks[-length(breaks_volume)]
totale_frequenze_volume <- sum(frequenze_volume)
# 
#la classe modale è la prima, ovvero quella da [79,129]
table(volume_length_cl)
## volume_length_cl
## [8.17,18.2] (18.2,28.2] (28.2,38.2] (38.2,48.2] (48.2,58.2] (58.2,68.2] 
##          66          57          48          27          22          12 
## (68.2,78.2] 
##           6
volume_distr_freq <- as.data.frame(
  cbind(
    ni=table(volume_length_cl),
    fi=table(volume_length_cl)/n_volume_float,
    Ni=cumsum(table(volume_length_cl)),
    Fi=cumsum(table(volume_length_cl))/n_volume_float
  )
)
print(volume_distr_freq)
##             ni         fi  Ni        Fi
## [8.17,18.2] 66 0.27500000  66 0.2750000
## (18.2,28.2] 57 0.23750000 123 0.5125000
## (28.2,38.2] 48 0.20000000 171 0.7125000
## (38.2,48.2] 27 0.11250000 198 0.8250000
## (48.2,58.2] 22 0.09166667 220 0.9166667
## (58.2,68.2] 12 0.05000000 232 0.9666667
## (68.2,78.2]  6 0.02500000 238 0.9916667
# calcolo degli indici di forma
# Vi è un'asimmetria positiva, quindi sono più frequenti modalità basse 
skewness(volume_float)
## [1] 0.884742
# la curtosi risulta essere maggiore di 0 e quindi leptocurtica. Il grafico avrà una forma più allungata rispetto alla normale.Tuttavia, è vicino allo zero, quindi non sarà molto accentuata
kurtosis(volume_float)-3
## [1] 0.176987

Considerazioni

  • Conversione: Questa variabile risulta essere un char anche se contiene solo valori numerici decimali.Quindi è stata eseguita una conversione in float e saranno individuati eventuali valori nulli o diversi da numeri
  • Range = La variabile volume ha un range di valori di ampiezza 75.381, inteso come un valore numerico decimale che viene espresso come milioni di dollari
  • Mean = 31.00519
  • Median = 27.0625
  • IQR = 23.2335 [Questo indica che il corpo centrale dei dati ha un range di ampiezza 23]
  • SD = 16.65145 [questo indica di quanto in media i valori si discostano dalla media]
  • CV = 53.70536 [Questo indica che la deviazione standard è circa il 54% della media]
  • volume_length_cl = ho diviso in classi per un valore coerente, in modo tale da non ottenere classi vuote o disperdere troppe informazioni {Classe modale = (8.17, 18.2] }
  • Indice di Asimmetria = 884742 [L’indice di assimetria è maggiore di 0, questo vuol dire che vi è un’asimmetria positiva dove media> moda >mediana (verificato). Questo indica che sono più frequenti modalità basse]
  • Curtosi = 0.176987 [la curtosi positiva indica che vi è una distribuzione leptocurtica, Il grafico avrà una forma più allungata rispetto alla normale.Tuttavia, è vicino allo zero, quindi non sarà molto accentuata]

Analisi variabile median_price

#studio preliminare variabile median_price
# si potrebbe rapportare agli anni per vedere come è aumentato nel tempo con un line chart

range(median_price)
## [1]  73800 180000
mean(median_price)
## [1] 132665.4
quantile(median_price)
##     0%    25%    50%    75%   100% 
##  73800 117300 134500 150050 180000
IQR(median_price)
## [1] 32750
varianza_median_price <- var(median_price)
print(varianza_median_price)
## [1] 513572983
deviazione_standard_median_price <- sd(median_price)
print(deviazione_standard_median_price)
## [1] 22662.15
CV(median_price)
## [1] 17.08218
n <- length(median_price)
median_price_length_cl <- cut(median_price, breaks = seq(min(median_price), max(median_price), by = 25000), include.lowest = TRUE)
frequenze_median_price <- c(table(median_price))
# Ottieni i break points
breaks_median_price <- seq(min(median_price), max(median_price), by = 25000)
# I limiti inferiori sono i break points tranne l'ultimo
limiti_inferiori_median_price <- breaks_median_price[-length(breaks_median_price)]
totale_frequenze_median_price <- sum(frequenze_median_price)
# 
#la classe modale è la prima, ovvero quella da [79,129]
table(median_price_length_cl)
## median_price_length_cl
## [7.38e+04,9.88e+04] (9.88e+04,1.24e+05] (1.24e+05,1.49e+05] (1.49e+05,1.74e+05] 
##                  22                  56                  96                  63
median_price_distr_freq <- as.data.frame(
  cbind(
    ni=table(median_price_length_cl),
    fi=table(median_price_length_cl)/n,
    Ni=cumsum(table(median_price_length_cl)),
    Fi=cumsum(table(median_price_length_cl))/n
  )
)
print(median_price_distr_freq)
##                     ni         fi  Ni         Fi
## [7.38e+04,9.88e+04] 22 0.09166667  22 0.09166667
## (9.88e+04,1.24e+05] 56 0.23333333  78 0.32500000
## (1.24e+05,1.49e+05] 96 0.40000000 174 0.72500000
## (1.49e+05,1.74e+05] 63 0.26250000 237 0.98750000
#calcolo degli indici di forma
# asimmetria negativa indica che sono più frequenti modalità alte e che la media> mediana>moda. La "campana" sarà traslata verso destra
skewness(median_price)
## [1] -0.3645529
# risulta negativa e questo indica che è presente una distribuzione platicurtica dove la campana risulterà più appiattita
kurtosis(median_price)-3
## [1] -0.6229618

Considerazioni

  • Range = La variabile median_price ha un range di valori di ampiezza 106200, inteso come un valore numerico intero
  • Mean = 132665.4
  • Median = 134500 [la mediana risulta essere molto vicina alla media. Questo indica che non sono presenti molti outlier che alterano il valore della media]
  • IQR = 32750 [Questo indica che il corpo centrale dei dati ha un range di ampiezza 32750. ]
  • SD = 22662.15 [questo indica di quanto in media i valori si discostano dalla media]
  • CV = 17.08218 [Questo indica che la deviazione standard è circa il 17% della media. Quindi, i valori rilevati si allontanano poco dalla media. Questo, era indicato anche dalla bassa differenza tra media e mediana]
  • median_price_length_cl = ho diviso in classi per un valore coerente, in modo tale da non ottenere classi vuote o disperdere troppe informazioni {Classe modale = (1.24e+05,1.49e+05] }
  • Indice di Asimmetria = -0.3645529 [L’indice di assimetria è minore di 0, questo vuol dire che sono più frequenti modalità alte e che la media> mediana>moda. La “campana” sarà traslata verso destra]
  • Curtosi = -0.6229618 [la curtosi negativa indica che vi è una distribuzione platicurtica, Il grafico avrà una forma più appiattita rispetto alla normale]

Analisi variabile listings

#studio preliminare variabile listings
range(listings)
## [1]  743 3296
mean(listings)
## [1] 1738.021
quantile(listings)
##     0%    25%    50%    75%   100% 
##  743.0 1026.5 1618.5 2056.0 3296.0
IQR(listings)
## [1] 1029.5
varianza_listings <- var(listings)
print(varianza_listings)
## [1] 566569
deviazione_standard_listings <- sd(listings)
print(deviazione_standard_listings)
## [1] 752.7078
CV(listings)
## [1] 43.30833
n_listings <- length(listings)
listings_length_cl <- cut(listings, breaks = seq(min(listings), max(listings), by = 500), include.lowest = TRUE)
frequenze_listings <- c(table(listings))
# Ottieni i break points
breaks_listings <- seq(min(listings), max(listings), by = 500)
# I limiti inferiori sono i break points tranne l'ultimo
limiti_inferiori_listings <- breaks_listings[-length(breaks_listings)]
totale_frequenze_listings <- sum(frequenze_listings)
# 
table(listings_length_cl)
## listings_length_cl
##      [743,1.24e+03] (1.24e+03,1.74e+03] (1.74e+03,2.24e+03] (2.24e+03,2.74e+03] 
##                  74                  83                  23                  15 
## (2.74e+03,3.24e+03] 
##                  38
listings_distr_freq <- as.data.frame(
  cbind(
    ni=table(listings_length_cl),
    fi=table(listings_length_cl)/n_listings,
    Ni=cumsum(table(listings_length_cl)),
    Fi=cumsum(table(listings_length_cl))/n_listings
  )
)

print(listings_distr_freq)
##                     ni         fi  Ni        Fi
## [743,1.24e+03]      74 0.30833333  74 0.3083333
## (1.24e+03,1.74e+03] 83 0.34583333 157 0.6541667
## (1.74e+03,2.24e+03] 23 0.09583333 180 0.7500000
## (2.24e+03,2.74e+03] 15 0.06250000 195 0.8125000
## (2.74e+03,3.24e+03] 38 0.15833333 233 0.9708333
# calcolo degli indici di forma
# si ha un'asimmetria positiva
skewness(listings)
## [1] 0.6494982
# si ha una distribuzione leptocurtica poichè è minore di 0
kurtosis(listings)-3
## [1] -0.79179

Considerazioni

  • Range = La variabile listings ha un range di valori di ampiezza 2553, inteso come un valore numerico intero
  • Mean = 1738.021
  • Median = 1618.5 [la mediana risulta essere molto vicina alla media. Questo indica che non sono presenti molti outlier che alterano il valore della media]
  • IQR = 1029 [Questo indica che il corpo centrale dei dati ha un range di ampiezza 1029 ]
  • SD = 752.7078 [questo indica di quanto in media i valori si discostano dalla media]
  • CV = 43.30833 [Questo indica che la deviazione standard è circa il 43% della media.]
  • listings_length_cl = ho diviso in classi per un valore coerente, in modo tale da non ottenere classi vuote o disperdere troppe informazioni {Classe modale = ((1.24e+03,1.74e+03] }
  • Indice di Asimmetria = 0.6494982 [L’indice di assimetria è maggiore di 0, questo vuol dire che sono più frequenti modalità basse
  • Curtosi = -0.79179 [la curtosi negativa indica che vi è una distribuzione platicurtica, Il grafico avrà una forma più appiattita rispetto alla normale]

Analisi variabile months_inventory

#studio preliminare variabile months_inventory
#convertiamo in float da string la variabile months inventory per poter calcolare i vari indici
months_inventory_float <- as.numeric(months_inventory)

# Calcoliamo il numero di valori nulli
num_nulls_months_inventory <- sum(is.na(months_inventory_float))
cat("Numero di valori nulli trovati:", num_nulls_months_inventory, "\n")
## Numero di valori nulli trovati: 0
range(months_inventory_float)
## [1]  3.4 14.9
mean(months_inventory_float)
## [1] 9.1925
quantile(months_inventory_float)
##    0%   25%   50%   75%  100% 
##  3.40  7.80  8.95 10.95 14.90
IQR(months_inventory_float)
## [1] 3.15
varianza_months_inventory <- var(months_inventory_float)
print(varianza_months_inventory)
## [1] 5.306889
deviazione_standard_months_inventory <- sd(months_inventory_float)
print(deviazione_standard_months_inventory)
## [1] 2.303669
CV(months_inventory_float)
## [1] 25.06031
n_months_inventory <- length(months_inventory_float)
months_inventory_length_cl <- cut(months_inventory_float, breaks = seq(min(months_inventory_float), max(months_inventory_float), by = 1.5), include.lowest = TRUE)
frequenze_months_inventory <- c(table(months_inventory_float))
# Ottieni i break points
breaks_months_inventory <- seq(min(months_inventory_float), max(months_inventory_float), by = 1.5)
# I limiti inferiori sono i break points tranne l'ultimo
limiti_inferiori_months_inventory <- breaks_months_inventory[-length(months_inventory_float)]
totale_frequenze_months_inventory <- sum(frequenze_months_inventory)
# 
table(months_inventory_length_cl)
## months_inventory_length_cl
##   [3.4,4.9]   (4.9,6.4]   (6.4,7.9]   (7.9,9.4]  (9.4,10.9] (10.9,12.4] 
##          10          13          49          73          35          42 
## (12.4,13.9] 
##          13
months_inventory_distr_freq <- as.data.frame(
  cbind(
    ni=table(months_inventory_length_cl),
    fi=table(months_inventory_length_cl)/n_months_inventory,
    Ni=cumsum(table(months_inventory_length_cl)),
    Fi=cumsum(table(months_inventory_length_cl))/n_months_inventory
  )
)
print(months_inventory_distr_freq)
##             ni         fi  Ni         Fi
## [3.4,4.9]   10 0.04166667  10 0.04166667
## (4.9,6.4]   13 0.05416667  23 0.09583333
## (6.4,7.9]   49 0.20416667  72 0.30000000
## (7.9,9.4]   73 0.30416667 145 0.60416667
## (9.4,10.9]  35 0.14583333 180 0.75000000
## (10.9,12.4] 42 0.17500000 222 0.92500000
## (12.4,13.9] 13 0.05416667 235 0.97916667
skewness(months_inventory_float)
## [1] 0.04097527
kurtosis(months_inventory_float)-3
## [1] -0.1744475

Considerazioni

  • Conversione: Questa variabile risulta essere un char anche se contiene solo valori numerici decimali.Quindi è stata eseguita una conversione in float e saranno individuati eventuali valori nulli o diversi da numeri
  • Range = La variabile months_inventory ha un range di valori di ampiezza 11.5
  • Mean = 9.1925
  • Median = 8.95
  • IQR = 3.15 [Questo indica che il corpo centrale dei dati ha un range di ampiezza 3]
  • SD = 2.303669 [questo indica di quanto in media i valori si discostano dalla media]
  • CV = 25.0631 [Questo indica che la deviazione standard è circa il 25% della media]
  • months_inventory_length_cl = ho diviso in classi per un valore coerente, in modo tale da non ottenere classi vuote o disperdere troppe informazioni {Classe modale = (7.9, 9.4] }
  • Indice di Asimmetria = 0.0409 [L’indice di assimetria è maggiore di 0, questo vuol dire che vi è un’asimmetria positiva dove media> moda >mediana (verificato). Questo indica che sono più frequenti modalità basse. Tuttavia, è molto vicino allo zero, quindi si può definire come variabile simmetrica]
  • Curtosi = -0.1744475 [la curtosi negativa indica che vi è una distribuzione platicurtica, Il grafico avrà una forma più schiacciata rispetto alla normale.Tuttavia, è vicino allo zero, quindi non sarà molto accentuata]

3. Identificazione delle variabili con maggiore variabilità e asimmetria

Considerazioni sulla variabilità

La variabile con maggiore variabilità è il volume che presenta valori che distano dalla media in media del 53%. Ovvero, che la deviazione standard è il 53% della media. Ho usato il coefficiente di variazione per misurare la variabilità perchè questo indice non viene influenzato dall’ordine di grandezza delle variabili

# Variabili con maggiore variabilità e asimmetria
# Considerazioni sulla variabilità:
CV(year)
## [1] 0.07043584
CV(month)
## [1] 53.21949
CV(sales)
## [1] 41.42203
CV(volume_float)
## [1] 53.70536
CV(median_price)
## [1] 17.08218
CV(listings)
## [1] 43.30833
CV(months_inventory_float)
## [1] 25.06031

Considerazioni sull’asimmetria

  • year, month e months_inventory risultano essere simmetriche (quindi stessa distribuzione della normale)
  • sales, volume e listings risultano essere asimmetriche positive e dunque il grafico sarà traslato verso destra.Quindi saranno presenti con più frequenza le modalità basse.
  • median_price risulta asimmetrico negativo, e quindi saranno più frequenti modalità alte
  • La variabile più asimmetrica, ovvero quella che ha la distribuzione che si discosta maggiormente da quella normale, è il volume
skewness(year)
## [1] 0
skewness(month)
## [1] 0
skewness(sales)
## [1] 0.718104
skewness(volume_float)
## [1] 0.884742
skewness(median_price)
## [1] -0.3645529
skewness(listings)
## [1] 0.6494982
skewness(months_inventory_float)
## [1] 0.04097527

4. Creazione di classi per una variabile quantitativa

n <- length(sales)
sales_length_cl <- cut(sales, breaks = seq(min(sales), max(sales), by = 50), include.lowest = TRUE)
frequenze <- table(sales_length_cl)


#la classe modale è la prima, ovvero quella da [79,129]
sales_distr_freq <- data.frame(
  sales_classes = names(frequenze),
  ni = as.numeric(frequenze),
  fi = as.numeric(frequenze) / n,
  Ni = cumsum(as.numeric(frequenze)),
  Fi = cumsum(as.numeric(frequenze)) / n
)
# Ottieni l'ordine delle classi dalle righe di sales_distr_freq
ordered_classes <- levels(sales_length_cl)

# Converti sales_classes in un fattore con i livelli ordinati
sales_classes <- factor(sales_length_cl, levels = ordered_classes)

ggplot(sales_distr_freq, aes(x = sales_classes, y = ni)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  labs(title = "Distribuzione delle vendite", x = "Classe sales", y = "Frequenza assoluta") +
  theme_minimal()

gini.index(sales_distr_freq)
## [1] 0.7600977

Considerazioni

  • E’ possibile notare come la distribuzione si distribuisca come una normale
  • L’indice di Gini indica che la distribuzione delle vendite, in termini di quantità di vendite risulta essere perlopiù eterogenea, ovvero la frequenza con cui si verificano i possibili valori della variabile tende ad essere equidistribuita
  • Dal grafico si può notare come le modalità più basse siano più frequenti come indicato anche dall’indice di simmetria calcolato per la variabile sales

5. Calcolo della probabilità

Nota: Dato che tutti questi dati sono equamente distribuiti, il calcolo delle probabilità è risultato semplice, eseguendo l’operazione 1/n dove n è il numero totale di valori possibili per quella variabile

6. Creazione di nuove variabili

# calcola `prezzo_medio` espressa in centinaia di migliaia di dollari. Es:150k
dati_immobiliari_texas <- dati_immobiliari_texas %>%
  mutate(
    prezzo_medio_k = (volume_float / sales) * 1000
  )

head(dati_immobiliari_texas)
##       city year month sales volume median_price listings months_inventory
## 1 Beaumont 2010     1    83 14.162       163800     1533              9.5
## 2 Beaumont 2010     2   108  17.69       138200     1586               10
## 3 Beaumont 2010     3   182 28.701       122400     1689             10.6
## 4 Beaumont 2010     4   200 26.819       123200     1708             10.6
## 5 Beaumont 2010     5   202 28.833       123100     1771             10.9
## 6 Beaumont 2010     6   189 27.219       122800     1803             11.1
##   prezzo_medio_k
## 1       170.6265
## 2       163.7963
## 3       157.6978
## 4       134.0950
## 5       142.7376
## 6       144.0159
# valutazione efficienza annunci

# calcolo delle correlazioni tra le due variabili - argomento non svolto ma ho cercato online su come farlo
# Le due variabili risultano fortemente correlate
correlazione <- cor(dati_immobiliari_texas$listings, months_inventory_float)
print(correlazione)
## [1] 0.7351499
percent_annunci_efficaci <- dati_immobiliari_texas$sales / dati_immobiliari_texas$listings * 100
# CV(percent_annunci_efficaci) # Assicurati che CV sia definito o rimuovilo se non necessario
median(percent_annunci_efficaci)
## [1] 10.96268
dati_immobiliari_texas <- dati_immobiliari_texas %>%
  mutate(
    percentuale_annunci_efficaci = percent_annunci_efficaci
  )

# Crea il grafico base
p <- ggplot(dati_immobiliari_texas, aes(x = listings, y = months_inventory_float)) +
  geom_point() +
  labs(title = "Relazione tra Numero di Annunci e Tempo di Vendita",
       x = "Numero di Annunci",
       y = "Tempo di Vendita (mesi)")

# Assicurati che `step` sia definito
step <- 1  # o un altro valore numerico appropriato

# Aggiungi scala continua all'asse Y
p <- p + scale_y_continuous(limits = c(min(months_inventory_float, na.rm = TRUE), max(months_inventory_float, na.rm = TRUE)), 
                            breaks = seq(min(months_inventory_float, na.rm = TRUE), max(months_inventory_float, na.rm = TRUE), by = step))

# evidenziazione punti di interesse
p <- p + 
  geom_point(data = data.frame(listings = c(1500, 3000), months_inventory_float = c(9, 13.5)),
             aes(x = listings, y = months_inventory_float),
             color = "red", size = 3) +
  # Annotazioni per spiegare i punti chiave
  annotate("text", x = 1500, y = 9, label = "9 mesi", vjust = -1) +
  annotate("text", x = 3000, y = 13.5, label = "13.5 mesi", vjust = -1)

# Visualizza il grafico
print(p)

Considerazioni sui risultati

7-8. Analisi Condizionata e grafici con ggplot2

Vendite mensili per città e anno

# Raggruppare i dati per città, anno e mese e sommare le vendite
vendite_per_mese <- dati_immobiliari_texas %>%
  group_by(city, year, month) %>%
  summarise(total_sales = sum(sales, na.rm = TRUE), .groups = "keep") %>%
  ungroup()
print(vendite_per_mese)
## # A tibble: 240 × 4
##    city      year month total_sales
##    <chr>    <int> <int>       <int>
##  1 Beaumont  2010     1          83
##  2 Beaumont  2010     2         108
##  3 Beaumont  2010     3         182
##  4 Beaumont  2010     4         200
##  5 Beaumont  2010     5         202
##  6 Beaumont  2010     6         189
##  7 Beaumont  2010     7         164
##  8 Beaumont  2010     8         174
##  9 Beaumont  2010     9         124
## 10 Beaumont  2010    10         150
## # ℹ 230 more rows
ggplot(data = vendite_per_mese, aes(x = month, y = total_sales, color = city, group = interaction(city, year))) +
  geom_line(lwd = 1) +
  geom_point(size = 2) +
  facet_wrap(~ year, ncol = 1, scales = "free_y") +
  labs(title = "Vendite Mensili per Città e Anno",
       x = "Mese",
       y = "Vendite Totali") +
  theme_minimal() +
  scale_x_continuous(breaks = 1:12, labels = month.abb) +
  scale_color_discrete(name = "Città")

Considerazioni

  • Peggior performance di vendite: Wichita Falls
  • Miglior performance di vendite: Tyler
  • Picco più alto: Il picco più alto di vendite è stato raggiunto dalla città di Tyler nel Giugno 2014

Vendite mensili con deviazione standard

# Identificare il mese con il massimo delle vendite per ciascun anno
mese_max_vendite <- vendite_per_mese %>%
  group_by(year) %>%
  filter(total_sales == max(total_sales)) %>%
  ungroup()

print(mese_max_vendite)
## # A tibble: 5 × 4
##   city                   year month total_sales
##   <chr>                 <int> <int>       <int>
## 1 Bryan-College Station  2013     7         402
## 2 Tyler                  2010     4         316
## 3 Tyler                  2011     6         313
## 4 Tyler                  2012     7         322
## 5 Tyler                  2014     6         423
# I mesi dove si è venduto di più negli anni risultano essere luglio e giugno nella città di tyler

### Il mese dove si è venduto di più negli anni
# Raggruppare i dati per mese e calcolare la media delle vendite
media_vendite_per_mese <- dati_immobiliari_texas %>%
  group_by(month) %>%
  summarise(media_vendite = mean(sales, na.rm = TRUE), 
            deviazione_standard = sd(sales, na.rm = TRUE)) %>%
  ungroup()

print(media_vendite_per_mese)
## # A tibble: 12 × 3
##    month media_vendite deviazione_standard
##    <int>         <dbl>               <dbl>
##  1     1          127.                43.4
##  2     2          141.                51.1
##  3     3          189.                59.2
##  4     4          212.                65.4
##  5     5          239.                83.1
##  6     6          244.                95.0
##  7     7          236.                96.3
##  8     8          231.                79.2
##  9     9          182.                72.5
## 10    10          180.                75.0
## 11    11          157.                55.5
## 12    12          169.                60.7
media_vendite_per_mese <- media_vendite_per_mese %>%
  mutate(Legenda = "Deviazione Standard")

ggplot(data = media_vendite_per_mese, aes(x = month, y = media_vendite)) + 
  geom_line(color = "blue", lwd = 1) + 
  geom_point(color = "blue", size = 2) + 
  geom_errorbar(
    aes(
      ymin = media_vendite - deviazione_standard, 
      ymax = media_vendite + deviazione_standard, 
      color = Legenda
    ),
    width = 0.2
  ) + 
  labs(
    title = "Media delle Vendite Mensili con Deviazione Standard", 
    x = "Mese", 
    y = "Media Vendite"
  ) + 
  theme_minimal() + 
  scale_x_continuous(breaks = 1:12, labels = month.abb) + 
  scale_color_manual(values = c("Deviazione Standard" = "gray")) +
  guides(color = guide_legend(
    override.aes = list(
      shape = NA,
      size = 3,
      linetype = 1,
      color = "gray",
      alpha = 1,
      linewidth = 2
    )
  )) +
  theme(legend.title = element_blank()) 

Considerazioni

  • In questo grafico, i baffi simili a quelli presenti nel boxplot, indicano il range della deviazione standard per ogni mese, avente come valore centrale(individuato dal punto blu) la media delle vendite per quel mese.
  • Da questo grafico si può comprendere che i mesi dove si è venduto di più sono stati i mesi tra maggio e agosto con picco a giugno

Media delle vendite per anno e città

# Identificare il mese con la media di vendite più alta
mese_max_media_vendite <- media_vendite_per_mese %>%
  filter(media_vendite == max(media_vendite))

print(mese_max_media_vendite)
## # A tibble: 1 × 4
##   month media_vendite deviazione_standard Legenda            
##   <int>         <dbl>               <dbl> <chr>              
## 1     6          244.                95.0 Deviazione Standard
# Calcolare la media delle vendite per città
media_vendite_citta <- dati_immobiliari_texas %>%
  group_by(city) %>%
  summarise(media_vendite = mean(sales, na.rm = TRUE), .groups = "keep") %>%
  ungroup()
print(media_vendite_citta)
## # A tibble: 4 × 2
##   city                  media_vendite
##   <chr>                         <dbl>
## 1 Beaumont                       177.
## 2 Bryan-College Station          206.
## 3 Tyler                          270.
## 4 Wichita Falls                  116.
media_vendite_citta_anno <- dati_immobiliari_texas %>%
  group_by(city, year) %>%
  summarise(media_vendite = mean(sales, na.rm = TRUE), .groups = "keep") %>%
  ungroup()

ggplot(data = media_vendite_citta_anno, aes(x = as.factor(year), y = media_vendite, fill = city)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(title = "Media delle Vendite per Anno e Città",
       x = "Anno",
       y = "Media Vendite",
       fill = "Città") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Considerazioni

  • Con questo grafico possiamo evidenziare il margine di crescita in media di vendite nelle varie città nel corso degli anni
  • La città di Tyler è cresciuta gradualmente ogni anno, attestandosi sempre come la migliore città per vendite, in media
  • La città di Beaumont dopo la decrescita dal 2010 al 2011 è cresciuta gradualmente dopo quest’ ultimo
  • La città di Bryan-College-Station è cresciuta gradualmente ogni anno
  • La città di Wichita Falls ha avuto un comportamento altalenante. Gli anni si sono alternati tra crescite e descrescita. L’anno peggiore è stato il 2011

Media pesata delle vendite

#Confrontare questo grafico con i valori non pesati
# grafico per comprendere quali città abbiano eseguito delle vendite con valore economico più alto negli anni. Quindi, pesando il numero di vendite totali con il prezzo mediano di ciascuna vendita
weighted_average_sales <- sum(sales * median_price) / sum(sales)
print(weighted_average_sales)
## [1] 138177.6
ggplot(dati_immobiliari_texas, aes(x = factor(year), y = sales, fill = city)) +
  geom_bar(stat = "identity", position = "dodge") +
  geom_hline(yintercept = weighted_average_sales, linetype="dashed", color = "red", linewidth=1) +
  ylim(0, max(sales) * 1.2) +
  labs(title = "Numero di Vendite per Città e Anno con Media Ponderata",
       x = "Anno",
       y = "Numero di Vendite") +
  theme_minimal()
## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_hline()`).

Considerazioni

  • Questo grafico contiene la media pesata delle vendite, dove i pesi sono rappresentati dal prezzo mediano. E’ stata utilizzata la media pesata poichè non solo è importante il numero di vendite ma è altrettanto importante, per determinare quale sia la città che realizza introiti migliori, il prezzo degli immobili
  • Possiamo notare dal grafico che la città di Bryan-College-Station ha avuto performance simili a quelle della città di Tyler, superandola nell’anno 2013, al contrario di quanto evidenziato dal grafico delle medie di numero di vendite
  • Si potrebbe considerare di investire maggiormente nella città di Bryan-College-Station poichè è una città con numero di vendite pesate al prezzo mediano degli immobili molto alta e negli ultimi due anni ha avuto un incremento sostanziale di quest’ultimo. ### Distribuzione del prezzo mediano per città
# Visualizzare la città con la media di vendite più alta
citta_top <- media_vendite_citta %>%
  filter(media_vendite == max(media_vendite))

print(citta_top)
## # A tibble: 1 × 2
##   city  media_vendite
##   <chr>         <dbl>
## 1 Tyler          270.
# La città che in media ha venduto di più negli anni è stata Tyler

# BoxPlot
ggplot(data = dati_immobiliari_texas, aes(x = city, y = median_price)) +
  geom_boxplot(fill = "lightblue") +
  labs(title = "Distribuzione del Prezzo Mediano per Città",
       x = "Città",
       y = "Prezzo Mediano") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Considerazioni

  • La città di Tyler non presenta nessun outlier, dunque si attesta come miglior città a livello di performance e stabilità dei prezzi delle case. Lo si può notare anche dalla mediana che è vicina alla media
  • La città di Wichita Falls si attesta come la peggiore

9. Conclusioni

IMPORTANTE: Le conclusioni le ho generate con profAI sulla base di tutte le considerazioni fatte da me nel corso del progetto. Dopodichè ho revisionato la sintesi e corretto inesattezze. Mi è sembrato corretto farvelo sapere :)

Potremmo riassumere l’analisi con le seguenti conclusioni

  1. Distribuzione delle Vendite e Asimmetria:
    • Le variabili sales, volume e listings presentano una distribuzione asimmetrica positiva, indicando che le modalità più basse sono quelle più frequenti.
    • La variabile median_price è asimmetrica negativa, con una prevalenza di modalità alte, suggerendo che i prezzi degli immobili sono generalmente più elevati.
    • L’indice di asimmetria per la variabile volume è il più alto, indicando che questa variabile è la più distante dalla normale, con una distribuzione positivamente asimmetrica.
  2. Variabilità:
    • La variabile con la maggiore variabilità è il volume, con una deviazione standard che è circa il 54% della media. Questo indica un’alta dispersione nei valori di volume, in confronto alle altre variabili.
    • Il coefficiente di variazione (CV) è stato utilizzato per misurare la variabilità, poiché non è influenzato dall’ordine di grandezza delle variabili. Per sales, volume e listings, il CV è relativamente alto, indicando una significativa variabilità nelle vendite e nel volume delle case.
  3. Indice di Gini:
    • L’Indice di Gini per le variabili city, year, e month suggerisce che c’è eterogeneità nelle vendite in termini di quantità e distribuzione geografica.
  4. Comportamento delle Città:
    • Le città mostrano andamenti diversi nel tempo: Tyler ha mostrato una crescita continua e costante nelle vendite, mentre Beaumont ha visto un periodo di declino prima di una ripresa, mentre Bryan-College-Station ha superato Tyler in termini di vendite pesate nel 2013.
    • Wichita Falls è risultata la città con le peggiori performance di vendite, con un andamento altalenante che non ha mostrato una crescita costante.
  5. Media Ponderata e Performance:
    • L’uso della media pesata delle vendite ha evidenziato che, sebbene Tyler fosse il leader in termini di numero di vendite, Bryan-College-Station ha avuto performance superiori in termini di introiti, suggerendo che questa città stia guadagnando sempre più attrattiva come potenziale investimento.
    • L’analisi delle medie ponderate indica che il prezzo mediano degli immobili è un fattore chiave nell’analisi delle performance, e che città come Bryan-College-Station potrebbero essere una scelta migliore per investimenti a lungo termine.
  6. Analisi dei Tempi di Vendita:
    • Un’analisi degli annunci pubblicati ha mostrato che maggiore è il numero di annunci pubblicati, più velocemente si vendono le case. Ad esempio, aumentando il numero di annunci da 1500 a 3000, il tempo di vendita si riduce di circa il 50%, con una percentuale di vendite media pari all’11%.
  7. Confronto tra Anni e Mesi:
    • I mesi da maggio a agosto sono stati i più favorevoli in termini di vendite, con un picco a giugno, mentre la distribuzione annuale delle vendite evidenzia un picco in estate (giugno 2014), in particolare per la città di Tyler.
    • L’analisi dei mesi ha rivelato che il numero di vendite si concentra principalmente nei mesi estivi.
  8. Considerazioni Finali:
  • Tyler è risultata la città con la migliore performance stabile nel lungo periodo, con vendite in aumento ogni anno. Tuttavia, Bryan-College-Station ha mostrato un forte incremento nelle vendite, suggerendo che potrebbe essere un luogo interessante per nuovi investimenti.
    • Le città con una distribuzione più equa delle vendite come Beaumont e Wichita Falls devono considerare l’importanza di bilanciare il numero di annunci con la strategia di vendita per migliorare ulteriormente le performance.
  • L’analisi delle probabilità di vendita, basata su città, anni e mesi, ha indicato una distribuzione equa di eventi, con città come Beaumont e Tyler aventi probabilità uguali di vendere rispetto alle altre città.

In sintesi, i dati evidenziano significative differenze tra le città del Texas in termini di performance di vendita, distribuzione temporale e variabilità dei valori di vendita. Tyler emerge come il leader stabile, mentre Bryan-College-Station sta guadagnando terreno, e Wichita Falls presenta la performance più debole.