Symbolic models
SoleModels.AbstractModel
SoleModels.Branch
SoleModels.ConstantModel
SoleModels.DecisionEnsemble
SoleModels.DecisionForest
SoleModels.DecisionList
SoleModels.DecisionTree
SoleModels.FunctionModel
SoleModels.LeafModel
SoleModels.MixedModel
SoleModels.Rule
SoleLogics.atoms
SoleLogics.connectives
SoleLogics.height
SoleLogics.height
SoleLogics.natoms
SoleLogics.nconnectives
SoleLogics.nleaves
SoleLogics.nleaves
SoleModels.antecedent
SoleModels.apply
SoleModels.checkantecedent
SoleModels.consequent
SoleModels.defaultconsequent
SoleModels.displaymodel
SoleModels.evaluaterule
SoleModels.f
SoleModels.hasinfo
SoleModels.immediatesubmodels
SoleModels.info
SoleModels.info!
SoleModels.iscomplete
SoleModels.joinrules
SoleModels.listimmediaterules
SoleModels.listrules
SoleModels.negconsequent
SoleModels.nimmediatesubmodels
SoleModels.nnodes
SoleModels.nnodes
SoleModels.nsyntaxleaves
SoleModels.ntrees
SoleModels.outcome
SoleModels.outcometype
SoleModels.outputtype
SoleModels.parse_orange_decision_list
SoleModels.posconsequent
SoleModels.printmodel
SoleModels.readmetrics
SoleModels.root
SoleModels.root
SoleModels.rulebase
SoleModels.rulemetrics
SoleModels.solemodel
SoleModels.submodels
SoleModels.syntaxleaves
SoleModels.trees
SoleModels.wrap
SoleModels.ConstantModel
— Typestruct ConstantModel{O} <: LeafModel{O}
outcome::O
info::NamedTuple
end
The simplest type of model is the ConstantModel
; it is a LeafModel
that always outputs the same outcome.
Examples
julia> cm = ConstantModel(2);
julia> outcome(cm)
2
SoleModels.FunctionModel
— Typestruct FunctionModel{O} <: LeafModel{O}
f::FunctionWrapper{O}
info::NamedTuple
end
A FunctionModel
is a LeafModel
that applies a native Julia Function
in order to compute the outcome.
Over efficiency concerns, it is mandatory to make explicit the output type O
by wrapping the Function
into an object of type FunctionWrapper{O}
(see FunctionWrappers.
See also LeafModel
.
SoleModels.Rule
— Typestruct Rule{O} <: AbstractModel{O}
antecedent::Formula
consequent::M where {M<:AbstractModel{<:O}}
info::NamedTuple
end
A Rule
is one of the fundamental building blocks of symbolic modeling, and has the semantics:
IF (antecedent) THEN (consequent) END
where the antecedent
is a formula to be checked, and the consequent
is the local outcome of the block.
Examples
julia> Rule(CONJUNCTION(Atom("p"), Atom("q")), ConstantModel(2))
▣ (p) ∧ (q) ↣ 2
See also AbstractModel
, antecedent
, consequent
, SoleLogics.Formula
.
SoleModels.Branch
— Typestruct Branch{O} <: AbstractModel{O}
antecedent::Formula
posconsequent::M where {M<:AbstractModel{<:O}}
negconsequent::M where {M<:AbstractModel{<:O}}
info::NamedTuple
end
A Branch
is one of the fundamental building blocks of symbolic modeling, and has the semantics:
IF (antecedent) THEN (positive consequent) ELSE (negative consequent) END
where the antecedent
is a formula to be checked and the consequent
s are the feasible local outcomes of the block. If checking the antecedent evaluates to the top of the algebra, then the positive consequent is applied; otherwise, the negative consequent is applied.
See also AbstractModel
, antecedent
, SoleLogics.check
, SoleLogics.Formula
, negconsequent
, posconsequent
, Rule
.
SoleModels.DecisionList
— Typestruct DecisionList{O} <: AbstractModel{O}
rulebase::Vector{Rule{_O} where {_O<:O}}
defaultconsequent::M where {M<:AbstractModel{<:O}}
info::NamedTuple
end
A DecisionList
(or decision table, or rule-based model) is a symbolic model that has the semantics of an IF-ELSEIF-ELSE block:
IF (antecedent_1) THEN (consequent_1)
ELSEIF (antecedent_2) THEN (consequent_2)
...
ELSEIF (antecedent_n) THEN (consequent_n)
ELSE (consequent_default) END
where the antecedent
s are formulas to be, and the consequent
s are the feasible local outcomes of the block.
Using the classical semantics, the antecedent
s are evaluated in order, and a consequent
is returned as soon as a valid antecedent is found, or when the computation reaches the ELSE clause.
See also AbstractModel
, DecisionTree
, Rule
.
SoleModels.DecisionTree
— Typestruct DecisionTree{O} <: AbstractModel{O}
root::M where {M<:Union{LeafModel{O},Branch{O}}}
info::NamedTuple
end
DecisionTree
wraps a constrained sub-tree of Branch
and LeafModel
.
In other words, a DecisionTree
is a symbolic model that operates as a nested structure of IF-THEN-ELSE blocks:
IF (antecedent_1) THEN
IF (antecedent_2) THEN
(consequent_1)
ELSE
(consequent_2)
END
ELSE
IF (antecedent_3) THEN
(consequent_3)
ELSE
(consequent_4)
END
END
where the antecedent
s are formulas to be, and the consequent
s are the feasible local outcomes of the block.
!!!note Note that this structure also includes an info::NamedTuple
for storing additional information.
See also Branch
, DecisionList
, DecisionForest
, LeafModel
, MixedModel
.
SoleModels.DecisionForest
— Typeconst DecisionForest{O} = DecisionEnsemble{<:DecisionTree{O}}
A DecisionForest
is a symbolic model that wraps an ensemble of DecisionTree
's.
See also DecisionList
, DecisionTree
, MixedModel
.
SoleModels.printmodel
— Functionprintmodel(io::IO, m::AbstractModel; kwargs...)
displaymodel(m::AbstractModel; kwargs...)
print or return a string representation of model m
.
Arguments
header::Bool = false
: when set totrue
, a header is printed, displaying theinfo
structure form
;show_subtree_info::Bool = false
: when set totrue
, the header is printed for models in the sub-tree ofm
;show_metrics::Bool = false
: when set totrue
, performance metrics at each point of the subtree are shown, whenever they are available in theinfo
structure;max_depth::Union{Nothing,Int} = nothing
: when it is anInt
, models in the sub-tree with a depth higher thanmax_depth
are ellipsed with "...";syntaxstring_kwargs::NamedTuple = (;)
: kwargs to be passed tosyntaxstring
for formatting logical formulas.
See also syntaxstring
, AbstractModel
.
Evaluating symbolic models
SoleModels.evaluaterule
— Methodevaluaterule(
r::Rule{O},
X::AbstractInterpretationSet,
Y::AbstractVector{L}
) where {O,L<:Label}
Evaluate the rule on a labeled dataset, and return a NamedTuple
consisting of:
antsat::Vector{Bool}
: satsfaction of the antecedent for each instance in the dataset;ys::Vector{Union{Nothing,O}}
: rule prediction. For each instance in X:consequent(rule)
if the antecedent is satisfied,nothing
otherwise.
See also Rule
, SoleLogics.AbstractInterpretationSet
, Label
, checkantecedent
.
SoleModels.readmetrics
— Methodreadmetrics(m::AbstractModel; round_digits = nothing)
Return a NamedTuple
with some performance metrics for the given symbolic model. Performance metrics can be computed when the info
structure of the model has the following keys:
:supporting_labels
:supporting_predictions
The round_digits
keyword argument, if provided, is used to round
accuracy/confidence metrics.
SoleModels.rulemetrics
— Methodrulemetrics(
r::Rule,
X::AbstractInterpretationSet,
Y::AbstractVector{<:Label}
)
Compute metrics for a rule with respect to a labeled dataset and returns a NamedTuple
consisting of:
support
: number of instances satisfying the antecedent of the rule divided by the total number of instances;error
:- For classification problems: number of instances that were not classified
- For regression problems: mean squared error;
length
: number of atoms in the rule's antecedent.
See also Rule
, SoleLogics.AbstractInterpretationSet
, Label
, evaluaterule
, outcometype
, consequent
.
Manipulating symbolic knowledge
SoleModels.joinrules
— Functionjoinrules(rules::AbstractVector{<:Rule})::Vector{<:Rule}
Return a set of rules, with exactly one rule per different outcome from the input set of rules. For each outcome, the output rule is computed as the logical disjunction of the antecedents of the input rules for that outcome.
Examples
julia> using SoleLogics
julia> branch = Branch(SoleLogics.parseformula("p"), Branch(SoleLogics.parseformula("q"), "YES", "NO"), "NO")
p
├✔ q
│├✔ YES
│└✘ NO
└✘ NO
julia> printmodel.(listrules(branch); tree_mode = true);
▣ p ∧ q
└✔ YES
▣ p ∧ ¬q
└✔ NO
▣ ¬p
└✔ NO
julia> printmodel.(joinrules(listrules(branch)); tree_mode = true);
▣ (p ∧ q)
└✔ YES
▣ (p ∧ ¬q) ∨ ¬p
└✔ NO
See also listrules
, SoleLogics.DISJUNCTION
, LeafModel
, AbstractModel
.
SoleModels.listrules
— Methodlistrules(
m::AbstractModel;
use_shortforms::Bool = true,
use_leftmostlinearform::Union{Nothing,Bool} = nothing,
normalize::Bool = false,
force_syntaxtree::Bool = false,
)::Vector{<:Rule}
Return a list of rules capturing the knowledge enclosed in symbolic model. The behavior of any symbolic model can be synthesised and represented as a set of mutually exclusive (and jointly exaustive, if the model is closed) rules, which can be useful for many purposes.
The keyword argument force_syntaxtree
, when set to true, causes the logical antecedents in the returned rules to be represented as SyntaxTree
s, as opposed to other syntax structure (e.g., LeftmostConjunctiveForm
).
Examples
julia> using SoleLogics
julia> branch = Branch(SoleLogics.parseformula("p"), Branch(SoleLogics.parseformula("q"), "YES", "NO"), "NO")
p
├✔ q
│├✔ YES
│└✘ NO
└✘ NO
julia> printmodel.(listrules(branch); tree_mode = true);
▣ p ∧ q
└✔ YES
▣ p ∧ ¬q
└✔ NO
▣ ¬p
└✔ NO
See also AbstractModel
, SoleLogics.CONJUNCTION
, joinrules
, listimmediaterules
, LeafModel
.
SoleModels.submodels
— Methodsubmodels(m::AbstractModel)
Enumerate all submodels in the sub-tree. This function is the transitive closure of immediatesubmodels
; in fact, the returned list includes the immediate submodels (immediatesubmodels(m)
), but also their immediate submodels, and so on.
Examples
julia> using SoleLogics
julia> branch = Branch(SoleLogics.parseformula("p∧q∨r"), "YES", "NO");
julia> submodels(branch)
2-element Vector{SoleModels.ConstantModel{String}}:
ConstantModel
YES
ConstantModel
NO
julia> branch2 = Branch(SoleLogics.parseformula("s→p"), branch, 42);
julia> printmodel.(submodels(branch2));
Branch
┐ p ∧ (q ∨ r)
├ ✔ YES
└ ✘ NO
ConstantModel
YES
ConstantModel
NO
ConstantModel
42
julia> submodels(branch) == immediatesubmodels(branch)
true
julia> submodels(branch2) == immediatesubmodels(branch2)
false
See also AbstractModel
, immediatesubmodels
, LeafModel
.