confusion-mapper 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- confusion_mapper-1.0.0/CHANGELOG.md +39 -0
- confusion_mapper-1.0.0/CITATION.cff +87 -0
- confusion_mapper-1.0.0/CODE_OF_CONDUCT.md +52 -0
- confusion_mapper-1.0.0/CONTRIBUTING.md +51 -0
- confusion_mapper-1.0.0/LICENSE +6 -0
- confusion_mapper-1.0.0/MANIFEST.in +19 -0
- confusion_mapper-1.0.0/PKG-INFO +231 -0
- confusion_mapper-1.0.0/README.md +185 -0
- confusion_mapper-1.0.0/confusion_mapper.egg-info/PKG-INFO +231 -0
- confusion_mapper-1.0.0/confusion_mapper.egg-info/SOURCES.txt +26 -0
- confusion_mapper-1.0.0/confusion_mapper.egg-info/dependency_links.txt +1 -0
- confusion_mapper-1.0.0/confusion_mapper.egg-info/entry_points.txt +2 -0
- confusion_mapper-1.0.0/confusion_mapper.egg-info/requires.txt +6 -0
- confusion_mapper-1.0.0/confusion_mapper.egg-info/top_level.txt +1 -0
- confusion_mapper-1.0.0/confusion_mapper.py +1474 -0
- confusion_mapper-1.0.0/docs/methodology.md +19 -0
- confusion_mapper-1.0.0/docs/research-context.md +7 -0
- confusion_mapper-1.0.0/docs/taxonomy.md +38 -0
- confusion_mapper-1.0.0/examples/demo.py +106 -0
- confusion_mapper-1.0.0/paper.bib +104 -0
- confusion_mapper-1.0.0/paper.md +135 -0
- confusion_mapper-1.0.0/pyproject.toml +77 -0
- confusion_mapper-1.0.0/sample_data/custom_taxonomy.json +29 -0
- confusion_mapper-1.0.0/sample_data/example_labels.csv +31 -0
- confusion_mapper-1.0.0/sample_data/example_session.json +10 -0
- confusion_mapper-1.0.0/setup.cfg +4 -0
- confusion_mapper-1.0.0/tests/__init__.py +1 -0
- confusion_mapper-1.0.0/tests/test_kappa.py +800 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to ConfusionMapper are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [1.0.0] - 2026-06-23
|
|
8
|
+
|
|
9
|
+
First public release.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `compute_cohens_kappa(human, ai)` for nominal Cohen's kappa with Landis-Koch interpretation.
|
|
14
|
+
- `compute_cohens_kappa(..., weights="linear")` and `weights="quadratic"` for weighted kappa over ordinal taxonomies (Cicchetti-Allison and Fleiss-Cohen schemes).
|
|
15
|
+
- `build_confusion_matrix(human, ai)` returning the full N x N category cross-tabulation as a nested dict.
|
|
16
|
+
- `get_per_type_stats(human, ai)` returning per-category agreement counts and percentages.
|
|
17
|
+
- `bootstrap_kappa_ci(human, ai, method="bca", seed=...)` for percentile and bias-corrected and accelerated (BCa) bootstrap confidence intervals on kappa, with a seed parameter for bit-identical reproducibility.
|
|
18
|
+
- `load_taxonomy_from_json(path)` for swapping the default Confusion Fingerprint Index categories for any two-or-more category nominal scheme.
|
|
19
|
+
- Built-in NCERT-aligned MCQ bank covering five Class 7 science questions with fifteen pre-labelled distractors.
|
|
20
|
+
- OpenAI-backed AI rater (`classify_with_ai`) with `model="gpt-4o"`, `temperature=0.0`, and a deterministic structured prompt.
|
|
21
|
+
- Optional AI question generator (`generate_ai_questions`).
|
|
22
|
+
- Tkinter results dashboard (`show_results_window`) with a kappa gauge, 4 x 4 confusion matrix, and per-type bar chart. Falls back to console output when no display is available.
|
|
23
|
+
- JSON session export for full reproducibility records.
|
|
24
|
+
- Headless tutorial at `examples/demo.py` reproducing a complete kappa analysis on the bundled 30-item paired-label set.
|
|
25
|
+
- Case study at `case_study/` with a fully reproducible IRR analysis (kappa, weighted kappa, bootstrap CI, confusion matrix, per-type stats) on the NCERT-aligned distractor set.
|
|
26
|
+
- 55-test pytest suite covering the kappa formula, weighted kappa, bootstrap CI determinism, custom taxonomy loading, and confusion matrix invariants.
|
|
27
|
+
- GitHub Actions CI building the pytest matrix on Python 3.9 through 3.12 and producing a JOSS-formatted paper PDF as a downloadable artifact on every push.
|
|
28
|
+
|
|
29
|
+
### Documentation
|
|
30
|
+
|
|
31
|
+
- README with install, usage, advanced features, and citation sections.
|
|
32
|
+
- JOSS-ready `paper.md` and `paper.bib` (994 body words, ten resolved citations).
|
|
33
|
+
- `CITATION.cff` validated and including the Zenodo software DOI.
|
|
34
|
+
- `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md` (Contributor Covenant 2.1), bug-report and feature-request issue templates, pull-request template.
|
|
35
|
+
- `docs/` containing taxonomy, methodology, and research-context notes.
|
|
36
|
+
|
|
37
|
+
### Archive
|
|
38
|
+
|
|
39
|
+
- Version 1.0.0 archived on Zenodo: <https://doi.org/10.5281/zenodo.20807432>.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: >-
|
|
3
|
+
If you use ConfusionMapper in your research, please cite it using
|
|
4
|
+
the metadata below.
|
|
5
|
+
type: software
|
|
6
|
+
title: "ConfusionMapper"
|
|
7
|
+
abstract: >-
|
|
8
|
+
ConfusionMapper is a Python tool for human-AI hybrid inter-rater
|
|
9
|
+
reliability (IRR) assessment of cognitive error taxonomy classification
|
|
10
|
+
in multiple-choice question distractors. It implements the Confusion
|
|
11
|
+
Fingerprint Index (CFI) taxonomy, computes Cohen's kappa, builds a
|
|
12
|
+
full 4x4 confusion matrix across all category pairs, and enforces a
|
|
13
|
+
pre-registration-compliant reliability gate (kappa >= 0.70) before
|
|
14
|
+
downstream data collection may proceed.
|
|
15
|
+
authors:
|
|
16
|
+
- family-names: "Maurya"
|
|
17
|
+
given-names: "Manik"
|
|
18
|
+
orcid: "https://orcid.org/0009-0005-3554-693X"
|
|
19
|
+
email: "manikmaurya.in@gmail.com"
|
|
20
|
+
affiliation: >-
|
|
21
|
+
Department of Cognitive Science, Indian Institute of Technology
|
|
22
|
+
Kanpur, India
|
|
23
|
+
version: "1.0.0"
|
|
24
|
+
date-released: "2026-06-22"
|
|
25
|
+
license: MIT
|
|
26
|
+
repository-code: "https://github.com/Manik-Maurya/Confusion-Mapper"
|
|
27
|
+
url: "https://github.com/Manik-Maurya/Confusion-Mapper"
|
|
28
|
+
doi: "10.5281/zenodo.20807432"
|
|
29
|
+
keywords:
|
|
30
|
+
- inter-rater reliability
|
|
31
|
+
- Cohen's kappa
|
|
32
|
+
- cognitive science
|
|
33
|
+
- educational assessment
|
|
34
|
+
- multiple-choice questions
|
|
35
|
+
- distractor classification
|
|
36
|
+
- Confusion Fingerprint Index
|
|
37
|
+
- human-AI collaboration
|
|
38
|
+
- Python
|
|
39
|
+
- pre-registration
|
|
40
|
+
preferred-citation:
|
|
41
|
+
type: article
|
|
42
|
+
title: >-
|
|
43
|
+
ConfusionMapper: A Human-AI Hybrid Inter-Rater Reliability Tool for
|
|
44
|
+
Cognitive Error Taxonomy Classification
|
|
45
|
+
authors:
|
|
46
|
+
- family-names: "Maurya"
|
|
47
|
+
given-names: "Manik"
|
|
48
|
+
orcid: "https://orcid.org/0009-0005-3554-693X"
|
|
49
|
+
year: 2026
|
|
50
|
+
journal: "Journal of Open Source Software"
|
|
51
|
+
# volume and pages to be updated post-publication
|
|
52
|
+
references:
|
|
53
|
+
- type: article
|
|
54
|
+
title: "A coefficient of agreement for nominal scales"
|
|
55
|
+
authors:
|
|
56
|
+
- family-names: "Cohen"
|
|
57
|
+
given-names: "Jacob"
|
|
58
|
+
year: 1960
|
|
59
|
+
journal: "Educational and Psychological Measurement"
|
|
60
|
+
volume: 20
|
|
61
|
+
issue: 1
|
|
62
|
+
start: 37
|
|
63
|
+
end: 46
|
|
64
|
+
doi: "10.1177/001316446002000104"
|
|
65
|
+
- type: article
|
|
66
|
+
title: "The measurement of observer agreement for categorical data"
|
|
67
|
+
authors:
|
|
68
|
+
- family-names: "Landis"
|
|
69
|
+
given-names: "J. Richard"
|
|
70
|
+
- family-names: "Koch"
|
|
71
|
+
given-names: "Gary G."
|
|
72
|
+
year: 1977
|
|
73
|
+
journal: "Biometrics"
|
|
74
|
+
volume: 33
|
|
75
|
+
issue: 1
|
|
76
|
+
start: 159
|
|
77
|
+
end: 174
|
|
78
|
+
doi: "10.2307/2529310"
|
|
79
|
+
- type: misc
|
|
80
|
+
title: >-
|
|
81
|
+
Confusion Fingerprint Index: A Taxonomy of Cognitive Error Types
|
|
82
|
+
in Multiple-Choice Assessment
|
|
83
|
+
authors:
|
|
84
|
+
- family-names: "Maurya"
|
|
85
|
+
given-names: "Manik"
|
|
86
|
+
year: 2026
|
|
87
|
+
doi: "10.35542/osf.io/cr53e_v1"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
|
|
6
|
+
|
|
7
|
+
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
|
|
8
|
+
|
|
9
|
+
## Our Standards
|
|
10
|
+
|
|
11
|
+
Examples of behavior that contributes to a positive environment for our community include:
|
|
12
|
+
|
|
13
|
+
- Demonstrating empathy and kindness toward other people
|
|
14
|
+
- Being respectful of differing opinions, viewpoints, and experiences
|
|
15
|
+
- Giving and gracefully accepting constructive feedback
|
|
16
|
+
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
|
|
17
|
+
- Focusing on what is best not just for us as individuals, but for the overall community
|
|
18
|
+
|
|
19
|
+
Examples of unacceptable behavior include:
|
|
20
|
+
|
|
21
|
+
- The use of sexualized language or imagery, and sexual attention or advances of any kind
|
|
22
|
+
- Trolling, insulting or derogatory comments, and personal or political attacks
|
|
23
|
+
- Public or private harassment
|
|
24
|
+
- Publishing others' private information, such as a physical or email address, without their explicit permission
|
|
25
|
+
- Other conduct which could reasonably be considered inappropriate in a professional setting
|
|
26
|
+
|
|
27
|
+
## Enforcement Responsibilities
|
|
28
|
+
|
|
29
|
+
The project maintainer is responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
|
|
30
|
+
|
|
31
|
+
## Scope
|
|
32
|
+
|
|
33
|
+
This Code of Conduct applies within all community spaces, issues, pull requests, discussions, and any other project-related communication, and also applies when an individual is officially representing the community in public spaces.
|
|
34
|
+
|
|
35
|
+
## Enforcement
|
|
36
|
+
|
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the project maintainer at **manikmaurya.in@gmail.com**. All complaints will be reviewed and investigated promptly and fairly.
|
|
38
|
+
|
|
39
|
+
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
|
|
40
|
+
|
|
41
|
+
## Enforcement Guidelines
|
|
42
|
+
|
|
43
|
+
Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
|
|
44
|
+
|
|
45
|
+
1. **Correction**, A private, written warning, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate.
|
|
46
|
+
2. **Warning**, A warning with consequences for continued behavior. No interaction with the people involved for a specified period of time.
|
|
47
|
+
3. **Temporary Ban**, A temporary ban from any sort of interaction or public communication with the community for a specified period of time.
|
|
48
|
+
4. **Permanent Ban**, A permanent ban from any sort of public interaction within the community.
|
|
49
|
+
|
|
50
|
+
## Attribution
|
|
51
|
+
|
|
52
|
+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Contributing to ConfusionMapper
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing. ConfusionMapper is a research-grade tool used as a methodological reliability gate for pre-registered educational RCTs, so changes must preserve numerical correctness and reproducibility.
|
|
4
|
+
|
|
5
|
+
## Ways to Contribute
|
|
6
|
+
|
|
7
|
+
- **Report a bug**, open an issue using the Bug Report template. Include a minimal reproducible example, the expected output, and the actual output.
|
|
8
|
+
- **Request a feature**, open an issue using the Feature Request template. Explain the research use case the feature would unlock.
|
|
9
|
+
- **Submit a pull request**, see the workflow below.
|
|
10
|
+
- **Improve documentation**, typo fixes, clearer examples, and translation of the docstrings are all welcome.
|
|
11
|
+
|
|
12
|
+
## Development Setup
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
git clone https://github.com/Manik-Maurya/Confusion-Mapper.git
|
|
16
|
+
cd Confusion-Mapper
|
|
17
|
+
pip install -e ".[dev]"
|
|
18
|
+
pytest tests/ -v
|
|
19
|
+
python examples/demo.py
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The full test suite (33 tests) runs in under a second and requires no API key or display.
|
|
23
|
+
|
|
24
|
+
## Pull Request Workflow
|
|
25
|
+
|
|
26
|
+
1. Fork the repository and create a feature branch from `main` (e.g. `fix/kappa-edge-case` or `feat/weighted-kappa`).
|
|
27
|
+
2. Make your changes in small, focused commits with clear messages.
|
|
28
|
+
3. Add or update tests covering the change. New numerical code requires at least one hand-verified worked example in the test docstring.
|
|
29
|
+
4. Run the full suite locally: `pytest tests/ -v`, every test must pass.
|
|
30
|
+
5. Run the headless demo: `python examples/demo.py`, must exit 0.
|
|
31
|
+
6. Update `README.md`, `paper.md`, or `CITATION.cff` if the change affects user-facing behaviour or scholarly attribution.
|
|
32
|
+
7. Open a pull request describing what changed and why. Link the issue it resolves.
|
|
33
|
+
|
|
34
|
+
## Coding Standards
|
|
35
|
+
|
|
36
|
+
- **Python 3.9+**, no third-party dependencies in the core module beyond `openai` and the standard library.
|
|
37
|
+
- **No silent behaviour changes** in `compute_cohens_kappa`, `build_confusion_matrix`, or `get_per_type_stats` without an explicit version bump and migration note.
|
|
38
|
+
- **Docstrings** on every public function: one-line summary, parameters, returns, and at least one worked example for numerical functions.
|
|
39
|
+
- **Deterministic output**, no randomness in user-facing functions; tests use seeded RNG.
|
|
40
|
+
|
|
41
|
+
## Reporting Security Issues
|
|
42
|
+
|
|
43
|
+
Email security concerns privately to manikmaurya.in@gmail.com rather than opening a public issue.
|
|
44
|
+
|
|
45
|
+
## Code of Conduct
|
|
46
|
+
|
|
47
|
+
Participation in this project is governed by the [Code of Conduct](CODE_OF_CONDUCT.md). By contributing, you agree to abide by its terms.
|
|
48
|
+
|
|
49
|
+
## Attribution and Licensing
|
|
50
|
+
|
|
51
|
+
All contributions are licensed under the project's MIT License. Significant code contributions will be acknowledged in release notes; contributions that meet the [JOSS authorship criteria](https://joss.readthedocs.io/en/latest/submitting.html#authorship) (substantive design, code, or scholarly contribution) may be added to the author list of future paper versions.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
include LICENSE
|
|
2
|
+
include README.md
|
|
3
|
+
include CITATION.cff
|
|
4
|
+
include CONTRIBUTING.md
|
|
5
|
+
include CODE_OF_CONDUCT.md
|
|
6
|
+
include CHANGELOG.md
|
|
7
|
+
include paper.md
|
|
8
|
+
include paper.bib
|
|
9
|
+
include pyproject.toml
|
|
10
|
+
|
|
11
|
+
recursive-include sample_data *.csv *.json
|
|
12
|
+
recursive-include examples *.py
|
|
13
|
+
recursive-include tests *.py
|
|
14
|
+
recursive-include docs *.md
|
|
15
|
+
|
|
16
|
+
global-exclude __pycache__
|
|
17
|
+
global-exclude *.py[cod]
|
|
18
|
+
global-exclude .pytest_cache
|
|
19
|
+
global-exclude *.egg-info
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: confusion-mapper
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Human-AI hybrid inter-rater reliability tool for cognitive error taxonomy classification in MCQ distractors.
|
|
5
|
+
Author-email: Manik Maurya <manikmaurya.in@gmail.com>
|
|
6
|
+
Maintainer-email: Manik Maurya <manikmaurya.in@gmail.com>
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2026 Manik Maurya
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files...
|
|
13
|
+
Project-URL: Homepage, https://github.com/Manik-Maurya/Confusion-Mapper
|
|
14
|
+
Project-URL: Repository, https://github.com/Manik-Maurya/Confusion-Mapper
|
|
15
|
+
Project-URL: Source, https://github.com/Manik-Maurya/Confusion-Mapper
|
|
16
|
+
Project-URL: Documentation, https://github.com/Manik-Maurya/Confusion-Mapper#readme
|
|
17
|
+
Project-URL: Issues, https://github.com/Manik-Maurya/Confusion-Mapper/issues
|
|
18
|
+
Project-URL: Changelog, https://github.com/Manik-Maurya/Confusion-Mapper/blob/main/CHANGELOG.md
|
|
19
|
+
Project-URL: Archive, https://doi.org/10.5281/zenodo.20807432
|
|
20
|
+
Keywords: inter-rater-reliability,cohens-kappa,weighted-kappa,bootstrap-confidence-interval,cognitive-science,educational-assessment,multiple-choice-questions,distractor-classification,human-ai-collaboration,preregistration
|
|
21
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
22
|
+
Classifier: Intended Audience :: Science/Research
|
|
23
|
+
Classifier: Intended Audience :: Education
|
|
24
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
25
|
+
Classifier: Natural Language :: English
|
|
26
|
+
Classifier: Operating System :: OS Independent
|
|
27
|
+
Classifier: Programming Language :: Python
|
|
28
|
+
Classifier: Programming Language :: Python :: 3
|
|
29
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
30
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
31
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
32
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
33
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
34
|
+
Classifier: Topic :: Scientific/Engineering
|
|
35
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
36
|
+
Classifier: Topic :: Education :: Testing
|
|
37
|
+
Requires-Python: >=3.9
|
|
38
|
+
Description-Content-Type: text/markdown
|
|
39
|
+
License-File: LICENSE
|
|
40
|
+
Requires-Dist: openai>=1.0.0
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
43
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
44
|
+
Requires-Dist: twine>=4.0; extra == "dev"
|
|
45
|
+
Dynamic: license-file
|
|
46
|
+
|
|
47
|
+
# ConfusionMapper
|
|
48
|
+
|
|
49
|
+
A Python tool for classifying wrong answer choices in multiple-choice questions by the type of cognitive error they represent, and for computing how well a human researcher and an AI rater agree on those labels.
|
|
50
|
+
|
|
51
|
+
[](https://doi.org/10.5281/zenodo.20807432)
|
|
52
|
+
[](https://github.com/Manik-Maurya/Confusion-Mapper/actions/workflows/tests.yml)
|
|
53
|
+
[](https://opensource.org/licenses/MIT)
|
|
54
|
+
[](https://www.python.org/)
|
|
55
|
+
|
|
56
|
+
## What it does
|
|
57
|
+
|
|
58
|
+
In educational research, you cannot use qualitative labels in a statistical analysis unless two independent raters can produce roughly the same labels on the same items. The usual way to check this is Cohen's kappa.
|
|
59
|
+
|
|
60
|
+
ConfusionMapper handles the full workflow. You go through a set of distractors one by one and pick a label for each. If you have an OpenAI API key, an AI rater labels the same distractors in parallel. At the end, the program computes Cohen's kappa, draws a 4x4 confusion matrix of where the two raters agreed and disagreed, and saves everything to JSON.
|
|
61
|
+
|
|
62
|
+
It was built as the reliability check for a preregistered RCT on cognitive error feedback in government junior high schools (OSF: https://doi.org/10.17605/OSF.IO/YU6P5). Data collection in that study could only start once kappa cleared 0.70.
|
|
63
|
+
|
|
64
|
+
## The four error types
|
|
65
|
+
|
|
66
|
+
The taxonomy is called the Confusion Fingerprint Index (CFI). It splits wrong answers into four categories:
|
|
67
|
+
|
|
68
|
+
| Code | Name | What it looks like |
|
|
69
|
+
|------|------|---------------------|
|
|
70
|
+
| RF | Recall Failure | No memory trace at all; the answer is essentially random |
|
|
71
|
+
| PK | Partial Knowledge | Almost right; the direction is correct but the model is incomplete |
|
|
72
|
+
| CF | Confabulation | A coherent misconception held with confidence |
|
|
73
|
+
| INT | Interference | A correct answer pulled from the wrong topic |
|
|
74
|
+
|
|
75
|
+
## Install
|
|
76
|
+
|
|
77
|
+
Once a versioned release is on PyPI:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
pip install confusion-mapper
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
From source (until the first PyPI release, this is the recommended path):
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
git clone https://github.com/Manik-Maurya/Confusion-Mapper.git
|
|
87
|
+
cd Confusion-Mapper
|
|
88
|
+
pip install -e .
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The only runtime dependency is `openai>=1.0.0`. `tkinter` ships with Python on most systems; on a minimal Debian or Ubuntu image install it with `sudo apt-get install python3-tk`. If `tkinter` is missing, ConfusionMapper drops to console output instead of the GUI.
|
|
92
|
+
|
|
93
|
+
Python 3.9 or higher.
|
|
94
|
+
|
|
95
|
+
For the test extras:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
pip install -e ".[dev]"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Run
|
|
102
|
+
|
|
103
|
+
Without an API key (you label everything by hand):
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
python confusion_mapper.py
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
With the AI rater on:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# macOS / Linux
|
|
113
|
+
export OPENAI_API_KEY="your-key-here"
|
|
114
|
+
python confusion_mapper.py
|
|
115
|
+
|
|
116
|
+
# Windows
|
|
117
|
+
set OPENAI_API_KEY=your-key-here
|
|
118
|
+
python confusion_mapper.py
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
For each distractor, type `1` for RF, `2` for PK, `3` for CF, or `4` for INT. When you finish, the dashboard opens and the session writes itself to JSON.
|
|
122
|
+
|
|
123
|
+
## Case study
|
|
124
|
+
|
|
125
|
+
A fully reproducible worked example lives in [`case_study/`](case_study/). It runs the entire
|
|
126
|
+
pipeline (nominal kappa, weighted kappa under linear and quadratic schemes, BCa
|
|
127
|
+
bootstrap 95% CI, confusion matrix, per-category stats) on the bundled 30-item
|
|
128
|
+
paired-label set with a fixed seed, then writes a publication-ready bundle to
|
|
129
|
+
`case_study/results/` (JSON summary, CSV matrix, CSV per-type stats, full bootstrap
|
|
130
|
+
distribution, and a Markdown report). Regenerate with one command:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
python case_study/run_case_study.py
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Headline result on the bundled data: nominal kappa = 0.8653, BCa 95% CI = (0.6856, 1.0000),
|
|
137
|
+
pre-registration gate PASSES at the 0.70 threshold.
|
|
138
|
+
|
|
139
|
+
## Headless example
|
|
140
|
+
|
|
141
|
+
A non-interactive demo runs the three core functions on 30 pre-labelled distractors in under a second. No API key, no display:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
python examples/demo.py
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
It prints kappa, the full confusion matrix, per-category agreement, and a PASS / HOLD verdict against the 0.70 gate. Swap in your own paired labels by replacing `sample_data/example_labels.csv`.
|
|
148
|
+
|
|
149
|
+
## Tests
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
pip install -e ".[dev]"
|
|
153
|
+
pytest tests/ -v
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
55 tests, runs in under a second. Covers the kappa formula (with hand-verified worked examples), weighted kappa (nominal / linear / quadratic), bootstrap confidence intervals (percentile + BCa, seedable), custom-taxonomy loading, the confusion matrix, and the mathematical invariants that tie everything together. Doesn't need an API key or a display.
|
|
157
|
+
|
|
158
|
+
## Advanced features
|
|
159
|
+
|
|
160
|
+
All three are stdlib-only and tested.
|
|
161
|
+
|
|
162
|
+
**Weighted kappa for ordinal taxonomies.** Pass `weights="linear"` or
|
|
163
|
+
`weights="quadratic"` to penalise far-apart disagreements more than adjacent ones:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from confusion_mapper import compute_cohens_kappa
|
|
167
|
+
r = compute_cohens_kappa(human, ai, weights="linear")
|
|
168
|
+
print(r["kappa"], r["weights"])
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Bootstrap 95% confidence interval (BCa or percentile).** Cohen's kappa is a point
|
|
172
|
+
estimate; this gives you uncertainty around it. The `seed` makes the interval
|
|
173
|
+
bit-identically reproducible:
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
from confusion_mapper import bootstrap_kappa_ci
|
|
177
|
+
ci = bootstrap_kappa_ci(human, ai, n_resamples=10000, method="bca", seed=42)
|
|
178
|
+
print(f"kappa = {ci['point_estimate']} (95% CI {ci['ci_lower']} to {ci['ci_upper']})")
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Custom taxonomy via JSON.** Swap the default CFI categories for any 2-or-more
|
|
182
|
+
category nominal scheme. A working example sits at
|
|
183
|
+
`sample_data/custom_taxonomy.json`:
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
from confusion_mapper import load_taxonomy_from_json, compute_cohens_kappa
|
|
187
|
+
codes, tax = load_taxonomy_from_json("sample_data/custom_taxonomy.json")
|
|
188
|
+
r = compute_cohens_kappa(human, ai, categories=codes)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Why a 4x4 confusion matrix instead of just kappa
|
|
192
|
+
|
|
193
|
+
The single kappa number tells you how much you and the AI agree overall. It does not tell you which category boundary is causing the disagreement. CF vs INT is the hardest distinction in the CFI taxonomy (a confident wrong belief looks a lot like a correct answer applied to the wrong topic), and the [CF, INT] cell of the confusion matrix is where most disagreement tends to land. Looking at the full 4x4 matrix lets you see exactly that, and rewrite the AI prompt or your own rubric until the cell stops glowing.
|
|
194
|
+
|
|
195
|
+
## A note on ethics
|
|
196
|
+
|
|
197
|
+
The AI rater is a starting point, not a substitute for a second human. For published research you should still run kappa between two trained human raters on the same calibration set. Treat the AI labels as a way to surface boundaries that need rubric work, not as a replacement for human judgment.
|
|
198
|
+
|
|
199
|
+
## How to cite
|
|
200
|
+
|
|
201
|
+
Archived release on Zenodo: https://doi.org/10.5281/zenodo.20807432
|
|
202
|
+
|
|
203
|
+
APA:
|
|
204
|
+
|
|
205
|
+
> Maurya, M. (2026). *ConfusionMapper: A Python Tool for AI-Assisted Distractor Classification and Inter-Rater Reliability Computation in Cognitive Error Taxonomy Research* (Version 1.0.0) [Software]. Zenodo. https://doi.org/10.5281/zenodo.20807432
|
|
206
|
+
|
|
207
|
+
BibTeX:
|
|
208
|
+
|
|
209
|
+
```bibtex
|
|
210
|
+
@software{maurya2026confusionmapper,
|
|
211
|
+
author = {Maurya, Manik},
|
|
212
|
+
title = {ConfusionMapper: A Python Tool for AI-Assisted Distractor Classification
|
|
213
|
+
and Inter-Rater Reliability Computation in Cognitive Error Taxonomy Research},
|
|
214
|
+
year = {2026},
|
|
215
|
+
version = {1.0.0},
|
|
216
|
+
doi = {10.5281/zenodo.20807432},
|
|
217
|
+
url = {https://doi.org/10.5281/zenodo.20807432}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Contributing
|
|
222
|
+
|
|
223
|
+
Bug reports, feature requests, and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
|
|
224
|
+
|
|
225
|
+
## Acknowledgements
|
|
226
|
+
|
|
227
|
+
Initial development was completed as part of Stanford Code in Place 2026. The tool is used in the Confusion Fingerprint Index research programme at the Department of Cognitive Science, IIT Kanpur.
|
|
228
|
+
|
|
229
|
+
## License
|
|
230
|
+
|
|
231
|
+
MIT License © 2026 Manik Maurya. See [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# ConfusionMapper
|
|
2
|
+
|
|
3
|
+
A Python tool for classifying wrong answer choices in multiple-choice questions by the type of cognitive error they represent, and for computing how well a human researcher and an AI rater agree on those labels.
|
|
4
|
+
|
|
5
|
+
[](https://doi.org/10.5281/zenodo.20807432)
|
|
6
|
+
[](https://github.com/Manik-Maurya/Confusion-Mapper/actions/workflows/tests.yml)
|
|
7
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
|
+
[](https://www.python.org/)
|
|
9
|
+
|
|
10
|
+
## What it does
|
|
11
|
+
|
|
12
|
+
In educational research, you cannot use qualitative labels in a statistical analysis unless two independent raters can produce roughly the same labels on the same items. The usual way to check this is Cohen's kappa.
|
|
13
|
+
|
|
14
|
+
ConfusionMapper handles the full workflow. You go through a set of distractors one by one and pick a label for each. If you have an OpenAI API key, an AI rater labels the same distractors in parallel. At the end, the program computes Cohen's kappa, draws a 4x4 confusion matrix of where the two raters agreed and disagreed, and saves everything to JSON.
|
|
15
|
+
|
|
16
|
+
It was built as the reliability check for a preregistered RCT on cognitive error feedback in government junior high schools (OSF: https://doi.org/10.17605/OSF.IO/YU6P5). Data collection in that study could only start once kappa cleared 0.70.
|
|
17
|
+
|
|
18
|
+
## The four error types
|
|
19
|
+
|
|
20
|
+
The taxonomy is called the Confusion Fingerprint Index (CFI). It splits wrong answers into four categories:
|
|
21
|
+
|
|
22
|
+
| Code | Name | What it looks like |
|
|
23
|
+
|------|------|---------------------|
|
|
24
|
+
| RF | Recall Failure | No memory trace at all; the answer is essentially random |
|
|
25
|
+
| PK | Partial Knowledge | Almost right; the direction is correct but the model is incomplete |
|
|
26
|
+
| CF | Confabulation | A coherent misconception held with confidence |
|
|
27
|
+
| INT | Interference | A correct answer pulled from the wrong topic |
|
|
28
|
+
|
|
29
|
+
## Install
|
|
30
|
+
|
|
31
|
+
Once a versioned release is on PyPI:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pip install confusion-mapper
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
From source (until the first PyPI release, this is the recommended path):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
git clone https://github.com/Manik-Maurya/Confusion-Mapper.git
|
|
41
|
+
cd Confusion-Mapper
|
|
42
|
+
pip install -e .
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The only runtime dependency is `openai>=1.0.0`. `tkinter` ships with Python on most systems; on a minimal Debian or Ubuntu image install it with `sudo apt-get install python3-tk`. If `tkinter` is missing, ConfusionMapper drops to console output instead of the GUI.
|
|
46
|
+
|
|
47
|
+
Python 3.9 or higher.
|
|
48
|
+
|
|
49
|
+
For the test extras:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install -e ".[dev]"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Run
|
|
56
|
+
|
|
57
|
+
Without an API key (you label everything by hand):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
python confusion_mapper.py
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
With the AI rater on:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# macOS / Linux
|
|
67
|
+
export OPENAI_API_KEY="your-key-here"
|
|
68
|
+
python confusion_mapper.py
|
|
69
|
+
|
|
70
|
+
# Windows
|
|
71
|
+
set OPENAI_API_KEY=your-key-here
|
|
72
|
+
python confusion_mapper.py
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
For each distractor, type `1` for RF, `2` for PK, `3` for CF, or `4` for INT. When you finish, the dashboard opens and the session writes itself to JSON.
|
|
76
|
+
|
|
77
|
+
## Case study
|
|
78
|
+
|
|
79
|
+
A fully reproducible worked example lives in [`case_study/`](case_study/). It runs the entire
|
|
80
|
+
pipeline (nominal kappa, weighted kappa under linear and quadratic schemes, BCa
|
|
81
|
+
bootstrap 95% CI, confusion matrix, per-category stats) on the bundled 30-item
|
|
82
|
+
paired-label set with a fixed seed, then writes a publication-ready bundle to
|
|
83
|
+
`case_study/results/` (JSON summary, CSV matrix, CSV per-type stats, full bootstrap
|
|
84
|
+
distribution, and a Markdown report). Regenerate with one command:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
python case_study/run_case_study.py
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Headline result on the bundled data: nominal kappa = 0.8653, BCa 95% CI = (0.6856, 1.0000),
|
|
91
|
+
pre-registration gate PASSES at the 0.70 threshold.
|
|
92
|
+
|
|
93
|
+
## Headless example
|
|
94
|
+
|
|
95
|
+
A non-interactive demo runs the three core functions on 30 pre-labelled distractors in under a second. No API key, no display:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
python examples/demo.py
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
It prints kappa, the full confusion matrix, per-category agreement, and a PASS / HOLD verdict against the 0.70 gate. Swap in your own paired labels by replacing `sample_data/example_labels.csv`.
|
|
102
|
+
|
|
103
|
+
## Tests
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
pip install -e ".[dev]"
|
|
107
|
+
pytest tests/ -v
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
55 tests, runs in under a second. Covers the kappa formula (with hand-verified worked examples), weighted kappa (nominal / linear / quadratic), bootstrap confidence intervals (percentile + BCa, seedable), custom-taxonomy loading, the confusion matrix, and the mathematical invariants that tie everything together. Doesn't need an API key or a display.
|
|
111
|
+
|
|
112
|
+
## Advanced features
|
|
113
|
+
|
|
114
|
+
All three are stdlib-only and tested.
|
|
115
|
+
|
|
116
|
+
**Weighted kappa for ordinal taxonomies.** Pass `weights="linear"` or
|
|
117
|
+
`weights="quadratic"` to penalise far-apart disagreements more than adjacent ones:
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from confusion_mapper import compute_cohens_kappa
|
|
121
|
+
r = compute_cohens_kappa(human, ai, weights="linear")
|
|
122
|
+
print(r["kappa"], r["weights"])
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Bootstrap 95% confidence interval (BCa or percentile).** Cohen's kappa is a point
|
|
126
|
+
estimate; this gives you uncertainty around it. The `seed` makes the interval
|
|
127
|
+
bit-identically reproducible:
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from confusion_mapper import bootstrap_kappa_ci
|
|
131
|
+
ci = bootstrap_kappa_ci(human, ai, n_resamples=10000, method="bca", seed=42)
|
|
132
|
+
print(f"kappa = {ci['point_estimate']} (95% CI {ci['ci_lower']} to {ci['ci_upper']})")
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**Custom taxonomy via JSON.** Swap the default CFI categories for any 2-or-more
|
|
136
|
+
category nominal scheme. A working example sits at
|
|
137
|
+
`sample_data/custom_taxonomy.json`:
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
from confusion_mapper import load_taxonomy_from_json, compute_cohens_kappa
|
|
141
|
+
codes, tax = load_taxonomy_from_json("sample_data/custom_taxonomy.json")
|
|
142
|
+
r = compute_cohens_kappa(human, ai, categories=codes)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Why a 4x4 confusion matrix instead of just kappa
|
|
146
|
+
|
|
147
|
+
The single kappa number tells you how much you and the AI agree overall. It does not tell you which category boundary is causing the disagreement. CF vs INT is the hardest distinction in the CFI taxonomy (a confident wrong belief looks a lot like a correct answer applied to the wrong topic), and the [CF, INT] cell of the confusion matrix is where most disagreement tends to land. Looking at the full 4x4 matrix lets you see exactly that, and rewrite the AI prompt or your own rubric until the cell stops glowing.
|
|
148
|
+
|
|
149
|
+
## A note on ethics
|
|
150
|
+
|
|
151
|
+
The AI rater is a starting point, not a substitute for a second human. For published research you should still run kappa between two trained human raters on the same calibration set. Treat the AI labels as a way to surface boundaries that need rubric work, not as a replacement for human judgment.
|
|
152
|
+
|
|
153
|
+
## How to cite
|
|
154
|
+
|
|
155
|
+
Archived release on Zenodo: https://doi.org/10.5281/zenodo.20807432
|
|
156
|
+
|
|
157
|
+
APA:
|
|
158
|
+
|
|
159
|
+
> Maurya, M. (2026). *ConfusionMapper: A Python Tool for AI-Assisted Distractor Classification and Inter-Rater Reliability Computation in Cognitive Error Taxonomy Research* (Version 1.0.0) [Software]. Zenodo. https://doi.org/10.5281/zenodo.20807432
|
|
160
|
+
|
|
161
|
+
BibTeX:
|
|
162
|
+
|
|
163
|
+
```bibtex
|
|
164
|
+
@software{maurya2026confusionmapper,
|
|
165
|
+
author = {Maurya, Manik},
|
|
166
|
+
title = {ConfusionMapper: A Python Tool for AI-Assisted Distractor Classification
|
|
167
|
+
and Inter-Rater Reliability Computation in Cognitive Error Taxonomy Research},
|
|
168
|
+
year = {2026},
|
|
169
|
+
version = {1.0.0},
|
|
170
|
+
doi = {10.5281/zenodo.20807432},
|
|
171
|
+
url = {https://doi.org/10.5281/zenodo.20807432}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Contributing
|
|
176
|
+
|
|
177
|
+
Bug reports, feature requests, and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md).
|
|
178
|
+
|
|
179
|
+
## Acknowledgements
|
|
180
|
+
|
|
181
|
+
Initial development was completed as part of Stanford Code in Place 2026. The tool is used in the Confusion Fingerprint Index research programme at the Department of Cognitive Science, IIT Kanpur.
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
MIT License © 2026 Manik Maurya. See [LICENSE](LICENSE) for details.
|