func TestTrainGaussian(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } dim := 8 mean := []float64{0.1, 0.2, 0.3, 0.4, 1, 1, 1, 1} std := []float64{0.5, 0.5, 0.5, 0.5, 0.1, 0.2, 0.3, 0.4} g := NewModel(dim, Name("test training")) r := rand.New(rand.NewSource(33)) for i := 0; i < 2000000; i++ { rv := model.RandNormalVector(r, mean, std) g.UpdateOne(model.F64ToObs(rv, ""), 1.0) } g.Estimate() t.Logf("Mean: \n%+v", g.Mean) t.Logf("STD: \n%+v", g.StdDev) for i, _ := range mean { if !gjoa.Comparef64(mean[i], g.Mean[i], tolerance) { t.Errorf("Wrong Mean[%d]. Expected: [%f], Got: [%f]", i, mean[i], g.Mean[i]) } if !gjoa.Comparef64(std[i], g.StdDev[i], tolerance) { t.Errorf("Wrong STD[%d]. Expected: [%f], Got: [%f]", i, std[i], g.StdDev[i]) } } }
func TestTrainGaussian2(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") } dim := 8 numSamp := 2000000 // Use a FloatObserver. values := make([][]float64, numSamp, numSamp) labels := make([]model.SimpleLabel, numSamp, numSamp) mean := []float64{0.1, 0.2, 0.3, 0.4, 1, 1, 1, 1} std := []float64{0.5, 0.5, 0.5, 0.5, 0.1, 0.2, 0.3, 0.4} g := NewModel(dim, Name("test training")) r := rand.New(rand.NewSource(33)) for i := 0; i < numSamp; i++ { rv := model.RandNormalVector(r, mean, std) values[i] = rv } fo, err := model.NewFloatObserver(values, labels) if err != nil { t.Fatal(err) } g.Update(fo, model.NoWeight) g.Estimate() t.Logf("Mean: \n%+v", g.Mean) t.Logf("STD: \n%+v", g.StdDev) for i, _ := range mean { if !gjoa.Comparef64(mean[i], g.Mean[i], tolerance) { t.Errorf("Wrong Mean[%d]. Expected: [%f], Got: [%f]", i, mean[i], g.Mean[i]) } if !gjoa.Comparef64(std[i], g.StdDev[i], tolerance) { t.Errorf("Wrong STD[%d]. Expected: [%f], Got: [%f]", i, std[i], g.StdDev[i]) } } }
// Another version of previous test. func TestTrainGMM2(t *testing.T) { dim := 2 numComp := 2 numIter := 10 numObs := 2000000 gmm0 := MakeGMM(t) gmm := NewModel(dim, numComp, Name("mygmm")) t.Logf("Initial Weights: \n%+v", gmm.Weights) mean01 := []float64{2.5, 3} sd01 := []float64{0.70710678118, 0.70710678118} gmm = RandomModel(mean01, sd01, numComp, "mygmm", 99) for iter := 0; iter < numIter; iter++ { t.Logf("Starting GMM training iteration %d.", iter) // Reset all counters.. gmm.Clear() for i := 0; i < numObs; i++ { // random from gmm0 // rv := gmm0.Sample().(model.FloatObs) // gmm.UpdateOne(rv.Value().([]float64), 1.0) rv := gmm0.Sample() gmm.UpdateOne(rv, 1.0) } gmm.Estimate() t.Logf("Iter: %d", iter) t.Logf("GMM: %+v", gmm) t.Logf("Weights: \n%+v", gmm.Weights) t.Logf("Likelihood: %f", gmm.Likelihood) t.Logf("Num Samples: %f", gmm.NSamples) for _, c := range gmm.Components { t.Logf("%s: Mean: \n%+v", c.Name(), c.Mean) t.Logf("%s: STD: \n%+v", c.Name(), c.StdDev) } } // Checking results // The components can be in different orders if gjoa.Comparef64(1.0, gmm.Components[0].Mean[0], epsilon) { CompareGaussians(t, gmm0.Components[0], gmm.Components[0], epsilon) CompareGaussians(t, gmm0.Components[1], gmm.Components[1], epsilon) } else { CompareGaussians(t, gmm0.Components[1], gmm.Components[0], epsilon) CompareGaussians(t, gmm0.Components[0], gmm.Components[1], epsilon) } }
func TestGaussian(t *testing.T) { mean := []float64{0.5, 1, 2} sd := []float64{1, 1, 1} g := NewModel(3, Name("testing"), Mean(mean), StdDev(sd)) obs := []float64{1, 1, 1} p := g.logProb(obs) t.Logf("LogProb: %f", p) t.Logf("Prob: %f", g.prob(obs)) expected := -3.3818 if !gjoa.Comparef64(expected, p, tolerance) { t.Errorf("Wrong LogProb. Expected: [%f], Got: [%f]", expected, p) } }
// Trains a GMM as follows: // 1 - Estimate a Gaussian model params for the training set. // 2 - Use the mean and sd of the training set to generate // a random GMM to be used as seed. // 3 - Run several iterations of the GMM max likelihood training algorithm // to estimate the GMM weights and the Gaussian component mean, and // variance vectors. func TestTrainGMM(t *testing.T) { var seed int64 = 33 numComp := 2 numIter := 10 numObs := 1000000 mean0 := []float64{1, 2} std0 := []float64{0.3, 0.3} mean1 := []float64{4, 4} std1 := []float64{1, 1} dim := len(mean0) gmm := NewModel(dim, numComp, Name("mygmm")) t.Logf("Initial Weights: \n%+v", gmm.Weights) { // Estimate mean variance of the data. g := gaussian.NewModel(dim, gaussian.Name("test training")) r := rand.New(rand.NewSource(seed)) for i := 0; i < numObs; i++ { rv, err := model.RandNormalVector(mean0, std0, r) if err != nil { t.Fatal(err) } g.UpdateOne(model.F64ToObs(rv), 1.0) rv, err = model.RandNormalVector(mean1, std1, r) if err != nil { t.Fatal(err) } g.UpdateOne(model.F64ToObs(rv), 1.0) } g.Estimate() t.Logf("Gaussian Model for training set:") t.Logf("Mean: \n%+v", g.Mean) t.Logf("SD: \n%+v", g.StdDev) // Use the estimated mean and sd to generate a seed GMM. gmm = RandomModel(g.Mean, g.StdDev, numComp, "mygmm", 99) t.Logf("Random GMM: %+v.", gmm) t.Logf("Component 0: %+v.", gmm.Components[0]) t.Logf("Component 1: %+v.", gmm.Components[1]) } for iter := 0; iter < numIter; iter++ { t.Logf("Starting GMM training iteration %d.", iter) // Reset the same random number generator to make sure we use the // same observations in each iterations. r := rand.New(rand.NewSource(seed)) // Update GMM stats. for i := 0; i < numObs; i++ { rv, err := model.RandNormalVector(mean0, std0, r) if err != nil { t.Fatal(err) } gmm.UpdateOne(model.F64ToObs(rv), 1.0) rv, err = model.RandNormalVector(mean1, std1, r) if err != nil { t.Fatal(err) } gmm.UpdateOne(model.F64ToObs(rv), 1.0) } // Estimates GMM params. gmm.Estimate() t.Logf("Iter: %d", iter) t.Logf("GMM: %+v", gmm) t.Logf("Weights: \n%+v", gmm.Weights) t.Logf("Likelihood: %f", gmm.Likelihood) t.Logf("Num Samples: %f", gmm.NSamples) for _, c := range gmm.Components { t.Logf("%s: Mean: \n%+v", c.Name(), c.Mean) t.Logf("%s: STD: \n%+v", c.Name(), c.StdDev) } // Prepare for next iteration. gmm.Clear() } for i := 0; i < dim; i++ { g := gmm.Components[1] if !gjoa.Comparef64(mean0[i], g.Mean[i], epsilon) { t.Errorf("Wrong Mean[%d]. Expected: [%f], Got: [%f]", i, mean0[i], g.Mean[i]) } if !gjoa.Comparef64(std0[i], g.StdDev[i], epsilon) { t.Errorf("Wrong STD[%d]. Expected: [%f], Got: [%f]", i, std0[i], g.StdDev[i]) } } for i := 0; i < dim; i++ { g := gmm.Components[0] if !gjoa.Comparef64(mean1[i], g.Mean[i], epsilon) { t.Errorf("Wrong Mean[%d]. Expected: [%f], Got: [%f]", i, mean1[i], g.Mean[i]) } if !gjoa.Comparef64(std1[i], g.StdDev[i], epsilon) { t.Errorf("Wrong STD[%d]. Expected: [%f], Got: [%f]", i, std1[i], g.StdDev[i]) } } if !gjoa.Comparef64(0.5, gmm.Weights[0], epsilon) { t.Errorf("Wrong weights[0]. Expected: [%f], Got: [%f]", 0.5, gmm.Weights[0]) } if !gjoa.Comparef64(0.5, gmm.Weights[1], epsilon) { t.Errorf("Wrong weights[0]. Expected: [%f], Got: [%f]", 0.5, gmm.Weights[1]) } }