Did you know ... | Search Documentation: |
Pack pascal -- docs/_build/html/_sources/index.rst.txt |
.. pascal documentation master file, created by
sphinx-quickstart on Thu May 30 15:47:04 2019.
You can adapt this file completely to your liking, but it should at least
contain the root toctree
directive.
=========================================== Pascal Manual ===========================================
.. toctree:: :maxdepth: 2
Pasccal is an algorithm for learning probabilistic integrity constraints. It was
proposed in :cite:RigBelZesAlbLam21-ML-IJ
.
It contains modules for both structure and parameter learning.
Pascal is also available in the cplint on SWISH web application at `http://cplint.eu`_.
Pascal is distributed as a `pack http://www.swi-prolog.org/pack/list?p=pack`_ of `SWI-Prolog http://www.swi-prolog.org/`_. To install it, use
.. code:: prolog
?- pack_install(pack).
It requires the pack
It is installed automatically when installing pack pascal
or can be installed manually as ::
$ swipl ?- pack_install(lbfgs).
lbfgs
uses a foreign library and contains the library binaries for 32 and 64 bits Linux. If you want to recompile the foreign library you can use ::
?- pack_rebuild(lbfgs).
On 32 and 64 bits Linux this should work out of the box.
You can upgrade the pack with ::
$ swipl ?- pack_upgrade(pack).
Note that the pack on which pascal
depends is not upgraded automatically in this case so it needs to be upgraded manually.
::
$ cd <pack>/pascal/prolog/examples $ swipl ?- [bongardkeys]. ?- induce_pascal([train]),T).
::
$ swipl ?- [library(test_pascal)]. ?- test_pascal.
.. Datasets
Other machine learning datasets are available in pack `cplint_datasets https://github.com/friguzzi/cplint_datasets`_.
Use the Google group `https://groups.google.com/forum/#!forum/cplint`_.
A Probabilistic Constraint Logic Theory (PCLT) is a set of Probabilistic Integrity Constraints (PIC) of the form
.. math::
p \ ::\ L_1,\ldots,L_b\rightarrow \exists(P_1)
;\ldots;\exists(P_n)
;\forall\neg(N_1)
;\ldots;\forall\neg(N_m)
where :math:p
is a probability, each :math:L_i is a literal and each :math:P_j and :math:N_j is a conjunction of literals.
We call each :math:P_j a P conjunction and each :math:N_k an
N conjunction. We call each
:math:\exists(P_j)
a P disjunct and each :math:`\forall\neg(N_k)
` an N disjunct.
The variables that occur in the body are quantified universally with scope the PIC. The variables in the head that do not occur in the body are quantified existentially if they occur in a P disjunct and universally if they occur in an N disjunct, with scope the disjunct they occur in.
An example of a PIC for the Bongard problems of :cite:RaeLae95-ALT95
.. _`example of a PIC`:
.. math::
0.5\ ::\ triangle(T)
,square(S)
,in(T,S)
\rightarrow \exists(circle(C),in(C,S))
;\forall\neg(circle(C),in(C,T))
which states that if there is a triangle inside a square then either there exists a circle inside the square or there doesn't exist a circle inside the triangle. This constraint has probability 0.5.
The following learning algorithms are available:
To execute the learning algorithms, prepare a Prolog file divided in five parts
For example, consider the Bongard problems of :cite:RaeLae95-ALT95
.
`bongardkeys.pl http://cplint.eu/example/pascal/bongardkeys.pl`__ represents a Bongard problem for Pascal.
Preamble ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In the preamble, the Pascal library is loaded with (`bongardkeys.pl http://cplint.eu/e/pascal/bongardkeys.pl`__):
.. code:: prolog
:- use_module(library(pascal))
.
Now you can initialize pascal with
.. code:: prolog
:- pascal.
At this point you can start setting parameters for Pascal such as for example
.. code:: prolog
:-set_pascal(examples,keys(pos))
.
:-set_pascal(learning_algorithm,gradient_descent)
.
:-set_pascal(learning_rate,fixed(0.5))
.
:-set_pascal(verbosity,1)
.
We will see later the list of available parameters.
A parameter that is particularly important for Pascal is :code:verbosity
: if set to 1,
nothing is printed and learning is fastest,
if set to 3 much information is printed and learning is slowest, 2 is in between. This ends the preamble.
Background and Initial PCLT
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Now you can specify the background knowledge by including a set of Prolog clauses
in a section between :code::- begin_bg.
and :code::- end_bg.
For example
.. code:: prolog
:- begin_bg.
in(A,B)
:- inside(A,B)
.
in(A,D)
:- inside(A,C)
,in(C,D)
.
:- end_bg.
Moreover, you can specify an initial PCLT in a section between :code::- begin_in.
and :code::- end_in.
.
The initial program is used in parameter learning for providing the structure.
In the section, facts for the predicates :code:rule/2 or :code:ic/1 can be given.
Facts for :code:rule/2 take the form :code:rule(ic,prob)
where :code:prob
is a probability and
:code:ic
is a term of the form :code:head:-body
. In it, :code:body
is a list of literals and :code:head
is a list of head disjuncts. Each head disjunct is couple :code:(sign,conjunction)
where sign is
either :code:(+)
for P disjuncts or :code:(-)
for N disjuncts and :code:conjunction
is a list of literals.
The `example of a PIC`_ above can be expressed as
.. code:: prolog
:- begin_in. rule(([((+),[circle(C),in(C,S)]),((-),[circle(C),in(C,T)])]:- [triangle(T),square(S),in(T,S)]),0.5). :- end_in.
Facts for the predicate :code:ic/1 take the form :code:ic(string)
where :code:string
is a Prolog
string wher a constraint is encoded as :code:`prob::body--->head`.
:code:body
is a conjuntion of literals where the conjunction symbol is :code:/\
.
:code:head
is a disjunction where the disjunction symbol is :code:\/
.
Each disjunct is either a conjunction of literals, in the case of a P disjunct, or of the form
:code:not(conjunction)
where :code:conjunction
is a conjunction of literals.
The `example of a PIC`_ above can be expressed as
.. code::
:- begin_in.
ic("0.5 :: triangle(T)/\\square(S)/\\in(T,S)
--->
circle(C)/\\in(C,S)
\\/
not(circle(C)/\\in(C,T)).")
.
:- end_in.
Language Bias ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The language bias part is specified by means of mode declarations in the style of `Progol https://www.doc.ic.ac.uk/~shm/progol.html`_. ::
modeh(<recall>,<predicate>(<arg1>,...)).
specifies the atoms that can appear in the head of clauses, while ::
modeb(<recall>,<predicate>(<arg1>,...)).
specifies the atoms that can appear in the body of clauses. :code:`<recall>` can be an integer or :code:*
.
:code:`<recall>` indicates how many atoms for the predicate specification are considered.
:code:*
stands for all those that are found.
Otherwise the indicated number is randomly chosen.
Arguments of the form ::
+<type>
specifies that the argument should be an input variable of type :code:`<type>`, i.e., a variable replacing a :code:`+<type>` argument in the head or a :code:`-<type>` argument in a preceding literal in the current hypothesized clause.
Another argument form is ::
-<type>
for specifying that the argument should be a output variable of type :code:`<type>`. Any variable can replace this argument, either input or output. The only constraint on output variables is that those in the head of the current hypothesized clause must appear as output variables in an atom of the body.
Other forms are ::
#<type>
for specifying an argument which should be replaced by a constant of type :code:`<type>` ::
<constant>
for specifying a constant.
An example of language bias for the Bongard domain is
.. code:: prolog
modeh(*,triangle(+obj))
.
modeh(*,square(+obj))
.
modeh(*,circle(+obj))
.
modeh(*,in(+obj,-obj))
.
modeh(*,in(-obj,+obj))
.
modeh(*,in(+obj,+obj))
.
modeh(*,config(+obj,#dir))
.
modeb(*,triangle(-obj))
.
modeb(*,square(-obj))
.
modeb(*,circle(-obj))
.
modeb(*,in(+obj,-obj))
.
modeb(*,in(-obj,+obj))
.
modeb(*,config(+obj,#dir))
.
Example Interpretations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The last part of the file contains the data. You can specify data with two modalities: models and keys. In the models type, you specify an example model (or interpretation or megaexample) as a list of Prolog facts initiated by :code:`begin(model(<name>)).` and terminated by :code:`end(model(<name>)).` as in
.. code:: prolog
begin(model(2)). pos. triangle(o5). config(o5,up). square(o4). in(o4,o5). circle(o3). triangle(o2). config(o2,up). in(o2,o3). triangle(o1). config(o1,up). end(model(2)).
The facts in the interpretation are loaded in SWI-Prolog database by adding an extra initial argument equal to the name of the model.
After each interpretation is loaded, a fact of the form :code:`int(<id>)` is asserted, where :code:id
is the name of the interpretation.
This can be used in order to retrieve the list of interpretations.
Alternatively, with the keys modality, you can directly write the facts and the first argument will be interpreted as a model identifier. The above interpretation in the keys modality is
.. code:: prolog
pos(2). triangle(2,o5). config(2,o5,up). square(2,o4). in(2,o4,o5). circle(2,o3). triangle(2,o2). config(2,o2,up). in(2,o2,o3). triangle(2,o1). config(2,o1,up).
which is contained in the `bongardkeys.pl http://cplint.eu/e/bongardkeys.pl_. This is also how model :code:2` above is stored in SWI-Prolog database. The two modalities, models and keys, can be mixed in the same file. Facts for :code:int/1 are not asserted for interpretations in the key modality but can be added by the user explicitly.
In order to specify if an interpretation is positive or negative, you should include in the interpretation a
fact. The form of the fact dependes on the parameter :code:examples
whose values are :code:{auto, keys(pred)}
. If set to :code:auto
, positive examples in the models format should contain a :code:pos
fact and in the keys format a :code:pos(id)
fact, where :code:id
is the identifier of the interpretation. If set to :code:keys(pred)
, :code:pred
or :code:pred(pos)
(:code:pred(id)
or :code:pred(id,pos)
in the keys format) is used instead of :code:pos
to determine positive exmples.
Then you must indicate how the examples are divided in folds with facts of the form: :code:`fold(<fold_name>,<list of model identifiers>)`, as for example
.. code:: prolog
fold(train,[2,3,...]). fold(test,[490,491,...]).
As the input file is a Prolog program, you can define intensionally the folds as in
.. code:: prolog
fold(all,F):- findall(I,int(I),F).
which however must be inserted after the input interpretations otherwise the facts for :code:int/1 will not be available and fold :code:all
would be empty.
Parameter Learning ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To execute parameter learning, prepare an input file as indicated above and call
.. code:: prolog
?- induce_par_pascal(<list of folds>,T).
where :code:`<list of folds>` is a list of the folds for training and :code:T will contain the input theory with updated parameters.
For example `bongardkeys.pl http://cplint.eu/e/pascal/bongardkeys.pl`__, you can perform parameter learning on the :code:train
fold with
.. code:: prolog
?- induce_par_pascal([train],P).
Structure Learning ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To execute structure learning, prepare an input file in the editor panel as indicated above and call
.. code:: prolog
induce(+List_of_folds:list,-T:list) is det
where :code:List_of_folds is a list of the folds for training and :code:T will contain the learned PCLT.
For example `bongardkeys.pl http://cplint.eu/e/pascal/bongardkeys.pl`__, you can perform structure learning on the :code:train
fold with
.. code:: prolog
?- induce([train],P).
A PCLT can also be tested on a test set with :code:test_pascal/7 or :code:test_prob_pascal/6 as described below.
Testing ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ A PCLT can also be tested on a test set with
.. code:: prolog
test_pascal(+T:list,+List_of_folds:list,-LL:float,-AUCROC:float,-ROC:list,-AUCPR:float,-PR:list) is det
or ::
test_prob_pascal(+T:list,+List_of_folds:list,-NPos:int,-NNeg:int,-LL:float,-ExampleList:list) is det
where :code:T is a list of terms representing clauses and :code:List_of_folds is a list of folds.
:code:test_pascal/7 returns the log likelihood of the test examples in :code:LL, the Area Under the ROC curve in :code:AUCROC, a dictionary containing the list of points (in the form of Prolog pairs :code:x-y
) of the ROC curve in :code:ROC, the Area Under the PR curve in :code:AUCPR, a dictionary containing the list of points of the PR curve in :code:PR.
:code:test_prob_pascal/6 returns the log likelihood of the test examples in :code:LL, the numbers of positive and negative examples in :code:NPos and :code:NNeg and the list :code:ExampleList containing couples :code:Prob-Ex
where :code:Ex is :code:a
for :code:a
a positive example and :code:\+(a)
for :code:a
a negative example and :code:Prob is the probability of example :code:a
.
Then you can draw the curves in :code:cplint
on SWISH using C3.js using ::
compute_areas_diagrams(+ExampleList:list,-AUCROC:float,-ROC:dict,-AUCPR:float,-PR:dict) is det
(from pack `auc.pl http://www.swi-prolog.org/pack/list?p=auc`_) that takes as input a list :code:ExampleList of pairs probability-literal of the form that is returned by :code:test_prob_pascal/6.
For example, to test on fold :code:test
the program learned on fold :code:train
you can run the query
.. code:: prolog
?- induce_par([train],P), test(P,[test],LL,AUCROC,ROC,AUCPR,PR).
Or you can test the input program on the fold :code:test
with ::
.. code:: prolog
?- in(P),test(P,[test],LL,AUCROC,ROC,AUCPR,PR).
In :code:cplint
on SWISH, by including ::
.. code:: prolog
:- use_rendering(c3). :- use_rendering(lpad).
in the code before :code::- pascal.
the curves will be shown as graphs using C3.js and the output program will be pretty printed.
Parameters are set with commands of the form ::
:- set_pascal(<parameter>,<value>).
The available parameters are:
examples
: (values: :code:{auto, keys(pred)}
, default value: :code:auto
) if set to :code:auto
, positive examples in the models format should contain a :code:pos
fact and in the keys format a :code:pos(id)
fact, where :code:id
is the identifier of the interpretation. If set to :code:keys(pred)
, :code:pred
is used instead of :code:pos
to determine positive exmplesbeamsize
(values: integer, default value: 10): size of the beamverbosity
(values: integer in [1,3], default value: 1): level of verbosity of the algorithms.max_nodes
(values: integer, defualt value: 10): maximum number of iteration of beam searchoptimal
(values: :code:{yes, no}
, default value: :code:no
): whether ther refinement operator is optimal or notmax_length
(values: integer, defualt value: 4): maximum number of body literals and head disjunctsmax_lengths
(values: list of integers :code:`[Body,Disjuncts,LitIn+,LitIn-]`, defualt value: :code:[1,1,1,0]
): maximum number of, respectively, body literals, head disjuncts, literals in P disjuncts and literals in N disjunctsmax_initial_weight
(values: real, default value :math:`0.1)`: absolute value of the maximum of the initial weights in weight learning.learning_algorithm
(values: :code:{gradient_descent, lbfgs}
, default value: :code:gradient_descent
): algorithm for parameter learningrandom_restarts_number
(values: integer, default value: 1): number of random restarts for gradient descent parameter learninglearning_rate
(values: :code:{fixed(value),decay(eta_0,eta_tau,tau)}
, default value: :code:fixed(0.01)
): value of the learning rate, either fixed to a value or set with a decay strategygd_iter
(values: integer, default value: 1000): maximum number of gradient descent iterationsepsilon
(values: real, default value: 0.0001): if the difference in the log likelihood in two successive parameter gradient descent iterations is smaller than :code:epsilon
, then the algorithm stopsepsilon_fraction
(values: real, default value: 0.00001): if the difference in the log likelihood in two successive parameter gradient descent iterations is smaller than :code:`epsilon_fraction*(-current log likelihood)`, then the algorithm stopsregularization
(values: :code:{1,2}
, default value: :code:2
): either L1 or L2 regularization in gradient descent and lbfgsregularizing_constant
(values: real, default value: 5): value of the regularizatiom constant in gradient descent and lbfgsmax_rules
(values: integer, default value: 10): maximum number of PIC in the final theorylogzero
(values: negative real, default value :math:\log(0.01)
: value assigned to :math:\log(0)
zero
(values: positive real, default value :code:0.0001
: value assigned to :math:0
when computing denominators that are countsminus_infinity
(values: negative real, default value :code:-1.0e20
: value assigned to :math:`-\infty`, used as the intial value of the log likelihood in parameter learning
The :code:pack/pascal/prolog/examples
folder in SWI-Prolog home contains some example programs.
The :code:pack/pascal/docs
folder contains this manual in html and pdf.
A PDF version of the manual is available at `http://friguzzi.github.io/pascal/_build/latex/pascal.pdf http://friguzzi.github.io/pascal/_build/latex/pascal.pdf`_.
Pascal follows the BSD 2-Clause License that you can find in the root folder. The copyright is by Fabrizio Riguzzi.
.. bibliography:: newbib.bib