You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于Computer Adaptive Testing Simulation (Catsim)库实现自适应测试的技术咨询

自适应测试模型开发答疑(基于Catsim库)

嘿,结合你提到的自适应测试需求和Catsim库的使用场景,我来逐个拆解你的疑问:

1. 题库参数矩阵[a,b,c,d]的参数配置

你说的这个四元组对应项目反应理论(IRT)的四参数模型,Catsim正是基于IRT实现自适应测试的,每个参数的具体含义和配置建议如下:

  • a:区分度参数:数值越大,题目越能精准区分不同能力水平的考生。比如a值高的题目,能力强的考生答对概率远高于能力弱的考生,适合用来快速定位考生的能力区间,建议设置在[0.5, 2.0]之间。
  • b:难度参数:你已经明确了,数值代表题目的难度,通常范围在[-3, 3],数值越大难度越高。
  • c:猜测参数:代表能力极低的考生蒙对该题的概率,比如四选一选择题可以设为0.25,填空题这类几乎没法蒙的题目可以设为0,范围在[0, 1]之间。
  • d:上渐近线参数:代表能力极强的考生答对该题的最大概率,一般设为1.0(默认完全掌握知识点就能100%答对),如果有些题目即使能力很强也可能出错,可以设为0.95这类略低于1的值。

另外,建议给每个题目额外加主题标签(比如topic="代数"),方便后续实现同主题选题逻辑。

2. 适配需求的selector和estimator选择

你的核心需求是「基于上一题作答结果+主题,动态调整下一题难度」,对应的组件选择和改造建议如下:

能力估计器(estimator)

推荐用MAP估计器(Maximum A Posteriori),也就是Catsim里的MAPEstimator

  • 初始测试阶段考生作答数据少,MLE(最大似然估计)容易出现不稳定的情况;而MAP引入了能力的先验分布(比如正态分布),能给出更合理的初始能力估计,非常适合自适应测试的起步阶段。
  • 如果测试后期需要更精准的估计,也可以切换到MLEstimator

选题策略(selector)

Catsim自带的默认selector(比如MaximumInformationSelector)是基于题目信息量选题,没法直接满足「同主题+基于作答结果调难度」的需求,所以需要自定义Selector

  1. 先给题库里的每个题目添加topic属性;
  2. 继承Catsim的Selector类,重写select()方法:
    • 记录上一题的主题、作答结果和难度;
    • 从题库过滤出同主题的未使用题目;
    • 答错的话,选同主题中难度更低的题目;答对的话,选同主题中难度更高的题目;
    • 如果同主题没有符合要求的题目,再用其他逻辑兜底(比如选其他主题的中等难度题)。

3. 基于Catsim的具体推进方案

这里给你一个分步实现的框架,附代码示例:

步骤1:准备结构化题库

先把你的题库整理成符合Catsim要求的格式,加上IRT参数和主题标签:

from catsim.irt import Item
from catsim.cat import generate_item_bank

# 方式1:手动定义题目
items = [
    Item(a=1.2, b=0.5, c=0.25, d=1.0, topic="代数"),  # 中等难度代数题
    Item(a=1.0, b=-0.3, c=0.25, d=1.0, topic="代数"), # 低难度代数题
    Item(a=1.5, b=1.2, c=0.25, d=1.0, topic="代数"),  # 高难度代数题
    # 其他主题的题目...
]

# 方式2:批量生成模拟题库(用于测试)
items = generate_item_bank(100)
# 给生成的题目批量添加主题标签
for idx, item in enumerate(items):
    item.topic = "代数" if idx < 30 else "几何"

步骤2:自定义选题策略

from catsim.cat import Selector

class TopicDifficultySelector(Selector):
    def __init__(self):
        self.last_topic = None
        self.last_response = None
        self.last_b = None

    def select(self, items: list[Item], administered_items: list[Item], est_theta: float) -> int:
        # 过滤未作答的同主题题目
        available_items = [
            idx for idx, item in enumerate(items)
            if item not in administered_items and item.topic == self.last_topic
        ]

        # 没有同主题未答题时,选其他主题的题兜底
        if not available_items:
            available_items = [idx for idx, item in enumerate(items) if item not in administered_items]
            return available_items[0]

        # 根据上一题作答结果筛选难度
        if self.last_response is False:
            # 答错:选同主题难度更低的题
            candidate_idxs = [idx for idx in available_items if items[idx].b < self.last_b]
        else:
            # 答对:选同主题难度更高的题
            candidate_idxs = [idx for idx in available_items if items[idx].b > self.last_b]

        # 没有符合难度的题时,选同主题最接近当前能力的题
        if not candidate_idxs:
            candidate_idxs = available_items

        # 优先选区分度高的题(也可以改成随机选)
        candidate_idxs.sort(key=lambda x: items[x].a, reverse=True)
        return candidate_idxs[0]

步骤3:初始化并运行自适应测试

from catsim.estimation import MAPEstimator
from catsim.simulation import Simulator

# 初始化MAP能力估计器(先验均值设为0,代表中等水平)
estimator = MAPEstimator(prior_mean=0, prior_variance=1)

# 初始化自定义选题器
selector = TopicDifficultySelector()

# 初始化模拟器,设置最多测10题
simulator = Simulator(
    items=items,
    estimator=estimator,
    selector=selector,
    initial_theta=0,
    max_items=10
)

# 模拟测试流程(实际场景中替换成真实用户输入)
for step in simulator.run():
    item_idx = step[1]
    current_item = items[item_idx]
    print(f"当前题目:主题={current_item.topic},难度={current_item.b}")

    # 模拟用户作答(这里改成真实的用户输入逻辑)
    user_response = False  # 示例:答错中等难度题

    # 更新选题器的上一题信息
    selector.last_topic = current_item.topic
    selector.last_response = user_response
    selector.last_b = current_item.b

    # 告知模拟器作答结果,更新能力估计
    simulator.update(user_response)

# 输出最终能力估计值
print(f"最终能力估计:{simulator.current_theta}")

其他可行实现路径

如果Catsim的封装没法满足你更灵活的需求,也可以考虑:

  • 自行实现IRT逻辑:基于三参数/四参数IRT模型,用scipy编写能力估计(MLE/MAP)的计算代码,用pandas管理题库(方便按主题、难度筛选),完全自定义选题规则;
  • 轻量框架搭建:不用依赖Catsim,直接用基础Python代码实现「作答结果→能力更新→选题」的循环逻辑,适合需求简单的场景。

内容的提问来源于stack exchange,提问作者sana

火山引擎 最新活动