GmmTrainer extends SingleLabelDatasetTrainer<GmmModel> { private Optional<GmmModel> fit(Dataset<EmptyContext, GmmPartitionData> dataset) { return init(dataset).map(model -> { GmmModel currentModel = model; do { UpdateResult updateResult = updateModel(dataset, currentModel); currentModel = updateResult.model; double minCompProb = currentModel.componentsProbs().minElement().get(); if (countOfComponents >= maxCountOfClusters || minCompProb < minClusterProbability) break; double maxXProb = updateResult.maxProbInDataset; NewComponentStatisticsAggregator newMeanAdder = NewComponentStatisticsAggregator.computeNewMean(dataset, maxXProb, maxLikelihoodDivergence, currentModel); Vector newMean = newMeanAdder.mean(); if (newMeanAdder.rowCountForNewCluster() < minElementsForNewCluster) break; countOfComponents += 1; Vector[] newMeans = new Vector[countOfComponents]; for (int i = 0; i < currentModel.countOfComponents(); i++) newMeans[i] = currentModel.distributions().get(i).mean(); newMeans[countOfComponents - 1] = newMean; initialMeans = newMeans; Optional<GmmModel> newModelOpt = init(dataset); if (newModelOpt.isPresent()) currentModel = newModelOpt.get(); else break; } while (true); return filterModel(currentModel); }); } GmmTrainer();  GmmTrainer(int countOfComponents, int maxCountOfIterations);  GmmTrainer(int countOfComponents); @Override GmmModel fitWithInitializedDeployingContext(DatasetBuilder<K, V> datasetBuilder,
        Preprocessor<K, V> extractor); GmmTrainer withInitialCountOfComponents(int numberOfComponents); GmmTrainer withInitialMeans(List<Vector> means); GmmTrainer withMaxCountIterations(int maxCountOfIterations); GmmTrainer withEps(double eps); GmmTrainer withMaxCountOfInitTries(int maxCountOfInitTries); GmmTrainer withMaxCountOfClusters(int maxCountOfClusters); GmmTrainer withMaxLikelihoodDivergence(double maxLikelihoodDivergence); GmmTrainer withMinElementsForNewCluster(int minElementsForNewCluster); GmmTrainer withMinClusterProbability(double minClusterProbability); @Override boolean isUpdateable(GmmModel mdl);  }
@Test public void testFit() { GmmTrainer trainer = new GmmTrainer(2, 1) .withInitialMeans(Arrays.asList( VectorUtils.of(1.0, 2.0), VectorUtils.of(-1.0, -2.0))); GmmModel model = trainer.fit( new LocalDatasetBuilder<>(data, parts), new DoubleArrayVectorizer<Integer>().labeled(Vectorizer.LabelCoordinate.LAST) ); Assert.assertEquals(2, model.countOfComponents()); Assert.assertEquals(2, model.dimension()); Assert.assertArrayEquals(new double[] {1.33, 1.33}, model.distributions().get(0).mean().asArray(), 1e-2); Assert.assertArrayEquals(new double[] {-1.33, -1.33}, model.distributions().get(1).mean().asArray(), 1e-2); }