Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/henomis/linear-regression-go
Linear Regression using tools and libraries in Go language
https://github.com/henomis/linear-regression-go
Last synced: 13 days ago
JSON representation
Linear Regression using tools and libraries in Go language
- Host: GitHub
- URL: https://github.com/henomis/linear-regression-go
- Owner: henomis
- License: mit
- Created: 2022-06-04T18:35:05.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2022-06-04T22:27:00.000Z (over 2 years ago)
- Last Synced: 2024-06-19T16:16:55.315Z (5 months ago)
- Language: Go
- Homepage:
- Size: 239 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Linear regression in Go
L'analisi dei **big data** e il parallelo sviluppo dell'**intelligenza artificiale** sono i protagonisti delle innovazioni tecnologiche di quest'ultimo decennio. Chi approccia lo studio della materia, tuttavia, avrà prima o poi a che fare con il linguaggio **Python** che, usato spesso in ambito accademico, rappresenta il punto riferimento grazie alla disponibilità di una serie di librerie, tool e veri e propri framework per la manipolazione dei dati.
Sebbene, in molti casi, l'uso di tali strumenti è inserito all'interno di procedure **batch** o **offline** , non possiamo escludere che alcuni servizi cloud possano necessitare di processi avanzati per la manipolazione dati **on demand**. In questo caso uno dei linguaggi più usati in ambito **backend** Cloud è **Go**.
Compito di questo articolo è la verifica e la validazione di strumenti e librerie **Go** in grado di essere al passo con i più famosi disponibili per **Python**. Come dataset di riferimento ho scelto la lista dei film americani con il relativo budget per la produzione e incasso totale ai botteghini.
## Data gathering
Il primo passo che andremo a considerare è la raccolta di dati. Recuperare un **dataset** in rete è abbastanza semplice, può essere scaricato attraverso una semplice GET http, o ad esempio recuperato grazie ad apposite API di fornitori terzi. I nostri dati, una volta in nostro possesso, dovranno essere inseriti all'interno di un contenitore chiamato **dataframe**. Nel mondo **Python** la libreria di riferimento è [Pandas](https://pandas.pydata.org), nel nostro caso useremo invece **[Gota](https://github.com/go-gota/gota)**.### pkg/dataminer
Ho sviluppato un package apposito per lo step di **data gathering** usando le funzionalità di `gota/dataframe`. Il metodo che verrà esposto è `GatherFromFile()`che si occuperà di creare un dataframe a partire da un file CSV usando esclusivamente le colonne di interesse per la manipolazione dati.```go
func (dm *DataMiner) GatherFromFile(
filename string,
) (*plottabledataframe.PlottableDataFrame, error) {csvFile, err := os.Open(filename)
if err != nil {
return nil, err
}dataFrame := dataframe.ReadCSV(csvFile).Select(
[]string{dm.xDataName, dm.yDataName},
)return plottabledataframe.NewDataFramePlottable(
dataFrame,
dm.xDataName,
dm.yDataName,
), nil}
```Il dato restituito sarà un wrapper al dataframe che ne estenderà le funzionalità per poter essere poi passato al plotter.
## Data cleaning
Il dato grezzo importato non sempre è pronto per l'analisi dei dati. Potrebbe,infatti, presentare **valori non ammessi**, includere **transienti da filtrare** o avere, semplicemente, un **formato non corretto**. Per questa fase sarà ancora utile il dataframe di `gota`.### pkg/datacleaner
In questo package è presente l'implementazione del metodo `Clean()` che provvederà ad applicare 3 filtri:* Un filtro che **rimuove caratteri di valuta e formattazione**. Questo step agisce attraverso il metodo `Capply()`che prende in input una funzione filtro da applicare iterativamente a tutte le colonne del dataframe. Internamente alla serie viene, poi, usato il metodo `Map()` che accetta un'ulteriore funzione che elabora iterativamente tutti gli elementi.
* Un filtro che **converte il tipo di dato**. Il metodo `Mutate()` provvede a sostituire entrambe le serie del dataframe applicando la conversione di tipo da `string` a `float64`.
* Un filtro per **rimuovere valori indesiderati**. In questo caso la funzione filtro rimuove i film che hanno avuto un incasso nullo perché, ad esempio, non sono mai usciti nelle sale cinematografiche.```go
func (dc *DataCleaner) Clean() {// remove $ symbol and useless ','
dc.dataFrame.DataFrame = dc.dataFrame.DataFrame.Capply(func(s series.Series) series.Series {
return s.Map(
func(e series.Element) series.Element {
elementAsString := strings.ReplaceAll(e.String(), "$", "")
elementAsString = strings.ReplaceAll(elementAsString, ",", "")
e.Set(elementAsString)return e
},
)
})// mutate series to float64 type
dc.dataFrame.DataFrame = dc.dataFrame.DataFrame.Mutate(
series.New(
dc.dataFrame.DataFrame.Col(dc.dataFrame.XColumnName).Float(),
series.Float,
dc.dataFrame.XColumnName,
),
)dc.dataFrame.DataFrame = dc.dataFrame.DataFrame.Mutate(
series.New(
dc.dataFrame.DataFrame.Col(dc.dataFrame.YColumnName).Float(),
series.Float,
dc.dataFrame.YColumnName,
),
)// remove movies without worldwide gross (value = $0)
dc.dataFrame.DataFrame = dc.dataFrame.DataFrame.Filter(
dataframe.F{
Colname: dc.dataFrame.YColumnName,
Comparator: series.Greater,
Comparando: 0,
},
)}
```## Data training
I dati sono ora pronti per il **training**. In questo caso sceglieremo una **regressione lineare** per poter graficare una funzione di interpolazione. Ancora una volta sostituiremo il tool [NumPy](https://numpy.org/) di Python con **[Gonum](https://www.gonum.org/)** libreria del linguaggio Go.### pkg/datatrainer
Questo package espone un metodo `LinearRegression` che lavorando sulle serie di dati dei passaggi precedenti restituisce due variabili `alpha` e `beta` coefficienti della funzione lineare di interpolazione.```go
func (dt *DataTrainer) LinearRegression() (alpha, beta float64) {
alpha, beta = stat.LinearRegression(
dt.xData,
dt.yData,
nil,
false,
)return
}
```## Data plotting
I dati elaborati possono essere infine graficati per esaminarne il risultato. In Python uno dei principali tool per graficare i dati è [Matplotlib](https://matplotlib.org), per il nostro esempio in Go, invece, useremo sempre **[Gonum](https://www.gonum.org/)** che include delle funzionalità per la generazione di grafici.### pkg/dataplotter
Il nostro intento è quello di salvare il grafico all'interno di una immagine PNG. Grazie al metodo esposto `PlotToFile()` viene impostato un grafico con uno **scatter** in rosso dei dati grezzi e la funzione di **regressione lineare** in blu.```go
func (dp *DataPlotter) PlotToFile(filename string) error {line := plotter.NewFunction(
func(x float64) float64 {
return dp.beta*x + dp.alpha
},
)
line.Color = color.RGBA{R: 0, G: 0, B: 255, A: 255}scatter, err := plotter.NewScatter(dp.dataFrame)
if err != nil {
return err
}
scatter.Color = color.RGBA{R: 255, G: 0, B: 0, A: 255}dp.plot.Add(scatter, line)
if err := dp.plot.Save(8*vg.Inch, 4*vg.Inch, filename); err != nil {
return err
}return nil
}
```## Mettiamo tutto insieme
Nella visualizzazione complessiva del file `main.go` è possibile vedere come il processo attraversi in maniera chiara ed ordinata le fasi di
* **Gathering**
* **Cleaning**
* **Training**
* **Plotting**```go
func main() {// GATHER DATA
dataminer := dataminer.New(
"production_budget_usd",
"worldwide_gross_usd",
)dataFrame, err := dataminer.GatherFromFile(
"cost_revenue_dirty.csv",
)
if err != nil {
log.Fatal("unable to gather data: ", err)
}// CLEAN DATA
dataCleaner := datacleaner.New(dataFrame)
dataCleaner.Clean()dataFrame.Dump()
// TRAIN DATA
dataTrainer := datatrainer.New(
dataFrame.X(),
dataFrame.Y(),
)alpha, beta := dataTrainer.LinearRegression()
fmt.Println("alpha =", alpha, " beta =", beta)// PLOT DATA
dataPlotter := dataplotter.New(
dataFrame,
alpha,
beta,
)
dataPlotter.SetTitles(
"Movies production budget and gross",
"Production budget",
"Worldwide gross",
)err = dataPlotter.PlotToFile("output.png")
if err != nil {
log.Fatal("unable to plot data: ", err)
}fmt.Println("plot saved successfully")
}
```L'esempio può essere eseguito in maniera interpretata "alla python" col comando
`go run ./cmd/`
oppure compilato col comando
`go build -o linear_regression ./cmd/`
## Grafico finale
![output graphic data](output.png)
## Conclusioni
Abbiamo dimostrato che, almeno per questo primo esempio di regressione lineare, anche in **Go** esistono gli strumenti adatti per la manipolazione dei dati, per l'elaborazione di funzioni di interpolazione e per la generazione di grafici. Tali strumenti ci permettono di implementare all'interno di servizi Cloud backend realizzati in linguaggio Go un vero e proprio sistema completo per la gestione dei dati **on demand**.Il codice completo dell'esempio mostrato è disponibile all'interno del repository Github [github.com/henomis/linear-regression.go](https://github.com/henomis/linear-regression-go)