func init() { // create the /tmp/.goml/ dir for persistance testing // if it doesn't already exist! err := os.MkdirAll("/tmp/.goml", os.ModePerm) if err != nil { panic(fmt.Sprintf("You should be able to create the directory for goml model persistance testing.\n\tError returned: %v\n", err.Error())) } // the line y=3 flatX = [][]float64{} flatY = []float64{} for i := -10; i < 10; i++ { for j := -10; j < 10; j++ { for k := -10; k < 10; k++ { flatX = append(flatX, []float64{float64(i), float64(j), float64(k)}) flatY = append(flatY, 3.0) } } } // the line y=x increasingX = [][]float64{} increasingY = []float64{} for i := -10; i < 10; i++ { increasingX = append(increasingX, []float64{float64(i)}) increasingY = append(increasingY, float64(i)) } threeDLineX = [][]float64{} threeDLineY = []float64{} normX = [][]float64{} normY = []float64{} // the line z = 10 + (x/10) + (y/5) for i := -10; i < 10; i++ { for j := -10; j < 10; j++ { threeDLineX = append(threeDLineX, []float64{float64(i), float64(j)}) threeDLineY = append(threeDLineY, 10+float64(i)/10+float64(j)/5) normX = append(normX, []float64{float64(i), float64(j)}) } } base.Normalize(normX) for i := range normX { normY = append(normY, 10+float64(normX[i][0])/10+float64(normX[i][1])/5) } // noisy x has random noise embedded rand.Seed(42) noisyX = [][]float64{} noisyY = []float64{} for i := 256.0; i < 1024; i += 2 { noisyX = append(noisyX, []float64{i + (rand.Float64()-0.5)*3}) noisyY = append(noisyY, 0.5*i+rand.NormFloat64()*25) } // save the random data to make some nice plots! base.SaveDataToCSV("/tmp/.goml/noisy_linear.csv", noisyX, noisyY, true) }
func init() { // create the /tmp/.goml/ dir for persistance testing // if it doesn't already exist! err := os.MkdirAll("/tmp/.goml", os.ModePerm) if err != nil { panic(fmt.Sprintf("You should be able to create the directory for goml model persistance testing.\n\tError returned: %v\n", err.Error())) } // the line y=3 flatX = [][]float64{} flatY = []float64{} for i := -10; i < 10; i++ { for j := -10; j < 10; j++ { for k := -10; k < 10; k++ { flatX = append(flatX, []float64{float64(i), float64(j), float64(k)}) flatY = append(flatY, 3.0) } } } // the line y=x increasingX = [][]float64{} increasingY = []float64{} for i := -10; i < 10; i++ { increasingX = append(increasingX, []float64{float64(i)}) increasingY = append(increasingY, float64(i)) } threeDLineX = [][]float64{} threeDLineY = []float64{} normX = [][]float64{} normY = []float64{} // the line z = 10 + (x/10) + (y/5) for i := -10; i < 10; i++ { for j := -10; j < 10; j++ { threeDLineX = append(threeDLineX, []float64{float64(i), float64(j)}) threeDLineY = append(threeDLineY, 10+float64(i)/10+float64(j)/5) normX = append(normX, []float64{float64(i), float64(j)}) } } base.Normalize(normX) for i := range normX { normY = append(normY, 10+float64(normX[i][0])/10+float64(normX[i][1])/5) } }
// use normalized data func TestTriangleKMeansShouldPass2(t *testing.T) { norm := append([][]float64{}, circles...) base.Normalize(norm) model := NewTriangleKMeans(4, 2, norm) assert.Nil(t, model.Learn(), "Learning error should be nil") // now predict with the same training set and // make sure the classes are the same within // each block c1, err := model.Predict([]float64{-10, -10}, true) assert.Nil(t, err, "Prediction error should be nil") c2, err := model.Predict([]float64{-10, 10}, true) assert.Nil(t, err, "Prediction error should be nil") c3, err := model.Predict([]float64{10, -10}, true) assert.Nil(t, err, "Prediction error should be nil") c4, err := model.Predict([]float64{10, 10}, true) assert.Nil(t, err, "Prediction error should be nil") var count int var wrong int for i := -12.0; i < -8; i += 0.2 { for j := -12.0; j < -8; j += 0.2 { guess, err := model.Predict([]float64{i, j}, true) assert.Nil(t, err, "Prediction error should be nil") if c1[0] != guess[0] { wrong++ } count++ } for j := 8.0; j < 12; j += 0.2 { guess, err := model.Predict([]float64{i, j}, true) assert.Nil(t, err, "Prediction error should be nil") if c2[0] != guess[0] { wrong++ } count++ } } for i := 8.0; i < 12; i += 0.2 { for j := -12.0; j < -8; j += 0.2 { guess, err := model.Predict([]float64{i, j}, true) assert.Nil(t, err, "Prediction error should be nil") if c3[0] != guess[0] { wrong++ } count++ } for j := 8.0; j < 12; j += 0.2 { guess, err := model.Predict([]float64{i, j}, true) assert.Nil(t, err, "Prediction error should be nil") if c4[0] != guess[0] { wrong++ } count++ } } accuracy := 100 * (1 - float64(wrong)/float64(count)) assert.True(t, accuracy > 87, "Accuracy (%v) should be greater than 87 percent", accuracy) fmt.Printf("Accuracy: %v percent\n\tPoints Tested: %v\n\tMisclassifications: %v\n\tClasses: %v\n", accuracy, count, wrong, []float64{c1[0], c2[0], c3[0], c4[0]}) }
// use normalized data func TestKNNShouldPass2(t *testing.T) { norm := append([][]float64{}, fourClusters...) base.Normalize(norm) model := NewKNN(3, norm, fourClustersY, base.EuclideanDistance) var count int var wrong int duration := time.Duration(0) for i := -12.0; i < -8; i += 0.5 { for j := -12.0; j < -8; j += 0.5 { now := time.Now() guess, err := model.Predict([]float64{i, j}, true) duration += time.Now().Sub(now) assert.Nil(t, err, "Prediction error should be nil") if 0.0 != guess[0] { wrong++ } count++ } for j := 8.0; j < 12; j += 0.5 { now := time.Now() guess, err := model.Predict([]float64{i, j}, true) duration += time.Now().Sub(now) assert.Nil(t, err, "Prediction error should be nil") if 1.0 != guess[0] { wrong++ } count++ } } for i := 8.0; i < 12; i += 0.5 { for j := -12.0; j < -8; j += 0.5 { now := time.Now() guess, err := model.Predict([]float64{i, j}, true) duration += time.Now().Sub(now) assert.Nil(t, err, "Prediction error should be nil") if 2.0 != guess[0] { wrong++ } count++ } for j := 8.0; j < 12; j += 0.5 { now := time.Now() guess, err := model.Predict([]float64{i, j}, true) duration += time.Now().Sub(now) assert.Nil(t, err, "Prediction error should be nil") if 3.0 != guess[0] { wrong++ } count++ } } accuracy := 100 * (1 - float64(wrong)/float64(count)) assert.True(t, accuracy > 95, "Accuracy (%v) should be greater than 95 percent", accuracy) fmt.Printf("Accuracy: %v percent\n\tPoints Tested: %v\n\tMisclassifications: %v\n\tAverage Prediction Time: %v\n", accuracy, count, wrong, duration/time.Duration(count)) }
// tests basically make a bunch of planes where // when the input is above the plane the resultant // output is 1.0, else 0.0 func init() { // create the /tmp/.goml/ dir for persistance testing // if it doesn't already exist! err := os.MkdirAll("/tmp/.goml", os.ModePerm) if err != nil { panic(fmt.Sprintf("You should be able to create the directory for goml model persistance testing.\n\tError returned: %v\n", err.Error())) } // 1 when ( 10*i + j/20 + k ) > 0 fourDX = [][]float64{} fourDY = []float64{} for i := -40; i < 40; i += 4 { for j := -40; j < 40; j += 4 { for k := -40; k < 40; k += 4 { fourDX = append(fourDX, []float64{float64(i), float64(j), float64(k)}) if 10*i+j/20+k > 0 { fourDY = append(fourDY, 1.0) } else { fourDY = append(fourDY, 0.0) } } } } // 1 when i > 0 twoDX = [][]float64{} twoDY = []float64{} for i := -40.0; i < 40.0; i += 0.15 { twoDX = append(twoDX, []float64{i}) if i/2+10 > 0 { twoDY = append(twoDY, 1.0) } else { twoDY = append(twoDY, 0.0) } } threeDX = [][]float64{} threeDY = []float64{} nX = [][]float64{} nY = []float64{} // 1 when i+j > 5 for i := -10; i < 10; i++ { for j := -10; j < 10; j++ { threeDX = append(threeDX, []float64{float64(i), float64(j)}) nX = append(nX, []float64{float64(i), float64(j)}) if i+j > 5 { threeDY = append(threeDY, 1.0) } else { threeDY = append(threeDY, 0.0) } } } base.Normalize(nX) for i := range nX { if nX[i][0]+nX[i][1] > 5 { nY = append(nY, 1.0) } else { nY = append(nY, 0.0) } } }
// tests basically make a bunch of planes where // when the input is above the plane the resultant // output is 1.0, else 0.0 func init() { // create the /tmp/.goml/ dir for persistance testing // if it doesn't already exist! err := os.MkdirAll("/tmp/.goml", os.ModePerm) if err != nil { panic(fmt.Sprintf("You should be able to create the directory for goml model persistance testing.\n\tError returned: %v\n", err.Error())) } // 1 when ( 10*i + j/20 + k ) > 0 fourDX = [][]float64{} fourDY = []float64{} for i := -40; i < 40; i += 4 { for j := -40; j < 40; j += 4 { for k := -40; k < 40; k += 4 { fourDX = append(fourDX, []float64{float64(i), float64(j), float64(k)}) if 10*i+j/20+k > 0 { fourDY = append(fourDY, 1.0) } else { fourDY = append(fourDY, 0.0) } } } } // 1 when i > 0 twoDX = [][]float64{} twoDY = []float64{} for i := -40.0; i < 40.0; i += 0.15 { twoDX = append(twoDX, []float64{i}) if i/2+10 > 0 { twoDY = append(twoDY, 1.0) } else { twoDY = append(twoDY, 0.0) } } threeDX = [][]float64{} threeDY = []float64{} nX = [][]float64{} nY = []float64{} // 1 when i+j > 5 for i := -10; i < 10; i++ { for j := -10; j < 10; j++ { threeDX = append(threeDX, []float64{float64(i), float64(j)}) nX = append(nX, []float64{float64(i), float64(j)}) if i+j > 5 { threeDY = append(threeDY, 1.0) } else { threeDY = append(threeDY, 0.0) } } } base.Normalize(nX) for i := range nX { if nX[i][0]+nX[i][1] > 5 { nY = append(nY, 1.0) } else { nY = append(nY, 0.0) } } // now make gaussian clusters for cool plots! rand.Seed(42) gaussianX = [][]float64{} gaussianY = []float64{} for i := 0; i < 100; i++ { gaussianX = append(gaussianX, []float64{ rand.NormFloat64()*3 + 10, rand.NormFloat64()*3 + 10, }) gaussianY = append(gaussianY, 1.0) } for i := 0; i < 100; i++ { gaussianX = append(gaussianX, []float64{ rand.NormFloat64() * 5, rand.NormFloat64() * 5, }) gaussianY = append(gaussianY, 0.0) } base.SaveDataToCSV("/tmp/.goml/gaussian_clusters.csv", gaussianX, gaussianY, true) }