diff --git a/regr/src/LogisticRegression.go b/regr/src/LogisticRegression.go index c727192..dc34157 100644 --- a/regr/src/LogisticRegression.go +++ b/regr/src/LogisticRegression.go @@ -34,7 +34,7 @@ func (regr *LogisticRegression) Loss(yTrue, yPred mat.Matrix) float64 { sum := &mat.Dense{} sum.Add(y1, y2) w, h := yTrue.Dims() - return mat.Sum(sum) / float64(w*h) + return -(mat.Sum(sum) / float64(w*h)) } func (regr *LogisticRegression) forward(X mat.Matrix) mat.Matrix { @@ -76,8 +76,8 @@ func (regr *LogisticRegression) backprop(x, y mat.Matrix) float64 { return loss } -func (regr *LogisticRegression) Fit(X, Y mat.Matrix, epochs int, losses *[]float64) { - for i := 0; i < epochs; i++ { +func (regr *LogisticRegression) Fit(X, Y mat.Matrix, losses *[]float64) { + for i := 0; i < regr.Epochs; i++ { regr.backprop(X, Y) if losses != nil { *losses = append(*losses, regr.Loss(Y, regr.forward(X))) diff --git a/regr/src/LogisticRegression_test.go b/regr/src/LogisticRegression_test.go index 1e957bc..b449c3a 100644 --- a/regr/src/LogisticRegression_test.go +++ b/regr/src/LogisticRegression_test.go @@ -6,16 +6,55 @@ import ( ) func TestLogisticRegression(t *testing.T) { - X := [][]float64{{.1, .1, .1}, {.2, .2, .2}, {.1, .1, .1}, {.2, .2, .2}} - Y := [][]float64{{0}, {1}, {0}, {1}} + X := [][]float64{ + {.1, .1, .1}, + {.2, .2, .2}, + {.1, .1, .1}, + {.2, .2, .2}, + } + //Y := [][]float64{{1}, {0}, {1}, {0}} + Y := [][]float64{ + {0}, + {1}, + {0}, + {1}, + } XDense := Array2DToDense(X) YDense := Array2DToDense(Y) epochs := 1000 regr := &LogisticRegression{ - LearningRate: .1, + Epochs: epochs, + LearningRate: .01, } - regr.Fit(XDense, YDense, epochs, nil) + regr.Fit(XDense, YDense, nil) fmt.Println(regr.Weights, regr.Bias) yPred := regr.Predict(XDense) fmt.Println(YDense, yPred, regr.Loss(YDense, yPred)) } + +func TestMCLogisticRegression(t *testing.T) { + X := [][]float64{ + {.1, .1, .1}, + {.2, .2, .2}, + {.1, .1, .1}, + {.2, .2, .2}, + } + //Y := [][]float64{{1}, {0}, {1}, {0}} + Y := [][]float64{ + {0, 1}, + {1, 0}, + {0, 1}, + {1, 0}, + } + XDense := Array2DToDense(X) + YDense := Array2DToDense(Y) + epochs := 1000 + regr := &MCLogisticRegression{ + Epochs: epochs, + LearningRate: .01, + } + regr.Fit(XDense, YDense) + // fmt.Println(regr.Weights, regr.Bias) + yPred := regr.Predict(XDense) + fmt.Println(YDense, yPred) //, regr.Loss(YDense, yPred)) +} diff --git a/regr/src/MCLogisticRegression.go b/regr/src/MCLogisticRegression.go new file mode 100644 index 0000000..39db3f7 --- /dev/null +++ b/regr/src/MCLogisticRegression.go @@ -0,0 +1,44 @@ +package src + +import ( + "sync" + + "gonum.org/v1/gonum/mat" +) + +type MCLogisticRegression struct { + Epochs int + LearningRate float64 + Models []*LogisticRegression + cols int + rows int +} + +func (regr *MCLogisticRegression) Fit(x, y mat.Matrix) { + regr.rows, regr.cols = y.Dims() + regr.Models = make([]*LogisticRegression, regr.cols) + for j := 0; j < regr.cols; j++ { + regr.Models[j] = &LogisticRegression{ + Epochs: regr.Epochs, + LearningRate: regr.LearningRate, + } + yj := mat.Col(nil, j, y) + Y := mat.NewDense(len(yj), 1, yj) + regr.Models[j].Fit(x, Y, nil) + } +} + +func (regr *MCLogisticRegression) Predict(x mat.Matrix) mat.Matrix { + probs := mat.NewDense(regr.rows, regr.cols, nil) + wg := sync.WaitGroup{} + wg.Add(regr.cols) + for j := 0; j < regr.cols; j++ { + go func(j int) { + pred := regr.Models[j].Predict(x).(*mat.Dense) + probs.SetCol(j, mat.Col(nil, 0, pred)) + wg.Done() + }(j) + } + wg.Wait() + return probs +}