# Load dataset
sem_path = r"0_Sem_2014"
sem1_path = r"1_Sem_2014.csv"
sem2_path = r"2_Sem_2014.csv"

if not os.path.isfile(sem_path):
    utils.join_dataframes(sem_path, sem1_path, sem2_path)
dataset = pd.read_pickle(sem_path)

dataset.describe()

dataset.shape

"""
Explanation: Sul sito http://dati.comune.roma.it/, nella sezione incidenti stradali, abbiamo scaricato due file, relativi agli incidenti nel primo e secondo semestre dell'anno 2014. I dati sono per lo più di tipo categorico, con poche colonne di tipo numerico. Di conseguenza, si è scelto di lavorare con dati totalmente categorici, creando delle categorie dove ci fossero dei valori numerici. Per iniziare, fondiamo i due dataset per avere una tabella che rappresenti l'intero anno. L'obiettivo è quello di predire il tipo di lesione causato da un incidente stradale, a scopo puramente dimostrativo. Tuttavia, si possono pensare a molteplici applicazioni: capire cosa separa gli incidenti gravi da quelli non, capire che tipo di incidenti potrebbero verificarsi sotto certe condizioni, ecc.
End of explanation
"""


# Assign correct values to columns
dataset = utils.assign_columns(dataset)
# Remove columns we don't need
dataset = utils.remove_columns(dataset)
# Fix broken values
dataset = utils.fix_columns(dataset)

dataset.describe()

dataset.shape

"""
Explanation: Come possiamo vedere, i dati sono formattati male e ci sono molti valori mancanti. Ad esempio, i campi a valore numerico sono tuti con la virgola; alcuni campi hanno molti valori mancanti, come il campo airbag o i campi relativi alle strade. Il campo "DecedutoDopo" ha pochi valori solo perchè funge da ausilio al campo "Deceduto". I campi "Progressivo", "TipoVeicolo", "StatoVeicolo", "Marca" e "Modello" hanno dei campi mancanti quando il record fa riferimento ad un pedone. I campi che presentano veramente dei valori mancanti sono "Sesso", "AnnoNascita" e "Traffico", per cui provvederemo a gestirli in modo opportuno.
Quello che faremo ora, è formattare le colonne in modo opportuno, rimuovere le colonne che non ci servono, e fixare la colonna "AnnoNascita". Infatti, da una prima ispezione visiva, risulta che alcuni record hanno come anno di nascita date superiori al 2014, il che è un assurdo. Per cui, rimuoveremo tali record dal dataset, rimuovendo anche i record corrispondenti allo stesso incidente, non potendoci fidare del modo in cui i dati sono stati inseriti.
End of explanation
"""


# Create new features using DataOraIncidente column
dataset = utils.expand_DataOraIncidente(dataset)

"""
Explanation: La colonna "DataOraIncidente" contiene tante informazioni, che possiamo sfruttare per avere una descrizione migliore dei dati, più ricca di informazione. Ad esempio, possiamo creare nuove colonne per il giorno, il mese e l'orario in cui l'incidente è avvenuto. Ancora meglio, possiamo creare nuove categorie; in questo caso, ci siamo concentrati solamente sulla fascia oraria (nel codice vengono anche trattati altri campi), e abbiamo creato 6 categorie.
End of explanation
"""


# Create new features using NUM columns
dataset = utils.expand_NUM(dataset)

"""
Explanation: Un'altra informazione che possiamo estrarre è la dimensione dell'incidente. Per calcolarla, abbiamo due modi: il primo è quello di utilizzare il campo "IDProtocollo", che è lo stesso per tutti i veicoli e pedoni facenti parte dello stesso incidente, mentre il secondo è quello di utilizzare le colonne relative al numero di feriti, illesi, deceduti e persone in prognosi riservata. Il secondo modo va chiaramente contro lo scopo dell'analisi, perchè il nostro obiettivo è predire il tipo di lesione, ma essendo più banale del primo da scrivere, abbiamo usato quello. Tuttavia, essendoci un modo "lecito" di ottenere la dimensione dell'incidente, possiamo ignorare questo aspetto.
End of explanation
"""


# Create new features using DecedutoDopo column
dataset = utils.expand_DecedutoDopo(dataset)

"""
Explanation: Utilizziamo ora la colonna "DecedutoDopo" per modificare il campo "TipoLesione": in particolare, consideriamo come decedute anche le persone morte non sul posto, ovvero in ospedale. Questa ci sembra una considerazione adatta, in quanto è più mirata a valutare la quantità di danni prodotta da un incidente piuttosto che condizioni fortuite che hanno permesso alla persona di non morire sul colpo, nonostante l'incidente fosse effettivamente brutto.
End of explanation
"""


# Adjust NaturaIncidente column
dataset = utils.adjust_NaturaIncidente(dataset)
#dataset['NaturaIncidente'].unique()
#dataset['NaturaIncidente'].value_counts()

"""
Explanation: La colonna "NaturaIncidente" ha 22 categorie, molte delle quali sono ridondanti o addirittura contengono pochi record per la categoria. Provvediamo perciò a mapparle in 8 categorie.
End of explanation
"""


# Adjust ParticolaritaStrade column
dataset = utils.adjust_ParticolaritaStrade(dataset)
#dataset['ParticolaritaStrade'].unique()
#dataset['ParticolaritaStrade'].value_counts()

"""
Explanation: La colonna "ParticolaritaStrade" ha 20 categorie, molte delle quali sono ridondanti o addirittura contengono pochi record per la categoria. Provvediamo perciò a mapparle in 7 categorie.
End of explanation
"""


# Adjust FondoStradale column
dataset = utils.adjust_FondoStradale(dataset)
#dataset['FondoStradale'].unique()
#dataset['FondoStradale'].value_counts()

"""
Explanation: La colonna "FondoStradale" ha 10 categorie, ma la maggior parte dei valori cadono solo in due di queste. Per questo motivo, abbiamo scelto di utilizzare solamente 3 categorie, accorpando tutte le altre.
End of explanation
"""


# Adjust Pavimentazione column
dataset = utils.adjust_Pavimentazione(dataset)
#dataset['Pavimentazione'].unique()
#dataset['Pavimentazione'].value_counts()

"""
Explanation: La colonna "Pavimentazione" ha 10 categorie, molte delle quali sono ridondanti o addirittura contengono pochi record per la categoria. Provvediamo perciò a mapparle in 3 categorie.
End of explanation
"""


# Adjust CondizioneAtmosferica column
dataset = utils.adjust_CondizioneAtmosferica(dataset)
#dataset['CondizioneAtmosferica'].unique()
#dataset['CondizioneAtmosferica'].value_counts()

"""
Explanation: La colonna "CondizioneAtmosferica" ha 8 categorie, molte delle quali sono ridondanti o addirittura contengono pochi record per la categoria. Provvediamo perciò a mapparle in 3 categorie.
End of explanation
"""


# Adjust Traffico column
dataset = utils.adjust_Traffico(dataset)
#dataset['Traffico'].unique()
#dataset['Traffico'].value_counts()

"""
Explanation: La colonna "Traffico" ha solo 3 categorie, ma presenta dei valori mancanti. Dato che la condizione di traffico regolare compare nella maggioranza dei record, scegliamo di rimpiazzare i valori mancanti utilizzando il valore più comune.
End of explanation
"""


# Adjust TipoVeicolo column
dataset = utils.adjust_TipoVeicolo(dataset)
#dataset['TipoVeicolo'].unique()
#dataset['TipoVeicolo'].value_counts()

"""
Explanation: La colonna "TipoVeicolo" ha 41 categorie, molte delle quali sono ridondanti o addirittura contengono pochi record per la categoria. Provvediamo perciò a mapparle in 14 categorie. 
Le categorie ottenute non sono poche, e potevano sicuramente essere ridotte, a patto di utilizzare una mappatura dei veicoli che tenesse conto del loro peso. E' molto probabile, infatti, che sia il peso del veicolo ad influire sul danno.
End of explanation
"""


# Adjust TipoPersona column
dataset = utils.adjust_TipoPersona(dataset)
#dataset['TipoPersona'].unique()
#dataset['TipoPersona'].value_counts()

"""
Explanation: La colonna "TipoPersona" ha 6 categorie, molte delle quali sono ridondanti. Provvediamo perciò a mapparle in 3 categorie.
End of explanation
"""


# Adjust AnnoNascita column
dataset = utils.adjust_AnnoNascita(dataset)
#dataset['AnnoNascita'].unique()
#dataset['AnnoNascita'].value_counts()

"""
Explanation: Il valore mancante della colonna "AnnoNascita" è stato eliminato nella fase iniziale di lavorazione del dataset. Procediamo ora a creare delle nuove categorie, che rappresentano le fascie di età. Alla fine di questa procedura, otteniamo 6 categorie.
End of explanation
"""


# Adjust Sesso column
dataset = utils.adjust_Sesso(dataset)
#dataset['Sesso'].unique()
#dataset['Sesso'].value_counts()

"""
Explanation: La colonna "Sesso" ha dei valori mancanti, che sono comunque pochi rispetto ai valori presenti. Per riempire i valori mancanti, si è scelto di campionare dalla distribuzione della colonna, il chè equivale a tirare una moneta dove le probabilità di testa e croce non sono 50/50 ma sono date dal numero di record già presenti.
End of explanation
"""


# Adjust TipoLesione column
dataset = utils.adjust_TipoLesione(dataset)
#dataset['TipoLesione'].unique()
#dataset['TipoLesione'].value_counts()

dataset.describe()

dataset.shape

"""
Explanation: La colonna "TipoLesione" ha 8 categorie, molte delle quali sono ridondanti. Provvediamo perciò a mapparle in 4 categorie.
End of explanation
"""


save_path = r"0_CarIncident_2014"
save_path_csv = r"0_CarIncident_2014.csv"
dataset.to_pickle(save_path)
dataset.to_csv(save_path_csv)

"""
Explanation: Per concludere, serializziamo il dataset e salviamolo anche in formato csv. Siamo ora pronti a passare alla parte di machine learning, dove cercheremo di predire il tipo di lesione che viene riportato dalle persone coinvolte in un incidente, utilizzando appunto la colonna "TipoLesione".
End of explanation
"""


