-
Notifications
You must be signed in to change notification settings - Fork 0
/
elm.go
107 lines (92 loc) · 2.22 KB
/
elm.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package elm
import (
"math/rand"
"time"
"github.com/Yamashou/mpinverse"
"gonum.org/v1/gonum/mat"
)
// ELM is a learning model type
type ELM struct {
W mat.Dense
Beta mat.Dense
}
func (e *ELM) getWeightMatrix(X mat.Dense) mat.Dense {
var b mat.Dense
b.Mul(&e.W, X.T())
return mpinverse.NewMPInverse(SetSigmoid(b))
}
// Fit is a learning function, d: Learning data, hidNum: Hidden neurons
func (e *ELM) Fit(d *DataSet, hidNum int, seed int64) int64 {
var data mat.Dense
xArray := e.GetAddBiasArray(d)
if seed == 0 {
seed = time.Now().UnixNano()
}
rundArray := getRundomArray(hidNum, d.XSize+1, seed)
yArray := mat.NewDense(len(d.Y)/d.YSize, d.YSize, d.Y)
e.W = *rundArray
H := e.getWeightMatrix(*xArray)
data.Mul(H.T(), yArray)
e.Beta = data
return seed
}
//Score returns the accuracy of the model, d: Test data
func (e *ELM) Score(d *DataSet) float64 {
var data mat.Dense
testArray := e.GetAddBiasArray(d)
data.Mul(&e.W, testArray.T())
gData := SetSigmoid(data)
var result mat.Dense
result.Mul(gData.T(), &e.Beta)
return evaluationCheck(result, d.Y)
}
//GetAddBiasArray adds bias to data, d: data(learning, test, etc...)
func (e *ELM) GetAddBiasArray(d *DataSet) *mat.Dense {
dataSize := d.XSize
t := addBias(d.X, len(d.X)/dataSize, dataSize)
return mat.NewDense(len(t)/(dataSize+1), dataSize+1, t)
}
// GetResult returns the evaluation result on certain data, d: feature vector
func (e *ELM) GetResult(d []float64) int {
d = append(d, 1)
vec := mat.NewDense(1, len(d), d)
var hneuron mat.Dense
hneuron.Mul(&e.W, vec.T())
gData := SetSigmoid(hneuron)
var X mat.Dense
X.Mul(gData.T(), &e.Beta)
n, m := X.Caps()
for i := 0; i < n; i++ {
for j := 0; j < m; j++ {
if X.At(i, j) > 0 {
return j
}
}
}
return -1
}
func getRundomArray(n, m int, seed int64) *mat.Dense {
data := make([]float64, n*m)
floadRand := rand.New(rand.NewSource(seed))
for i := range data {
data[i] = floadRand.NormFloat64() / 10
}
return mat.NewDense(n, m, data)
}
func addBias(X []float64, n, m int) []float64 {
result := make([]float64, n*(m+1))
k := 0
count := 0
for _, v := range X {
result[k] = v
if count == (m - 1) {
result[k+1] = 1.0
k += 2
count = 0
continue
}
k++
count++
}
return result
}