package trackerModule.weka;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.JFrame;
import trackerModule.core.datastructure.TDB;
import trackerModule.core.datastructure.Unit;
import trackerModule.core.rulestructure.RDB;
import trackerModule.util.SortableValueMap;
import weka.associations.Apriori;
import weka.classifiers.bayes.BayesNet;
import weka.classifiers.bayes.NaiveBayesUpdateable;
import weka.classifiers.bayes.net.BIFReader;
import weka.classifiers.bayes.net.EditableBayesNet;
import weka.classifiers.bayes.net.MarginCalculator;
import weka.core.Attribute;
import weka.core.DenseInstance;
import weka.core.Instances;
import weka.core.SerializedObject;
import weka.core.converters.ArffSaver;
import weka.core.converters.ConverterUtils.DataSource;
import weka.gui.graphvisualizer.BIFFormatException;
import weka.gui.graphvisualizer.GraphVisualizer;
/**
* The Class WekaInterface.
*/
public class WekaInterface {
/** Container of Bayesian network. */
EditableBayesNet m_BayesNet = null;
/** The m_margin calculator. */
MarginCalculator m_marginCalculator = null;
/** The m_margin calculator with evidence. */
MarginCalculator m_marginCalculatorWithEvidence = null;
/**
* Instantiates a new weka interface.
*/
public WekaInterface() {
// TODO Auto-generated constructor stub
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Converter
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Gets the weka data from unit matrix2.
*
* @param unit
* @param className
* @return the weka data from unit matrix2
*/
public Instances getWekaDataFromUMatrix2( Unit u, String className ){
//////////////////////////////////////////////////////////////////////////////////////////
//create attributes list
ArrayList<Attribute> atts = new ArrayList<Attribute>();
SortableValueMap<String, ArrayList<String>> mapValues = new SortableValueMap<String, ArrayList<String>>();
String strName;
String strTemp;
for( Integer j = 0; j < u.n; j++ ) {
strName = u.A[0][j].getData();
ArrayList<String> values = new ArrayList<String>();
for( Integer i = 1; i < u.m; i++) {
strTemp = u.A[i][j].getData();
if( !values.contains(strTemp) && strTemp != null )
values.add(strTemp);
}
mapValues.put(strName, values);
atts.add(new Attribute(strName, values));
}
//////////////////////////////////////////////////////////////////////////////////////////
//create Instances object
Instances data = new Instances("MyRelation", atts, 0);
//////////////////////////////////////////////////////////////////////////////////////////
//fill all matrix data to weka data
for( Integer i = 1; i < u.m; i++ ) {
double[] vals = new double[data.numAttributes()];
for( Integer j = 0; j < u.n; j++) {
strName = u.A[0][j].getData();
strTemp = u.A[i][j].getData();
ArrayList<String> values = mapValues.get(strName);
vals[j] = values.indexOf(strTemp);
}
// add
data.add(new DenseInstance(1.0, vals));
}
//2.4. set class attribute
for( Integer j = 0; j < u.n; j++) {
strName = u.A[0][j].getData();
if( strName.equalsIgnoreCase(className) ){
data.setClassIndex(j);
break;
}
}
System.out.println("");
System.out.println(data);
return data;
}
/**
* Gets the weka data from u matrix.
*
* @param className the class name
* @param attributeList the attribute list
* @return the weka data from u matrix
*/
public Instances getWekaDataFromUMatrix( String className, String[] attributeList ){
Unit ships = TDB.This().get("TDBROOT.MODEL.WORLD.SHIPS");
//////////////////////////////////////////////////////////////////////////////////////////
//create attributes list
ArrayList<Attribute> atts = new ArrayList<Attribute>();
SortableValueMap<String, ArrayList<String>> mapValues = new SortableValueMap<String, ArrayList<String>>();
for( String strAtrribute : attributeList){
ArrayList<String> values = new ArrayList<String>();
mapValues.put(strAtrribute, values);
}
for( Unit s : ships.list ){
for( String strAtrribute : attributeList){
Unit c = s.get(strAtrribute);
ArrayList<String> values = mapValues.get(strAtrribute);
//fill all data to matrix
for( Integer t = 0; t < RDB.This().getTime(); t++ ){
String d = c.getNominal(t);
if( !values.contains(d) && d != null )
values.add(d);
}
}
}
for( String strAtrribute : attributeList){
ArrayList<String> values = mapValues.get(strAtrribute);
atts.add(new Attribute(strAtrribute, values));
}
//////////////////////////////////////////////////////////////////////////////////////////
//create Instances object
Instances data = new Instances("MyRelation", atts, 0);
//////////////////////////////////////////////////////////////////////////////////////////
//fill all matrix data to weka data
for( Unit s : ships.list ){
for( Integer t = 0; t < RDB.This().getTime(); t++ ){
double[] vals = new double[data.numAttributes()];
int j = 0;
for( String strAtrribute : attributeList){
Unit c = s.get(strAtrribute);
ArrayList<String> values = mapValues.get(strAtrribute);
String d = c.getNominal(t);
vals[j++] = values.indexOf(d);
}
// add
data.add(new DenseInstance(1.0, vals));
}
}
//2.4. set class attribute
int j = 0;
for( String strAtrribute : attributeList ){
if( strAtrribute.equalsIgnoreCase(className) ){
data.setClassIndex(j);
break;
}
j++;
}
System.out.println("");
System.out.println(data);
return data;
}
/**
* Gets the weka data from sim data.
*
* @param name
* @return the weka data from sim data
*/
public Instances getWekaDataFromSimData(String name) {
Unit printRoot = TDB.This().get(name);
printRoot.print("");
//////////////////////////////////////////////////////////////////////////////////////////
//find all Unit having data
SortableValueMap<String, Unit> mapUnit = new SortableValueMap<String, Unit>();
printRoot.findUnitsHavingData( "", mapUnit);
//////////////////////////////////////////////////////////////////////////////////////////
//modify data to fit Weka data
// EX) 1232.213 -> n1232
for( String strName: mapUnit.keySet() ){
Unit u = mapUnit.get(strName);
u.modifyToNominal();
}
printRoot.print("");
//////////////////////////////////////////////////////////////////////////////////////////
//create attributes list
mapUnit.sortByValue();
ArrayList<Attribute> atts = new ArrayList<Attribute>();
SortableValueMap<String, ArrayList<String>> mapValues = new SortableValueMap<String, ArrayList<String>>();
for( String strName: mapUnit.keySet() ){
Unit u = mapUnit.get(strName);
ArrayList<String> values = new ArrayList<String>();
u.getAllDataVaules( values );
mapValues.put(strName, values);
atts.add(new Attribute(strName, values));
}
//////////////////////////////////////////////////////////////////////////////////////////
//create Instances object
Instances data = new Instances("MyRelation", atts, 0);
//////////////////////////////////////////////////////////////////////////////////////////
//fill all TDB data to weka data
for( Integer t = 0; t < RDB.This().getTime(); t++ ){
int i = 0;
double[] vals = new double[data.numAttributes()];
for( String strName: mapUnit.keySet() ){
Unit u = mapUnit.get(strName);
ArrayList<String> values = mapValues.get(strName);
String strData = u.getLastDataByTime(t);
vals[i] = values.indexOf(strData);
i++;
}
// add
data.add(new DenseInstance(1.0, vals));
}
//2.4. set class attribute
data.setClassIndex(data.numAttributes() - 3);
System.out.println("");
System.out.println(data);
return data;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// I/O
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Save weka file.
*
* @param strFile
* @param dataSet the data set
*/
public void saveWekaFile(String strFile, Instances dataSet) {
ArffSaver saver = new ArffSaver();
saver.setInstances(dataSet);
try {
saver.setFile(new File(strFile));
} catch (IOException e) {
e.printStackTrace();
}
try {
saver.writeBatch();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Save bif from file.
*
* @param sFileName
* @param BN the bN
*/
public void saveBIFFromFile(String sFileName, BayesNet BN ){
FileWriter outfile;
try {
outfile = new FileWriter(sFileName);
outfile.write(BN.toXMLBIF03());
outfile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Load bif from file.
*
* @param sFileName
*/
public void loadBIFFromFile(String sFileName){
BIFReader bayesNet = new BIFReader();
try {
bayesNet.processFile(sFileName);
m_BayesNet = new EditableBayesNet(bayesNet);
updateStatus();
} catch (Exception e) {
e.printStackTrace();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Trainer
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Train apriori.
*
* @param data the data
*/
public void trainApriori(Instances data) {
Apriori nb = new Apriori();
nb.setUpperBoundMinSupport(0.8);
try {
nb.buildAssociations(data);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(nb);
}
/**
* Train naive bayes.
*
* @param data
*/
public void trainNaiveBayes(Instances data) {
NaiveBayesUpdateable nb = new NaiveBayesUpdateable();
try {
nb.buildClassifier(data);
} catch (Exception e) {
e.printStackTrace();
}
for( int n = 0; n < data.size(); n++ ) {
try {
nb.updateClassifier(data.get(n));
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println(nb);
}
/**
* Train bayes net.
*
* @param data
* @return the bayes net
*/
public BayesNet trainBayesNet(Instances data) {
BayesNet cls = new BayesNet();
try {
String[] str = cls.getOptions();
// str[2] = "weka.classifiers.bayes.net.search.local.TAN";
// str[4] = "";
// str[5] = "";
cls.setOptions(str);
cls.buildClassifier(data);
} catch (Exception e) {
e.printStackTrace();
}
return cls;
}
/**
* Run bayes net gui.
*
* @param bayesnet
*/
public void runBayesNetGUI(BayesNet bayesnet) {
// display graph
GraphVisualizer gv = new GraphVisualizer();
try {
gv.readBIF(bayesnet.graph());
} catch (BIFFormatException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
JFrame jf = new JFrame("BayesNet graph");
jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jf.setSize(800, 600);
jf.getContentPane().setLayout(new BorderLayout());
jf.getContentPane().add(gv, BorderLayout.CENTER);
jf.setVisible(true);
gv.layoutGraph();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Bayes Net
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Gets the marginal.
*
* @param nodeName
* @param state
* @return the marginal
*/
public double getMarginal(String nodeName, String state) {
int nCurrentNode = 0;
String [] outcomes = m_BayesNet.getValues(nodeName);
try {
nCurrentNode = m_BayesNet.getNode(nodeName);
int iValue = 0;
while (iValue < outcomes.length && !outcomes[iValue].equals(state)) {
iValue++;
}
double[] d= m_BayesNet.getMargin(nCurrentNode);
return d[iValue];
} catch (Exception e) {
e.printStackTrace();
}
return 0.0;
}
/**
* Sets the evidence.
*
* @param nodeName
* @param evidence
*/
public void setEvidence(String nodeName, String evidence) {
if( m_BayesNet != null ){
int nCurrentNode = 0;
try {
String [] outcomes = m_BayesNet.getValues(nodeName);
nCurrentNode = m_BayesNet.getNode(nodeName);
int iValue = 0;
while (iValue < outcomes.length && !outcomes[iValue].equals(evidence)) {
iValue++;
}
if (iValue == outcomes.length) {
iValue = -1;
}
if (iValue < outcomes.length) {
if (m_BayesNet.getEvidence(nCurrentNode) < 0 && iValue >= 0) {
m_BayesNet.setEvidence(nCurrentNode, iValue);
m_marginCalculatorWithEvidence.setEvidence(nCurrentNode, iValue);
} else {
m_BayesNet.setEvidence(nCurrentNode, iValue);
SerializedObject so = new SerializedObject(m_marginCalculator);
m_marginCalculatorWithEvidence = (MarginCalculator) so.getObject();
for (int iNode = 0; iNode < m_BayesNet.getNrOfNodes(); iNode++) {
if (m_BayesNet.getEvidence(iNode) >= 0) {
m_marginCalculatorWithEvidence.setEvidence(iNode, m_BayesNet.getEvidence(iNode));
}
}
}
for (int iNode = 0; iNode < m_BayesNet.getNrOfNodes(); iNode++) {
m_BayesNet.setMargin(iNode, m_marginCalculatorWithEvidence.getMargin(iNode));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Update status.
*/
void updateStatus() {
try {
m_marginCalculator = new MarginCalculator();
m_marginCalculator.calcMargins(m_BayesNet);
SerializedObject so = new SerializedObject(m_marginCalculator);
m_marginCalculatorWithEvidence = (MarginCalculator) so.getObject();
for (int iNode = 0; iNode < m_BayesNet.getNrOfNodes(); iNode++) {
if (m_BayesNet.getEvidence(iNode) >= 0) {
m_marginCalculatorWithEvidence.setEvidence(iNode, m_BayesNet.getEvidence(iNode));
}
}
for (int iNode = 0; iNode < m_BayesNet.getNrOfNodes(); iNode++) {
m_BayesNet.setMargin(iNode, m_marginCalculatorWithEvidence.getMargin(iNode));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}