Справочная информация:
Если я открою графический интерфейс Weka Explorer, обучу дерево J48 и протестирую, используя наборы обучения и тестирования NSL-KDD, будет получено сокращенное дерево. Графический интерфейс Weka Explorer выражает алгоритмы, обосновывающие, будет ли что-то классифицироваться как аномалия или нет в терминах запросов, таких как src_bytes <= 28 </em>.
Снимок экрана графического интерфейса пользователя Weka Explorer, на котором показано обрезанное дерево
Вопрос:
Обращаясь к примеру с обрезанным деревом, созданному с помощью графического интерфейса Weka Explorer, как программно заставить weka выразить обоснование для каждой классификации экземпляров в Java?
т.е. Экземпляр A был классифицирован как аномалия как src_bytes <28 &&
dst_host_srv_count <88 && dst_bytes <3 и т. д. </p>
Пока я смог:
Обучите и протестируйте дерево J48 в наборе данных NSL-KDD.
Вывести описание дерева J48 в Java.
Возвращает дерево J48 как оператор if-then.
Но Я просто понятия не имею, как во время итерации каждого экземпляра на этапе тестирования выражать обоснование каждой классификации; без того, чтобы каждый раз вручную выводить дерево J48 в виде оператора if-then и добавлять многочисленные выражения println, когда каждое из них было запущено (что я действительно предпочел бы не делать, так как это значительно увеличило бы требования вмешательства человека в долгосрочной перспективе).
Дополнительные снимки экрана:
Снимок экрана 'описания дерева J48 в Java'
Снимок экрана 'дерева J48 как оператора if-then'
Код:
public class Junction_Tree {
String train_path = "KDDTrain+.arff";
String test_path = "KDDTest+.arff";
double accuracy;
double recall;
double precision;
int correctPredictions;
int incorrectPredictions;
int numAnomaliesDetected;
int numNetworkRecords;
public void run() {
try {
Instances train = DataSource.read(train_path);
Instances test = DataSource.read(test_path);
train.setClassIndex(train.numAttributes() - 1);
test.setClassIndex(test.numAttributes() - 1);
if (!train.equalHeaders(test))
throw new IllegalArgumentException("datasets are not compatible..");
Remove rm = new Remove();
rm.setAttributeIndices("1");
J48 j48 = new J48();
j48.setUnpruned(true);
FilteredClassifier fc = new FilteredClassifier();
fc.setFilter(rm);
fc.setClassifier(j48);
fc.buildClassifier(train);
numAnomaliesDetected = 0;
numNetworkRecords = 0;
int n_ana_p = 0;
int ana_p = 0;
correctPredictions = 0;
incorrectPredictions = 0;
for (int i = 0; i < test.numInstances(); i++) {
double pred = fc.classifyInstance(test.instance(i));
String a = "anomaly";
String actual;
String predicted;
actual = test.classAttribute().value((int) test.instance(i).classValue());
predicted = test.classAttribute().value((int) pred);
if (actual.equalsIgnoreCase(a))
numAnomaliesDetected++;
if (actual.equalsIgnoreCase(predicted))
correctPredictions++;
if (!actual.equalsIgnoreCase(predicted))
incorrectPredictions++;
if (actual.equalsIgnoreCase(a) && predicted.equalsIgnoreCase(a))
ana_p++;
if ((!actual.equalsIgnoreCase(a)) && predicted.equalsIgnoreCase(a))
n_ana_p++;
numNetworkRecords++;
}
accuracy = (correctPredictions * 100) / (correctPredictions + incorrectPredictions);
recall = ana_p * 100 / (numAnomaliesDetected);
precision = ana_p * 100 / (ana_p + n_ana_p);
System.out.println("\n\naccuracy: " + accuracy + ", Correct Predictions: " + correctPredictions
+ ", Incorrect Predictions: " + incorrectPredictions);
writeFile(j48.toSource(J48_if-then.java));
writeFile(j48.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Junction_Tree JT1 = new Junction_Tree();
JT1.run();
}
}