Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
Test Information Function (TIF) = Σ_i I_i(θ)
Standard Error of Measurement = 1 / √TIF(θ)
Differential Item Functioning (DIF)
An item shows DIF if examinees from different groups (e.g., gender, ethnicity)
with the same ability have different probabilities of answering correctly.
Uniform DIF: systematic advantage for one group across all θ levels
Non-uniform DIF: group advantage reverses across θ levels
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.optimize import minimize
from scipy.stats import chi2
deficc_3pl(theta: np.ndarray, a: float, b: float, c: float) -> np.ndarray:
"""
Three-parameter logistic (3PL) item characteristic curve.
Args:
theta: Array of ability values.
a: Discrimination parameter (a > 0, typically 0.5–2.5).
b: Difficulty parameter (typically -3 to +3).
c: Guessing parameter (typically 0.0–0.35).
Returns:
Array of P(correct | theta) values in [c, 1].
"""return c + (1 - c) / (1 + np.exp(-a * (theta - b)))
deficc_2pl(theta: np.ndarray, a: float, b: float) -> np.ndarray:
"""Two-parameter logistic (2PL) ICC — special case of 3PL with c=0."""return icc_3pl(theta, a, b, c=0.0)
deficc_1pl(theta: np.ndarray, b: float) -> np.ndarray:
"""One-parameter logistic / Rasch ICC — special case with a=1, c=0."""return icc_3pl(theta, a=1.0, b=b, c=0.0)
defiif_3pl(theta: np.ndarray, a: float, b: float, c: float) -> np.ndarray:
"""
Item information function for the 3PL model.
Args:
theta: Ability values.
a: Discrimination.
b: Difficulty.
c: Guessing.
Returns:
Array of item information values I(θ).
"""
p = icc_3pl(theta, a, b, c)
q = 1 - p
info = (a ** 2) * ((p - c) ** 2) * q / ((1 - c) ** 2 * p)
return info
deftif(theta: np.ndarray, params: list[tuple]) -> np.ndarray:
"""
Test information function — sum of item information functions.
Args:
theta: Ability values.
params: List of (a, b, c) tuples for each item.
Returns:
Array of test information TIF(θ).
"""
total = np.zeros_like(theta)
for a, b, c in params:
total += iif_3pl(theta, a, b, c)
return total
defsem_from_tif(theta: np.ndarray, params: list[tuple]) -> np.ndarray:
"""Standard error of measurement from test information: SEM(θ) = 1/√TIF(θ)."""
test_info = tif(theta, params)
return1.0 / np.sqrt(np.maximum(test_info, 1e-6))
Step 2 — 2PL Parameter Estimation (Marginal MLE)
defestimate_2pl_jml(
response_matrix: np.ndarray,
n_iter: int = 100,
lr_theta: float = 0.1,
lr_params: float = 0.05,
) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
"""
Joint Maximum Likelihood Estimation for 2PL IRT model.
Alternates between updating ability (θ) estimates and item parameters (a, b)
using gradient ascent on the log-likelihood. For production use, prefer
marginal MLE via the R `mirt` package.
Args:
response_matrix: Binary matrix of shape (n_persons, n_items).
1 = correct, 0 = incorrect.
n_iter: Number of EM/JML iterations.
lr_theta: Learning rate for ability updates.
lr_params: Learning rate for item parameter updates.
Returns:
Tuple (theta_hat, a_hat, b_hat) — estimated abilities and item parameters.
"""
n_persons, n_items = response_matrix.shape
theta = np.zeros(n_persons)
a = np.ones(n_items)
b = np.zeros(n_items)
for iteration inrange(n_iter):
# E-step equivalent: update theta for fixed item paramsfor s inrange(n_persons):
p = icc_2pl(np.array([theta[s]] * n_items), a, b)
p = np.clip(p, 1e-6, 1 - 1e-6)
y = response_matrix[s]
grad_theta = np.sum(a * (y - p))
theta[s] += lr_theta * grad_theta
# M-step equivalent: update item params for fixed thetafor i inrange(n_items):
p = icc_2pl(theta, a[i], b[i])
p = np.clip(p, 1e-6, 1 - 1e-6)
y = response_matrix[:, i]
residuals = y - p
grad_a = np.sum(residuals * (theta - b[i]))
grad_b = np.sum(residuals * (-a[i]))
a[i] += lr_params * grad_a
b[i] += lr_params * grad_b
a[i] = max(a[i], 0.05) # Discrimination must be positiveif (iteration + 1) % 20 == 0:
p_mat = np.array([icc_2pl(theta, a[i], b[i]) for i inrange(n_items)]).T
p_mat = np.clip(p_mat, 1e-6, 1 - 1e-6)
ll = np.sum(response_matrix * np.log(p_mat) + (1 - response_matrix) * np.log(1 - p_mat))
print(f" Iteration {iteration + 1:3d}: log-likelihood = {ll:.2f}")
return theta, a, b