Knowledge space theory (KST) was founded by Doignon and Falmagne (1985, 1999; see also Falmagne et al., 2013; Heller & Stefanutti, 2024a) as a means for efficient adaptive assessment of knowledge. Efficiency here means that the number of items tested should be relatively small. KST models prerequisite relationships between test items and infers from previous answers to the mastery of other items based on these prerquisites. However, it is a behavioral model, i.e. it does not look into the skills and competencies underlying the response behaviour.
Competence-based Knowledge Space Theory (CbKST; see, e.g., Doignon, 1994; Düntsch & Gediga, 1995; Korossy, 1997; Albert & Lukas, 1999; Heller et al., 2006, Heller et al., 2013, Heller & Stefanutti, 2024b) aims at mending this. Its core element are skill maps or skill multimaps assigning to each test items the skills and competencies required for solving it.
In the context of knowledge space theory, the terms skill and competence are often used synonymously. When skill multimaps are used, however, there is a clear distinction: competences are the subsets of skills assigned to an item through the skill multimap. The competences are interpreted as alternative sets of prerequisites for solving the item, especially for different possible solujtion paths.
It should be noticed that, for two competence states \(C\) and \(C'\) and the corresponding performance states \(P\) and \(P'\), the
performance state corresponding to \(C\cup C'\) is not necessarily \(P\cup P'\) but may be a (strict) superset of it. As a consequence,
the performance structure corresponding to a competence space (cbkst_performancestructure(multimap, comp)) is not necessarily
a performance space, i.e. closed under union. Also, if we map an arbitrary subset \(P\) of test items with cbkst_perf2comp()
to the minimal competence states and map them back to the performance level with cbkst_comp2perf(), we may obtain a larger
subset \(P'\supset P\); more concretely, we would obtain one or more performance states, actually the minimal ones containing \(P\).
While generally, CbKST focuses on skill maps with skill multimaps as an extension allowing for different solution paths for the
test items, within the implementation of the CbKST package, the skill multimaps are the core element and basic object class.
Skill maps are a mere special case (and thus a sub class) of skill multimaps. Practically, both classes are identical, i.e. data
frames. These data frames contain item IDs in the first columns and a binary matrix in subsequent columns (one per skill) where
a ‘1’ denotes the case that a skill is a prerequisite for the mastery of the respective test item (and ‘0’ otherwise). If a skill
multimap data frame has exactly one row per test item, it describes a skill map.
Skill (multi-) map files can be in ODS or XLSX spreadsheet format. Their table layout is basically the same as the data frame
structure. A preceding header row contains the skill IDs in the columns 2 to \(n\). The first entry in the header row is not used
by the functions in CbKST.
exampledata$mu
| Item.ID | a | b | c | d |
|---|---|---|---|---|
| z | 1 | 0 | 0 | 0 |
| y | 0 | 1 | 0 | 0 |
| x | 1 | 1 | 0 | 0 |
| w | 1 | 1 | 1 | 0 |
| v | 1 | 1 | 0 | 1 |
CbKSTWe start CbKST activities with reading a skill (multi) map from file. This is done through read_skillmultimap(). For practical
reasons, only spreadsheet format files are allowed, currently concretely ODS (Libreoffice/Openoffice) and XLSX (Microsoft Excel)
format. CSV files (comma separated values) may follow at a later time.
The read_skillmultimap() function is deliberately kept simple, it takes a filename as only parameter. This includes certain
assumptions, e.g. the existence of a header row in the file containing the skill names (see next section).
fpath <- system.file("extdata", "skillmap.ods", package="CbKST")
sm <- read_skillmultimap(fpath)
sm
| Item.ID | a | b | c | d |
|---|---|---|---|---|
| z | 1 | 0 | 0 | 0 |
| y | 0 | 1 | 0 | 0 |
| x | 1 | 1 | 0 | 0 |
| w | 1 | 1 | 1 | 0 |
| v | 1 | 1 | 0 | 1 |
class(sm)
#> [1] "cbkst_skillmap" "cbkst_skillmultimap" "data.frame"
fpath <- system.file("extdata", "multimap.ods", package="CbKST")
mm <- read_skillmultimap(fpath)
mm
| Item.ID | a | b | c | d |
|---|---|---|---|---|
| z | 1 | 0 | 0 | 0 |
| y | 0 | 1 | 0 | 0 |
| x | 1 | 1 | 0 | 0 |
| w | 1 | 1 | 1 | 0 |
| w | 1 | 1 | 0 | 1 |
| v | 1 | 1 | 1 | 1 |
class(mm)
#> [1] "cbkst_skillmultimap" "data.frame"
As can be seen in the code and results above, the result of read_skillmultimap() is of class cbkst_skillmultimap. If,
however, we have the special case of a skill map, i.e. every item is assigned exactly one competence, the result belongs
additionally also to class cbkst_skillmap.
There are three functions mapping states between skill/competence and performance level. cbkst_comp2per() determines the
subset of items (performance state) solvable by a person in a given skill state. In the counter direction, cbkst_perf2comp()
determines the minimal skill states (as binary matrix of class kmfamset) allowing for a specified performance state. This function can also regard an additionally
specified skill structure further constraining the result. A simplified variant is cbkst_simple_perf2comp() which required
a skill map (instead of a more general skill multimap) as parameter and does not allow for further constraints through a
competence structure. Here, the result is again (like in cbkst_comp2perf()) a single state (as a vector).
Please note that for
cbkst_perf2comp() and cbkst_simple_perf2comp(), the performance state must be specified as a named vector. The item IDs
of the performance state must fit to the item IDs used in the skill (multi) map.
cbkst_comp2perf(c(1,1,0,0), exampledata$mu)
#> z y x w v
#> 1 1 1 0 0
perf <- c(1,1,1,0,0)
names(perf) <- c("z", "y", "x", "w", "v")
cbkst_perf2comp(perf, exampledata$multi, exampledata$cspace)
| 1 | 1 | 0 | 0 |
cbkst_simple_perf2comp(perf, exampledata$mu)
#> [1] 1 1 0 0
The functions cbkst_performaancestructure() and cbkst_competencestructure() map whole structures. cbkst_performancestructure()
determines the family of all subset of test items which are a performance state for some competence state.
cbkst_competencestructure() on the other hand provides all minimal competence states behind some performance state.
cbkst_performancestructure(exampledata$mu)
| z | y | x | w | v |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 | 0 |
| 1 | 1 | 1 | 0 | 0 |
| 1 | 1 | 1 | 1 | 0 |
| 1 | 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 1 | 1 |
cbkst_performancestructure(exampledata$mu, comp=exampledata$cspace)
| z | y | x | w | v |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 0 | 0 |
| 1 | 1 | 1 | 1 | 0 |
| 1 | 1 | 1 | 1 | 1 |
cbkst_competencestructure(exampledata$multi)
| a | b | c | d |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 |
| 1 | 1 | 1 | 0 |
| 1 | 1 | 0 | 1 |
| 1 | 1 | 0 | 0 |
| 0 | 1 | 0 | 0 |
| 1 | 0 | 0 | 0 |
cbkst_competencestructure(exampledata$multi, perf=exampledata$pspace)
| a | b | c | d |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 1 | 0 | 0 | 0 |
| 1 | 1 | 0 | 0 |
| 1 | 1 | 1 | 0 |
| 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 1 |
The CbKST package provides some example data — mainly for testing and illustration. They can be accessed as elements of the
list exampledata.
mu is a skill map on five test items and four skills.multi is a very similar skill multi map.
- cpsace and pspace are simple competence and performance spaces. Actually both follow a linear structure between the items
or skills, repetively.exampledata
#> $mu
#> Item.ID a b c d
#> 1 z 1 0 0 0
#> 2 y 0 1 0 0
#> 3 x 1 1 0 0
#> 4 w 1 1 1 0
#> 5 v 1 1 0 1
#>
#> $multi
#> Item.ID a b c d
#> 1 z 1 0 0 0
#> 2 y 0 1 0 0
#> 3 x 1 1 0 0
#> 4 w 1 1 1 0
#> 5 w 1 1 0 1
#> 6 v 1 1 1 1
#>
#> $cspace
#> a b c d
#> [1,] 0 0 0 0
#> [2,] 1 0 0 0
#> [3,] 1 1 0 0
#> [4,] 1 1 1 0
#> [5,] 1 1 1 1
#> attr(,"class")
#> [1] "kmspace" "kmstructure" "kmfamset" "matrix" "array"
#>
#> $pspace
#> z y x w v
#> [1,] 0 0 0 0 0
#> [2,] 1 0 0 0 0
#> [3,] 1 1 0 0 0
#> [4,] 1 1 1 0 0
#> [5,] 1 1 1 1 0
#> [6,] 1 1 1 1 1
#> attr(,"class")
#> [1] "kmspace" "kmstructure" "kmfamset" "matrix" "array"
#>
These data are in parallel also given as files in the package’s extdata directory. The file path can be built as shown below.
fpath <- system.file("extdata", "skillmap.ods", package="CbKST")
The following four files are provided:
linearCompSpace.ods is a linear skill/competence space — the same as exampledata$cspace.linearPerfSpace.ods is teh pendant on the performance level — exampledata.pspace.multimap.ods and skillmap.ods contain the skill multimap and skill map also available as exampledata$multi
and exampledata$mu.