Prerequisiti :
Se non sai perchĆØ utilizzeremo python, clicca qui
Se non hai ancora installato Python, clicca qui
Se non sai come scaricare e gestire le librerie, clicca qui
Se non sai cosa sia un Dataset, clicca qui
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:
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.
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Ć .
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.
Creiamo il nostro modello:Utilizzando un algoritmo appropriato, addestriamo il modello sul set di dati specificato.
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.
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.
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.
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:
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)
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:
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:
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:
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_split
ā
X_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
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 mae
ā
X_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 model
ā
modelloLM = visualizza_Linear_Regression_Model(newdataset[['GrLivArea','SalePrice']],'SalePrice')
Output:
Coefficients:
[111.91917371]
Mean squared error: 2827781279.81
Coefficient of determination: 0.08
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.
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 !
Complimenti per la chiarezza espositiva che sembra persino rendere semplici i concetti che invece a mio giudizio... non lo sono... Gran bell'esempio applicativo!