package org.neuroph.adapters.weka;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.neuroph.core.data.DataSet;
import org.neuroph.core.data.DataSetRow;
import weka.core.Attribute;
import weka.core.DenseInstance;
import weka.core.FastVector;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.converters.ConverterUtils;
/**
* Provides methods to convert dataset instances from Neuroph to Weka
* and from Weka to Neuroph.
*
* @author Zoran Sevarac
*/
public class WekaDataSetConverter {
/**
* Converts Weka data set to Neuroph data set
* @param wekaDataset Instances Weka data set
* @param numInputs int Number of inputs
* @param numOutputs int Number of outputs
* @return Neuroph data set
*/
public static DataSet convertWekaToNeurophDataset(Instances wekaDataset, int numInputs, int numOutputs) {
if (numInputs <= 0) {
throw new IllegalArgumentException("Number of inputs in DataSet cannot be zero or negative!");
}
if (numOutputs < 0) {
throw new IllegalArgumentException("Number of outputs in DataSet cannot be negative!");
}
if (numOutputs + numInputs < wekaDataset.numAttributes()) {
throw new IllegalArgumentException("Number of outputs and inputs should be equal to number of attributes from data set!");
}
// create supervised or unsupervised data set that will be returned
DataSet neurophDataset=null;
if(numOutputs > 0){
neurophDataset = new DataSet(numInputs,numOutputs);
}else{
neurophDataset = new DataSet(numInputs);
}
List classValues = new ArrayList();
// get all different class values (as ints) from weka dataset
for(Instance inst: wekaDataset){
Double classDouble = inst.classValue();
if(!classValues.contains(classDouble)){
classValues.add(classDouble);
}
}
Enumeration en = wekaDataset.enumerateInstances();
while(en.hasMoreElements()) { // iterate all instances from dataset
Instance instance = (Instance) en.nextElement();
double[] values = instance.toDoubleArray(); // get all the values from current instance
if(numOutputs == 0){ // add unsupervised row
neurophDataset.addRow(values);
} else { // add supervised row
double[] inputs = new double[numInputs];
double[] outputs = new double[numOutputs];
// set inputs
for(int k = 0; k < values.length; k++){
if(k < numInputs){
inputs[k] = values[k];
}
}
// set binary values for class outputs
int k = 0;
for(Double entry : classValues){
if(entry.doubleValue() == instance.classValue()){ // if the
outputs[k] = 1;
}else{
outputs[k] = 0;
}
k++;
}
DataSetRow row = new DataSetRow(inputs, outputs);
row.setLabel(instance.stringValue(instance.classIndex()));
neurophDataset.addRow(row);
}
}
return neurophDataset;
}
/**
* Converts Neuroph data set to Weka data set
* @param neurophDataset DataSet Neuroph data set
* @return instances Weka data set
*/
public static Instances convertNeurophToWekaDataset(DataSet neurophDataset) {
Map classValues = getClassValues(neurophDataset);
Instances instances = createEmptyWekaDataSet(neurophDataset.getInputSize(), neurophDataset.size(), classValues);
int numInputs = neurophDataset.getInputSize();
// int numOutputs = neurophDataset.getOutputSize();
int numOutputs = 1; // why is this, and the above line is commented? probably because weka
instances.setClassIndex(numInputs);
Iterator iterator = neurophDataset.iterator();
while(iterator.hasNext()) { // iterate all dataset rows
DataSetRow row = iterator.next();
if (numOutputs> 0) { // if it is supervised (has outputs)
Instance instance = new DenseInstance(numInputs + numOutputs);
for(int i=0; i< numInputs; i++) {
instance.setValue(i, row.getInput()[i] );
}
instance.setDataset(instances);
// set output attribute, as String and double value of class
for(Map.Entry entry : classValues.entrySet()){
if(entry.getValue().equals(row.getLabel())){
instance.setValue(numInputs, entry.getValue());
double[] rowDouble = row.getDesiredOutput();
for(int i = 0; i < rowDouble.length; i++){
if(rowDouble[i] == 1){
instance.setValue(numInputs, i);
}
break;
}
break;
}
}
instances.add(instance);
} else { // if it is unsupervised - has only inputs
// create new instance
Instance instance = new DenseInstance(numInputs);
// set all input values
for(int i=0; i< numInputs; i++) {
instance.setValue(i, row.getInput()[i] );
}
// and add instance to weka dataset
instance.setDataset(instances);
instances.add(instance);
}
}
return instances;
}
/**
* Creates and returns empty weka data set
* @param numOfAttr int Number of attributes without class attribute
* @param capacity int Capacity of sample
* @return empty weka data set
*/
private static Instances createEmptyWekaDataSet(int numOfAttr, int capacity, Map classValues) {
//Vector for class attribute possible values
FastVector fvClassVal = new FastVector();
//Map double value for every possible class value
HashMap classVals = new HashMap();
//Map class label with double key value
HashMap classValsDoubleAsKey = new HashMap();
//ind represents double value for class attribute
int ind = 0;
//loop through possible class values
for (Map.Entry values : classValues.entrySet()) {
//add value to vector
fvClassVal.addElement(values.getValue());
//map double value for class value
classVals.put(values.getValue(), new Double(ind));
//map class label for double key value
classValsDoubleAsKey.put(new Double(ind),values.getValue());
ind++;
}
//Class attribute with possible values
Attribute classAttribute = new Attribute("theClass", fvClassVal, classValues.size());
//Creating attribute vector for Instances class instance
FastVector fvWekaAttributes = new FastVector(numOfAttr + 1);
//Fill vector with simple attributes
for (int i = 0; i < numOfAttr; i++) {
fvWekaAttributes.addElement(new Attribute(i + "", i));
}
//Add class attribute to vector
fvWekaAttributes.addElement(classAttribute);
//newDataSet as Instances class instance
Instances newDataSet = new Instances("newDataSet", fvWekaAttributes, capacity);
return newDataSet;
}
/**
* Returns all posisible class values
* @param neurophDataset Neuroph data set
* @return Map with all possible class values
*/
private static Map getClassValues(DataSet neurophDataset) {
Map classValues = new HashMap();
for(DataSetRow row : neurophDataset.getRows()){
if(!classValues.containsValue(row.getLabel())){
classValues.put(row.getDesiredOutput(), row.getLabel());
}
}
return classValues;
}
/**
* Creates neuroph dataset from arff weka file.
*
* @param filePath Path to the file.
* @param numInputs Number of inputs.
* @return Neuroph dataset.
* @throws Exception
*/
public static DataSet createDataSetFromFile(String filePath, int numInputs) throws Exception {
return createDataSetFromFile(filePath, numInputs, 0);
}
/**
* Creates neuroph dataset from arff weka file.
*
* @param filePath Path to the file.
* @param numInputs Number of inputs.
* @param numOutputs Number of outputs.
* @return Neuroph dataset.
*/
public static DataSet createDataSetFromFile(String filePath, int numInputs, int numOutputs) {
try {
ConverterUtils.DataSource dataSource = new ConverterUtils.DataSource(filePath);
Instances wekaDataset = dataSource.getDataSet();
wekaDataset.setClassIndex(numInputs);
DataSet neurophDataset = WekaDataSetConverter.convertWekaToNeurophDataset(wekaDataset, numInputs, numOutputs);
return neurophDataset;
} catch (Exception e) {
return new DataSet(0);
}
}
}
Ads help maintain this website.