protected static void randomLearn(String[] args) {
    if (args.length != 3) {
      System.out.println(
          "Please specify the number of classes as the second argument "
              + "and the number of features as the third argument.");
    } else {
      final int numClassIndices = Integer.parseInt(args[1]);
      final int maxFeatureIndex = Integer.parseInt(args[2]);

      // Initialize the classifier to random parameters.
      DiscretizingNaiveBayesClassifier classifier = new DiscretizingNaiveBayesClassifier();
      classifier.initializeRandomly(
          DiscretizingNaiveBayesClassifier.makeClassIndexSet(numClassIndices),
          maxFeatureIndex,
          new DiscretizingNaiveBayesClassifier.SimpleBinaryDiscretizer());

      // Save the trained model.
      saveTrainedModelFileData(classifier.toFileData());
    }
  }
  protected static void semiSupervisedLearn(String[] args) {
    if (args.length < 2) {
      System.out.println(
          "Please specify the path for the training data as the second argument. "
              + "(Optionally, you can give the number of EM iterations as the third argument.)");
    } else {
      final String trainingDataFilename = args[1];

      int maxNumIterations;
      if (args.length == 3) {
        maxNumIterations = Integer.parseInt(args[2]);
      } else {
        maxNumIterations = Integer.MAX_VALUE;
      }

      try {
        // Parse the sparse training data.
        final Map.Entry<List<SparseLineAST>, Integer> instancesToMaxFeatureIndex =
            SparseLineAST.parseSparseEncodingFromInputFilename(
                trainingDataFilename,
                new SparseLineAST.SemiSupervisedTrainingValidator(
                    new SparseLineAST.NumericValidator()));
        final List<SparseLineAST> instances = instancesToMaxFeatureIndex.getKey();
        final int maxFeatureIndex = instancesToMaxFeatureIndex.getValue();

        // Initialize and train the classifier on the training data.
        DiscretizingNaiveBayesClassifier classifier =
            DiscretizingNaiveBayesClassifierEMTrainer.train(
                getKForSmoothing().getSecond(),
                instances,
                maxFeatureIndex,
                new DiscretizingNaiveBayesClassifier.SimpleBinaryDiscretizer(),
                maxNumIterations);

        // Save the trained model.
        saveTrainedModelFileData(classifier.toFileData());
      } catch (RuntimeException x) {
        System.out.println(x.getMessage());
      }
    }
  }
  protected static void learn(String[] args) {
    if (args.length != 2) {
      System.out.println("Please specify the path for the training data as the second argument.");
    } else {
      final String trainingDataFilename = args[1];

      try {
        // Parse the sparse training data.
        // Note: "u" outputs for training instances are accepted; they'll just be ignored.
        final Map.Entry<List<SparseLineAST>, Integer> instancesToMaxFeatureIndex =
            SparseLineAST.parseSparseEncodingFromInputFilename(
                trainingDataFilename,
                new SparseLineAST.SemiSupervisedTrainingValidator(
                    new SparseLineAST.NumericValidator()));
        final List<SparseLineAST> instances = instancesToMaxFeatureIndex.getKey();
        final int maxFeatureIndex = instancesToMaxFeatureIndex.getValue();

        // Ignore unlabeled instances.
        final List<SparseLineAST> labeledInstances = SparseLineAST.getLabeledInstances(instances);

        // Initialize and train the classifier on the training data.
        DiscretizingNaiveBayesClassifier classifier = new DiscretizingNaiveBayesClassifier();
        classifier.initialize(getKForSmoothing().getSecond());
        classifier.train(
            labeledInstances,
            maxFeatureIndex,
            new DiscretizingNaiveBayesClassifier.SimpleBinaryDiscretizer());

        // Save the trained model.
        saveTrainedModelFileData(classifier.toFileData());
      } catch (RuntimeException x) {
        System.out.println(x.getMessage());
        for (StackTraceElement element : x.getStackTrace()) {
          System.out.println(element);
        }
      }
    }
  }