首页 > 其他分享 >1PL模拟研究代码片段

1PL模拟研究代码片段

时间:2023-11-10 12:34:14浏览次数:40  
标签:片段 真值 1PL 生成 参数估计 参数 JAGS 模拟

模拟研究

模拟研究是教育测量研究中常见的组成部分,也是重要组成部分。其目的在于说明在模拟情况为真的情况下,模型的统计性能如何。我们可以根据我们的理论假设来设定或者调整数据生成的过程,由此探讨在不同条件下模型的统计性能如何。

此外,模拟研究还有以下优势

a) 可以操纵多个条件(e.g., 被试数量; 题目难度分布), 如果使用真实数据,其耗费将是巨大到不可承受的。

b) 模拟研究可以知道能力和难度等模型参数的真值,可以比较真值和估计值之间的差异。而实证研究是不知道的,不能比较。

c) 在模拟研究中,由于数据生成过程是我们自己设定的,是已知的,可以完全排除其他无关因素的干扰。而真实数据中,由于测验过程的复杂性,可能纳入了太多的无关变量。

因此无论是学术研究还是实践应用,模拟研究均被广泛采用。

在下面的部分中,将展示如何对1PL进行模拟研究。主要使用到的语言为R,使用到的包为JAGS。

模拟研究可分为3部分,数据生成,参数估计,模型评估。

数据生成负责根据真值生成观测数据,参数估计则根据观测数据估计真值(注意,参数估计程序不会用到真值),模型评估则通常评估参数估计和真值的差异。

image

1.数据生成

数据生成的部分要根据理论假设去模仿学生真实的作答情况。在当前这个例子中,我们假设学生的数据生成过程符合1PL。因此我们根据1PL的公式去生成数据,如下。

\(P_{i}(\theta_n)= \frac{e^{\theta_n-b_{i}}}{1+e^{\theta_n-b_{i}}}\)

其中能力\(\theta_n\)为人层面的参数能力,\(b_{i}\)为题目层面的因素题目难度。学生能力高且题目难度低时,作答正确概率最高。

我们假设学生人数N=500,题目数量I=20 。将数据生成过程分成3步,人层面参数的生成,题目层面参数的生成,计算作答正确概率。

# 设定题目参数个数和人的参数个数
N <- 500
I <- 20

# 人层面参数的生成(N)
theta <- as.matrix(rnorm(N, mean = 0, sd = 1), ncol=1)
# 题目层面参数的生成(I)
b <- as.matrix(rnorm(I, mean = 0, sd = 1), ncol=1)

# 计算作答正确概率(N*I)和作答结果(N*I)
correct_p <- matrix(NA, N, I)
response <- matrix(NA, N, I)
for (n in 1:N){
  for (i in 1:I){
    # 作答正确概率
    correct_p[n,i] <- exp(theta[n]-b[i])/(1+exp(theta[n]-b[i]))
    # 作答结果
    response[n,i] <- rbinom(1,1,correct_p[n,i])
  }
}


2.参数估计

在这部分中,我们介绍如何使用JAGS实现参数估计。

JAGS代码

首先我们要用JAGS语法定义1PL并保存至1PL.bug。JAGS语法可见JAGS文档

https://people.stat.sc.edu/hansont/stat740/jags_user_manual.pdf

以下是JAGS的1PL代码:


model{
  # 计算过程
  for (n in 1:N){
    for (i in 1:I){
      p[n,i] <- ilogit(theta[n]-b[i])
      response[n,i] ~ dbern(p[n,i])
    }
  }

# 参数先验
for (n in 1:N){
  theta[n] ~ dnorm(0,1)
}
for (i in 1:I){
  b[i] ~ dnorm(0, 0.25)
}

}
  

在【计算过程】这一部分和数据生成很类似,仅仅是从R的语法替换成了JGAS的语法。其中ilogit(p) = exp(p)/(1+exp(p))。

在【参数先验】这一部分中,我们给定了参数的先验,dnorm为正态先验,第一个参数为均值,而第二个参数为密度(1/方差)。

R代码

随后我们利用R2jags这个包调用JAGS对我们的模型进行估计。

library(R2jags)
# 模型输入数据,这里包括作答response,学生数量N,以及题目数量I
jags.data <- list("response", "N", "I") 

# 配置并运行参数估计程序
# parameters.to.save:需要保存的变量|model:模型路径| n.chains:独立运行的链条数
# n.iter:总迭代次数| n.burnin:预热次数
sim<-jags(data=jags.data,inits=NULL,parameters.to.save=c("b","theta")
          ,model="1PL.bug", n.chains=2,n.iter=5000,n.burnin=2500,DIC=T)
 
# 获取EAP作为点估计
theta_hat <- sim$BUGSoutput$mean$theta
b_hat <-  sim$BUGSoutput$mean$b

3. 模型评估

通常我们采用所有参数Bias的均值Mean(Bias)和RMSE的均值Mean(RMSE)来评估模型的返真性能,也就是真值和我们估计值之间的差异

\[Mean(Bias) =\frac{\sum_{i=1}^{P}\sum_{i=1}^{K} \left(\hat{X_{pk}}-X_{pk}\right)}{P \times K} \]

其中\(\hat{X_i}\)为估计值,而\(X_{i}\)为真值,P为参数个数,K为重复次数。在我们的例子中,仅重复了一次,因此K=1 。

Bias计算的其实是所有参数和估计值差异的平均值,评估的是参数估计是否有偏,而非参数估计的精确性。

\[Mean(R M S E)=\sum_{i=1}^{P} \frac{{\sqrt{\frac{\sum_{i=1}^{K}\left(\hat{X_{pk}}-X_{pk}\right)^{2}}{K}}}}{P} \]

RMSE计算的是每个参数在不同重复次数的估计精度如何,评估的则是估计的精确程度。

在当前例子中K=1

代码实现如下:


Bias_theta <- mean(as.matrix(theta_hat, ncol=1) - theta)
RMSE_theta <- mean(((as.matrix(theta_hat, ncol=1) - theta)^2)^0.5)

整体代码:

#############################
########【数据生成】###########
#############################
# 设定题目参数个数和人的参数个数
N <- 500
I <- 20

# 人层面参数的生成(N)
theta <- as.matrix(rnorm(N, mean = 0, sd = 1), ncol=1)
# 题目层面参数的生成(I)
b <- as.matrix(rnorm(I, mean = 0, sd = 1), ncol=1)

# 计算作答正确概率(N*I)和作答结果(N*I)
correct_p <- matrix(NA, N, I)
response <- matrix(NA, N, I)
for (n in 1:N){
  for (i in 1:I){
    # 作答正确概率
    correct_p[n,i] <- exp(theta[n]-b[i])/(1+exp(theta[n]-b[i]))
    # 作答结果
    response[n,i] <- rbinom(1,1,correct_p[n,i])
  }
}

#############################
########【参数估计】###########
#############################
library(R2jags)
# 模型输入数据,这里包括作答response,学生数量N,以及题目数量I
jags.data <- list("response", "N", "I") 

# 配置并运行参数估计程序
# parameters.to.save:需要保存的变量|model:模型路径| n.chains:独立运行的链条数
# n.iter:总迭代次数| n.burnin:预热次数
sim<-jags(data=jags.data,inits=NULL,parameters.to.save=c("b","theta")
          ,model="1PL.bug", n.chains=2,n.iter=5000,n.burnin=2500,DIC=T)
 
# 获取EAP作为点估计
theta_hat <- sim$BUGSoutput$mean$theta
b_hat <-  sim$BUGSoutput$mean$b

#############################
########【模型评估】###########
#############################
Bias_theta <- mean(as.matrix(theta_hat, ncol=1) - theta)
RMSE_theta <- mean(((as.matrix(theta_hat, ncol=1) - theta)^2)^0.5)

相关链接:

Curtis, S. M. (2010). BUGS Code for Item Response Theory. Journal of Statistical Software, Code Snippets, 36(1), 1–34. https://doi.org/10.18637/jss.v036.c01

Bayesian IRT in JAGS: A Tutorial. (2023). Journal of Behavioral Data Science, 3(1), 84-107. https://doi.org/10.35566/jbds/v3n1/mccure

Luecht, R.M., & Ackerman, T.A. (2018). A Technical Note on IRT Simulation Studies: Dealing With Truth, Estimates, Observed Data, and Residuals. Educational Measurement: Issues and Practice, 37, 65-76. https://doi.org/10.1111/emip.12185

Bulut, O. & Sünbül, Ö. (2017). R Programlama Dili ile Madde Tepki Kuramında Monte Carlo Simülasyon Çalışmaları . Journal of Measurement and Evaluation in Education and Psychology , 8 (3) , 266-287 . DOI: 10.21031/epod.305821

标签:片段,真值,1PL,生成,参数估计,参数,JAGS,模拟
From: https://www.cnblogs.com/qpchen/p/17823827.html

相关文章

  • 模拟集成电路设计系列博客——3.4.2 稳压器反馈分析
    3.4.2稳压器反馈分析上一小节中介绍的稳压器的开环分析与基本源极跟随器很相似,假定使用一个跨导为\(G_{ma}\),输出阻抗为\(R_{oa}\)的单级放大器,环路在放大器的输入处断开并是呀一个测试信号\(v_{t}\),可以得到如下图所示的小信号等效电路。稳压器负载通过小信号电阻\(R_L\)建模,并......
  • NOIP 模拟15
    20+25+0+100寄了,前仨题每道题都只会了一半也是挺厉害的。A.数字变换每次操作后\((a+b)\bmodp\)的值不变,所以可以先判断\((a+b)\bmodp\)是否等于\((c+d)\bmodp\),不等的话一定无解。然后就只需要考虑\(a\),当\(a=c\)时就找到了答案。每次可以将\(a\gets2a\bmodp\)......
  • 11.8 模拟赛小记
    僕を連れてって,浸み込んでしまう前に菜哭了。不会打,看了半个小时史铁生散文集。100+0+80+0喵。A.俨俨与道路(constructure)正解是最小生成树。我的思路差不多。为了全部联通,需要n-1条边。随意先计算给定的确定起始点的边,根据边权排序,从中挑至少\(n-1-k\)条边。剩下的用......
  • 10.31 模拟赛小记
    抽象场。打完人自闭的那种。得分情况:\(80-0-30-30\)。A:从\(0\)走到\(n\)。在\(i\)位置时,等概率走的走到\([i+1,n]\)(视为一步)。求期望步数。哥们赛时,爆搜打表找规律。。。最后写的O(n),没看到第九个数据点没有特判。对于最后一个点1e18,递推式写出来但不会进一步求。遗憾......
  • 苹果电子iPad Pro系列或推出OLED版,改善PG模拟游戏体验
    在过去的一年中,苹果iPad系列未推出任何新品,然而,明年可能会带来令人振奋的更新。PG游戏软件APP猜测,苹果将进行全面的iPad产品线升级,包括最基础的iPad到高端的iPadPro。其中,最引人瞩目的是采用OLED显示屏的iPadPro,该款产品还将搭载M3芯片,这将是重大升级。根据韩媒的报道,LG、三星和......
  • 即将推出的《深夜拉面》demo游戏版:在PG模拟试玩中倾听客人故事并疗愈心灵
    独立游戏工作室CointinueGames宣布了他们即将在12月中旬推出的《MidnightRamen深夜拉面》(深夜のラーメン)的试玩版。这款游戏将在Steam等平台上推出,并支持简体中文等语言。《深夜拉面》受到了《VA-11Hall-A:CyberpunkBartenderAction赛博朋克酒保行动》和《CoffeeTalk》等游戏......
  • STL之unordered_set与unordered_map的模拟实现(万字长文详解)
    unordered_set与unordered_map的模拟实现哈希节点类#pragmaonce#include<iostream>#include<vector>namespaceMySTL{template<classT>structHashNode{HashNode(constT&data=T())......
  • 模拟集成电路设计系列博客——3.4.1 稳压器概述
    3.4.1稳压器概述稳压器的作用是产生一个低噪声的直流电压,并且从中可以流出电流。一般我们在电路中使用它来提供一个干净的电源提供给模拟电路,尤其是在有噪声的供电会限制电路性能的场景中,稳压器的使用是必要的。一个基本的稳压器结构如下图所示,其以参考电压\(V_{ref}\)作为输入......
  • 2023年11月8日模拟赛
    这里观看体验更佳总结今天是模拟赛。还是比较难的。但是暴力能拿到210pts。说什么好呢。好像也没有什么好说的。感觉似乎还是那样。今天hyb生病了。可怜,希望他快点好起来。以前总是能在这个地方水一些东西,现在不想水了乎哉。题解今天的题思维和代码能力各需参半。看起来这......
  • NOIP模拟<反思>
    NOIP2023模拟12联测33构造手摸你就会发现\(ryxyryxyr\),这样会更优,而且从第三行开始会有多余的贡献。点击查看代码//ubsan:undefined//accoders#include<bits/stdc++.h>usingnamespacestd;chars[100];charans[100][100];intmain(){freopen("ryx.in","r",s......