Introduction

In this vignette, we present the main functionalities and data structures of the fcaR package when working with formal contexts and concepts, in FCA.

We load the fcaR package by:

library(fcaR)

Datasets

We are going to work with two datasets, a crisp one and a fuzzy one.

The classical (binary) dataset is the well-known planets formal context, presented in

Wille R (1982). “Restructuring Lattice Theory: An Approach Based on Hierarchies of Concepts.” In Ordered Sets, pp. 445–470. Springer.

knitr::kable(planets, format = "html", booktabs = TRUE)
small medium large near far moon no_moon
Mercury 1 0 0 1 0 0 1
Venus 1 0 0 1 0 0 1
Earth 1 0 0 1 0 1 0
Mars 1 0 0 1 0 1 0
Jupiter 0 0 1 0 1 1 0
Saturn 0 0 1 0 1 1 0
Uranus 0 1 0 0 1 1 0
Neptune 0 1 0 0 1 1 0
Pluto 1 0 0 0 1 1 0

The other formal context is fuzzy and is defined by the following matrix I:

knitr::kable(I, format = "html", booktabs = TRUE)
P1 P2 P3 P4 P5 P6
O1 0.0 0.0 0.5 0.5 1.0 0
O2 1.0 1.0 1.0 0.0 0.0 0
O3 0.5 0.5 0.0 0.0 0.0 1
O4 0.0 0.0 0.0 1.0 0.5 0
O5 0.0 0.0 1.0 0.5 0.0 0
O6 0.5 0.5 0.0 0.0 0.0 1

Working with Formal Contexts

The first step when using the fcaR package to analyze a formal context is to create an object of class FormalContext which will store all the information related to the context.

In our examples, we create two objects:

fc_planets <- FormalContext$new(planets) fc_I <- FormalContext$new(I)

Internally, the object stores information about whether the context is binary or the names of objects and attributes, which are taken from the rownames and colnames of the provided matrix.

Plotting, printing and latex-ing the FormalContext

Once created the FormalContext objects, we can print them or plot them as heatmaps (with functions print() and plot()):

print(fc_planets)
#> FormalContext with 9 objects and 7 attributes.
#>            small   medium   large   near   far   moon   no_moon
#>   Mercury    X                       X                     X
#>     Venus    X                       X                     X
#>     Earth    X                       X            X
#>      Mars    X                       X            X
#>   Jupiter                     X             X     X
#>    Saturn                     X             X     X
#>    Uranus            X                      X     X
#>   Neptune            X                      X     X
#>     Pluto    X                              X     X
print(fc_I)
#> FormalContext with 6 objects and 6 attributes.
#>       P1    P2    P3    P4    P5    P6
#>   O1   0     0    0.5   0.5    1    0
#>   O2   1     1     1     0     0    0
#>   O3  0.5   0.5    0     0     0    1
#>   O4   0     0     0     1    0.5   0
#>   O5   0     0     1    0.5    0    0
#>   O6  0.5   0.5    0     0     0    1
fc_planets$plot() fc_I$plot()

Also, we can export the formal context as a LaTeX table:

fc_planets$to_latex() #> \begin{table} \centering \begin{tabular}{lccccccc} #> \toprule #> & small & medium & large & near & far & moon & no_moon\\ #> \midrule #> Mercury &$\times$& & &$\times$& & &$\times$\\ #> Venus &$\times$& & &$\times$& & &$\times$\\ #> Earth &$\times$& & &$\times$& &$\times$& \\ #> Mars &$\times$& & &$\times$& &$\times$& \\ #> Jupiter & & &$\times$& &$\times$&$\times$& \\ #> Saturn & & &$\times$& &$\times$&$\times$& \\ #> Uranus & &$\times$& & &$\times$&$\times$& \\ #> Neptune & &$\times$& & &$\times$&$\times$& \\ #> Pluto &$\times$& & & &$\times$&$\times$& \\ #> \bottomrule #> \end{tabular} \caption{\label{}} \end{table} Closures The basic operation in FCA is the computation of closures given an attribute set, by using the two derivation operators, extent and intent. The intent of a (probably fuzzy) set of objects is the set of their common attributes: # Define a set of objects S <- SparseSet$new(attributes = fc_planets$objects) S$assign(Earth = 1, Mars = 1)
S
#> {Earth, Mars}

# Compute the intent of S
fc_planets$intent(S) #> {small, near, moon} Analogously, the extent of a set of attributes is the set of objects which possess all the attributes in the given set: # Define a set of objects S <- SparseSet$new(attributes = fc_planets$attributes) S$assign(moon = 1, large = 1)
S
#> {large, moon}

# Compute the extent of S
fc_planets$extent(S) #> {Jupiter, Saturn} The composition of intent and extent is the closure of a set of attributes: # Compute the closure of S Sc <- fc_planets$closure(S)
Sc
#> {large, far, moon}

This means that all planets which have the attributes moon and large also have far in common.

We can check whether a set is closed (that is, it is equal to its closure), using is_closed():

fc_planets$is_closed(S) #> [1] FALSE fc_planets$is_closed(Sc)
#> [1] TRUE

Clarification and Reduction

An interesting point when managing formal contexts is the ability to reduce the context, removing redundancies, while retaining all the knowledge. This is accomplished by two functions: clarify(), which removes duplicated attributes and objects (columns and rows in the original matrix); and reduce(), which uses closures to remove dependent attributes, but only on binary formal contexts. The resulting FormalContext is equivalent to the original one in both cases.

fc_planets$reduce(TRUE) #> FormalContext with 5 objects and 7 attributes. #> small medium large near far moon no_moon #> Pluto X X X #> [Mercury, Venus] X X X #> [Earth, Mars] X X X #> [Jupiter, Saturn] X X X #> [Uranus, Neptune] X X X fc_I$clarify(TRUE)
#> FormalContext with 5 objects and 5 attributes.
#>             P3    P4    P5    P6   [P1, P2]
#>         O1  0.5   0.5    1    0       0
#>         O2   1     0     0    0       1
#>         O4   0     1    0.5   0       0
#>         O5   1    0.5    0    0       0
#>   [O3, O6]   0     0     0    1      0.5

Note that merged attributes or objects are stored in the new formal context by using squared brackets to unify them, e.g. [Mercury, Venus].

Extracting Implications and Concepts

The function to extract the canonical basis of implications and the concept lattice is find_implications(). Its use is to store a ConceptLattice and an ImplicationSet objects internally in the FormalContext object after running the NextClosure algorithm.

It can be used both for binary and fuzzy formal contexts, resulting in binary or fuzzy concepts and implications:

fc_planets$find_implications() fc_I$find_implications()

We can inspect the results as:

# Concepts
fc_planets$concepts #> A set of 12 concepts: #> 1: ({Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto}, {}) #> 2: ({Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto}, {moon}) #> 3: ({Jupiter, Saturn, Uranus, Neptune, Pluto}, {far, moon}) #> 4: ({Jupiter, Saturn}, {large, far, moon}) #> 5: ({Uranus, Neptune}, {medium, far, moon}) #> 6: ({Mercury, Venus, Earth, Mars, Pluto}, {small}) #> 7: ({Earth, Mars, Pluto}, {small, moon}) #> 8: ({Pluto}, {small, far, moon}) #> 9: ({Mercury, Venus, Earth, Mars}, {small, near}) #> 10: ({Mercury, Venus}, {small, near, no_moon}) #> 11: ({Earth, Mars}, {small, near, moon}) #> 12: ({}, {small, medium, large, near, far, moon, no_moon}) # Implications fc_planets$implications
#> Implication set with 10 implications.
#> Rule 1: {no_moon} -> {small, near}
#> Rule 2: {far} -> {moon}
#> Rule 3: {near} -> {small}
#> Rule 4: {large} -> {far, moon}
#> Rule 5: {medium} -> {far, moon}
#> Rule 6: {medium, large, far, moon} -> {small, near, no_moon}
#> Rule 7: {small, near, moon, no_moon} -> {medium, large, far}
#> Rule 8: {small, near, far, moon} -> {medium, large, no_moon}
#> Rule 9: {small, large, far, moon} -> {medium, near, no_moon}
#> Rule 10: {small, medium, far, moon} -> {large, near, no_moon}

Standard Context

Once we have computed the concepts, we can build the standard context (J, M, $$\le$$), where J is the set of join-irreducible concepts and M are the meet-irreducible ones. Join and meet are another name for supremum and infimum operations in the concept lattice.

The function standardize() works for all FormalContext where the concept lattice has been found, and it produces a new FormalContext object:

fc_planets$standardize() #> FormalContext with 5 objects and 7 attributes. #> M1 M2 M3 M4 M5 M6 M7 #> J1 X X X #> J2 X X X #> J3 X X X #> J4 X X X #> J5 X X X fc_I$standardize()
#> FormalContext with 9 objects and 9 attributes.
#>       M1   M2   M3   M4   M5   M6   M7   M8   M9
#>   J1  X    X         X
#>   J2  X    X    X    X
#>   J3  X    X    X         X
#>   J4  X                   X    X
#>   J5  X              X    X    X
#>   J6  X    X    X    X    X    X
#>   J7                                X    X
#>   J8                                X    X    X
#>   J9                      X    X    X         X

Note that now objects are named J1, J2… and attributes are M1, M2…, from join and meet.

A FormalContext is saved and loaded (in RDS format) using its own methods save() and load(), which are more efficient than the base saveRDS() and readRDS().

fc$save(filename = "./fc.rds") # Create an empty FormalContext where to # import the previously saved fc2 <- FormalContext$new()
fc2$load("./fc.rds") Concept Lattice We are going to use the previously computed concept lattices for the two FormalContext objects. Plot, print and LaTeX The concept lattice can be plotted using a Hasse diagram and the function plot() inside the ConceptLattice component: fc_planets$concepts$plot() fc_I$concepts$plot() If one desires to get the list of concepts printed, or in $$\LaTeX$$ format, just: # Printing fc_planets$concepts
#> A set of 12 concepts:
#> 1: ({Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto}, {})
#> 2: ({Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto}, {moon})
#> 3: ({Jupiter, Saturn, Uranus, Neptune, Pluto}, {far, moon})
#> 4: ({Jupiter, Saturn}, {large, far, moon})
#> 5: ({Uranus, Neptune}, {medium, far, moon})
#> 6: ({Mercury, Venus, Earth, Mars, Pluto}, {small})
#> 7: ({Earth, Mars, Pluto}, {small, moon})
#> 8: ({Pluto}, {small, far, moon})
#> 9: ({Mercury, Venus, Earth, Mars}, {small, near})
#> 10: ({Mercury, Venus}, {small, near, no_moon})
#> 11: ({Earth, Mars}, {small, near, moon})
#> 12: ({}, {small, medium, large, near, far, moon, no_moon})

# LaTeX
fc_planets$concepts$to_latex()
#> \begin{longtable}{lll}
#> 1: &$\left(\,\ensuremath{\left\{\mathrm{Mercury},\, \mathrm{Venus},\, \mathrm{Earth},\, \mathrm{Mars},\, \mathrm{Jupiter},\, \mathrm{Saturn},\, \mathrm{Uranus},\, \mathrm{Neptune},\, \mathrm{Pluto}\right\}},\right.$&$\left.\ensuremath{\varnothing}\,\right)$\\
#> 2: &$\left(\,\ensuremath{\left\{\mathrm{Earth},\, \mathrm{Mars},\, \mathrm{Jupiter},\, \mathrm{Saturn},\, \mathrm{Uranus},\, \mathrm{Neptune},\, \mathrm{Pluto}\right\}},\right.$&$\left.\ensuremath{\left\{\mathrm{moon}\right\}}\,\right)$\\
#> 3: &$\left(\,\ensuremath{\left\{\mathrm{Jupiter},\, \mathrm{Saturn},\, \mathrm{Uranus},\, \mathrm{Neptune},\, \mathrm{Pluto}\right\}},\right.$&$\left.\ensuremath{\left\{\mathrm{far},\, \mathrm{moon}\right\}}\,\right)$\\
#> 4: &$\left(\,\ensuremath{\left\{\mathrm{Jupiter},\, \mathrm{Saturn}\right\}},\right.$&$\left.\ensuremath{\left\{\mathrm{large},\, \mathrm{far},\, \mathrm{moon}\right\}}\,\right)$\\
#> 5: &$\left(\,\ensuremath{\left\{\mathrm{Uranus},\, \mathrm{Neptune}\right\}},\right.$&$\left.\ensuremath{\left\{\mathrm{medium},\, \mathrm{far},\, \mathrm{moon}\right\}}\,\right)$\\
#> 6: &$\left(\,\ensuremath{\left\{\mathrm{Mercury},\, \mathrm{Venus},\, \mathrm{Earth},\, \mathrm{Mars},\, \mathrm{Pluto}\right\}},\right.$&$\left.\ensuremath{\left\{\mathrm{small}\right\}}\,\right)$\\
#> 7: &$\left(\,\ensuremath{\left\{\mathrm{Earth},\, \mathrm{Mars},\, \mathrm{Pluto}\right\}},\right.$&$\left.\ensuremath{\left\{\mathrm{small},\, \mathrm{moon}\right\}}\,\right)$\\
#> 8: &$\left(\,\ensuremath{\left\{\mathrm{Pluto}\right\}},\right.$&$\left.\ensuremath{\left\{\mathrm{small},\, \mathrm{far},\, \mathrm{moon}\right\}}\,\right)$\\
#> 9: &$\left(\,\ensuremath{\left\{\mathrm{Mercury},\, \mathrm{Venus},\, \mathrm{Earth},\, \mathrm{Mars}\right\}},\right.$&$\left.\ensuremath{\left\{\mathrm{small},\, \mathrm{near}\right\}}\,\right)$\\
#> 10: &$\left(\,\ensuremath{\left\{\mathrm{Mercury},\, \mathrm{Venus}\right\}},\right.$&$\left.\ensuremath{\left\{\mathrm{small},\, \mathrm{near},\, \mathrm{no_moon}\right\}}\,\right)$\\
#> 11: &$\left(\,\ensuremath{\left\{\mathrm{Earth},\, \mathrm{Mars}\right\}},\right.$&$\left.\ensuremath{\left\{\mathrm{small},\, \mathrm{near},\, \mathrm{moon}\right\}}\,\right)$\\
#> 12: &$\left(\,\ensuremath{\varnothing},\right.$&$\left.\ensuremath{\left\{\mathrm{small},\, \mathrm{medium},\, \mathrm{large},\, \mathrm{near},\, \mathrm{far},\, \mathrm{moon},\, \mathrm{no_moon}\right\}}\,\right)$\\
#> \end{longtable}

Getting all extents, intents and retrieving concepts

For a ConceptLattice, one may want to retrieve particular concepts, using a subsetting as in R:

Subconcepts, superconcepts, infimum and supremum

It may be interesting to use the notions of subconcept and superconcept. Given a concept, we can compute all its subconcepts and all its superconcepts:

# The fifth concept
C <- fc_planets$concepts[5][[1]] C #> ({Uranus, Neptune}, {medium, far, moon}) # Its subconcepts: fc_planets$concepts$subconcepts(C) #> ({Uranus, Neptune}, {medium, far, moon}) #> ({}, {small, medium, large, near, far, moon, no_moon}) # And its superconcepts: fc_planets$concepts$superconcepts(C) #> ({Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto}, {}) #> ({Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto}, {moon}) #> ({Jupiter, Saturn, Uranus, Neptune, Pluto}, {far, moon}) #> ({Uranus, Neptune}, {medium, far, moon}) Also, we can define infimum and supremum of a set of concepts as the greatest common subconcept of all the given concepts, and the lowest common superconcept of them, and can be computed by: # A list of concepts C <- fc_planets$concepts[5:7]
C
#> ({Uranus, Neptune}, {medium, far, moon})
#> ({Mercury, Venus, Earth, Mars, Pluto}, {small})
#> ({Earth, Mars, Pluto}, {small, moon})

# Supremum of the concepts in C
fc_planets$concepts$supremum(C)
#> ({Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto}, {})
# Infimum of the concepts in C
fc_planets$concepts$infimum(C)
#> ({}, {small, medium, large, near, far, moon, no_moon})

Join- and meet- irreducible elements

Also irreducible elements with respect to join (supremum) and meet (infimum) can be computed for a given concept lattice:

fc_planets$concepts$join_irreducibles()
#> ({Jupiter, Saturn}, {large, far, moon})
#> ({Uranus, Neptune}, {medium, far, moon})
#> ({Pluto}, {small, far, moon})
#> ({Mercury, Venus}, {small, near, no_moon})
#> ({Earth, Mars}, {small, near, moon})
fc_planets$concepts$meet_irreducibles()
#> ({Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Pluto}, {moon})
#> ({Jupiter, Saturn, Uranus, Neptune, Pluto}, {far, moon})
#> ({Jupiter, Saturn}, {large, far, moon})
#> ({Uranus, Neptune}, {medium, far, moon})
#> ({Mercury, Venus, Earth, Mars, Pluto}, {small})
#> ({Mercury, Venus, Earth, Mars}, {small, near})
#> ({Mercury, Venus}, {small, near, no_moon})

This are the concepts used to build the standard context, mentioned above.