Mô hình IRT 3PL

https://drive.google.com/file/d/19YQB_WOZsrdtPYuDLEYdZz2r0tgvG5tf/view?usp=sharing


import pandas as pd

import numpy as np

from scipy.optimize import minimize


# Hàm logistic 3PL

def logistic_3pl(theta, a, b, c):

    return c + (1 - c) / (1 + np.exp(-a * (theta - b)))


# Hàm likelihood để tối ưu hóa tham số câu hỏi

def likelihood_3pl(params, theta, responses):

    a, b, c = params

    prob = logistic_3pl(theta, a, b, c)

    return -np.sum(responses * np.log(prob) + (1 - responses) * np.log(1 - prob))


# Hàm tối ưu hóa tham số câu hỏi

def estimate_item_params_3pl(responses, initial_params=(1, 0, 0.2)):

    n_items = responses.shape[1]

    item_params = []

    for i in range(n_items):

        result = minimize(

            likelihood_3pl,

            x0=initial_params,

            args=(0, responses[:, i]),  # Khởi tạo theta = 0

            bounds=[(0.01, 3), (-3, 3), (0, 0.5)]  # Giới hạn tham số a, b, c

        )

        item_params.append(result.x)  # Lưu a, b, c

    return np.array(item_params)


# Hàm likelihood để tối ưu hóa năng lực học sinh

def likelihood_theta(theta, responses, item_params):

    likelihood = 0

    for response, (a, b, c) in zip(responses, item_params):

        prob = logistic_3pl(theta, a, b, c)

        likelihood += response * np.log(prob) + (1 - response) * np.log(1 - prob)

    return -likelihood


# Ước lượng năng lực học sinh

def estimate_theta(responses, item_params, initial_theta=0):

    n_students = responses.shape[0]

    abilities = []

    for i in range(n_students):

        result = minimize(

            likelihood_theta,

            x0=[initial_theta],

            args=(responses[i], item_params),

            bounds=[(-3, 3)]  # Giới hạn theta

        )

        abilities.append(result.x[0])

    return np.array(abilities)


# Tính điểm dựa trên năng lực và tham số câu hỏi

def calculate_scores(abilities, item_params):

    scores = []

    for theta in abilities:

        score = 0

        for a, b, c in item_params:

            prob = logistic_3pl(theta, a, b, c)

            score += prob  # Tổng xác suất trả lời đúng

        scores.append(score)

    return scores


# Đọc dữ liệu từ file Excel

data = pd.read_excel("data.xlsx")  # File dữ liệu đầu vào

student_names = data.iloc[:, 0]  # Cột đầu tiên: Tên học sinh

responses = data.iloc[:, 1:].values  # Câu trả lời (1 = đúng, 0 = sai)


# Bước 1: Ước lượng tham số câu hỏi

item_params = estimate_item_params_3pl(responses)


# Bước 2: Ước lượng năng lực học sinh

student_abilities = estimate_theta(responses, item_params)


# Bước 3: Tính điểm của học sinh

scores = calculate_scores(student_abilities, item_params)


# Ghi kết quả ra file Excel

output = pd.DataFrame({

    "Tên Học Sinh": student_names,

    "Năng lực (θ)": student_abilities,

    "Điểm": scores

})

output.to_excel("ket_qua_irt.xlsx", index=False)

print("\nKết quả đã được lưu vào file 'ket_qua_irt.xlsx'.")

----------------------

Giải thích cách xây dựng mô hình IRT 3PL

1. Ý nghĩa của mô hình IRT (Item Response Theory)

IRT là một phương pháp phân tích dữ liệu trắc nghiệm để đánh giá:

  • Năng lực của học sinh (θ): Mức độ hiểu biết hoặc khả năng của học sinh.
  • Tham số câu hỏi:
    • a: Độ phân biệt (discrimination) - mức độ nhạy cảm của câu hỏi để phân biệt học sinh có năng lực khác nhau.
    • b: Độ khó (difficulty) - mức năng lực cần thiết để có xác suất trả lời đúng là 50%.
    • c: Đoán mò (guessing) - xác suất tối thiểu học sinh trả lời đúng dù không biết.

Xác suất một học sinh có năng lực θ trả lời đúng câu hỏi được tính bởi hàm logistic 3PL:


 

2. Quy trình:

Bước 1: Đọc dữ liệu đầu vào

  • Dữ liệu có cấu trúc như sau:

    • Tên Học Sinh: Danh sách học sinh.
    • Câu 1, Câu 2,..., Câu n: Kết quả trả lời (1 = đúng, 0 = sai).

Kết quả:

  • Ma trận Responses: Học sinh x Câu hỏi.
  • student_names: Tên của các học sinh.

Bước 2: Ước lượng tham số câu hỏi (a,b,c)

Công thức:

Ta cần tìm các tham số a,b,c cho từng câu hỏi để tối ưu hàm log-likelihood:

Quy trình:

1.     Khởi tạo giá trị ban đầu: a=1,b=0,c=0.2

2.     Tối ưu hóa: Dùng scipy.optimize.minimize để tìm a,b,c sao cho log-likelihood đạt cực đại.

3.     Giới hạn tham số:

·        a: [0.01, 3] - Độ phân biệt không âm.

·        b: [-3, 3] - Mức độ khó nằm trong khoảng hợp lý.

·        c: [0, 0.5] - Xác suất đoán mò.


Bước 3: Ước lượng năng lực học sinh (θ)

Công thức:

Tương tự tham số câu hỏi, ta tối ưu hóa năng lực học sinh θ dựa trên log-likelihood:

Quy trình:

1.     Khởi tạo giá trị ban đầu: θ=0 (trung bình năng lực).

2.     Tối ưu hóa: Dùng scipy.optimize.minimize để tìm θ cho từng học sinh.


Bước 4: Tính điểm của học sinh

Công thức:

Tính tổng xác suất trả lời đúng của từng học sinh dựa trên năng lực θ và tham số câu hỏi:

 

 

 

Quy trình:

1.     Với mỗi học sinh (θ):

·        Tính xác suất trả lời đúng P cho từng câu hỏi.

·        Cộng tổng xác suất này để có điểm.


Bước 5: Xuất kết quả ra file Excel

 

 

 

 

3.     Cách tính toán:

Bảng giá trị các tham số abc dựa trên cách tối ưu hóa hàm log-likelihood và tìm abc sao cho hàm log-likelihood đạt cực đại bằng cách sử dụng scipy.optimize.minimize 

 

*Ví dụ tính điểm cho học sinh 1:

Điểm được tính dựa trên tổng xác suất trả lời đúng của các câu hỏi

Tính toán như sau:

Các câu khác tính tương tự như câu 1:

èKết quả: Điểm được tính ra là :

 

 


Nhận xét

Bài đăng phổ biến từ blog này

AI chatbot hỗ trợ cho GV lên kế hoạch dạy học STEAM theo quy trinh 5E (GV mầm non và GV Tiểu học)

Trang blog của Nguyễn Thế Dũng - ĐHSP Huế. Mời đọc.