Skip to main content

Knowledge Space Theory in Python

Project description

knowledgespaces

Knowledge Space Theory in Python (Doignon & Falmagne) — from item analysis to adaptive assessment.

import knowledgespaces as ks

# Build a knowledge structure from prerequisites
structure = ks.space_from_prerequisites(
    ["add", "sub", "mul"],
    [("add", "sub"), ("sub", "mul")],
)

print(structure.n_states)          # 4 (out of 8 possible)
print(structure.is_learning_space) # True

# Assess a student
result = ks.assess(structure, {"add": True, "sub": True, "mul": False})
print(result["state"])        # {'add', 'sub'}
print(result["outer_fringe"]) # {'mul'} — what to learn next

Install

uv add knowledgespaces
# or
pip install knowledgespaces

Requires Python 3.10+. Dependencies: numpy, scipy, click, rich.

Quickstart

All examples below use the same domain — basic arithmetic:

import knowledgespaces as ks

# add → sub → mul (linear prerequisite chain)
structure = ks.space_from_prerequisites(
    items=["add", "sub", "mul"],
    prerequisites=[("add", "sub"), ("sub", "mul")],
)
print(f"{structure.n_states} valid states out of {2**structure.n_items} possible")
# 4 valid states out of 8 possible

1. Assess a student

# One observation per item
result = ks.assess(structure, {"add": True, "sub": True, "mul": False})
print(result["state"])        # {'add', 'sub'}
print(result["probability"])  # confidence
print(result["outer_fringe"]) # {'mul'} — what to learn next

# Multiple observations per item (from different instances)
result = ks.assess(structure, [("add", True), ("add", True), ("sub", True), ("mul", False)])

2. Adaptive assessment

In KST, each item (competency) can be tested through multiple instances (concrete questions). The engine selects the most informative instance, maps it to its parent item for the BLIM update, and never repeats the same question.

# Recommended: provide multiple instances per item
result = ks.adaptive_assess(
    structure,
    ask_fn=lambda instance_id: ask_student(instance_id),  # your UI/API
    instances={
        "add": ["3+2", "7+5", "12+9"],
        "sub": ["8-3", "15-7", "20-6"],
        "mul": ["4*3", "6*7", "9*8"],
    },
    max_questions=10,
)
print(result["state"])
print(f"Converged in {result['questions_asked']} questions")

# Quick testing without instances (one question per item)
result = ks.adaptive_assess(structure, lambda item: item in {"add", "sub"})

3. Estimate BLIM parameters from data

result = ks.fit_blim(
    structure,
    items=["add", "sub", "mul"],
    responses=[[1, 1, 1], [1, 1, 0], [1, 0, 0], [0, 0, 0]],
    counts=[45, 30, 20, 5],
)
print(result["converged"])  # True
print(result["beta"])       # {'add': 0.04, 'sub': 0.08, 'mul': 0.12}
print(result["eta"])        # {'add': 0.11, 'sub': 0.09, 'mul': 0.06}

# Goodness-of-fit statistics
print(result["gof"]["G2"])      # likelihood ratio statistic
print(result["gof"]["p_value"]) # chi-squared p-value
print(result["gof"]["AIC"])     # Akaike Information Criterion
print(result["gof"]["BIC"])     # Bayesian Information Criterion

# Use estimated parameters to assess a new student
assessment = ks.assess_from_fit(structure, result, {"add": True, "sub": True, "mul": False})
print(assessment["state"])  # {'add', 'sub'}

# Or run adaptive assessment with estimated parameters
assessment = ks.adaptive_assess_from_fit(structure, result, ask_fn=my_question_function)

For better parameter estimates, use multi-restart EM to avoid local optima:

from knowledgespaces.estimation import estimate_blim_restarts, ResponseMatrix

data = ResponseMatrix(items=["add", "sub", "mul"], patterns=responses, counts=counts)
best = estimate_blim_restarts(structure, data, n_restarts=10, seed=42)
print(best.log_likelihood)  # best LL across 10 random initializations

4. Visualize structures

Plotting requires the optional viz extra: pip install "knowledgespaces[viz]".

from knowledgespaces.viz import plot_hasse, plot_relation

# Hasse diagram of knowledge states
fig = plot_hasse(structure, title="Arithmetic Knowledge Space")
fig.savefig("hasse.png")

# Prerequisite relation diagram
rel = structure.surmise_relation()
fig = plot_relation(rel, title="Prerequisites")

5. Build from skill maps (CB-KST)

structure = ks.structure_from_skill_map(
    skill_map={"q1": ["s_add"], "q2": ["s_add", "s_carry"], "q3": ["s_mul"]},
    skill_prerequisites=[("s_add", "s_carry")],
)

6. Import/export CSV (compatible with R)

from knowledgespaces.io import read_skill_map, read_relation, read_structure, write_structure

structure = read_structure("learning_space.csv")
write_structure(structure, "output.csv")

7. Command-line interface

The knowledgespaces CLI provides interactive tools for non-programmers (e.g. teachers, domain experts):

# Inspect a structure file
ks inspect structure.json
ks inspect data.csv --kind structure --states --paths

# Derive a structure by querying an expert interactively
ks query add sub mul div -o structure.json

# Run an adaptive assessment
ks assess structure.json
ks assess structure.json --instances pool.json --threshold 0.9

All commands support --json for machine-readable output and --no-color for non-interactive environments.

8. Compare structures

from knowledgespaces.metrics import symmetric_difference, hausdorff, cohens_kappa

print(symmetric_difference(ks_human, ks_ai))  # states in one but not other
print(hausdorff(ks_human, ks_ai))             # max min-distance
print(cohens_kappa(rel_human, rel_ai))        # agreement on prerequisites

9. Use via LLM (MCP server)

The project provides an MCP server that lets you use KST directly from Claude, ChatGPT, or any MCP-compatible AI assistant — no Python code needed. It lives in the project's GitHub repository and is not bundled in the pip install knowledgespaces package.

You:   "Build a knowledge structure for arithmetic with items add, sub, mul
        where add is prerequisite for sub, and sub for mul."

Claude: [calls build_structure tool] → returns structure with 4 states, learning space ✓

You:   "Assess a student who got add and sub correct but mul wrong."

Claude: [calls assess_student tool] → state {add, sub}, outer fringe {mul}

You:   "Show me the Hasse diagram."

Claude: [calls plot_hasse tool] → displays diagram with student state highlighted

The server exposes tools, the full library documentation as MCP resources, and prompt templates for guided workflows. See the MCP server README for setup instructions.


Advanced usage

The high-level API (space_from_prerequisites, assess, etc.) covers most use cases. For full control, use the building blocks directly:

from knowledgespaces import KnowledgeStructure, SurmiseRelation, BLIM, BLIMParams, StatePosterior

# Build objects manually
rel = SurmiseRelation(["a", "b", "c"], [("a", "b"), ("b", "c")])
closure = rel.transitive_closure()
hasse = closure.transitive_reduction()
ks = KnowledgeStructure.from_surmise_relation(closure)

# Inspect structural properties
print(ks.is_knowledge_space)   # True
print(ks.is_closure_space)     # True
print(ks.base())               # minimal generating family
print(ks.learning_paths())     # all paths from ∅ to full domain
print(ks.atoms())              # {item: [minimal states containing item]}

# Query experts
from knowledgespaces import run_query
from knowledgespaces.query import CallbackExpert
result = run_query(["a", "b", "c"], CallbackExpert(my_expert_fn))

# Full BLIM control
blim = BLIM(structure, BLIMParams(beta=0.1, eta=0.2))
posterior = StatePosterior.uniform(blim)
posterior = posterior.update("a", True)

Modules

Module What it does
knowledgespaces High-level API: space_from_prerequisites, assess, fit_blim, ...
knowledgespaces.structures SurmiseRelation, KnowledgeStructure — core algebraic objects
knowledgespaces.query QUERY algorithm (Block 1 + Block N) — derive structures from expert queries
knowledgespaces.derivation CB-KST — derive structures from skill maps
knowledgespaces.assessment BLIM + Bayesian adaptive assessment with EIG item selection
knowledgespaces.estimation EM algorithm for BLIM parameter estimation
knowledgespaces.io CSV and JSON import/export
knowledgespaces.metrics Hausdorff, symmetric difference, Cohen's kappa, directional distances
knowledgespaces.cli CLI: ks inspect, ks query, ks assess
mcp/ MCP server (in the GitHub repo, not the PyPI package): use KST via LLM

Scalability note

This library uses exact enumeration of knowledge states. It works well for domains up to ~20 items. For larger domains, consider approximate or incremental methods (not yet implemented).

References

  • Doignon, J.-P., & Falmagne, J.-C. (1999). Knowledge Spaces. Springer-Verlag.
  • Falmagne, J.-C., & Doignon, J.-P. (2011). Learning Spaces. Springer-Verlag.
  • Koppen, M., & Doignon, J.-P. (1990). How to build a knowledge space by querying an expert. Journal of Mathematical Psychology, 34(3), 311–331.
  • Heller, J., & Wickelmaier, F. (2013). Minimum discrepancy estimation in probabilistic knowledge structures. Electronic Notes in Discrete Mathematics, 42, 49–56.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

knowledgespaces-0.1.0.tar.gz (249.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

knowledgespaces-0.1.0-py3-none-any.whl (85.7 kB view details)

Uploaded Python 3

File details

Details for the file knowledgespaces-0.1.0.tar.gz.

File metadata

  • Download URL: knowledgespaces-0.1.0.tar.gz
  • Upload date:
  • Size: 249.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for knowledgespaces-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f6cfa1d85193486c3893c83936b01bdfe3e59431cdfde5448f98ea9c094baea8
MD5 b8aa19d0eb315bfbb7c54b2608205495
BLAKE2b-256 fbc3c399cf41f10a6d5f085ecc2d11b0e463231efd7d120f04cd94e942e62641

See more details on using hashes here.

Provenance

The following attestation bundles were made for knowledgespaces-0.1.0.tar.gz:

Publisher: release.yml on UBarbieri/knowledgespaces

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file knowledgespaces-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for knowledgespaces-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f489fcf0c9f9b95605933c324fb02f5ec0a6904ed349c2f0ac121705e8783ca9
MD5 41651bc9caaf6670c52df8875ca28b37
BLAKE2b-256 c4d97e2e964970165a266e824afb9f0f7b7dc589c3a06a6ec078cf44a135ff99

See more details on using hashes here.

Provenance

The following attestation bundles were made for knowledgespaces-0.1.0-py3-none-any.whl:

Publisher: release.yml on UBarbieri/knowledgespaces

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page