Esempio pratico di Machine Learning con Python : Stimare / Prevedere il prezzo degli appartamenti

Aggiornato il: feb 11

Prerequisiti :


Stimare prezzo di una casa

Introduzione


Personalmente penso che i progetti sono il modo migliore per approfondire la conoscenza della scienza dei dati e delle applicazioni dell'intelligenza artificiale. Infatti, non solo i neofiti, ma anche i professionisti esperti di livello medio possono aggiornare il proprio curriculum con nuovi progetti interessanti. Dopotutto, non sono facili. Ci vuole molto tempo per creare un progetto che possa davvero mostrare la profondità e l'ampiezza delle tue conoscenze.

Spero che questo progetto ti aiuti ad acquisire le conoscenze necessarie e che il tuo curriculum venga inserito più rapidamente nella rosa dei candidati. Questo progetto mostra tutti i passaggi (da zero) effettuati per risolvere un problema di Machine Learning. Per la tua comprensione, ho preso un set di dati semplice ma impegnativo in cui puoi anche progettare le funzionalità a tua discrezione.

Questo progetto è più adatto a persone che hanno una conoscenza di base di Python.

Anche se sei assolutamente nuovo, provalo. E fai domande nei commenti qui sotto.




Processo di previsioni di machine learning


"Continua a tormentare i dati finché non iniziano a rivelare i loro segreti nascosti."


Fare previsioni utilizzando l'apprendimento automatico non significa solo acquisire i dati e fornirli agli algoritmi. L'algoritmo potrebbe emettere qualche previsione ma non è quello a cui stai mirando.

Il processo è il seguente:


  1. Capire il problema: prima di iniziare a lavorare sui dati, è necessario comprendere il problema che stiamo cercando di risolvere. Se conosci già la soluzione al problema di machine learning, pensa a quali fattori potrebbero svolgere un ruolo fondamentale nella risoluzione del problema e passa al terzo step. Se ancora devi elaborare una strategia o una risoluzione passa al secondo step.

  2. Facciamo qualche ipotesi: Questo è abbastanza importante, ma spesso viene dimenticato. In parole semplici, la generazione di ipotesi si riferisce alla creazione di un insieme di caratteristiche che potrebbero influenzare la variabile obiettivo/target. Possiamo farlo prima di esaminare i dati per evitare pensieri o conclusioni affrettate. Questo passaggio spesso aiuta a creare nuove funzionalità.

  3. Iniziamo a lavorare sui dati: ora, scarichiamo i dati e li esaminiamo. Determina quali funzionalità (possibili standardizazioni o normalizazioni ad esempio) dei dati sono disponibili e quali no. Rispondere a queste domande ci metterà sulla strada giusta.

  4. Creiamo il nostro modello:Utilizzando un algoritmo appropriato, addestriamo il modello sul set di dati specificato.

  5. Valutazione del modello: una volta addestrato il modello, valutiamo le prestazioni del modello utilizzando una metrica di errore adeguata. Qui, cerchiamo anche l'importanza della variabile, cioè quali variabili si sono dimostrate significative nel determinare la variabile di destinazione. Di conseguenza, possiamo selezionare le migliori variabili e addestrare nuovamente il modello.

  6. Testiamo il nostro modello: Infine, testiamo il modello sul set di dati invisibili (dati di test). Seguiremo questo processo nel progetto per arrivare alle nostre previsioni finali. Iniziamo.

  7. Scarica Gratis il progetto




1) Capire il problema

Il set di dati per questo progetto è stato preso dal set di appartamenti di Kaggle. Come accennato in precedenza, il set di dati è semplice. Questo progetto mira a prevedere i prezzi delle case (residenziali) ad Ames, USA. In questo caso il nostro problema è andare a creare un modello in grado di predire il prezzo di questi appartamenti in base alle caratteristiche che abbiamo.


2) Facciamo qualche ipotesi

Bene, ora arriva la parte divertente.

Quali fattori riesci a pensare in questo momento che possono influenzare i prezzi delle case? Mentre leggi questo, voglio che tu annoti anche i tuoi fattori.

La definizione di un'ipotesi ha due parti: ipotesi nulla (0) e ipotesi concreta (1). Possono essere intese come:

0 - Non esiste alcun impatto di una particolare caratteristica sulla variabile dipendente.

1 - Esiste un impatto diretto di una caratteristica particolare sulla variabile dipendente.

Sulla base di un criterio decisionale (diciamo, livello di significatività del 5%) definiamo due classi :

  • "Rifiuto"

  • "Accetto"

In pratica, durante la creazione del modello cerchiamo valori di probabilità (p). Se il valore p<0.05, Rifiuto e quindi si avvera l'ipotesi nulla. Se p> 0.05 ci troviamo nel caso di ipotesi concreta e quindi quella caratteristica la Accettiamo perchè ha una correlazione con il nostro target. Alcuni fattori a cui posso pensare che influenzano direttamente i prezzi delle case sono i seguenti:

  • Area della casa

  • Quanti anni ha la casa

  • Posizione della casa

  • Quanto è vicino / lontano il mercato

  • Connettività della posizione della casa con i trasporti

  • Quanti piani ha la casa

  • Quale materiale viene utilizzato nella costruzione

  • Disponibilità di acqua / elettricità

  • Area giochi / parchi per bambini (se presenti)

  • Se la terrazza è disponibile

  • Se il parcheggio è disponibile

  • Se la sicurezza è disponibile

…continua a pensare. Sono sicuro che puoi inventarne molti altri oltre a questi.




3) Iniziamo a lavorare sui dati

Puoi scaricare i dati e caricarli nel tuo IDE python.


Test.csv Train.csv


Il set di dati è costituito da 81 variabili esplicative. Sì, non sarà una passeggiata per chì vorrà approfondire fino in fondo tutto il Dataset. Ma impareremo come gestire così tante variabili. La variabile di destinazione è SalePrice.

Iniziamo a scrivere un po di codice e a divertiamoci.



#Importiamo le librerie necessarie
import numpy as np 
import pandas as pd
import seaborn as sns
from scipy import stats
from scipy.stats import norm
import matplotlib.pyplot as plt#Impostiamo la grandezza del grafico di matplotlib
%matplotlib inline
plt.rcParams['figure.figsize'] = (10.0, 8.0)

#Carichiamo i dati che hai scaricato dal link
train = pd.read_csv("train.csv")
test = pd.read_csv("test.csv")

#Stampiamo quante righe e colonne ha il nostro dataset
print ('Train contiene {0} righe e {1} colonne'.format(train.shape[0],train.shape[1]))
print ('----------------------------')
print ('Test contiene {0} righe e {1} colonne'.format(test.shape[0],test.shape[1]))

output :
Train contiene 1460 righe e 81 colonne
 ---------------------------- 
Test contiene 1459 righe e 80 colonne

In alternativa, puoi anche controllare le informazioni sul set di dati utilizzando il comando info ().


train.info()

output :
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1460 entries, 0 to 1459
Data columns (total 81 columns):
 #   Column         Non-Null Count  Dtype  
---  ------         --------------  -----  
 0   Id             1460 non-null   int64  
 1   MSSubClass     1460 non-null   int64  
 2   MSZoning       1460 non-null   object 
 3   LotFrontage    1201 non-null   float64
.....
 77  YrSold         1460 non-null   int64
 78  SaleType       1460 non-null   object   
 79  SaleCondition  1460 non-null   object   
 80  SalePrice      1460 non-null   int64   
 dtypes: float64(3), int64(35), object(43) 
 memory usage: 924.0+ KB 

Controlliamo se il set di dati ha valori mancanti. Questo è molto importante perchè in alcuni casi questi dati vengono completamente ignorati o scartati. In questo caso noi ci concentreremo solo sulle variabile numeriche e non nulle.


train.columns[train.isnull().any()]

Output:
Index(['LotFrontage', 'Alley', 'MasVnrType', 'MasVnrArea', 'BsmtQual',        'BsmtCond', 'BsmtExposure', 'BsmtFinType1', 'BsmtFinType2',        'Electrical', 'FireplaceQu', 'GarageType', 'GarageYrBlt',        'GarageFinish', 'GarageQual', 'GarageCond', 'PoolQC', 'Fence',        'MiscFeature'],       dtype='object')

Procediamo e controlliamo la distribuzione della variabile target.

#Distribuzione della variabile target
sns.distplot(train['SalePrice'])

Output:

sns.distplot(train['SalePrice'])

Vediamo che la variabile target SalePrice ha una distribuzione asimmetrica a destra. Avremo bisogno di registrare la trasformazione di questa variabile in modo che diventi normalmente distribuita. Una variabile target normalmente distribuita (o vicina al normale) aiuta a modellare meglio la relazione tra le variabili target e indipendenti. Inoltre, gli algoritmi lineari assumono una varianza costante nel termine di errore. In alternativa, possiamo anche confermare questo comportamento distorto utilizzando la metrica di asimmetria.

#skewness
print "Il skewness del prezzo è {}".format(train['SalePrice'].skew())

Output:
The skewness of SalePrice is 1.88287575977

Registriamo la trasformazione di questa variabile e vediamo se la distribuzione di questa variabile può avvicinarsi alla normalità.

#Trasformiamo la variabile di target
target = np.log(train['SalePrice'])
print('Skewness è', target.skew())
sns.distplot(target)

Output:
Skewness is 0.12133506220520406)

Che trasformazione

Come hai visto, la trasformazione logaritmica della variabile target ci ha aiutato a correggere la sua distribuzione asimmetrica e la nuova distribuzione sembra più vicina alla normalità. Dato che abbiamo 80 variabili, visualizzarne una per una non sarebbe un approccio astuto. Invece, siccome lo studio risulterebbe molto lungo e complesso ci dedicheremo solo alle variabile numeriche tralasciando le categoriche.

#Separiamo il dataset in altri 2 numerico e categorico
numeric_data = train.select_dtypes(include=[np.number])
cat_data = train.select_dtypes(exclude=[np.number])
print ("ci sono {} colonne numeriche e {} categoriche".format(numeric_data.shape[1],cat_data.shape[1]))

Output:
Ci sono 38 colonne numeriche e 43 categoriche. 

Dovremmo rimuovere la variabile Id dai dati numerici.

del numeric_data['Id']

Ora, siamo interessati a conoscere il comportamento di correlazione delle variabili numeriche. Su 38 variabili, presumo che alcune debbano essere correlate. Se trovate, possiamo successivamente rimuovere le variabili non correlate poiché non forniranno alcuna informazione utile al modello.

#correlation plot
corr = numeric_data.corr()
sns.heatmap(corr)

Notare l'ultima riga di questa mappa. Possiamo vedere la correlazione di tutte le variabili con SalePrice. Come puoi vedere, alcune variabili sembrano essere fortemente correlate con la variabile target. Qui, un punteggio di correlazione numerica ci aiuterà a capire meglio il grafico.

print (corr['SalePrice'].sort_values(ascending=False)[:15], '\n') #top 15 variabili correlate
print ('----------------------')
print (corr['SalePrice'].sort_values(ascending=False)[-5:]) 
#last 5 variabili non correlate 

Output:
SalePrice        1.000000
OverallQual        0.790982
GrLivArea        0.708624
GarageCars        0.640409
GarageArea      0.623431
TotalBsmtSF     0.6135811
stFlrSF        0.605852
FullBath        0.560664
TotRmsAbvGrd    0.533723
YearBuilt       0.522897
YearRemodAdd    0.507101
GarageYrBlt     0.486362
MasVnrArea      0.477493
Fireplaces      0.466929
BsmtFinSF1      0.386420
Name: SalePrice, dtype: float64

Qui vediamo che la OverallQual caratteristica è correlata al 79% con la variabile target. Overallqual variabile si riferisce al materiale complessivo e alla qualità dei materiali della casa completata. Bene, anche questo ha senso. Le persone di solito considerano questi parametri per la loro casa dei sogni. Inoltre, GrLivArea è correlato al 70% con la variabile target. GrLivAreasi riferisce alla zona giorno (in sq ft.). Le seguenti variabili mostrano che le persone si preoccupano anche se la casa ha un garage, l'area di quel garage, le dimensioni dell'area seminterrato, ecc.

Tracciamo dei grafici qualitativi per vedere meglio che tipo di correlazioni hanno OverallQual e GrLivAreasi con il nostro target.

Per quanto riguarda la variabile OverallQual procederemo dividendola in classi per poi rappresentarla in funzione del prezzo crescente per vedere cosa accade al prezzo con l'aumentare della qualità dei materiali. Il codice è il seguente

train['OverallQual'].unique()

Output:
array([ 7,  6,  8,  5,  9,  4, 10,  3,  1,  2])


#grafichiamo le 10 classi di OverallQual in corrispondenza del prezzo
pivot = train.pivot_table(index='OverallQual', values='SalePrice', aggfunc=np.median)
pivot.plot(kind='bar', color='red')

Outptu:
Grafico che indica l'aumento del prezzo in funzione dei diversi materiali della casa

Questo comportamento è abbastanza normale. Man mano che la qualità complessiva di una casa aumenta, aumenta anche il suo prezzo di vendita. Visualizziamo la successiva variabile correlata GrLivAreae comprendiamo il loro comportamento.

#GrLivArea
sns.jointplot(x=train['GrLivArea'], y=train['SalePrice'])

Outptu:

Ti suggerisce qualcosa?

Come visto sopra, anche qui vediamo una correlazione diretta della zona giorno con il prezzo di vendita. Tuttavia, possiamo individuare un valore anomalo GrLivArea> 5000. Ho visto valori anomali giocare un ruolo significativo nel rovinare le prestazioni di un modello. Quindi, ce ne sbarazzeremo. Se ti piace questa attività, puoi visualizzare anche altre variabili correlate. Arrivati a questo punto bisognerebbe applicare i ragionamenti fatti per le variabili GrLivAreae e OverallQual per tutte le variabili che abbiamo a disposizione. Essendo questo un articolo di tutorial ci fermeremo a queste due variabili per l'analisi dell'esempio pratico di machine learning per non risultare troppo complesso o pesante per chi è alle prime armi. Ti invito comunque a giocare con le altre variabili e a creare un modello migliore di quello che creeremo all'interno dell'articolo.

Ora elaboriamo le nostre variabili per avere un modello performante.

#rimuoviamo i valori anomali
train.drop(train[train['GrLivArea'] > 4000].index, inplace=True)
train.shape #removed 4 rows`

Output:
(1456, 81)

A questo punto ricreiamo i nostri dataset utilizzando solo le variabili che abbiamo scelto.

Nel nostro caso saranno solo due. Ma ti invito a trovarne altre per rendere il tutto più divertente.


#ridivido le x e y di allenamento e test
newdataset = train[['GrLivArea','OverallQual','SalePrice']]X_train = train[['GrLivArea','OverallQual']]
y_train = train['SalePrice']
​
​
X_test = train[['GrLivArea','OverallQual']]
y_test = train['SalePrice']

Creiamo adesso un Pairplot e la Heatmap per avere una visione più completa delle correlazioni.

sns.pairplot(newdataset)
plt.show()

Output:

Pairplot

Heatmap

4) Creiamo il nostro modello

Ora che abbiamo un idea più concreta del nostro problema, delle ipotesi e che abbiamo lavorato il dato possiamo concentrarci nella creazione del nostro modello.

In questo caso utilizzeremo due modelli diversi.

Utilizzeremo prima il Random_Forest_Regression_Model e successivamente il Linear_Regression_Model così da poter successivamente confrontare i due modelli.

Ho scritto questi due modelli come delle funzioni in modo tale che potrai riutilizzarli con i tuoi dati passandogli solamente il dataset e il target.

Vediamo adesso il Random_Forest_Regression_Model:


def Random_Forest_Regression_Model(dataset,target):
 X = dataset.loc[:, dataset.columns != target]
 y = dataset[target]from sklearn.ensemble import RandomForestRegressor
 from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
 model = RandomForestRegressor(random_state=1)
 model.fit(X_train, y_train)
 pred = model.predict(X_test)# Visualizing Feature Importance
 feat_importances = pd.Series(model.feature_importances_, index=X.columns)
 feat_importances.nlargest(25).plot(kind='barh',figsize=(10,10))
 plt.show()
 
 y_pred = model.predict(X)
 labels = dataset[target]
 df_temp = pd.DataFrame({'Previsto': labels, 'Predetto':y_pred})
 df_temp.head()# Creating Line Graph
 
 from matplotlib.pyplot import figure
 
 figure(num=None, figsize=(15, 6), dpi=80, facecolor='w', edgecolor='k')
 y1 = df_temp['Previsto']
 y2 = df_temp['Predetto']
 plt.plot(y1, label = 'Previsto')
 plt.plot(y2, label = 'Predetto')
 plt.legend()
 plt.show()
from sklearn.metrics import mean_absolute_error as mae	    print(f'Errore Medio Assoluto ( MAE ) : {mae(y,y_pred)}')
from sklearn.metrics import mean_squared_error, r2_score
# Mean Error
print('Mean squared error: %.2f' % mean_squared_error(y_pred, y))
# Se il coefficente di determinazione è 1 il modello è perfetto
print('Coefficient of determination: %.2f' % r2_score(y_pred, y))
return model
​
modelloRfM = Random_Forest_Regression_Model(newdataset,'SalePrice')

Output:
Errore Medio Assoluto ( MAE ) : 16674.011430222203
Mean squared error: 639043357.06
Coefficient of determination: 0.88


Correlazioni Random Forest Model

Grafico Predetto Vs Previsto

Passiamo ora alla regressione lineare. In realtà non andrai ad usare più modelli solitamente ma in questo caso ne vedremmo due per poi paragonarli e capire quali sono gli indicatori che ci aiutano a capire quale sia il migliore.

Volendo in questo caso avere un modello performante ed un modello non performante effettueremo lo regressione utilizzando solo GrLivArea e il target SalePrice.

Scriviamo il codice ed eseguiamolo

def visualizza_Linear_Regression_Model(dataset, target):
 X = dataset.loc[:, dataset.columns != target]
 y = dataset[target]from sklearn.linear_model import LinearRegression
 from sklearn.model_selection import train_test_split
 from sklearn.metrics import mean_absolute_error as maeX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
 model = LinearRegression()
 model.fit(X_train, y_train)
 y_pred = model.predict(X)from matplotlib.pyplot import figure# Plot outputs
 plt.scatter(X, y, color='black')
 plt.plot(X, y_pred, color='blue', linewidth=3)
 plt.xticks(())
 plt.yticks(())
 plt.show()
 
 from sklearn.metrics import mean_squared_error, r2_score# Stampiamo il coefficente
 print('Coefficients: \n', model.coef_)
 # Mean Error
 print('Mean squared error: %.2f' % mean_squared_error(y_pred, y))
 # Se il coefficente di determinazione è 1 il modello è perfetto
 print('Coefficient of determination: %.2f' % r2_score(y_pred, y))return modelmodelloLM = visualizza_Linear_Regression_Model(newdataset[['GrLivArea','SalePrice']],'SalePrice')


Output:
Coefficients: 
 [111.91917371]
Mean squared error: 2827781279.81
Coefficient of determination: 0.08

Regressione Lineare

5) Valutiamo i Modelli

Arrivati a questo punto, dove esserci divertiti a scrivere codice e a rubare ai dati informazioni nascoste, arriva un momento molto importante:

"Dobbiamo capire quanto il nostro modello è affidabile"

Riportiamo qui sotto i dati che abbiamo calcolato.


Come ci salta subito all'occhio il Random Forest Model è il modello più affidabile. Proprio come volevamo.

Solitamente quando si valuta un modello esistono diversi tipi di metriche che è possibile utilizzare. Io solitamente consiglio di utilizzare sempre questi tre campi, perche secondo un mio parere ci danno una visione generale sulle capacità del modello.



6) Testiamo il modello

Questo passaggio è fondamentale su vuoi capire a pieno quali sono i punti di "certezza" e "incertezza" del modello che hai creato. Nel nostro caso sarebbe inutile andare ad effettuare delle previsioni con i modelli che abbiamo creato, poichè, anche se "sembra" affidabile all'88% il nostro modello è stato allenato su un set molto ristretto di caratteristche e quindi non rispecchia nemmeno vagamente la realtà degli appartamenti Americani.

Arrivati a questo punto il Tutorial è terminato. Ti consiglio di non fermarti qui ma di espandere il progetto fino a dove riesci, utilizzando tutte le variabile che ritieni fondamentali per stimare il prezzo di questi appartamenti. Per qualsiasi Problema o Errore Scrivilo qui nei commenti oppure fai una domanda nel forum. Il nostro Team di Esperti di AI è pronto ad aiutarti.


Scarica Gratuitamente tutto il Progetto


Per scaricare gratuitamente devi prima registrati/accede al portale.

Scorri in fondo alla pagina per registrati o accedere


Sostienici condividendo e commentando l'articolo, Grazie !




3,165 visualizzazioni1 commento

Post recenti

Mostra tutti

VUOI SCRIVERE ARTICOLI PER NOI.

Se vuoi scrivere articoli sul mondo dell' AI ed avere la tua visibilità, contattaci adesso.
Grazie per l'interesse dimostrato.

VUOI DIVENTARE UN MEMBRO UFFICIALE DELLA NOSTRA COMMUNITY E TRARNE I SEGUENTI BENEFICI?

Forum

Accedi al forum e fai domande o crea discussioni con esperti del settore. Potrai anche fare proposte di lavoro, condividere i tuoi progetti ed altro

Sfide

Accedi a diverse e diverti sfide sulla programmazione e intelligenza artificiale. Appena completerai la sfida riverai la certificazione

Download

Potrai scaricare in modo gratuito tutti i file dei vari progetti nel portale. Ogni progetto è disponibile in formato PDF, PYTHON, NOTEBOOK

E molto altro

Appena ti sarai registrato ti arriverà un e-book in regalo e in futuro ne riceverai altri...

In oltre potresti ricevere sconti o buoni

Se ti piacciono i benefici, i regali e vuoi essere aggiornato quando escono nuovi articoli, progetti o news premi il tasto qui sotto e registrati/accedi con Google, Facebook o con la tua email

Se invece preferisci solo sapere quando esce un nuovo articolo Senza ricevere i privilegi nel portale sopra descritti iscriviti qui sotto alla news letter

Rimani aggiornato, tranquillo anche noi odiamo lo SPAM

Segui i nostri canali social

Segui i nostri canali social 

  • YouTube Icona sociale

Youtube

  • Instagram

Instagram

  • Spotify Icona sociale

Spotify

  • White Facebook Icon

Facebook

  • Twitter Icon sociale

Twitter

©2020 Intelligenza Artificiale Italia

  • Instagram
  • Facebook Icona sociale
  • Youtube