package org.codermind.demos.ltr.weka;

import org.codermind.core.evaluation.RankEvaluation;
import org.codermind.ltr.pairwise.order.weka.OrderingAlgorithm;
import org.codermind.ltr.pairwise.order.weka.PBO;
import weka.classifiers.Classifier;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.converters.ConverterUtils;

import java.io.*;
import java.util.List;

/**
 * Demo of using weka trained preference function to order objects.
 *
 * @author Pavel
 * @version 1.0
 *
 */
public class Order {

    public static void main(String[] args) throws Exception {
        final String rootPath = "D:\\datasets\\output\\learning_rank\\";

        ObjectInputStream oisClassifier = new ObjectInputStream(new FileInputStream(rootPath + "rf_1000.model"));
        Classifier classifier = (Classifier) oisClassifier.readObject();
        oisClassifier.close();

        ObjectInputStream oisHeader = new ObjectInputStream(new FileInputStream(rootPath + "header"));
        Instances header = (Instances) oisHeader.readObject();
        oisHeader.close();

        ConverterUtils.DataSource ds = new ConverterUtils.DataSource(rootPath + "features_2007.csv");
        Instances inss = ds.getDataSet();
        inss.setClassIndex(inss.numAttributes() - 1);

        OrderingAlgorithm orderAlgo = new PBO();
        List<Instance> rankedList = orderAlgo.order(inss, classifier, header, 1);

        System.out.println("Top-100 spam factor: " + RankEvaluation.factor(rankedList, 100, "spam"));
        System.out.println("Top-100 spam precision: " + RankEvaluation.precision(rankedList, 100, "spam"));

        writeResult(rankedList, rootPath, 50);
    }

    public static void writeResult(List<Instance> rankedList, String dicPath, int step) throws Exception {
        final String spamFactorFile = "//spamFactor.csv";
        final String spamPrecisionFile = "//spamPrecision.csv";

        PrintWriter pwSF = new PrintWriter(dicPath + spamFactorFile);
        PrintWriter pwSP = new PrintWriter(dicPath + spamPrecisionFile);

        pwSF.println("K,spam factor");
        pwSP.println("K,spam precision");

        for(int i = step; i < rankedList.size(); ++i) {
            if(i % step == 0) {
                pwSF.println(i + "," + RankEvaluation.factor(rankedList, i, "spam"));
                pwSP.println(i + "," + RankEvaluation.precision(rankedList, i, "spam"));
            }
        }
        pwSF.close();
        pwSP.close();
    }
}
