package edu.neu.ccs.pyramid.experiment;

import edu.neu.ccs.pyramid.configuration.Config;
import edu.neu.ccs.pyramid.dataset.DataSetType;
import edu.neu.ccs.pyramid.dataset.MultiLabel;
import edu.neu.ccs.pyramid.dataset.MultiLabelClfDataSet;
import edu.neu.ccs.pyramid.dataset.TRECFormat;
import edu.neu.ccs.pyramid.eval.Accuracy;
import edu.neu.ccs.pyramid.eval.Overlap;
import edu.neu.ccs.pyramid.multilabel_classification.bmm_variant.BMMClassifier;
import edu.neu.ccs.pyramid.multilabel_classification.bmm_variant.BMMInitializer;
import edu.neu.ccs.pyramid.multilabel_classification.bmm_variant.BMMOptimizer;

import java.io.File;


/**
 * Created by Rainicy on 10/24/15.
 */
public class Exp211 {
    public static void main(String[] args) throws Exception {
        if (args.length != 1) {
            throw new IllegalArgumentException("Please specify a properties file.");
        }

        Config config = new Config(args[0]);

        System.out.println(config);

        MultiLabelClfDataSet trainSet = TRECFormat.loadMultiLabelClfDataSet(config.getString("input.trainData"),
                DataSetType.ML_CLF_SPARSE, true);
        MultiLabelClfDataSet testSet = TRECFormat.loadMultiLabelClfDataSet(config.getString("input.testData"),
                DataSetType.ML_CLF_SPARSE, true);

        int numClusters = config.getInt("numClusters");
        double softmaxVariance = config.getDouble("softmaxVariance");
        double logitVariance = config.getDouble("logitVariance");
        int numIterations = config.getInt("numIterations");
        int numSamples = config.getInt("numSamples");

        String output = config.getString("output");
        String modelName = config.getString("modelName");

        BMMClassifier bmmClassifier;
        if (config.getBoolean("train.warmStart")) {
            bmmClassifier = BMMClassifier.deserialize(new File(output, modelName));
            bmmClassifier.setAllowEmpty(config.getBoolean("allowEmpty"));
        } else {
            bmmClassifier = new BMMClassifier(trainSet.getNumClasses(),numClusters,trainSet.getNumFeatures());
            BMMOptimizer optimizer = new BMMOptimizer(bmmClassifier, trainSet,softmaxVariance,logitVariance);
            bmmClassifier.setNumSample(numSamples);
            bmmClassifier.setAllowEmpty(config.getBoolean("allowEmpty"));
            bmmClassifier.setPredictMode(config.getString("predictMode"));

            MultiLabel[] trainPredict;
            MultiLabel[] testPredict;

//            trainPredict = bmmClassifier.predict(trainSet);
//            testPredict = bmmClassifier.predict(testSet);
            System.out.print("random init" + "\t" );
//            System.out.print("objective: "+optimizer.getObjective()+ "\t");
//            System.out.print("trainAcc : "+ Accuracy.accuracy(trainSet.getMultiLabels(), trainPredict) + "\t");
//            System.out.print("trainOver: "+ Overlap.overlap(trainSet.getMultiLabels(), trainPredict) + "\t");
//            System.out.print("testACC  : "+ Accuracy.accuracy(testSet.getMultiLabels(),testPredict) + "\t");
//            System.out.println("testOver : "+ Overlap.overlap(testSet.getMultiLabels(), testPredict) + "\t");

            if (config.getBoolean("initialize")) {
                BMMInitializer.initialize(bmmClassifier,trainSet,softmaxVariance,logitVariance, new File(config.getString("initializeBy")));
            }
            else {
                BMMInitializer.initialize(bmmClassifier,trainSet,softmaxVariance,logitVariance);
            }
            System.out.println("after initialization");
//            trainPredict = bmmClassifier.predict(trainSet);
//            testPredict = bmmClassifier.predict(testSet);
//
//            System.out.print("objective: "+optimizer.getObjective()+ "\t");
//            System.out.print("trainAcc : " + Accuracy.accuracy(trainSet.getMultiLabels(), trainPredict) + "\t");
//            System.out.print("trainOver: " + Overlap.overlap(trainSet.getMultiLabels(), trainPredict) + "\t");
//            System.out.print("testACC  : " + Accuracy.accuracy(testSet.getMultiLabels(), testPredict) + "\t");
//            System.out.println("testOver : "+ Overlap.overlap(testSet.getMultiLabels(), testPredict) + "\t");

            for (int i=1;i<=numIterations;i++){
                optimizer.iterate();
                trainPredict = bmmClassifier.predict(trainSet);
                testPredict = bmmClassifier.predict(testSet);
                System.out.print("iter : "+i + "\t");
                System.out.print("objective: "+optimizer.getTerminator().getLastValue() + "\t");
                System.out.print("trainAcc : "+ Accuracy.accuracy(trainSet.getMultiLabels(),trainPredict)+ "\t");
                System.out.print("trainOver: "+ Overlap.overlap(trainSet.getMultiLabels(), trainPredict)+ "\t");
                System.out.print("testAcc  : "+ Accuracy.accuracy(testSet.getMultiLabels(),testPredict)+ "\t");
                System.out.println("testOver : "+ Overlap.overlap(testSet.getMultiLabels(), testPredict)+ "\t");
            }
            System.out.println("history = "+optimizer.getTerminator().getHistory());
        }

        System.out.println("--------------------------------Results-----------------------------\n");
        System.out.println();
        System.out.print("trainAcc : " + Accuracy.accuracy(bmmClassifier, trainSet) + "\t");
        System.out.print("trainOver: "+ Overlap.overlap(bmmClassifier, trainSet)+ "\t");
        System.out.print("testAcc  : "+ Accuracy.accuracy(bmmClassifier,testSet)+ "\t");
        System.out.println("testOver : "+ Overlap.overlap(bmmClassifier, testSet)+ "\t");
        System.out.println();
        System.out.println();
        System.out.println(bmmClassifier);

        if (config.getBoolean("saveModel")) {
            (new File(output)).mkdirs();
            File serializeModel = new File(output, modelName);
            bmmClassifier.serialize(serializeModel);
        }
    }
}

@@ -3566,26 +3566,24 @@
 lization%22);%0A
-//
             
@@ -3622,34 +3622,32 @@
 dict(trainSet);%0A
-//
             test
@@ -3692,13 +3692,9 @@
 t);%0A
-//%0A//
+%0A
     
@@ -3757,34 +3757,32 @@
 ctive()+ %22%5Ct%22);%0A
-//
             Syst
@@ -3870,34 +3870,32 @@
 edict) + %22%5Ct%22);%0A
-//
             Syst
@@ -3981,34 +3981,32 @@
 edict) + %22%5Ct%22);%0A
-//
             Syst
@@ -4092,34 +4092,32 @@
 edict) + %22%5Ct%22);%0A
-//
             Syst

comment out only with random inits.