Skip to content

Latest commit

 

History

History
559 lines (433 loc) · 11.1 KB

icfca2013-tutorial-live.org

File metadata and controls

559 lines (433 loc) · 11.1 KB

conexp-clj Live Presentation at ICFCA 2013

This tutorial has been given by Daniel Borchmann at the 11th ICFCA 2013. There are also some slides (partial tex) and even an exercise sheet (partial tex) from this tutorial.

Note: the corresponding Org Mode file contains source blocks that can be exectued directly. See Setting up Emacs to Run Clojure Code for how to exectue those blocks from within the document.

Creating Formal Contexts

As conexp-clj is a general purpose tool for Formal Concept Analysis, it lets you easily work with the basic structure of FCA, namely formal contexts. This page discusses in which ways conexp-clj can work with and on formal contexts.

conexp-clj lets you easily create formal contexts in a number of ways. We shall describe some of them in the following.

Using a defined relation

The fasted way to construct a formal context is just by writing it down, as in the following example.

(def ctx-1 (make-context [1 2 3] [1 2 3] <=))

To see the formal context, just evaluate its variable explicitly

ctx-1
  |1 2 3 
--+------
1 |x x x 
2 |. x x 
3 |. . x 

Defining all sets explicitly

This is the ordered set called Chevron (in ASCII Art, don’t type this into the prompt)

 5   6
| \ / |
|  4  |
2     3
 \   /
   1

To obtain a formal context for this, we can use the following command

(def ctx-2 (make-context #{1 2 3 4 5 6}
                         #{1 2 3 4 5 6}
                         #{[1 1] [1 2] [1 3] [1 5]
                           [1 6] [2 2] [2 5] [3 3]
                           [3 6] [4 4] [4 5] [4 6]
                           [5 5] [6 6]}))
ctx-2
  |1 2 3 4 5 6 
--+------------
1 |x x x . x x 
2 |. x . . x . 
3 |. . x . . x 
4 |. . . x x x 
5 |. . . . x . 
6 |. . . . . x 

One can enter the cross-table explicitly, using the function make-context-from-matrix, like this

(def ctx-3 (make-context-from-matrix 6 6
                                     [1 1 1 0 1 1
                                      0 1 0 0 1 0
                                      0 0 1 0 0 1
                                      0 0 0 1 1 1
                                      0 0 0 0 1 0
                                      0 0 0 0 0 1]))
ctx-3
  |0 1 2 3 4 5 
--+------------
0 |x x x . x x 
1 |. x . . x . 
2 |. . x . . x 
3 |. . . x x x 
4 |. . . . x . 
5 |. . . . . x 

Here, instead of writing out the sets of objects and attributes explicitly, we have just entered their cardinality 6. With this, the set of objects and attributes automatically gets set to #{1 2 3 4 5 6}. From time to time, this may save some typing time.

Creating Random Contexts

For some experiments it is often helpful to randomly create contexts. Here is how this can be done in conexp-clj. Of course, the exact result is probably not the one you see here

(rand-context #{1 2 3} 0.5)
  |1 2 3 
--+------
1 |x . . 
2 |x . x 
3 |x x . 

Here, the first parameter is the set of objects and attributes and the second parameter is the probality for the incidence.

More Functionality

Working with Formal Contexts

Having created a formal context, there a plenty of possibilities to work with it. To illustrate this, let us define the Chevron again

(def ctx-1 (make-context-from-matrix ['a 'b 'c 'd 'e 'f]
                                     ['a 'b 'c 'd 'e 'f]
                                     [1 1 1 0 1 1
                                      0 1 0 0 1 0
                                      0 0 1 0 0 1
                                      0 0 0 1 1 1
                                      0 0 0 0 1 0
                                      0 0 0 0 0 1]))
ctx-1
  |a b c d e f 
--+------------
a |x x x . x x 
b |. x . . x . 
c |. . x . . x 
d |. . . x x x 
e |. . . . x . 
f |. . . . . x 

Note that =’a= denotes the symbol named a.

Basic Accessors

The most basic operation on formal contexts is to retrieve its components. This can be done as follows

(objects ctx-1)
#{a e c b d f}
(attributes ctx-1)
#{a e c b d f}
(incidence ctx-1)
#{[a f] [a a] [f f] [c c] [d f] [a e] [d e] [a b] [c f] [d d] [a c]
  [e e] [b b] [b e]}

Clarifying and Reducing Contexts

To see if ctx-1 is clarified, you can also use

(object-clarified? ctx-1)
true
(attribute-clarified? ctx-1)
true

or both steps at once using

(context-clarified? ctx-1)
true

If ctx-1 would not be clarified, one could obtain a clarified version of ctx-1 by using

(clarify-attributes ctx-1)
(clarify-objects ctx-1)
(clarify-context ctx-1)

As another example, for ctx-1, we could for instance compute the arrow relations (e.g. to see which objects or attributes are irreducible)

(up-arrows ctx-1)
#{[d c] [e b] [f c] [e f] [f e] [b f] [a d] [d b] [c e]}
(down-arrows ctx-1)
#{[c b] [d c] [b a] [b f] [a d] [b c] [d b] [c a] [c e] [d a]}

To directly see whether ctx-1 is reduced, one could also use

(context-reduced? ctx-1)
false

and to obtain a reduced version of ctx-1

(reduce-context ctx-1)
  |b c d e f 
--+----------
a |x x . x x 
b |x . . x . 
c |. x . . x 
d |. . x x x 

Derivation Operations

Now I want to get all objects, which attribute a and b have in common

(attribute-derivation ctx-1 #{'a 'b})
#{a}

The same can be done for sets of objects

(object-derivation ctx-1 #{'c 'd 'f})
#{f}

Instead of using this long names, there are also the abbreviations aprime and oprime available.

If you want to compute the closure of a given set of objects or attributes in our context use

(context-attribute-closure ctx-1 #{'a 'b})
#{a e c b f}
(context-object-closure ctx-1 #{'a 'b})
#{a b}

Formal Concepts and Concept Lattices

We can compute all intents and extents via

(extents ctx-1)
(#{}
 #{d}
 #{a}
 #{a d}
 #{a b}
 #{a c}
 #{a c d f}
 #{a e b d}
 #{a e c b d f})
(intents ctx-1)
(#{}
 #{f}
 #{c f}
 #{e}
 #{e f}
 #{e d f}
 #{e b}
 #{a e c b f}
 #{a e c b d f})

To get all formal concepts use

(concepts ctx-1)
([#{a e c b d f} #{}]
 [#{a} #{a e c b f}]
 [#{} #{a e c b d f}]
 [#{a e b d} #{e}]
 [#{a b} #{e b}]
 [#{d} #{e d f}]
 [#{a d} #{e f}]
 [#{a c} #{c f}]
 [#{a c d f} #{f}])

If you are only interested in the number of formal concepts, you can instead write

(count (concepts ctx-1))
9

Finally, you can compute the concept lattice via

(concept-lattice ctx-1)
Lattice on 9 elements.

Note that this will not give you a picture of the lattice, but a representation of the algebraic structure. To get an picture of the lattice, do the following

(use 'conexp.gui.draw)
(draw-lattice (concept-lattice ctx-1))

This will open up a new window which should look like this

../../images/cevron-concept-lattice.png

Canonical Base

You get the canonical base with (who would have guessed that!)

(canonical-base ctx-1)
((#{d} ⟶ #{e f})
 (#{b} ⟶ #{e})
 (#{c} ⟶ #{f})
 (#{e b f} ⟶ #{a c})
 (#{e c f} ⟶ #{a b})
 (#{a} ⟶ #{e c b f}))

Further Operations

There a several further operations you can do with contexts, e.g. the context apposition. We define two contexts:

(def ctx-1 (make-context #{1 2 3} #{1 2 3} <))
(def ctx-2 (make-context-from-matrix [1 2 3]
                                     ['a 'b 'c 'd]
                                     [1 1 0 1
                                      1 0 1 0
                                      0 0 1 1]))
;; show both context in a vector
[ctx-1 ctx-2]
[  |1 2 3 
--+------
1 |. x x 
2 |. . x 
3 |. . . 
   |a b c d 
--+--------
1 |x x . x 
2 |x . x . 
3 |. . x x 
]

The apposition of these two contexts is

(context-apposition ctx-1 ctx-2)
  |[1 0] [2 0] [3 0] [a 1] [b 1] [c 1] [d 1] 
--+------------------------------------------
1 |.     x     x     x     x     .     x     
2 |.     .     x     x     .     x     .     
3 |.     .     .     .     .     x     x     

Note how the two sets of attributes are automatically made disjoint by considering pairs with different second entry.

To compute the dual context, we use

(dual-context ctx-2)
  |1 2 3 
--+------
a |x x . 
b |x . . 
c |. x x 
d |x . x 

Now we can build the subposition of ctx-1 and the dual of ctx-2

(context-subposition ctx-1 (dual-context ctx-2))
      |1 2 3 
------+------
[1 0] |. x x 
[2 0] |. . x 
[3 0] |. . . 
[a 1] |x x . 
[b 1] |x . . 
[c 1] |. x x 
[d 1] |x . x 

If you want to invert a given context use

(invert-context ctx-1)
  |1 2 3 
--+------
1 |x . . 
2 |x x . 
3 |x x x