Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/target/
.idea
30 changes: 24 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ The following algorithms are implemented:
Main class: myra.algorithm.AntMiner
```

The first rule induction ACO classification algorithm. Ant-Miner uses a sequentical covering strategy combined with an ACO search to create a list of rules. Ant-Miner only supports categorical attributes, continuous attributes need to be discretised in a pre-processing step.
The first rule induction ACO classification algorithm. Ant-Miner uses a sequential covering strategy combined with an ACO search to create a list of rules. Ant-Miner only supports categorical attributes, continuous attributes need to be discretised in a pre-processing step.

##### Continuous Ant-Miner (*c*Ant-Miner)
```
Expand Down Expand Up @@ -66,24 +66,29 @@ A decision tree induction algorithm that uses an ACO procedure to creates decisi
Main class: myra.algorithm.AntMinerReg
```

The first rule induction ACO regression algorithm. Ant-Miner-Reg uses a sequentical covering strategy combined with an ACO search to create a list of regression rules.
The first rule induction ACO regression algorithm. Ant-Miner-Reg uses a sequential covering strategy combined with an ACO search to create a list of regression rules.

##### Hierarchical Multi-Label Ant-Miner (*hm*Ant-Miner)
```
Main class: myra.algorithm.HierarchicalMultiLabelAntMiner
```

*hm*Ant-Miner is the first Ant-Miner variation for hierarchical multi-label classification problems. *hm*Ant-Miner uses a sequentical covering strategy combined with an ACO search to create a list of hierarchical classification rules that predict multiple class labels from a hierarchy.
*hm*Ant-Miner is the first Ant-Miner variation for hierarchical multi-label classification problems. *hm*Ant-Miner uses a sequential covering strategy combined with an ACO search to create a list of hierarchical classification rules that predict multiple class labels from a hierarchy.

#### *e*Ant-Miner<sub>PB+HMA</sub>
```
Main class: myra.algorithm.EnsemblePittsburghMixedAttributeAntMiner
```

### Running the algorithms

All algorihtms can be used in the command line:
All algorithms can be used in the command line:

```
java -cp myra-<version>.jar <main class> -f <arff training file>
```

where `<version>` is MYRA version number (e.g., `5.0`), `<main class>` is the main class name of the algorithm and `<aff training file>` is the path to the ARFF file to be used as training data. The minimum requirement to run an algorihtm is a training file. If no training file is specified, a list of options is printed:
where `<version>` is MYRA version number (e.g., `5.0`), `<main class>` is the main class name of the algorithm and `<aff training file>` is the path to the ARFF file to be used as training data. The minimum requirement to run an algorithm is a training file. If no training file is specified, a list of options is printed:

```
[febo@uok myra]$ java -cp myra-4.5.jar myra.algorithm.ContinuousAntMiner
Expand Down Expand Up @@ -129,7 +134,7 @@ The following options are available:
--parallel <cores> enable parallel execution in multiple cores; if no cores
are specified, use all available cores
```
Usinng command-line options you can tweak the parameters of an algorithm. Note that when running the algorithm in parallel (`--parallel` option), there is no guarantee that it will have the same behaviour even if the same seed value is used (`-s` option), since the thread allocation is not controlled by the code.
Using command-line options you can tweak the parameters of an algorithm. Note that when running the algorithm in parallel (`--parallel` option), there is no guarantee that it will have the same behaviour even if the same seed value is used (`-s` option), since the thread allocation is not controlled by the code.

### Citation Policy

Expand Down Expand Up @@ -288,3 +293,16 @@ If you also would like to make a reference to the MYRA repository, please includ
pages = {165–-181}
}
```

#### Ensemble Ant-Miner (*e*Ant-Miner<sub>PB+HMA</sub>)
* J. Brookhouse, A. Helal and F.E.B. Otero. An Ensemble Ant Colony Optimisation Algorithm with a Hybrid Pheromone Model for Learning Rule Lists. In: Proceedings of the Genetic and Evolutionary Computation Conference (GECCO '25), pp. 1532&ndash;1539, 2025.
```
@INPROCEEDINGS{Brookhouse2025ensemble,
author = {J. Brookhouse and A. Helal and F.E.B. Otero},
title = {An Ensemble Ant Colony Optimisation Algorithm with a Hybrid Pheromone Model for Learning Rule Lists},
booktitle = {Proceedings of the Genetic and Evolutionary Computation Conference (GECCO '25)},
publisher = {Association for Computing Machinery}
year = {2025},
pages = {1532--1539}
}
```
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,20 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>8</maven.compiler.release>
<maven.compiler.release>25</maven.compiler.release>
</properties>

<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.6.2</version>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.6.2</version>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down
147 changes: 147 additions & 0 deletions src/main/java/myra/algorithm/EnsembleMixedAttributeAntMiner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
/*
* EnsembleMixedAttributeAntMiner.java
* (this file is part of MYRA)
*
* Copyright 2008-2025
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package myra.algorithm;

import static myra.Config.CONFIG;
import static myra.Scheduler.COLONY_SIZE;
import static myra.ensemble.bagging.EnsembleModel.DEFAULT_COLONIES;
import static myra.ensemble.bagging.FeatureBagging.DEFAULT_FEATURE_BAGGING;
import static myra.ensemble.bagging.InstanceBootstrapping.DEFAULT_INSTANCE_BOOTSTRAPPING;
import static myra.rule.Heuristic.DEFAULT_HEURISTIC;
import static myra.rule.Heuristic.DYNAMIC_HEURISTIC;
import static myra.rule.irl.RuleFactory.DEFAULT_FACTORY;

import java.util.ArrayList;
import java.util.Collection;

import myra.Option;

import myra.Config.ConfigKey;
import myra.Option.DoubleOption;
import myra.Option.IntegerOption;

import myra.classification.ClassificationModel;
import myra.datamining.Dataset;
import myra.ensemble.bagging.BaggingArchiveRuleFactory;
import myra.ensemble.bagging.EnsembleModel;
import myra.ensemble.bagging.FeatureBagging;
import myra.ensemble.bagging.InstanceBootstrapping;

import myra.rule.archive.Graph;
import myra.rule.irl.SequentialCovering;

/**
* Executable class file for the <code><i>e</i>Ant-Miner<sub>HMA</sub></code>
* algorithm.
*
* @author Ayah Helal
* @author James Brookhouse
*/
public class EnsembleMixedAttributeAntMiner extends MixedAttributeAntMiner {

public static final ConfigKey<Double> DEFAULT_VALIDATION = new ConfigKey<>();

@Override
protected void defaults() {
super.defaults();

// configuration not set via command line
CONFIG.set(DEFAULT_FACTORY, new BaggingArchiveRuleFactory());

// default configuration values
CONFIG.set(DEFAULT_FEATURE_BAGGING, 0.4);
CONFIG.set(DEFAULT_INSTANCE_BOOTSTRAPPING, 0.4);
CONFIG.set(DEFAULT_VALIDATION, 0.2);
CONFIG.set(DEFAULT_COLONIES, 10);
CONFIG.set(COLONY_SIZE, 10);
}

@Override
protected Collection<Option<?>> options() {
ArrayList<Option<?>> options = new ArrayList<>();

for (Option<?> option : super.options()) {
if (option.getKey() != DEFAULT_HEURISTIC
&& option.getKey() != DYNAMIC_HEURISTIC) {
options.add(option);
}
}

// percentage of bagged features
options.add(new DoubleOption(DEFAULT_FEATURE_BAGGING,
"fb",
"specify the percentage of feature bagging %s",
"value"));

// percentage of bagged features
options.add(new IntegerOption(DEFAULT_COLONIES,
"ec",
"specify the number of different colonies %s",
"value"));

// percentage of bagged instances
options.add(new DoubleOption(DEFAULT_INSTANCE_BOOTSTRAPPING,
"ib",
"specify the percentage of instance bagging %s",
"value"));

// percentage of bagged instances
options.add(new DoubleOption(DEFAULT_VALIDATION,
"va",
"specify the percentage of the dataset to be used for validation %s",
"value"));

return options;
}

@Override
public ClassificationModel train(Dataset dataset) {
int colonies = CONFIG.get(DEFAULT_COLONIES);
EnsembleModel model = new EnsembleModel();

for(int i=0 ; i < colonies;i++) {
Dataset set = InstanceBootstrapping.bootstrapping(dataset,true);
set.setMask(FeatureBagging.generateBaggingMask(dataset.attributes().length));
SequentialCovering seco = new SequentialCovering();
model.add(new ClassificationModel(seco.train(dataset, new Graph(dataset))));
}
model.setQuality(dataset);
return new ClassificationModel(model);
}

@Override
public String description() {
return "Ensemble Mixed-Attribute Ant-Miner";
}

/**
* <code>Ant-Miner<sub>HMA</sub></code> entry point.
*
* @param args
* command-line arguments.
*
* @throws Exception
* If an error occurs &mdash; e.g., I/O error.
*/
public static void main(String[] args) throws Exception {
EnsembleMixedAttributeAntMiner algorithm = new EnsembleMixedAttributeAntMiner();
algorithm.run(args);
}
}
153 changes: 153 additions & 0 deletions src/main/java/myra/algorithm/EnsemblePittsburghContinuousAntMiner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/*
* EnsembleMixedAttributeAntMiner.java
* (this file is part of MYRA)
*
* Copyright 2008-2025
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package myra.algorithm;

import static myra.Config.CONFIG;
import static myra.Scheduler.COLONY_SIZE;
import static myra.rule.Heuristic.DEFAULT_HEURISTIC;
import static myra.rule.Heuristic.DYNAMIC_HEURISTIC;

import static myra.ensemble.bagging.EnsembleModel.DEFAULT_COLONIES;
import static myra.ensemble.bagging.FeatureBagging.DEFAULT_FEATURE_BAGGING;
import static myra.ensemble.bagging.InstanceBootstrapping.DEFAULT_INSTANCE_BOOTSTRAPPING;

import java.util.ArrayList;
import java.util.Collection;

import myra.IterativeActivity;
import myra.Option;
import myra.Scheduler;
import myra.Option.DoubleOption;
import myra.Option.IntegerOption;

import myra.classification.ClassificationModel;

import myra.datamining.Dataset;
import myra.ensemble.bagging.BaggingLevelRuleFactory;
import myra.ensemble.bagging.EnsembleModel;
import myra.ensemble.bagging.FeatureBagging;
import myra.ensemble.bagging.InstanceBootstrapping;
import myra.rule.RuleList;
import myra.rule.Graph;
import myra.rule.pittsburgh.FindRuleListActivity;
import myra.rule.pittsburgh.LevelPheromonePolicy;

/**
* This class represents the <code><i>ec</i>Ant-Miner<sub>PB</sub></code>
* implementation, as described in the paper:
*
* <pre>
* &#64;ARTICLE{Brookhouse2025ensemble,
* author = {J. Brookhouse and A. Helal and F.E.B. Otero},
* title = {An Ensemble Ant Colony Optimisation Algorithm with a Hybrid Pheromone Model for Learning Rule Lists},
* journal = {Genetic and Evolutionary Computation Conference (GECCO '25)},
* year = {2025},
* pages = {1--9}
* }
* </pre>
*
* @author Ayah Helal
* @author James Brookhouse
*/
public class EnsemblePittsburghContinuousAntMiner extends PittsburghContinuousAntMiner {

@Override
protected void defaults() {
super.defaults();
// default configuration values
CONFIG.set(DEFAULT_FEATURE_BAGGING, 0.4);
CONFIG.set(DEFAULT_INSTANCE_BOOTSTRAPPING, 0.4);
CONFIG.set(DEFAULT_COLONIES, 10);
CONFIG.set(COLONY_SIZE, 10);
}

@Override
protected Collection<Option<?>> options() {
ArrayList<Option<?>> options = new ArrayList<>();

for (Option<?> option : super.options()) {
if (option.getKey() != DEFAULT_HEURISTIC
&& option.getKey() != DYNAMIC_HEURISTIC) {
options.add(option);
}
}

// percentage of bagged features
options.add(new DoubleOption(DEFAULT_FEATURE_BAGGING,
"fb",
"specify the percentage of feature bagging %s",
"value"));

// percentage of bagged features
options.add(new IntegerOption(DEFAULT_COLONIES,
"ec",
"specify the number of different colonies %s",
"value"));

// percentage of bagged instances
options.add(new DoubleOption(DEFAULT_INSTANCE_BOOTSTRAPPING,
"ib",
"specify the percentage of instance bagging %s",
"value"));
return options;
}

@Override
public ClassificationModel train(Dataset dataset) {
int colonies = CONFIG.get(DEFAULT_COLONIES);
EnsembleModel model = new EnsembleModel();

for(int i=0 ; i < colonies;i++) {
Dataset set = InstanceBootstrapping.bootstrapping(dataset,true);
set.setMask(FeatureBagging.generateBaggingMask(dataset.attributes().length));
IterativeActivity<RuleList> activity =
new FindRuleListActivity(new Graph(dataset),
dataset,
new BaggingLevelRuleFactory(),
new LevelPheromonePolicy());

Scheduler<RuleList> scheduler = Scheduler.newInstance(1);
scheduler.setActivity(activity);
scheduler.run();
model.add(new ClassificationModel(activity.getBest()));
}
model.setQuality(dataset);
return new ClassificationModel(model);
}

@Override
public String description() {
return "Ensemble Pittsburgh Continuous-Attribute Ant-Miner";
}

/**
* <code><i>ec</i>Ant-Miner<sub>PB</sub></code> entry point.
*
* @param args
* command-line arguments.
*
* @throws Exception
* If an error occurs &mdash; e.g., I/O error.
*/
public static void main(String[] args) throws Exception {
EnsemblePittsburghContinuousAntMiner algorithm = new EnsemblePittsburghContinuousAntMiner();
algorithm.run(args);
}
}
Loading