/*
* KNNgui.java
*
* Created on December 17, 2005, 6:27 PM
*/
package cap5638;
import javax.swing.*;
import java.io.*;
import weka.gui.arffviewer.ArffPanel;
import java.awt.event.*;
import weka.core.*;
import weka.classifiers.*;
import weka.core.converters.ArffLoader;
/**
* A graphical implementation to perform k-nearest-neighbor classification
* @author JohnChap
*/
public class KnnGui extends javax.swing.JFrame {
private static String title = "John KNN";
private File trainingFilePath = new File(".");
private File testFilePath = new File(".");
private Instances trainingSet;
private Instances testSet;
private int classifierSelect = 0;
private int testSettingsSelect = 0;
private int[] leaveOutAttribute;
private boolean resultsToFile = false;
private ArffPanel arffPanel1;
private ArffPanel arffPanel2;
private int testNumber = 0;
/** Creates new form KNNgui */
public KnnGui() {
super(title);
initComponents();
initRadioButtons();
initButtons();
//setting up for first run
useTestSetRadio.setEnabled(false);
partialDistanceOptionsButton.setEnabled(false);
writeResultsCheckBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (!resultsToFile) {
resultsToFile = true;
}
else resultsToFile = false;
}
});
}
/** finish initializing buttons and binding them to actions
*/
private void initButtons() {
trainingLoadButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
loadTrainingFile();
tabPanel2.setEnabled(true);
}
});
testLoadButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
loadTestFile();
useTestSetRadio.setEnabled(true);
}
});
partialDistanceOptionsButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
partialDistanceDialog();
}
});
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
runKnn();
}
});
}
/** finishes the Radio button initializations not covered in initComponents
*/
private void initRadioButtons() {
// classifier selection
simpleKNNRadio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
partialDistanceOptionsButton.setEnabled(false);
classifierSelect = 0;
}
});
partialDistanceRadio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
partialDistanceOptionsButton.setEnabled(true);
classifierSelect = 1;
}
});
// test settings
useTestSetRadio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
testSettingsSelect = 0;
startButton.setEnabled(true);
}
});
useTrainingSetRadio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
testSettingsSelect = 1;
startButton.setEnabled(true);
}
});
// grouping radio buttons
final ButtonGroup classifierButtonGroup = new ButtonGroup();
classifierButtonGroup.add(simpleKNNRadio);
classifierButtonGroup.add(partialDistanceRadio);
final ButtonGroup settingsButtonGroup = new ButtonGroup();
settingsButtonGroup.add(useTrainingSetRadio);
settingsButtonGroup.add(useTestSetRadio);
}
/** displays the patial distance dialog.
*/
private void partialDistanceDialog() {
String leaveOut = (String)JOptionPane.showInputDialog(partialDistanceOptionsButton,
"Enter the indices of attributes to leave out\n"
+ "(e.g. 1,2,3...)", "Partial distance Options",
JOptionPane.PLAIN_MESSAGE);
printStatus("Read user input: " + leaveOut);
try {
if ((leaveOut != null) && (leaveOut.length() > 0)) {
String[] strArray = leaveOut.split(",");
int[] indices = new int[strArray.length];
for (int i = 0; i < strArray.length; i++) {
indices[i] = Integer.parseInt(strArray[i]);
}
}
}
catch (NumberFormatException nfe) {
printStatus("Partial distance error: " + nfe.getMessage());
}
return;
}
/**
* Prints a message in the status text area
* @param message message to be printed to status text area
*/
private void printStatus(String message) {
statusTextArea.append(message + "\n");
}
/** Presents the training set file chooser dialog
*/
private void loadTrainingFile() {
try {
JFileChooser openChooser = new JFileChooser(trainingFilePath);
openChooser.showOpenDialog(null);
trainingFilePath = openChooser.getSelectedFile();
ArffLoader arffLoad = new ArffLoader();
arffLoad.setSource(trainingFilePath);
arffPanel1 = new ArffPanel(trainingFilePath.getPath());
trainingArffScrollPane.setViewportView(arffPanel1);
trainingSet = arffLoad.getDataSet();
printStatus("Training file: " + trainingFilePath.getPath() + " Loaded.");
}
catch (Exception e) {
printStatus("Error loading training set: " + e.getMessage());
}
}
/** Presents the test set file chooser dialog
*/
private void loadTestFile() {
try {
JFileChooser openChooser = new JFileChooser(testFilePath);
openChooser.showOpenDialog(null);
testFilePath = openChooser.getSelectedFile();
ArffLoader arffLoad = new ArffLoader();
arffLoad.setSource(trainingFilePath);
arffPanel2 = new ArffPanel(testFilePath.getPath());
testArffScrollPane.setViewportView(arffPanel2);
useTestSetRadio.setEnabled(true);
testSet = arffLoad.getDataSet();
printStatus("Test file: " + testFilePath.getPath() + " Loaded.");
}
catch (Exception e) {
printStatus("Error loading test set: " + e.getMessage());
}
}
/** builds a Weka-compliant array of arguments for Evaluation
* @param trainingFilename name of the file containing the training set.
* @param testFilename name of the file containing the test set.
* @param classAttribute index of the class attribute (1,2,3 etc.)
* @return an array of arguments
*/
private String[] argumentBuilder(String trainingFilename, String testFilename, int classAttribute) {
String[] args = new String[6];
args[0] = "-t";
args[1] = trainingFilename;
args[2] = "-T";
args[3] = testFilename;
args[4] = "-c";
args[5] = Integer.toString(classAttribute);
return args;
}
private void runKnn() {
try {
testNumber++;
if (trainingSet.classIndex() < 0) {
trainingSet.setClassIndex(trainingSet.numAttributes() - 1);
}
startButton.setEnabled(false);
//Evaluation knnEval = new Evaluation(trainingSet);
String output;
int cl