Full Reference

SoleModels.AbstractModelType
abstract type AbstractModel{O} end

Abstract type for symbolic models that, given an instance object (i.e., a piece of data), output an outcome of type O.

A model is said to be symbolic when its application relies on checking formulas of a certain logical language (see SoleLogics.jl package) on the instance. Symbolic models provide a form of transparent and interpretable modeling, as a symbolic model can be synthethised into a set of mutually exclusive logical rules that can often be translated into natural language.

Examples of symbolic models are Rules, Branches, DecisionLists and DecisionTrees. Examples of non-symbolic (or sub-symbolic) models include those encoding algebraic mathematical functions (e.g., neural networks).

Symbolic models can wrap other AbstractModels, and use them to compute the outcome. As such, an AbstractModel can actually be the result of a composition of many models, and enclose a tree of AbstractModels (with LeafModels at the leaves).

TODO - bring missing dispatches here (do the same for other model types)

Interface

  • apply(m::AbstractModel, i::AbstractInterpretation; kwargs...)

  • iscomplete(m::AbstractModel)

  • outcometype(m::AbstractModel)

  • outputtype(m::AbstractModel)

  • immediatesubmodels(m::AbstractModel)

  • nimmediatesubmodels(m::AbstractModel)

  • listimmediaterules(m::AbstractModel)

  • info(m::AbstractModel, [key, [defaultval]])

  • info!(m::AbstractModel, key, value)

  • hasinfo(m::AbstractModel, key)

Utility functions

  • apply(m::AbstractModel, i::AbstractInterpretationSet; kwargs...)

  • See AbstractTrees...

  • submodels(m::AbstractModel)

  • nsubmodels(m::AbstractModel)

  • leafmodels(m::AbstractModel)

  • nleafmodels(m::AbstractModel)

  • subtreeheight(m::AbstractModel)

  • listrules( m::AbstractModel; use_shortforms::Bool=true, use_leftmostlinearform::Union{Nothing,Bool}=nothing, normalize::Bool=false, force_syntaxtree::Bool=false, )

  • joinrules(m::AbstractModel, silent=false; kwargs...)

Examples

TODO

See also apply, Branch, info, iscomplete, LeafModel, outcometype, Rule.

source
SoleModels.BranchType
struct 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 consequents 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.

source
SoleModels.ConstantModelType
struct 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

See also apply, LeafModel.

source
SoleModels.DecisionListType
struct 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 antecedents are formulas to be, and the consequents are the feasible local outcomes of the block.

Using the classical semantics, the antecedents 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.

source
SoleModels.DecisionTreeType
struct 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 antecedents are formulas to be, and the consequents 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.

source
SoleModels.FunctionModelType
struct 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.

Warning

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.

source
SoleModels.LeafModelType
abstract type LeafModel{O} <: AbstractModel{O} end

Abstract type for leaf models, that is, models which outcomes do not depend other models, and represents the bottom of the computation.

In general, an AbstractModel can generally wrap other AbstractModels; in such case, the outcome can depend on the inner models being applied on the instance object. Otherwise, the model is considered as a leaf, or final, and is the leaf of a tree of AbstractModels.

Examples

julia> SoleModels.LeafModel(2) isa SoleModels.ConstantModel

julia> SoleModels.LeafModel(sum) isa SoleModels.FunctionModel
┌ Warning: Over efficiency concerns, please consider wrappingJulia Function's into FunctionWrapper{O,Tuple{SoleModels.AbstractInterpretation}} structures,where O is their return type.
└ @ SoleModels ~/.julia/dev/SoleModels/src/base.jl:337
true

See also AbstractModel, ConstantModel, FunctionModel.

source
SoleModels.MixedModelType
struct MixedModel{O,FM<:AbstractModel} <: AbstractModel{O}
    root::M where {M<:AbstractModel{<:O}}
    info::NamedTuple
end

A MixedModel is a wrapper of multiple AbstractModels such as Rules, Branchs, DecisionLists, DecisionTree.

In other words, a MixedModel is a symbolic model that operates as a free nested structure of IF-THEN-ELSE and IF-ELSEIF-ELSE blocks:

IF (antecedent_1) THEN
    IF (antecedent_1)     THEN (consequent_1)
    ELSEIF (antecedent_2) THEN (consequent_2)
    ELSE (consequent_1_default) END
ELSE
    IF (antecedent_3) THEN
        (consequent_3)
    ELSE
        (consequent_4)
    END
END

where the antecedents are formulas to be checked, and the consequents are the feasible local outcomes of the block.

Note

Note that FM refers to the Feasible Models (FM) allowed in the model's sub-tree.

See also AbstractModel, Branchs, DecisionLists, DecisionTree, Rules.

source
SoleModels.RuleType
struct 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.

source
SoleLogics.atomsMethod
atoms(::AbstractModel)
connectives(::AbstractModel)
syntaxleaves(::AbstractModel)

natoms(::AbstractModel)
nconnectives(::AbstractModel)
nsyntaxleaves(::AbstractModel)

See also AbstractModel, listrules.

source
SoleLogics.natomsMethod
atoms(::AbstractModel)
connectives(::AbstractModel)
syntaxleaves(::AbstractModel)

natoms(::AbstractModel)
nconnectives(::AbstractModel)
nsyntaxleaves(::AbstractModel)

See also AbstractModel, listrules.

source
SoleModels.applyMethod
apply(m::AbstractModel, i::AbstractInterpretation; kwargs...)::outputtype(m)

apply(
    m::AbstractModel,
    d::AbstractInterpretationSet;
    kwargs...
)::AbstractVector{<:outputtype(m)}

Return the output prediction of a model m on a logical interpretation i, on the i_instance of a dataset d, or on all instances of a dataset d. Note that predictions can be nothing if the model is incomplete (e.g., if the model is a Rule).

Keyword Arguments

  • check_args::Tuple = ();
  • check_kwargs::NamedTuple = (;);
  • functional_args::Tuple = ();
  • functional_kwargs::NamedTuple = (;);
  • Any additional keyword argument is passed down to the model subtree's leaves

check_args and check_kwargs can influence check's behavior at the time of its computation (see SoleLogics.check).

functional_args and functional_kwargs can influence FunctionModel's behavior when the corresponding function is applied to AbstractInterpretation (see FunctionModel, SoleLogics.AbstractInterpretation)

A model state-changing version of the function, [apply!], exist. While producing the output, this function affects the info keys :supporting_labels and :supporting_predictions, which are useful for inspecting the statistical performance of parts of the model.

See also SoleLogics.AbstractInterpretation, SoleLogics.AbstractInterpretationSet, AbstractModel, iscomplete, readmetrics.

source
SoleModels.displaymodelMethod
printmodel(io::IO, m::AbstractModel; kwargs...)
displaymodel(m::AbstractModel; kwargs...)

print or return a string representation of model m.

Arguments

  • header::Bool = false: when set to true, a header is printed, displaying the info structure for m;
  • show_subtree_info::Bool = false: when set to true, the header is printed for models in the sub-tree of m;
  • show_metrics::Bool = false: when set to true, performance metrics at each point of the subtree are shown, whenever they are available in the info structure;
  • max_depth::Union{Nothing,Int} = nothing: when it is an Int, models in the sub-tree with a depth higher than max_depth are ellipsed with "...";
  • syntaxstring_kwargs::NamedTuple = (;): kwargs to be passed to syntaxstring for formatting logical formulas.

See also syntaxstring, AbstractModel.

source
SoleModels.evaluateruleMethod
evaluaterule(
    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.

source
SoleModels.immediatesubmodelsMethod
immediatesubmodels(m::AbstractModel)

Return the list of immediate child models.

Note

If the model is a leaf model, then the returned list will be empty.

Examples

julia> using SoleLogics

julia> branch = Branch(SoleLogics.parseformula("p∧q∨r"), "YES", "NO");

julia> immediatesubmodels(branch)
2-element Vector{SoleModels.ConstantModel{String}}:
 SoleModels.ConstantModel{String}
YES

 SoleModels.ConstantModel{String}
NO

julia> branch2 = Branch(SoleLogics.parseformula("s→p"), branch, 42);


julia> printmodel.(immediatesubmodels(branch2));
Branch
┐ p ∧ (q ∨ r)
├ ✔ YES
└ ✘ NO

ConstantModel
42

See also AbstractModel, LeafModel, submodels.

source
SoleModels.info!Method
info!(m::AbstractModel, info::NamedTuple; replace::Bool=false)
info!(m::AbstractModel, key, val)

Overwrite the info structure within m.

Keyword Arguments

  • replace::Bool: overwrite the entire info structure.

See also AbstractModel, info.

source
SoleModels.infoMethod
info(m::AbstractModel)::NamedTuple = m.info
info(m::AbstractModel, key) = m.info[key]
info(m::AbstractModel, key, defaultval)

Return the info structure for model m; this structure is used for storing additional information that does not affect the model's behavior.

This structure can hold, for example, information about the model's statistical performance during the learning phase.

See also AbstractModel, info!.

source
SoleModels.iscompleteMethod
iscomplete(::AbstractModel)::Bool

Return whether a model is complete.

An AbstractModel is complete if it is always able to provide an outcome of type O. Otherwise, the model can output nothing values and is referred to as incomplete.

Rule is an example of an incomplete model, while Branch is an example of complete model.

See also AbstractModel.

source
SoleModels.joinrulesFunction
joinrules(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.

source
SoleModels.listimmediaterulesMethod
listimmediaterules(m::AbstractModel{O} where {O})::Rule{<:O}

List the immediate rules equivalent to a symbolic model.

Examples

julia> using SoleLogics

julia> branch = Branch(SoleLogics.parseformula("p"), Branch(SoleLogics.parseformula("q"), "YES", "NO"), "NO")
 p
├✔ q
│├✔ YES
│└✘ NO
└✘ NO


julia> printmodel.(listimmediaterules(branch); tree_mode = true);
▣ p
└✔ q
 ├✔ YES
 └✘ NO

▣ ¬(p)
└✔ NO

See also AbstractModel, listrules.

source
SoleModels.listrulesMethod
listrules(
    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 SyntaxTrees, 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.

source
SoleModels.outcometypeMethod
outcometype(::Type{<:AbstractModel{O}}) where {O} = O
outcometype(m::AbstractModel) = outcometype(typeof(m))

Return the outcome type of a model (type).

See also AbstractModel.

source
SoleModels.outputtypeMethod
outputtype(m::AbstractModel)

Return a supertype for the outputs obtained when applying a model.

Implementation

The result depends on whether the model is incomplete or complete

julia> outputtype(m::AbstractModel{O}) where {O} = iscomplete(m) ? O : Union{Nothing,O}

Note that if the model is complete, then outputtype(m) is equal to outcometype(m).

See also AbstractModel, apply, iscomplete, outcometype.

source
SoleModels.parse_orange_decision_listFunction
parse_orange_decision_list(decision_list, ignoredefaultrule = false; featuretype = SoleData.VariableValue)

Parser for orange-style decision lists. Reference: https://orange3.readthedocs.io/projects/orange-visual-programming/en/latest/widgets/model/cn2ruleinduction.html

Arguments

  • decision_list is an AbstractString containing the orange-style representation of a decision list;
  • ignoredefaultrule is an optional, Boolean parameter indicating whether to use the default rule as the default rule for the resulting decision list. When false, the last rule is ignored, and the second last is used as the default rule;
  • featuretype specifies the feature type used in the parsed ScalarConditions.

Examples

julia> dl = "
[49, 0, 0] IF petal length<=3.0 AND sepal width>=2.9 THEN iris=Iris-setosa  -0.0
[0, 0, 39] IF petal width>=1.8 AND sepal length>=6.0 THEN iris=Iris-virginica  -0.0
[0, 8, 0] IF sepal length>=4.9 AND sepal width>=3.1 THEN iris=Iris-versicolor  -0.0
[0, 0, 2] IF petal length<=4.9 AND petal width>=1.7 THEN iris=Iris-virginica  -0.0
[0, 0, 5] IF petal width>=1.8 THEN iris=Iris-virginica  -0.0
[0, 35, 0] IF petal length<=5.0 AND sepal width>=2.4 THEN iris=Iris-versicolor  -0.0
[0, 0, 2] IF sepal width>=2.8 THEN iris=Iris-virginica  -0.0
[0, 3, 0] IF petal width<=1.0 AND sepal length>=5.0 THEN iris=Iris-versicolor  -0.0
[0, 1, 0] IF sepal width>=2.7 THEN iris=Iris-versicolor  -0.0
[0, 0, 1] IF sepal width>=2.6 THEN iris=Iris-virginica  -0.0
[0, 2, 0] IF sepal length>=5.5 AND sepal length>=6.2 THEN iris=Iris-versicolor  -0.0
[0, 1, 0] IF sepal length<=5.5 AND petal length>=4.0 THEN iris=Iris-versicolor  -0.0
[0, 0, 1] IF sepal length>=6.0 THEN iris=Iris-virginica  -0.0
[1, 0, 0] IF sepal length<=4.5 THEN iris=Iris-setosa  -0.0
[50, 50, 50] IF TRUE THEN iris=Iris-setosa  -1.584962500721156
" |> SoleModels.parse_orange_decision_list

julia> listrules(dl; normalize = true)
15-element Vector{ClassificationRule{String}}:
 ▣ ((:petal_length ≤ 3.0) ∧ (:sepal_width ≥ 2.9))  ↣  Iris-setosa

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width ≥ 1.8) ∧ (:sepal_length ≥ 6.0))  ↣  Iris-virginica

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length ≥ 4.9) ∧ (:sepal_width ≥ 3.1))  ↣  Iris-versicolor

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length < 4.9) ∨ (:sepal_width < 3.1)) ∧ ((:petal_length ≤ 4.9) ∧ (:petal_width ≥ 1.7))  ↣  Iris-virginica

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length < 4.9) ∨ (:sepal_width < 3.1)) ∧ ((:petal_length > 4.9) ∨ (:petal_width < 1.7)) ∧ (:petal_width ≥ 1.8)  ↣  Iris-virginica

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length < 4.9) ∨ (:sepal_width < 3.1)) ∧ ((:petal_length > 4.9) ∨ (:petal_width < 1.7)) ∧ (:petal_width < 1.8) ∧ ((:petal_length ≤ 5.0) ∧ (:sepal_width ≥ 2.4))  ↣  Iris-versicolor

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length < 4.9) ∨ (:sepal_width < 3.1)) ∧ ((:petal_length > 4.9) ∨ (:petal_width < 1.7)) ∧ (:petal_width < 1.8) ∧ ((:petal_length > 5.0) ∨ (:sepal_width < 2.4)) ∧ (:sepal_width ≥ 2.8)  ↣  Iris-virginica

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length < 4.9) ∨ (:sepal_width < 3.1)) ∧ ((:petal_length > 4.9) ∨ (:petal_width < 1.7)) ∧ (:petal_width < 1.8) ∧ ((:petal_length > 5.0) ∨ (:sepal_width < 2.4)) ∧ (:sepal_width < 2.8) ∧ ((:petal_width ≤ 1.0) ∧ (:sepal_length ≥ 5.0))  ↣  Iris-versicolor

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length < 4.9) ∨ (:sepal_width < 3.1)) ∧ ((:petal_length > 4.9) ∨ (:petal_width < 1.7)) ∧ (:petal_width < 1.8) ∧ ((:petal_length > 5.0) ∨ (:sepal_width < 2.4)) ∧ (:sepal_width < 2.8) ∧ ((:petal_width > 1.0) ∨ (:sepal_length < 5.0)) ∧ (:sepal_width ≥ 2.7)  ↣  Iris-versicolor

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length < 4.9) ∨ (:sepal_width < 3.1)) ∧ ((:petal_length > 4.9) ∨ (:petal_width < 1.7)) ∧ (:petal_width < 1.8) ∧ ((:petal_length > 5.0) ∨ (:sepal_width < 2.4)) ∧ (:sepal_width < 2.8) ∧ ((:petal_width > 1.0) ∨ (:sepal_length < 5.0)) ∧ (:sepal_width < 2.7) ∧ (:sepal_width ≥ 2.6)  ↣  Iris-virginica

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length < 4.9) ∨ (:sepal_width < 3.1)) ∧ ((:petal_length > 4.9) ∨ (:petal_width < 1.7)) ∧ (:petal_width < 1.8) ∧ ((:petal_length > 5.0) ∨ (:sepal_width < 2.4)) ∧ (:sepal_width < 2.8) ∧ ((:petal_width > 1.0) ∨ (:sepal_length < 5.0)) ∧ (:sepal_width < 2.7) ∧ (:sepal_width < 2.6) ∧ ((:sepal_length ≥ 5.5) ∧ (:sepal_length ≥ 6.2))  ↣  Iris-versicolor

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length < 4.9) ∨ (:sepal_width < 3.1)) ∧ ((:petal_length > 4.9) ∨ (:petal_width < 1.7)) ∧ (:petal_width < 1.8) ∧ ((:petal_length > 5.0) ∨ (:sepal_width < 2.4)) ∧ (:sepal_width < 2.8) ∧ ((:petal_width > 1.0) ∨ (:sepal_length < 5.0)) ∧ (:sepal_width < 2.7) ∧ (:sepal_width < 2.6) ∧ ((:sepal_length < 5.5) ∨ (:sepal_length < 6.2)) ∧ ((:sepal_length ≤ 5.5) ∧ (:petal_length ≥ 4.0))  ↣  Iris-versicolor

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length < 4.9) ∨ (:sepal_width < 3.1)) ∧ ((:petal_length > 4.9) ∨ (:petal_width < 1.7)) ∧ (:petal_width < 1.8) ∧ ((:petal_length > 5.0) ∨ (:sepal_width < 2.4)) ∧ (:sepal_width < 2.8) ∧ ((:petal_width > 1.0) ∨ (:sepal_length < 5.0)) ∧ (:sepal_width < 2.7) ∧ (:sepal_width < 2.6) ∧ ((:sepal_length < 5.5) ∨ (:sepal_length < 6.2)) ∧ ((:sepal_length > 5.5) ∨ (:petal_length < 4.0)) ∧ (:sepal_length ≥ 6.0)  ↣  Iris-virginica

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length < 4.9) ∨ (:sepal_width < 3.1)) ∧ ((:petal_length > 4.9) ∨ (:petal_width < 1.7)) ∧ (:petal_width < 1.8) ∧ ((:petal_length > 5.0) ∨ (:sepal_width < 2.4)) ∧ (:sepal_width < 2.8) ∧ ((:petal_width > 1.0) ∨ (:sepal_length < 5.0)) ∧ (:sepal_width < 2.7) ∧ (:sepal_width < 2.6) ∧ ((:sepal_length < 5.5) ∨ (:sepal_length < 6.2)) ∧ ((:sepal_length > 5.5) ∨ (:petal_length < 4.0)) ∧ (:sepal_length < 6.0) ∧ (:sepal_length ≤ 4.5)  ↣  Iris-setosa

 ▣ ((:petal_length > 3.0) ∨ (:sepal_width < 2.9)) ∧ ((:petal_width < 1.8) ∨ (:sepal_length < 6.0)) ∧ ((:sepal_length < 4.9) ∨ (:sepal_width < 3.1)) ∧ ((:petal_length > 4.9) ∨ (:petal_width < 1.7)) ∧ (:petal_width < 1.8) ∧ ((:petal_length > 5.0) ∨ (:sepal_width < 2.4)) ∧ (:sepal_width < 2.8) ∧ ((:petal_width > 1.0) ∨ (:sepal_length < 5.0)) ∧ (:sepal_width < 2.7) ∧ (:sepal_width < 2.6) ∧ ((:sepal_length < 5.5) ∨ (:sepal_length < 6.2)) ∧ ((:sepal_length > 5.5) ∨ (:petal_length < 4.0)) ∧ (:sepal_length < 6.0) ∧ (:sepal_length > 4.5)  ↣  Iris-setosa

See also DecisionList.

source
SoleModels.printmodelMethod
printmodel(io::IO, m::AbstractModel; kwargs...)
displaymodel(m::AbstractModel; kwargs...)

print or return a string representation of model m.

Arguments

  • header::Bool = false: when set to true, a header is printed, displaying the info structure for m;
  • show_subtree_info::Bool = false: when set to true, the header is printed for models in the sub-tree of m;
  • show_metrics::Bool = false: when set to true, performance metrics at each point of the subtree are shown, whenever they are available in the info structure;
  • max_depth::Union{Nothing,Int} = nothing: when it is an Int, models in the sub-tree with a depth higher than max_depth are ellipsed with "...";
  • syntaxstring_kwargs::NamedTuple = (;): kwargs to be passed to syntaxstring for formatting logical formulas.

See also syntaxstring, AbstractModel.

source
SoleModels.readmetricsMethod
readmetrics(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.

source
SoleModels.rulemetricsMethod
rulemetrics(
    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
    correctly divided by the total number of instances;
    • For regression problems: mean squared error;
  • length: number of atoms in the rule's antecedent.

See also Rule, SoleLogics.AbstractInterpretationSet, Label, evaluaterule, outcometype, consequent.

source
SoleModels.submodelsMethod
submodels(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.

source
SoleModels.wrapMethod
wrap(o::Any, FM::Type{<:AbstractModel})
wrap(m::AbstractModel)
wrap(o::Any)::AbstractModel

This function wraps anything into an AbstractModel. The default behavior is the following: - when called on an AbstractModel, the model is simply returned (no wrapping is performed); - Functions andFunctionWrappers are wrapped into a [FunctionModel](@ref); - every other object is wrapped into aConstantModel`.

See also AbstractModel, ConstantModel, FunctionModel, LeafModel.

source