Skip to content

Latest commit

 

History

History
629 lines (489 loc) · 15 KB

Formal-Contexts.org

File metadata and controls

629 lines (489 loc) · 15 KB

Working with 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.

Be sure to first read the ICFCA 2013 tutorial, as it already covers the most basic ways to create formal contexts.

The examples in this file have been provided in part by Sebastian Böhm.

Creating Formal Contexts

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

A context (G,M,I) consists of two sets G and M and an incidence realtion I ⊆ G×M. G is a set of objects, M is a set of attributes and gIm (short for (g,m) ∈ I) can be read as g has the attribute m. To create a context you only have to define these sets. There a (at least) three options:

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

A formal context can also be specified by directly listing the incidence relation (using Clojure’s own syntax for sets and tuples):

(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 make save some typing time.

### Using a custom function

This will create a formal context with G = M = {1,2,3,4,5,6} and (n,m) in I if and only if gcd(n,m) = 1:

(def ctx-4 (make-context [1 2 3 4 5 6]
                         [1 2 3 4 5 6]
                         (fn [x y]
                           (= 1 (gcd x y)))))
ctx-4
  |1 2 3 4 5 6 
--+------------
1 |x x x x x x 
2 |x . x . x . 
3 |x x . x x . 
4 |x . x . x . 
5 |x x x x . x 
6 |x . . . x . 

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 x 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.

Working with Formal Contexts

Having created a formal context, there a plenty of possibilities to work with it.

Basic Accessors

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

[(objects ctx-2), (attributes ctx-2), (incidence ctx-2)]
[#{1 4 6 3 2 5}
 #{1 4 6 3 2 5}
 #{[2 2] [2 5] [3 3] [1 1] [6 6] [4 6] [1 3] [1 5] [5 5] [3 6] [4 5]
   [1 6] [4 4] [1 2]}]

Clarifying and Reducing Contexts

To see if ctx-2 is clarified, you can use the functions object-clarified?, attribute-clarified?, and context-clarified?.

[(object-clarified? ctx-2),
 (attribute-clarified? ctx-2),
 (context-clarified? ctx-2)]
[true true true]

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

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

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

[(up-arrows ctx-2), (down-arrows ctx-2)]
[#{[4 3] [6 3] [4 2] [6 5] [5 2] [1 4] [5 6] [2 6] [3 5]}
 #{[4 3] [2 3] [4 2] [4 1] [1 4] [3 1] [2 1] [2 6] [3 5] [3 2]}]

To directly see whether ctx-2 is reduced, use context-reduced?, and to obtain a reduced version of ctx-2, call reduce-context like so:

(reduce-context ctx-2)
  |2 3 4 5 6 
--+----------
1 |x x . x x 
2 |x . . x . 
3 |. x . . x 
4 |. . x x x 

Derivation Operations

Now I want to get all objects, which attribute 1 and 2 have in common

(attribute-derivation ctx-2 #{1 2})
#{1}

The same can be done for sets of objects

(object-derivation ctx-1 #{1 2})
#{3 2}

Instead of using this long function 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-2 #{1 2}),
  (context-object-closure ctx-2 #{1 2}) ]
[#{1 6 3 2 5} #{1 2}]

Formal Concepts and Concept Lattices

We can compute all intents and extents via

[(extents ctx-2), (intents ctx-2)]
[(#{}
  #{4}
  #{1}
  #{1 4}
  #{1 2}
  #{1 3}
  #{1 4 2 5}
  #{1 4 6 3}
  #{1 4 6 3 2 5})
 (#{}
  #{5}
  #{2 5}
  #{6}
  #{6 5}
  #{6 3}
  #{4 6 5}
  #{1 6 3 2 5}
  #{1 4 6 3 2 5})]

To get all formal concepts use

(concepts ctx-2)
([#{1 4 6 3 2 5} #{}]
 [#{1} #{1 6 3 2 5}]
 [#{} #{1 4 6 3 2 5}]
 [#{4} #{4 6 5}]
 [#{1 4 6 3} #{6}]
 [#{1 3} #{6 3}]
 [#{1 4} #{6 5}]
 [#{1 2} #{2 5}]
 [#{1 4 2 5} #{5}])

If you are only interested in the number of formal concepts, you can instead just count the concepts, like so

(count (concepts ctx-2))
9

This can be combined neatly with map to get the number of concepts for all the formal contexts we have defined to far

(map (comp count concepts) [ctx-1 ctx-2 ctx-3 ctx-4])
(3 9 9 8)

The standard comp functions implements function composition in Clojure.

Finally, you can compute the concept lattice using the concept-lattice function like so:

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

Note that this will not give you a picture of the lattice, but a representation of the algebraic structure.

Canonical Base

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

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

The canonical-base function can take additional arguments like background knowledge and filter predicates. See the documentation of this function for further details:

(doc canonical-base)
-------------------------
conexp.fca.implications/canonical-base
([ctx] [ctx background-knowledge] [ctx background-knowledge predicate])
  Returns the canonical base of given context, as a lazy sequence.  Uses
  «background-knowledge» as starting set of implications, which will not appear
  in the result.  If «predicate» is given (a function), computes only those
  implications from the canonical base whose premise satisfy this predicate,
  i.e. «predicate» returns true on these premises.  Note that «predicate» has to
  satisfy the same conditions as the predicate to «next-closed-set-in-family».
nil

Further Operations

There a several further operations you can do with contexts, e.g., the context apposition, context subposition, and more. For illustration, let us define two contexts:

(def ctx-5 (make-context #{1 2 3} #{1 2 3} <))
(def ctx-6 (make-context-from-matrix [1 2 3]
                                     ['a 'b 'c 'd]
                                     [1 1 0 1
                                      1 0 1 0
                                      0 0 1 1]))
[ctx-5 ctx-6]
[  |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-5 ctx-6)
  |[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.

Context apposition is a partial operation, as the contexts must have the same set of objects. The following would not work:

(context-apposition ctx-1 ctx-2)
class java.lang.IllegalArgumentExceptionclass java.lang.IllegalArgumentExceptionIllegalArgumentException Cannot do context apposition, since object sets are not equal.  conexp.base/illegal-argument (base.clj:280)

To compute the dual context, use what you would expect to use:

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

Now we can build the subposition of ctx-5 and the dual of ctx-6

(context-subposition ctx-5 (dual-context ctx-6))
      |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-5)
  |1 2 3 
--+------
1 |x . . 
2 |x x . 
3 |x x x 

You can create a composition of two (suitable) contexts with

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

The union of two contexts is created by

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

Sum to contexts with

(context-sum ctx-5 ctx-6)

To compute the intersection of two contexts (which is essentially empty), use

(context-intersection ctx-5 ctx-6)
  |
--+
1 |
2 |
3 |

The context product goes like this

(context-product ctx-5 ctx-6)
      |[1 a] [2 a] [3 a] [1 b] [2 b] [3 b] [1 c] [2 c] [3 c] [1 d] [2 d] [3 d] 
------+------------------------------------------------------------------------
[1 1] |x     x     x     x     x     x     .     x     x     x     x     x     
[2 1] |x     x     x     x     x     x     .     .     x     x     x     x     
[3 1] |x     x     x     x     x     x     .     .     .     x     x     x     
[1 2] |x     x     x     .     x     x     x     x     x     .     x     x     
[2 2] |x     x     x     .     .     x     x     x     x     .     .     x     
[3 2] |x     x     x     .     .     .     x     x     x     .     .     .     
[1 3] |.     x     x     .     x     x     x     x     x     x     x     x     
[2 3] |.     .     x     .     .     x     x     x     x     x     x     x     
[3 3] |.     .     .     .     .     .     x     x     x     x     x     x     

If you want to do a context semiproduct

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

Compute Xia’s product

(context-xia-product ctx-5 ctx-6)
      |[1 a] [2 a] [3 a] [1 b] [2 b] [3 b] [1 c] [2 c] [3 c] [1 d] [2 d] [3 d] 
------+------------------------------------------------------------------------
[1 1] |.     x     x     .     x     x     x     .     .     .     x     x     
[2 1] |.     .     x     .     .     x     x     x     .     .     .     x     
[3 1] |.     .     .     .     .     .     x     x     x     .     .     .     
[1 2] |.     x     x     x     .     .     .     x     x     x     .     .     
[2 2] |.     .     x     x     x     .     .     .     x     x     x     .     
[3 2] |.     .     .     x     x     x     .     .     .     x     x     x     
[1 3] |x     .     .     x     .     .     .     x     x     .     x     x     
[2 3] |x     x     .     x     x     .     .     .     x     .     .     x     
[3 3] |x     x     x     x     x     x     .     .     .     .     .     .