/**
 * @author Uros Krcadinac
 * Oct 27, 2013
 * @version 0.1
 */
package rs.fon.is.weka.classifier;

import weka.classifiers.Classifier;
import weka.classifiers.Evaluation;
import weka.classifiers.bayes.NaiveBayes;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;

public class WekaToPlayDirectInput {

	private static FastVector attributes;

	public static void main(String[] args) throws Exception {

		// Declare nominal attributes along with its values
		// 1. Outlook
		FastVector outlookNominalValues = new FastVector(3);
		outlookNominalValues.addElement("sunny");
		outlookNominalValues.addElement("overcast");
		outlookNominalValues.addElement("rainy");
		Attribute outlook = new Attribute("Outlook", outlookNominalValues);

		// 2. Temperature
		FastVector tempNominalValues = new FastVector(3);
		tempNominalValues.addElement("hot");
		tempNominalValues.addElement("mild");
		tempNominalValues.addElement("cool");
		Attribute temperature = new Attribute("Temperature", tempNominalValues);

		// 3. Humidity
		FastVector humidityNominalValues = new FastVector(2);
		humidityNominalValues.addElement("high");
		humidityNominalValues.addElement("normal");
		Attribute humidity = new Attribute("Humidity", humidityNominalValues);

		// 4. Windy
		FastVector windyNominalValues = new FastVector(2);
		windyNominalValues.addElement("false");
		windyNominalValues.addElement("true");
		Attribute windy = new Attribute("Windy", windyNominalValues);

		// 5. Play
		FastVector playNominalValues = new FastVector(2);
		playNominalValues.addElement("no");
		playNominalValues.addElement("yes");
		Attribute play = new Attribute("Play", playNominalValues);

		// Declare the feature vector
		attributes = new FastVector(5);
		attributes.addElement(outlook);    
		attributes.addElement(temperature);    
		attributes.addElement(humidity);    
		attributes.addElement(windy);
		attributes.addElement(play);

		// Create an empty dataset
		Instances data = new Instances("TrainingSet", attributes, 14);

		// Create the instances
		Instance[] instances = new Instance[14];
		instances[0] = createInstance("sunny", "hot", "high", "false", "no");
		instances[1] = createInstance("sunny", "hot", "high", "true", "no");
		instances[2] = createInstance("overcast", "hot", "high", "false", "yes");
		instances[3] = createInstance("rainy", "mild", "high", "false", "yes");
		instances[4] = createInstance("rainy", "cool", "normal", "false", "yes");
		instances[5] = createInstance("rainy", "cool", "normal", "true", "no");
		instances[6] = createInstance("overcast", "cool", "normal", "true", "yes");
		instances[7] = createInstance("sunny", "mild", "high", "false", "no");
		instances[8] = createInstance("sunny", "cool", "normal", "false", "yes");
		instances[9] = createInstance("rainy", "mild", "normal", "false", "yes");
		instances[10] = createInstance("sunny", "mild", "normal", "true", "yes");
		instances[11] = createInstance("overcast", "mild", "high", "true", "yes");
		instances[12] = createInstance("overcast", "hot", "normal", "false", "yes");
		instances[13] = createInstance("rainy", "mild", "high", "true", "no");
		
		// Add the instances to the training set
		for (int i = 0; i < instances.length; i++) {
			data.add(instances[i]);
		}
		data.setClassIndex(data.numAttributes() - 1);
		
		// Create the Naive Bayes Classifier
		Classifier bayesClsf = (Classifier) new NaiveBayes();
		bayesClsf.buildClassifier(data);
		
		// print the model
		System.out.println(bayesClsf);
		

		// Create test set
		Instances testSet = new Instances("TestSet", attributes, 1);
		testSet.add(createInstance("rainy", "mild", "high", "true", "no"));
		testSet.setClassIndex(testSet.numAttributes() - 1);

		
		// Test the model with the training set
		Evaluation eval = new Evaluation(data);
		eval.evaluateModel(bayesClsf, testSet);
		

		// Print the result as in Weka explorer
		String strSummary = eval.toSummaryString();
		
		System.out.println("=== Evaluation on training set ===");
		System.out.println("=== Summary ===");
		System.out.println(strSummary);
		
		// Get the confusion matrix
		System.out.println(eval.toMatrixString());
	}

	public static Instance createInstance(String v1, String v2, String v3, String v4, String v5) {
		Instance i1 = new Instance(5);
		i1.setValue((Attribute)attributes.elementAt(0), v1);
		i1.setValue((Attribute)attributes.elementAt(1), v2);
		i1.setValue((Attribute)attributes.elementAt(2), v3);
		i1.setValue((Attribute)attributes.elementAt(3), v4);
		i1.setValue((Attribute)attributes.elementAt(4), v5);
		return i1;
	}

}
