Skip to content
Open
Show file tree
Hide file tree
Changes from 69 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
53682c8
fixs in main seq-cov loop
edo-007 Sep 30, 2025
9acf572
fixing tests on sequentialcovering
edo-007 Oct 9, 2025
d2ecfac
implementazione naive irep
NickkTr Oct 13, 2025
008166b
fixes for committing
NickkTr Oct 13, 2025
189f409
fixs tests
edo-007 Oct 13, 2025
8e01699
Merge branch 'clabels' of https://github.com/aclai-lab/ModalDecisionL…
edo-007 Oct 13, 2025
3ee20a6
clean TODO file
edo-007 Oct 14, 2025
8563bd7
added InstanceSet
edo-007 Oct 14, 2025
421c07e
restructuring functions for Antecedent
edo-007 Oct 14, 2025
9f96f3a
cleanup + using Antecedent structure
edo-007 Oct 15, 2025
aed6988
message
edo-007 Oct 15, 2025
27f3166
fixed sequentialcovering stopping condition
edo-007 Oct 18, 2025
51016e3
Fix after antecedent + sequentialcovering merge with clabels
NickT42 Oct 20, 2025
5eaa49c
Merge with latest commits for pushing
NickT42 Oct 20, 2025
5053f53
Syntax fixes from last commits
NickT42 Oct 20, 2025
de34e80
Further optimizations in IREP_Star
NickT42 Oct 20, 2025
4e02596
removed commented
edo-007 Oct 21, 2025
418fe5b
working with Atomgenerator, not working with RandomGenerator
edo-007 Oct 21, 2025
9796994
removed checks from IREP*
edo-007 Nov 5, 2025
003d463
refactoring of the pruning function. Correct functioning needs to be …
edo-007 Nov 5, 2025
500efab
Not working, breaking changes
edo-007 Nov 5, 2025
63fc9f4
Fixs in pruneantecedent
edo-007 Nov 8, 2025
afcdd76
fixs pruning function
edo-007 Nov 8, 2025
8111590
fixs
edo-007 Nov 8, 2025
a861eec
fixes after restructuring
NickT42 Nov 10, 2025
2aedd2d
TODO adds
edo-007 Nov 11, 2025
6700a0d
first sanity check on irepstar
NickT42 Nov 12, 2025
5c8f21e
further test on findbestantecedent
NickT42 Nov 14, 2025
2420846
bug fixes and first successful irepstar test
NickT42 Nov 17, 2025
537fe7e
Merge branch 'feature/smethods' of https://github.com/aclai-lab/Modal…
edo-007 Nov 19, 2025
ebf0d65
cleaning
edo-007 Nov 19, 2025
661af34
tip for working with vectors and indices
edo-007 Nov 19, 2025
991c795
Fixs
edo-007 Nov 19, 2025
155801b
WIP: local changes before pulling new updates
NickT42 Nov 19, 2025
99d64a0
Merge branch 'feature/smethods' of https://github.com/aclai-lab/Modal…
NickT42 Nov 19, 2025
f1c6295
multiclass irep first sketch
NickT42 Nov 20, 2025
db1c6cb
Commentend IREP for all classes
edo-007 Nov 24, 2025
184a475
code cleanup + weights used in pruning function
NickT42 Nov 27, 2025
9a6d4c3
Merge branch 'feature/smethods' of https://github.com/aclai-lab/Modal…
NickT42 Nov 27, 2025
a1c7452
loss functions system rewrite first blueprint
NickT42 Nov 27, 2025
0c5227f
Gini index modified as singleton
edo-007 Nov 27, 2025
fee6e23
fix comment
edo-007 Nov 27, 2025
223da24
dispatching system for symmetric/asymmetric loss functions
NickT42 Dec 11, 2025
76fcd6f
refactoring + circular imports fixed
NickT42 Feb 17, 2026
07bccc8
more import fixes and namespace handling
NickT42 Feb 19, 2026
3f3ba81
style and comments
edo-007 Feb 20, 2026
84791c0
Merge branch 'feature/smethods' of https://github.com/aclai-lab/Modal…
edo-007 Feb 20, 2026
fd44aea
Cleaned comments in loss_functions.jl
edo-007 Feb 20, 2026
013aa0d
tests + optimization + minor features
NickT42 Mar 2, 2026
f910aca
tests on metrics and loss functions completed
NickT42 Mar 6, 2026
3379264
FOILGain test updated and fixed
NickT42 Mar 6, 2026
9f93126
code cleanup + optimization in irepstar
NickT42 Mar 6, 2026
f0ce1c1
further tests and basic benchmarks on irep + slight code cleanup
NickT42 Mar 7, 2026
102995b
first actual random decision lists implementation
NickT42 Mar 8, 2026
5a6660d
added bootstrapping + feature selection in build_rdl function, tests …
NickT42 Mar 8, 2026
6105a94
fixed multiclass irep* + first multiclass irep* test
NickT42 Mar 8, 2026
b2a2c74
multiclass irep* bug fix + more formally accurate tests on irep*
NickT42 Mar 9, 2026
b6aa150
implemented repeated cross validation for each irep*/rdl test
NickT42 Mar 10, 2026
155d3e4
rng argument fixed in irepstar and build_rdl for reproducibility + sl…
NickT42 Mar 10, 2026
8460750
minor bug fix on irep* stopping condition
NickT42 Mar 10, 2026
6319ec2
ripper implementation + test on the iris dataset
NickT42 Mar 14, 2026
1a48da9
bug fix in ripper
NickT42 Mar 14, 2026
593dbf8
better tools for testing + slight bug fix in ripper
NickT42 Mar 16, 2026
952e005
added TrainingState and DataSplit structures for code cleanup
NickT42 Mar 22, 2026
875cdb8
multiclass ripper and build_rdl + build_rdl is now model agnostic + t…
NickT42 Mar 26, 2026
3388d34
parallelization of ensemble building loop + further tests for ensembl…
NickT42 Mar 30, 2026
dcb3473
added atoms and natoms for alphabet() to work + base test script for …
NickT42 Mar 31, 2026
8d7a579
bug fix + imports fix
NickT42 Apr 9, 2026
af3a44f
dependencies updated
NickT42 Apr 9, 2026
2f91f0c
bug fixes + removed ensemble learning (moved to SoleModels PR)
NickT42 Apr 13, 2026
a218725
changed test operators for compatibility with LUMEN
NickT42 Apr 14, 2026
4caa06a
fixed optimization in RIPPER
NickT42 Apr 27, 2026
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
38 changes: 27 additions & 11 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
name = "ModalDecisionLists"
uuid = "dbece2fb-9d58-4710-9902-4ec759308ae8"
authors = ["Giovanni PAGLIARINI", "Edoardo PONSANESI"]
version = "0.1.0"
authors = ["Giovanni PAGLIARINI", "Edoardo PONSANESI"]

[deps]
CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
MLJModelInterface = "e80e1ace-859a-464e-9ed9-23947d8ae3ea"
Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Expand All @@ -17,24 +18,37 @@ SoleData = "123f1ae1-6307-4526-ab5b-aab3a92a2b8c"
SoleLogics = "b002da8f-3cb3-4d91-bbe3-2953433912b5"
SoleModels = "4249d9c7-3290-4ddd-961c-e1d3ec2467f8"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"

[compat]
CategoricalArrays = "0.10"
DataFrames = "1.6"
BenchmarkTools = "1"
CSV = "0.10"
CategoricalArrays = "1"
DataFrames = "1.8"
DecisionTree = "0.12"
Distributions = "0.25"
FillArrays = "1"
MLJModelInterface = "1.11"
Logging = "1.11"
MLJ = "0.21 - 0.23"
MLJBase = "1.12"
MLJDecisionTreeInterface = "0.4"
MLJModelInterface = "1.12"
MLJModels = "0.18"
Parameters = "0.12"
Printf = "1.11 - 1.12"
Random = "1.11.0"
RDatasets = "0.8"
Reexport = "1"
SoleBase = "0.12 - 0.13"
StatsBase = "0.30 - 0.34"
SoleBase = "0.13"
SoleData = "0.16"
SoleLogics = "0.13"
SoleModels = "0.10"
StatsBase = "0.34"
Tables = "1.12"
Test = "1"
julia = "1"
SoleData = "0.15 - 0.16"
SoleLogics = "0.11 - 0.13"
SoleModels = "0.9 - 0.10"

[extras]
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
DecisionTree = "7806a523-6efd-50cb-b5f6-3fa6f1930dbb"
Expand All @@ -44,7 +58,9 @@ MLJDecisionTreeInterface = "c6f25543-311c-4c74-83dc-3ea6d1015661"
MLJModels = "d491faf4-2d78-11e9-2867-c94bc002c0b7"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["BenchmarkTools", "DecisionTree", "MLJ", "MLJModels", "Printf", "MLJDecisionTreeInterface", "RDatasets", "Test", "CSV"]
test = ["BenchmarkTools", "DecisionTree", "MLJ", "MLJModels", "Printf", "MLJDecisionTreeInterface", "Statistics", "RDatasets", "Test", "CSV"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ using Pkg; Pkg.add("MLJ");
using Pkg; Pkg.add("ModalDecisionLists");

# Import packages
using MLJ
# using MLJ
using ModalDecisionLists
using Random

Expand Down
140 changes: 59 additions & 81 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,89 +1,67 @@
Main:
IREP*:
✔ Ripulire codice @started(26-03-06 22:07) @done(26-03-06 22:23) @lasted(16m59s)
✔ Chiedersi se il numero totale delle condizioni non equivalenti n, in _r_theory_bits deve essere richiamato oppure no @done(26-03-26 18:38)
☐ Checking ordinato delle condizioni: guardare checkedatoms (specific to general o viceversa) per ottimizzazione
✔ Guardare pacchetto Logging.jl per gestire l'equivalente di verbosity @done(26-03-06 22:07)
✔ Inserire gestione pesi nella funzione di pruning @done(25-11-24 16:00)
✔ Fixare e testare la versione di IREP* multiclasse @done(26-03-08 22:33)
✔ Fare più test sulla versione di IREP* multiclasse, aggiungere print di debug anche lì come nel caso a classe singola @done(26-03-09 19:35)
☐ Il calcolo della description length in IREP* dovrebbe usare i pesi per determinare quanto costa descrivere ogni sample?
-> bisognerebbe assicurarsi che i pesi siano normalizzati

Generic:
☐ Delete unnecessary CN2 implementation
✔ arrivare a due implementazioni uguali @done(24-04-03 11:05)
✔ build_cn2 as orange_cn2(simple selector version) @done(24-03-14 20:39)
✔ build_base_cn2 as orange_cn2(simple selector version) @done(24-03-16 12:00)
Loss functions e Metrics:
✔ Creare funzione wrapper per count, prendere codice da laplace_accuracy @started(25-11-24 14:52) @done(25-11-24 15:12) @lasted(20m4s)
✔ Sostituire gli usi di counts() nel calcolo dell'entropia e di impurità di Gini con count_labels_distribution @done(26-03-02 17:37)
✔ Scrivere il sistema di dispatching per le loss functions in findbestantecedent e sortedantecedents @done(25-12-11 19:10)
✔ Gestire warning sugli import e più generalmente aggiornare il resto del codice/dei sistemando gli import @done(26-03-02 15:13)
✔ Creare funzione information gain usando accuratezza su true positive e true negatives come in wittgenstein (base.py linea 387) @done(25-12-11 19:09)
✔ Finire di implementare le varie loss functions @started(26-03-02 17:39) @done(26-03-06 18:38) @lasted(4d59m48s)
✔ Scrivere tests per le funzioni in metrics @done(26-03-06 18:38)

☐ new section in docu
✔ MLJ interface for cn2 @done(24-04-29 18:23)
☐ Metrics
✔ Entropy @done(24-04-29 18:23)
✔ Laplace @done(24-04-29 18:23)
✔ entropyMDL @done(24-04-29 18:23)
☐ Rule validation
☐ LRS
☐ Weighted relative accuracy
☐ SyntaxSearch
# Formule di una certa grammatica e di un certo alfabeto si generan così
# a = ExplicitAlphabet(@atoms p q r s)
# g = SoleLogics.CompleteFlatGrammar(a, [∧, ∨])
# formulas(g; maxdepth = 2)
# formulas(g; maxdepth = 100, nformulas = 100)
☐ Define DecisionSet and corresponding apply method


Utility:
✔ Implementing instances(PropositionalLogiset) @done(24-03-04 17:11)
✔ Gestione errore in istanziazione PropositionalLogiset{DataFrame}(SubDataFrame) @done(24-04-13 04:08)
# già scritta soluzione temporanea
✔ add alphabet parameter @done(24-04-03 11:06)
✔ check empty row table in ProposiionlLogiset costruction @done(24-04-03 17:35)
✔ map from integer to original class names @done(24-04-10 16:31)
☐ semplificazione LmCF o LmDF
# scalarminimizer
✔ BoundedScalarCond -> UnivariateScalarCondion @done(24-04-10 16:31)
Testing:
✔ 100% accuracy when testing on training data ? @done(24-03-01 03:02)
☐ Only real attributes
☐ Biopsy
☐ Ionosphere
☐ Mobile
☐ Yeast
☐ Abalone

Future:
✔ Differenziare caso attributi discreti/categoriali


MLJ-Interface:
✔ Constructor with keyword arguments @done(24-04-12 13:32)
✔ fit @done(24-06-01 13:59)
# parlare con gio di CategoricalArrays
✔ predict @done(24-06-01 13:59)
✔ clean! @done(24-06-01 13:59)
# https://juliaai.github.io/MLJModelInterface.jl/dev/quick_start_guide/
✔ MMI.metadata_pkg.MMI.metadata_pkg @done(24-06-01 13:59)
Test IREP*:
✔ Rimpiazzare rand_seed con un oggetto rng così come è standard in Julia @done(26-03-10 15:36)
✔ Testare che la riproducibilità di irep* funzioni davvero @done(26-03-10 15:36)
✔ Implementare stopping condition descritta realmente nel paper e confrontare le performance con quella precedente @done(26-03-10 18:47)
☐ Sviluppare benchmark su dataset vari di RDatasets, guardare anche quali tipi di test hanno fatto gli altri @started(26-03-10 14:55)
✔ Iris @done(26-03-10 14:55)
✔ Crab classification @done(26-03-10 14:55)
☐ Abalone
☐ Yeast
☐ Confrontare performance con quella di altri metodi o di altre implementazioni (ex: quello in wittgenstein)

RIPPER:
✔ Implementare RIPPER @done(26-03-15 15:27)
✔ Testare la riproducibilità dei risultati di RIPPER @done(26-03-15 17:14)
✔ Implementare il caso non binario @done(26-03-26 18:38)
☐ Pensare a se sono possibili ulteriori ottimizzazioni per risparmiare delle operazioni

Pulizia codice RIPPER/IREP*:
✔ Creare una struct ausiliaria "TrainingState" per gestire automaticamente le operazioni ripetute su uncoveredX, uncoveredy e così via @done(26-03-22 22:42)
✔ Creare una struct ausiliaria "DataSplit" per gestire lo splitting dei dati nella parte di growth e di pruning @done(26-03-22 22:43)
☐ Considerare la reintroduzione di InstanceSet? A quel punto TrainingState e DataSplit potrebbero usare InstanceSet a loro volta
☐ Spostare alcune funzioni relative allo splitting in core.jl?
☐ Considerare la possibilità di modificare sliceinstances e TrainingSet in modo da usare una selezione ripetuta degli indici attivi nel dataset, in modo da non dover aggiungere progressivamente campi opzionali come original_y e original_y_labes: forse si può fare tutto con un semplice mapping (i-esimo indice attivo --> corrispondente indice nel dataset inziale)?

Last:

☐ In RandSearch, when calling randformula, should you give it the right atompicking_mode and subalphabets_weights; right?
✔ :uniform working ? @done(24-06-01 18:59)
✔ :twostep working ? @done(24-06-01 18:59)
☐ subalphabets_weights working ?
# atompicker = ((rng,alph)->randatom(rng,alph; atompicking_mode = ..., subalphabets_weights = ...))
☐ was :uniform or :weighted working better...?
✔ And which one are we using now? @done(24-06-02 11:56)
☐ Uniform

✔ only one expression between "evaluation function" and "quality evaluator" and "loss_function" @done(24-06-01 15:05)
or maybe "loss function".
☐ TODO Remove Italian writings (@Italian)
✔ Rename SequentialCoveringLearner; "learner" is a bit old-fashioned in my opinion. Maybe something like "ExtendedSequentialCovering?" @done(24-06-01 15:05)
☐ add documentation for SequentialCoveringLearner
✔ Gather all the good code in "dev" branch, and delete unnecessary branches, edo, edo-memo, edo-dec-set, etc. @done(24-06-01 15:05)
# https://stackoverflow.com/questions/1307114/how-can-i-archive-git-branches/42232899#42232899
☐ keep edo ?
✔ edo-memo @done(24-06-01 15:05)
✔ edo-dec-set @done(24-06-01 15:05)
RandomDecisionForests:
✔ Implementare le ModalDecisionForest come stabilito in chiamata @done(26-03-08 18:00)
✔ Fare un test sul dataset di crab classification @done(26-03-08 20:21)
✔ Implementare repeated cross validation nei test di rdl e irep? @started(26-03-10 12:32) @done(26-03-10 14:44) @lasted(2h12m2s)
✔ Testare la riproducibilità di RandomDecisionLists, assicurarsi che i risultati siano deterministici @done(26-03-10 15:55)
✔ Far passare la funzione con cui addestrare il modello di base come parametro a build_rdl @done(26-03-15 17:25)
--> Automaticamente darebbe la possibilità di creare un modello misto, con subsampling di samples e features come random forest, ma unendo sia decision lists sia decision trees
✔ Scrivere funzione per caso non binario di Random Decision Lists @done(26-03-26 18:38)

Test RandomDecisionForests:
--> mi servirà per fare i confronti con Random Forests, che sono agnostiche rispetto al tipo di classe
✔ Scrivere template esperimenti vari per confrontare Random Decision Lists con Random Decision Forests e con modello misto tra alberi e Random Decision Lists @done(26-03-26 18:38)
✔ Crab classification @done(26-03-26 18:38)
✔ Iris dataset @done(26-03-30 15:07)
✔ Biopsy @done(26-03-30 15:07)
✔ Wine quality @done(26-03-30 15:08)
☐ Altri?

Post Experiments Patches:
☐ Unify names for maxinfogain
☐ In RandSearch default alpha and max_infogain_ratio to Nothing (after tuning phase)

✔ Cambiare "build_rdl" in "build_ensemble" @done(26-03-30 13:55)


Later:
✔ Considerare la possibilità di introdurre delle funzioni astratte per fare k-fold cross validation e repeated cross validation, magari da mettere in SoleModels? @done(26-03-15 17:14)
✔ Parallelizzare l'addestramento dei modelli in Random Decision Lists, o le parti di valutazione di ogni fold in repeated cross validation @done(26-03-30 15:15)
23 changes: 20 additions & 3 deletions src/ModalDecisionLists.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,42 @@ module ModalDecisionLists

using Random

export BeamSearch, RandSearch, AtomSearch, SearchMethod
export BeamSearch, RandSearch, SearchMethod

using Reexport
@reexport using SoleBase
@reexport using SoleLogics
@reexport using SoleData
@reexport using SoleModels




include("utils.jl")

include("metrics.jl")

using .Metrics

include("core.jl")

include("loss-functions.jl")

using .LossFunctions

include("core.jl")
include("search.jl")

export sequentialcovering

include("algorithms/sequentialcovering.jl")
# include("algorithms/sequentialcovering-unordered.jl")

export irepstar
export initialize_antecedents
export ripperk

include("ensemble_learning.jl")
export build_ensemble

module BaseCN2
using ModalDecisionLists: SatMask
Expand All @@ -29,7 +46,7 @@ end

export ExtendedSequentialCovering
export OrderedCN2Learner
export build_cn2
# export build_cn2

# MLJ Interface
include("interfaces/MLJ.jl")
Expand Down
Loading
Loading