Example #1
0
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)
		}
	}
}
Example #2
0
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)
}
Example #3
0
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)
}