Skip to content

Commit 7742674

Browse files
committed
pertamax
0 parents  commit 7742674

File tree

7 files changed

+193
-0
lines changed

7 files changed

+193
-0
lines changed

.gitignore

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
*.exe
2+
*.exe~
3+
*.dll
4+
*.so
5+
*.dylib
6+
7+
*.test
8+
9+
*.out
10+
11+
.DS_Store
12+
13+
/plot/scatter.png
14+
/plot/result.png

README..md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
## Overview
2+
3+
Simple Linear Regression implementation using Golang.
4+
Read my explanation here :
5+
6+
- en version :
7+
- id version :
8+
9+
## How to run
10+
11+
- Clone this repo
12+
- Make sure latest version of Golang is installed and setup properly
13+
- Run `go run main.go`

go.mod

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module go-linear-regression
2+
3+
go 1.14
4+
5+
require gonum.org/v1/plot v0.7.0

go.sum

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af h1:wVe6/Ea46ZMeNkQjjBW6xcqyQA/j5e0D6GytH95g0gQ=
2+
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
3+
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
4+
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
5+
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
6+
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
7+
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5 h1:PJr+ZMXIecYc1Ey2zucXdR73SMBtgjPgwa31099IMv0=
8+
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
9+
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
10+
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
11+
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81 h1:00VmoueYNlNz/aHIilyyQz/MHSqGoWJzpFv/HW8xpzI=
12+
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
13+
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
14+
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
15+
gonum.org/v1/plot v0.7.0 h1:Otpxyvra6Ie07ft50OX5BrCfS/BWEMvhsCUHwPEJmLI=
16+
gonum.org/v1/plot v0.7.0/go.mod h1:2wtU6YrrdQAhAF9+MTd5tOQjrov/zF70b1i99Npjvgo=
17+
rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4=
18+
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

linearregression/regression.go

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package linearregression
2+
3+
import (
4+
"fmt"
5+
"image/color"
6+
"log"
7+
"math"
8+
9+
"gonum.org/v1/plot"
10+
"gonum.org/v1/plot/plotter"
11+
"gonum.org/v1/plot/vg"
12+
)
13+
14+
// RegressionData for collecting some data that needed in linear regression calculation
15+
type RegressionData struct {
16+
XValues []float64
17+
YValues []float64
18+
Epoch int
19+
LearningRate float64
20+
slope float64
21+
intercept float64
22+
}
23+
24+
// New ...
25+
func New() *RegressionData {
26+
rd := &RegressionData{}
27+
return rd
28+
}
29+
30+
// PlotTheDataset will make the scatter plot based on x and y values
31+
func (d *RegressionData) PlotTheDataset() {
32+
d.plotMaker(false)
33+
}
34+
35+
// Calculate to calculate the linear regression
36+
func (d *RegressionData) Calculate(isWriteResultToPlot bool) (float64, float64) {
37+
if len(d.XValues) == 0 || len(d.YValues) == 0 {
38+
panic("x values and y values cannot be empty")
39+
}
40+
for i := 0; i < d.Epoch; i++ {
41+
d.slope, d.intercept = d.gradientDescent(d.slope, d.intercept)
42+
}
43+
//round float to 2 decimal
44+
d.slope = math.Round(d.slope*100) / 100
45+
d.intercept = math.Round(d.intercept*100) / 100
46+
if isWriteResultToPlot {
47+
d.plotMaker(true)
48+
}
49+
return d.slope, d.intercept
50+
}
51+
52+
func (d *RegressionData) gradientDescent(mCurrent float64, bCurrent float64) (finalM float64, finalB float64) {
53+
var mGradient float64
54+
var bGradient float64
55+
nData := len(d.XValues) //the x or y values length
56+
twoPerN := float64(2) / float64(nData)
57+
for i := 0; i < nData; i++ {
58+
mGradient += -twoPerN * d.XValues[i] * (d.YValues[i] - ((mCurrent * d.XValues[i]) + bCurrent))
59+
bGradient += -twoPerN * (d.YValues[i] - ((mCurrent * d.XValues[i]) + bCurrent))
60+
}
61+
finalM = mCurrent - (d.LearningRate * mGradient)
62+
finalB = bCurrent - (d.LearningRate * bGradient)
63+
return
64+
}
65+
66+
func (d *RegressionData) plotMaker(isWriteResultToPlot bool) {
67+
file := ""
68+
p, err := plot.New()
69+
if err != nil {
70+
panic(err)
71+
}
72+
p.Title.Text = "Linear Regression using Go"
73+
p.X.Min = 0
74+
p.X.Max = 6
75+
p.X.Label.Text = "X"
76+
p.Y.Min = 0
77+
p.Y.Max = 6
78+
p.Y.Label.Text = "Y"
79+
p.Add(plotter.NewGrid())
80+
81+
dataset := make(plotter.XYs, len(d.XValues))
82+
for i := range dataset {
83+
dataset[i].X = d.XValues[i]
84+
dataset[i].Y = d.YValues[i]
85+
}
86+
s, err := plotter.NewScatter(dataset)
87+
if err != nil {
88+
log.Panic(err)
89+
}
90+
s.GlyphStyle.Color = color.RGBA{R: 255, B: 128, A: 255}
91+
s.GlyphStyle.Radius = vg.Points(3)
92+
93+
if isWriteResultToPlot {
94+
lineData := make(plotter.XYs, 7)
95+
for i := 0; i < 7; i++ {
96+
x := float64(i)
97+
lineData[i].X = x
98+
lineData[i].Y = d.slope*x + d.intercept
99+
}
100+
l, err := plotter.NewLine(lineData)
101+
if err != nil {
102+
log.Panic(err)
103+
}
104+
l.LineStyle.Width = vg.Points(1)
105+
l.LineStyle.Color = color.RGBA{B: 255, A: 255}
106+
107+
p.Add(s, l)
108+
p.Legend.Add("dataset", s)
109+
110+
p.Legend.Add(fmt.Sprintf("y(x) = %.2fx + %.2f", d.slope, d.intercept), l)
111+
file = "plot/result.png"
112+
} else {
113+
p.Add(s)
114+
p.Legend.Add("dataset", s)
115+
file = "plot/scatter.png"
116+
}
117+
118+
err = p.Save(300, 300, file)
119+
if err != nil {
120+
log.Panic(err)
121+
}
122+
}

main.go

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"go-linear-regression/linearregression"
6+
)
7+
8+
func main() {
9+
xValues := []float64{1, 2, 3, 4, 5}
10+
yValues := []float64{1, 3, 2, 3, 5}
11+
lr := linearregression.New()
12+
lr.XValues = xValues
13+
lr.YValues = yValues
14+
lr.Epoch = 200
15+
lr.LearningRate = 0.05
16+
lr.PlotTheDataset()
17+
m, b := lr.Calculate(true)
18+
fmt.Println("m (slope) = ", m)
19+
fmt.Println("b (intercept) = ", b)
20+
fmt.Printf("so, the function is y(x) = %.2f x + %.2f", m, b)
21+
}

plot/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)