func TestGaussianKernelXORShouldPass1(t *testing.T) { // create the channel of data and errors stream := make(chan base.Datapoint, 100) errors := make(chan error) model := NewKernelPerceptron(base.GaussianKernel(1)) go model.OnlineLearn(errors, stream, func(supportVector [][]float64) {}) var count int go func() { for i := 0; i < 3; i++ { stream <- base.Datapoint{ X: []float64{0, 0}, Y: []float64{-1}, } stream <- base.Datapoint{ X: []float64{0, 1}, Y: []float64{1}, } stream <- base.Datapoint{ X: []float64{1, 0}, Y: []float64{1}, } stream <- base.Datapoint{ X: []float64{1, 1}, Y: []float64{-1}, } count += 4 } // close the dataset close(stream) }() fmt.Printf("%v Training Examples Pushed\n", count) err, more := <-errors assert.Nil(t, err, "Learning error should be nil") assert.False(t, more, "There should be no errors returned") for i := 0; i < 2; i++ { for j := 0; j < 2; j++ { guess, err := model.Predict([]float64{float64(i), float64(j)}) assert.Nil(t, err, "Prediction error should be nil") fmt.Printf("h(%v, %v) = %v should equal i^j = %v^%v = %v mapped to -1,1 from 0,1\n", i, j, guess[0], i, j, i^j) expected := 1.0 if i^j == 0 { expected = -1.0 } assert.Equal(t, expected, guess[0], "Guess should equal i^j (%v^%v = %v)", i, j, i^j) } } }
func TestGaussianKernelPersistPerceptronShouldPass1(t *testing.T) { // create the channel of data and errors stream := make(chan base.Datapoint, 100) errors := make(chan error) model := NewKernelPerceptron(base.GaussianKernel(50)) go model.OnlineLearn(errors, stream, func(supportVector [][]float64) {}) // start passing data to our datastream // // we could have data already in our channel // when we instantiated the Perceptron, though go func() { var count int for i := -200.0; abs(i) > 1; i *= -0.7 { for j := -200.0; abs(j) > 1; j *= -0.7 { for k := -200.0; abs(k) > 1; k *= -0.7 { for l := -200.0; abs(l) > 1; l *= -0.7 { if i/2+2*k-4*j+2*l+3 > 0 { stream <- base.Datapoint{ X: []float64{i, j, k, l}, Y: []float64{1.0}, } } else { stream <- base.Datapoint{ X: []float64{i, j, k, l}, Y: []float64{-1.0}, } } count++ } } } } fmt.Printf("%v Training Examples Pushed\n", count) // close the dataset close(stream) }() err, more := <-errors assert.Nil(t, err, "Learning error should be nil") assert.False(t, more, "There should be no errors returned") // test a larger dataset now var count int var wrong int for i := -200.0; i < 200; i += 99.9 { for j := -200.0; j < 200; j += 99.9 { for k := -200.0; k < 200; k += 99.9 { for l := -200.0; l < 200; l += 99.9 { guess, err := model.Predict([]float64{i, j, k, l}) assert.Nil(t, err, "Prediction error should be nil") assert.Len(t, guess, 1, "Guess should have length 1") count++ if i/2+2*k-4*j+2*l+3 > 0 { if guess[0] != 1.0 { wrong++ } } else { if guess[0] != -1.0 { wrong++ } } } } } } accuracy := 100 * (1 - float64(wrong)/float64(count)) assert.True(t, accuracy > 95, "There should be greater than 95 percent accuracy (currently %v)", accuracy) fmt.Printf("Accuracy: %v\n\tPoints Tested: %v\n\tMisclassifications: %v\n", accuracy, count, wrong) // now persist to file err = model.PersistToFile("/tmp/.goml/KernelPerceptron.json") assert.Nil(t, err, "Persistance error should be nil") model.SV = []base.Datapoint{} // make sure it WONT work now that we reset theta // // the result of Theta transpose * X should always // be 0 because theta is the zero vector right now. wrong = 0 count = 0 for i := -200.0; i < 200; i += 99.9 { for j := -200.0; j < 200; j += 99.9 { for k := -200.0; k < 200; k += 99.9 { for l := -200.0; l < 200; l += 99.9 { guess, err := model.Predict([]float64{i, j, k, l}) assert.Nil(t, err, "Prediction error should be nil") assert.Len(t, guess, 1, "Guess should have length 1") count++ if i/2+2*k-4*j+2*l+3 > 0 { if guess[0] != 1.0 { wrong++ } } else { if guess[0] != -1.0 { wrong++ } } } } } } accuracy = 100 * (1 - float64(wrong)/float64(count)) assert.True(t, accuracy < 51, "There should be less than 50 percent accuracy (currently %v)", accuracy) // restore from file err = model.RestoreFromFile("/tmp/.goml/KernelPerceptron.json") assert.Nil(t, err, "Persistance error should be nil") // test with original data // test a larger dataset now wrong = 0 count = 0 for i := -200.0; i < 200; i += 99.9 { for j := -200.0; j < 200; j += 99.9 { for k := -200.0; k < 200; k += 99.9 { for l := -200.0; l < 200; l += 99.9 { guess, err := model.Predict([]float64{i, j, k, l}) assert.Nil(t, err, "Prediction error should be nil") assert.Len(t, guess, 1, "Guess should have length 1") count++ if i/2+2*k-4*j+2*l+3 > 0 { if guess[0] != 1.0 { wrong++ } } else { if guess[0] != -1.0 { wrong++ } } } } } } accuracy = 100 * (1 - float64(wrong)/float64(count)) assert.True(t, accuracy > 95, "There should be greater than 95 percent accuracy (currently %v)", accuracy) fmt.Printf("Accuracy: %v\n\tPoints Tested: %v\n\tMisclassifications: %v\n", accuracy, count, wrong) }
func TestGaussianKernelFourDXShouldPass1(t *testing.T) { // create the channel of data and errors stream := make(chan base.Datapoint, 100) errors := make(chan error) var updates int model := NewKernelPerceptron(base.GaussianKernel(50)) go model.OnlineLearn(errors, stream, func(supportVector [][]float64) { updates++ }) var count int go func() { for i := -200.0; abs(i) > 1; i *= -0.7 { for j := -200.0; abs(j) > 1; j *= -0.7 { for k := -200.0; abs(k) > 1; k *= -0.7 { for l := -200.0; abs(l) > 1; l *= -0.7 { if i/2+2*k-4*j+2*l+3 > 0 { stream <- base.Datapoint{ X: []float64{i, j, k, l}, Y: []float64{1.0}, } } else { stream <- base.Datapoint{ X: []float64{i, j, k, l}, Y: []float64{-1.0}, } } count++ } } } } // close the dataset close(stream) }() fmt.Printf("%v Training Examples Pushed\n", count) err, more := <-errors assert.Nil(t, err, "Learning error should be nil") assert.False(t, more, "There should be no errors returned") assert.True(t, updates > 100, "There should be more than 100 updates of theta") count = 0 wrong := 0 for i := -200.0; i < 200; i += 100 { for j := -200.0; j < 200; j += 100 { for k := -200.0; k < 200; k += 100 { for l := -200.0; l < 200; l += 100 { guess, err := model.Predict([]float64{i, j, k, l}) assert.Nil(t, err, "Prediction error should be nil") assert.Len(t, guess, 1, "Guess should have length 1") count++ if i/2+2*k-4*j+2*l+3 > 0 { if guess[0] != 1.0 { wrong++ } } else { if guess[0] != -1.0 { wrong++ } } } } } } accuracy := 100 * (1 - float64(wrong)/float64(count)) assert.True(t, accuracy > 95, "There should be greater than 95 percent accuracy (currently %v)", accuracy) fmt.Printf("Accuracy: %v\n\tPoints Tested: %v\n\tMisclassifications: %v\n", accuracy, count, wrong) }