Move related works to chapter 2

This commit is contained in:
Raffaele Mignone 2021-06-14 19:49:45 +02:00
parent ef54268718
commit 11b18d668f
Signed by: norangebit
GPG Key ID: F5255658CB220573

View File

@ -1,110 +1,32 @@
# Collezione dei dati e analisi preliminare
# Stato dell'arte {#sec:related-works}
## Selezione dei progetti
In questo lavoro[@gonzalez2020statemluniverse10] sono stati studiati mediante tecniche di statistica descrittiva $9325$ progetti.
I progetti sono stati distinti tra sistemi di \ac{ML}, a loro volta suddivisi in framework ($700$ elementi) e applicazioni ($4524$ elementi), e sistemi generici ($4101$ elementi).
Gli aspetti considerati per l'analisi sono vari, si va dalla distribuzione dei contributi, a loro volta divisi tra interni ed esterni, fino all'analisi dei linguaggi più utilizzati, passando per un'analisi sulla popolarità dei vari repositories.
Inoltre vengono valutate anche le differenze per quanto riguarda le interazioni collaborative (discussioni, review, ecc.).
L'individuazione dei progetti da analizzare è avvenuta mediate l'ausilio dell'\ac{API} messa a disposizione da GitHub.
In particolare è stata eseguita una query per ottenere una lista di repository che fanno uso di librerie e framework di \ac{ML} come `TensorFlow`, `Pytorch` e `scikit-learn`.
In questo modo è stato possibile ottenere una lista di $26758$ repository che è stata successivamente filtrata per individuare solo i progetti d'interesse per il seguente studio.
In altri lavori[@han2020empiricalstudydependency] il focus è stato puntato sulla gestione delle dipendenze dei progetti di \acl{ML}.
In questo caso si va a valutare le eventuali differenze in base al framework utilizzato.
Le librerie considerate nello studio sono: `TensorFlow`, `PyTorch` e `Theano`.
Mentre eventuali differenze sono state ricercate rispetto agli obbiettivi del progetto (tutorial/libri, applicativi, ricerca), il dominio applicativo, la popolarità, la frequenza di aggiornamento delle dipendenze e i motivi degli aggiornamenti.
L'operazione di filtraggio è avvenuta attraverso due fasi; una prima automatica e una seconda manuale.
La prima fase ha avuto l'obiettivo di selezionare unicamente i repository *popolari*.
Nella maggior parte dei casi viene utilizzato il numero di stelle come indice della popolarità di un progetto [@borges2016understandingfactorsthat], ma per questo lavoro si è preferito dare maggiore rilevanza ad altri aspetti, come il numero di fork, il numero di *contributors* e il numero di issues chiuse.
Questa scelta è stata dettata dall'esigenza di selezionare non solo repository popolari, ma anche caratterizzati da una forte partecipazione della community.
In altri casi[@grichi2020impactmultilanguagedevelopment] ancora l'attenzione è stata rivolta alla natura *multi-linguaggio* tipica delle soluzioni di \acl{ML} e all'impatto che ciò ha sul sistema.
In questo caso sono stati considerati, tra progetti mono-linguaggio e multi-linguaggio, $27$ repository open source.
Per quanto riguarda l'analisi sono stati presi in considerazione la percentuale di pull request accettate, il tempo necessario per accettare una pull request e la propensione nell'introdurre i *bug* all'interno delle pull request.
I progetti che hanno superato questa prima selezione dovevano:
In letteratura sono presenti anche molti lavori che si concentrano sull'analisi delle problematiche e dei *bug* riscontrati all'interno di applicazioni di \acl{ML}.
In alcuni casi lo studio[@zhang2018empiricalstudytensorflow] è stato svolto in maniera specifica per una singola libreria.
Nello specifico sono state considerate $87$ domande postate su *StackOverflow* in relazione a bug di `TensorFlow` e $82$ commit, selezionati da $11$ progetti su *GitHub*.
Lo studio aveva l'obiettivo di individuare i sintomi e le cause scatenati di questi difetti e individuare le sfide per l'individuazione e la localizzazione di questi.
- essere lavori originali, per cui sono stati esclusi tutti i fork.
- avere almeno cento issues chiuse.
- avere almeno dieci contributors.
- avere almeno venticinque fork.
In altri casi[@humbatova-2019-taxonomyrealfaults] l'attenzione non è stata rivolta ad una libreria specifica, ma si è cercato di definire una tassonomia delle problematiche che fosse però generale per tutti i framework e le applicazioni di \ac{ML}.
Anche in questo caso i dati per lo studio sono stati recuperati sia da *GitHub* che da *StackOverflow*.
Altre volte ancora l'analisi[@liu2021exploratorystudyintroduction] è stata mirata su alcuni aspetti specifici come l'introduzione e la rimozione di \ac{SATD} all'interno di progetti che fanno uso di \ac{DL}.
Alla fine di questa prima selezione il numero di repository si è ridotto a sessantasei e sono stati analizzati manualmente per rimuovere listati associati a libri e/o tutorial, progetti non in lingua inglese e librerie.
Alla fine di questa seconda fase il numero di progetti è sceso a trenta.
Noi lavori precedentemente discussi l'analisi è stata svolta su dati recuperati dalla storia dei repositories e in alcuni casi recuperando informazioni aggiuntive da piattaforme di discussione online.
Altri lavori[@bangash2019whatdevelopersknow; @han2020whatprogrammersdiscuss; @alshangiti2019whydevelopingmachine] invece hanno analizzato unicamente le discussioni su *StackOverflow* per andare a capirne il contenuto.
Lo scopo di questi studi è quello di individuare le fasi più critiche del processo di sviluppo e capire quali sono gli argomenti che gli sviluppatori discutono più frequentemente.
## Fetch di issues e commit
Altri studi[@hassan2009predictingfaultsusing] ancora hanno traslando il concetto di entropia[@shannon1948mathematicaltheorycommunication] utilizzato nella teoria della comunicazione per andare a valutare la complessità del processo di cambiamento del software.
Andando, inoltre, ad evidenziare come la complessità del processo possa essere utilizzata per predire i *faults* all'interno dei prodotti software con risultati migliori rispetto alle metriche di complessità del software.
Una volta individuati i progetti da analizzare si è reso necessario recuperare l'intera storia dei progetti e le issues ad essi associate.
Per entrambe le operazioni è stato utilizzato il tool *perceval*[@duenas2018percevalsoftwareproject].
Nel caso delle issues, essendo queste informazioni non direttamente contenute all'interno del repository `git`, è stato necessario utilizzare nuovamente l'\ac{API} di GitHub.
Poiché le chiamate associate ad un singolo *token* sono limitate nel tempo si è scelto di configurare *perseval* in modo tale da introdurre in automatico uno ritardo ogni qualvolta veniva raggiunto il limite.
Inoltre il codice è stato dispiegato su un \ac{VPS} in modo da poter eseguire il fetch senza che fosse necessario mantenere attiva una macchina fisica.
Con il processo precedentemente illustrato è stato possibile recuperare:
- $34180$ commit.
- $15267$ tra issues e pull request.
## Classificazione dei dati
### Classificazione delle issues {#sec:classificazione-issues}
Al fine di poter eseguire un confronto tra i *fix* di \ac{ML} e quelli *generici* è stato necessario classificare sia le issues che i commit.
Per quanto riguarda i primi si è scelto di attuare una classificazione basata sul testo, in particolare considerando il titolo e il corpo della issue, ma escludendo i commenti di risposta in modo da non rendere i dati troppo rumorosi.
Il numero elevato di elementi non rende praticabile una classificazione manuale per cui si è optato per una classificazione automatica.
A tal fine sono stati implementati ed analizzati due classificatori, uno supervisionato e uno non supervisionato.
I due modelli considerati sono:
- un classificatore statico basato su una lista di vocaboli tipici del \ac{ML}.
- un modello *naïve Bayes* [@2021naivebayesclassifier; @harrington2012machinelearningaction].
La classificazione mediate il classificatore statico non necessita di un *labeling* manuale dei dati, ma richiede la definizione dei vocaboli tipici del \ac{ML}.
Lista dei termini caratteristici del \acl{ML} non è stata costruita da zero, ma è basata su lavori precedenti[@humbatova-2019-taxonomyrealfaults].
In questo modo tutte le issues che utilizzavano almeno un vocabolo tipico del \acl{ML} sono state classificate come issues di \ac{ML}.
Nel caso del modello *naïve Bayes*, essendo questo un algoritmo di apprendimento supervisionato, si è resa necessaria una classificazione manuale delle issues.
A tal scopo è stato eseguito un campionamento stratificato in base al progetto di provenienza di $376$ issues che sono state divise tra due lettori e labellate.
Durante il labeling si scelto di classificare ulteriormente le issue di \ac{ML} al fine di individuare anche la fase in cui il problema si è palesato.
La definizioni delle varie fasi è avvenuta partendo da un lavoro di *Microsoft*[@amershi-2019-softwareengineeringmachine].
Le fasi considerate sono:
- *Model Requirements*: questa fase comprende tutte le discussioni rispetto all'individuazione del modello più adatto, le funzionalità che questo deve esporre e come adattare un modello esistente per eseguire una diversa funzionalità.
- *Data Collection*: comprende le operazioni volte alla definizione di un dataset.
Rientrano in questa fase sia la ricerca di dataset già esistenti che la costruzione di nuovi dataset.
- *Data Labeling*: questa fase si rende necessaria ogni qual volta si opera con modelli basati su apprendimento supervisionato.
- *Data cleaning*: in questa fase non rientrano soltanto le operazioni strettamente di pulizia dei dati come ad esempio rimozione di record rumorosi o incompleti, ma tutte le trasformazioni eseguite sui dati, quindi anche operazioni di standardizzazione, flip di immagini ecc.
- *Feature Engineering*: questa fase serve per identificare le trasformazioni da attuare sui dati e le migliori configurazioni degli *hyperparametri* al fine di migliorare il modello.
- *Model Training*: questa fase racchiude il training vero e proprio del modello.
- *Model Evaluation*: in questa fase vengono valutate le performance del modello utilizzando metriche standard come *precision* e *recall*, ma anche andando a confrontare i risultati ottenuti rispetto a quelli generati da altri modelli o rispetto all'esperienza[^esperienza].
- *Model Deployment*: questa fase riguarda il dispiegamento del modello sul dispositivo target.
- *Model Monitoring*: una volta dispiegato il modello deve essere continuamente monitora al fini di assicurasi un corretto comportamento anche sui dati reali.
[^esperienza]: Non sempre è possibile valutare un modello in modo oggettivo, ci sono determinati contesti, come ad esempio la generazione di *deep fakes*, in cui è comunque necessaria una valutazione umana per determinare la qualità del risultato.
A partire dal dataset *labellato* è stato possibile costruire un training e un test set, mediante i quali è stato possibile allenare e valutare le performance del modello bayesiano.
Mentre le performance del primo modello sono state valutate sull'intero dataset.
\begin{figure}[!ht]
\subfloat[Numero di issues rispetto al tipo\label{fig:labeling-type}]{%
\includegraphics[width=0.45\textwidth]{src/figures/count-type.pdf}
}
\hfill
\subfloat[Numero di issues rispetto alla fase\label{fig:labeling-phases}]{%
\includegraphics[width=0.45\textwidth]{src/figures/count-phases.pdf}
}
\caption{Risultati della classificazione manuale delle issues}
\label{fig:labeling}
\end{figure}
Al fine di poter confrontare i due modelli sono state utilizzate le metriche di precision e recall.
Com'è possibile notare dai valori riportati in @tbl:confronto-modelli-classificazione-issues, il modello basato sulla lista di vocaboli è leggermente più preciso del modello bayesiano, ma presenta una recall decisamente più bassa.
Dalla @fig:labeling-type si evince la natura minoritaria delle issues di \ac{ML} rispetto alle issues generiche, per questo motivo si è scelto di preferire il modello naïve Bayes in modo da perdere quante meno istanze possibili anche a costo di sacrificare leggermente la precisione.
| | Classificatore statico | naïve Bayes |
|-----------|------------------------|-------------|
| precision | 0.46 | 0.41 |
| recall | 0.74 | 0.94 |
: Confronto dei due modelli per la classificazione delle issues. {#tbl:confronto-modelli-classificazione-issues}
### Classificazione dei commit {#sec:classificazione-commit}
Prima di poter classificare i commit si è reso necessaria un'ulteriore fase di filtraggio in modo da poter separare i commit di *issue fixing* da quelli generici.
Sono stati considerati come commit di *fix* tutti quei commit al cui interno veniva fatto riferimento a delle issues attraverso la notazione *"#"*.
Questa operazione ha ridotto il dataset dei commit a $3321$ unità la cui distribuzione in base al tipo è riportata in @fig:count-commit.
A questo punto è stato possibile separare i *fix* di \acl{ML} da quelli generici.
La classificazione è avvenuta attraverso la lista delle issues citate all'interno del *commit message* e sono stati considerati come commit di \ac{ML} tutti quei commit che facevano riferimento ad almeno una issue di \ac{ML}.
![Risultato della classificazione dei commit](figures/count-commit.pdf){#fig:count-commit}