Mục tiêu: tài liệu này giúp người không quen với CAT/IRT hiểu cách repository hoạt động, cách chạy demo, cách kiểm tra chất lượng item và cách diễn giải kết quả. Nội dung được tổ chức theo thứ tự từ thực hành nhanh (Quickstart) đến lý thuyết và troubleshooting.
- Mở PowerShell trong thư mục dự án và tạo virtualenv:
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -U pip
python -m pip install -r requirements.txt
# nếu muốn chạy tests (nếu chưa cài pytest):
python -m pip install pytest- Tạo dữ liệu phản hồi mô phỏng 3PL (mẫu có sẵn trong
scripts):
python scripts\generate_3pl_responses.py --n_respondents 500 --out data\simulated_responses_3pl.csv
# -> tạo data\simulated_responses_3pl.csv- Chạy công cụ đánh giá item (offline):
python eval_items.py --responses data\simulated_responses_3pl.csv --bank data\Java_Course_150_questions.json --out data\eval_java_3pl- Mở kết quả trong
data\eval_java_3pl:
item_stats.csv— thống kê itemdistractors.json— phân bố đáp án nếu responses là letter-codedcorr_report.json— tương quan giữa params (a/b/c) và thống kê thực nghiệm
- Dùng IRT (3PL) để mô tả mối quan hệ giữa năng lực ẩn (theta) và xác suất trả lời đúng một item.
- Hệ thống cho phép mô phỏng responses, đánh giá chất lượng item (p-value, point-biserial, Cronbach alpha), và chạy thử luồng CAT thông qua
cat_service_api.py.
- IRT: mô hình dùng để mô tả xác suất trả lời đúng dựa trên năng lực ẩn và tham số item.
- 3PL (3-parameter logistic): model với a (discrimination), b (difficulty), c (guessing).
- Theta (θ): năng lực ẩn của người thi (thường chuẩn hóa, ví dụ ~N(0,1)).
- p-value (item): tỉ lệ người đúng câu hỏi (proportion correct).
- Point-biserial (r_pb): tương quan giữa đúng item và tổng điểm (thể hiện discrimination thực nghiệm).
- Cronbach alpha: đo độ nhất quán nội bộ của bài kiểm tra.
- Fisher information: lượng thông tin item cung cấp về θ tại một điểm θ.
- Bank JSON: mỗi item là một object, ví dụ tối giản:
{
"id": "Q_001",
"question": "What is 2+2?",
"options": ["1", "2", "3", "4"],
"answer": "D",
"difficulty": "Easy",
"param_a": 1.2,
"param_b": 0.3,
"param_c": 0.2
}- Responses CSV: dạng nhị phân (1/0) hoặc letter-coded (A/B/C/D). Ví dụ header có thể là
user_id,Q_001,Q_002,....
-- Nếu letter-coded, eval_items.py sẽ sinh distractors.json để phân tích từng đáp án.
Command mẫu:
python eval_items.py --responses <path_to_csv> --bank <path_to_bank.json> --out <out_dir>Output chính:
<out_dir>/item_stats.csv— mỗi item:id, p_value, point_biserial, param_a, param_b, param_c, flags.<out_dir>/distractors.json— tần suất lựa chọn cho từng choice (nếu letter-coded).<out_dir>/corr_report.json— tương quan a vs r_pb, b vs p_value, v.v.
Ví dụ cách diễn giải nhanh:
p_value=0.85: item khá dễ; nếu >0.9 có thể flagtoo_easy.point_biserial=0.15: discrimination thấp; có thể flaglow_discriminationnếu <0.2.- Cronbach alpha toàn bài: nếu <0.5 thì bài kém nhất quán; 0.6–0.8 trung bình; >0.8 tốt.
scripts/generate_3pl_responses.py— mô phỏng responses theo 3PL (theta~N(0,1)).scripts/generate_sim_responses.py— mô phỏng đơn giản (ví dụ dùng p cố định) — chỉ để thử pipeline (không thực tế để kiểm tra reliability).eval_items.py— công cụ offline để tính p-values, r_pb, Cronbach alpha, distractor analysis, correlation report.cat_service_api.py— Flask demo API cho luồng CAT (lấy câu hỏi tiếp theo / submit kết quả).
- Trong venv, cài
pytestnếu chưa có:
python -m pip install pytest- Chạy tests (file kiểm tra JSON banks đã được thêm):
python -m pytest -qGợi ý: test tests/test_validate_data.py kiểm tra từng JSON trong data/ có load được và có các trường cần thiết.
- Dữ liệu mô phỏng phải chứa biến thiên năng lực (theta) — nếu responses được tạo cố định theo p, Cronbach alpha thường thấp.
- Dùng mô phỏng 3PL với n >= 200–500 để có ước lượng p và r_pb ổn định.
- Loại bỏ item có
param_aquá nhỏ (ví dụ a < 0.3) hoặcparam_ckhông hợp lý (c quá lớn) sau khi kiểm traitem_stats.csv. - Nếu muốn phân tích distractor, dùng letter-coded responses (A/B/C/D) để có tần suất lựa chọn mỗi đáp án.
- Nếu
eval_items.pykhông khớp id giữa CSV và bank: kiểm tra header và định dạng id của items. - Nếu
pytestbáo lỗi import: chắc venv chưa active hoặc thiếu packages — dùngpython -m pip install -r requirements.txt. - Nếu service không kết nối DB: thử chạy service ở chế độ đọc bank từ file JSON để debug logic trước.
- Chạy mô phỏng 3PL +
eval_items.pyvà tóm tắt các item bị flag (tôi có thể tự chạy và báo lại kết quả). - Chỉnh generator để xuất letter-coded responses và phân tích distractors.
- Thêm script nhỏ để calibrate a/b/c từ dữ liệu thực (dùng
pyirthoặc gọi Rmirt).
Nếu bạn muốn tôi thực hiện bước nào (ví dụ: A = tóm tắt item flagged, B = tạo letter-coded responses, C = chạy pytest ở môi trường này), hãy chọn — tôi sẽ chạy tiếp và báo kết quả.
Tài liệu này mô tả cách triển khai CAT trong repository, các file quan trọng, cách chạy service và test nhanh trên máy Windows.
Project này triển khai một service CAT (Computerized Adaptive Testing) sử dụng mô hình IRT 3PL (a, b, c). Bộ core gồm:
- Lựa chọn item dựa trên Fisher information (chọn top-K rồi random 1 trong top-K để tránh quá lặp).
- Ước lượng năng lực θ bằng
catsim.estimation.NumericalSearchEstimatorkhi có đủ lịch sử, và dùng fallback heuristic (±0.2–0.3) khi lịch sử quá ngắn hoặc estimator lỗi.
Các endpoints chính được cung cấp bởi cat_service_api.py (Flask):
POST /api/cat/next-question— nhậnuser_id,course_id,assignment_id,answered_questions,last_response,current_theta(tùy); trả về câu hỏi tiếp theo vàtemp_theta.POST /api/cat/submit— submit toàn bộ bài, tínhfinal_theta, lưuCAT_Results, và cập nhậtUserAbilitiesvới smoothing alpha.
-
cat_service_api.py— Flask service, chứa:- Hàm IRT:
irt_prob(a,b,c,theta)(3PL) vàitem_information(item,theta)(Fisher information). estimate_theta(...)— dùngNumericalSearchEstimatorhoặc fallback heuristic.- DB helpers: tạo bảng (nếu cần) và lưu
CAT_Logs,CAT_Results,UserAbilities.
- Hàm IRT:
-
cat_service_sqlserver_auto.py— script mô phỏng CAT bằng thư việncatsim(Simulator). Dùng để thử nghiệm chiến lược selection/estimation. -
add_question_DB.py— script import câu hỏi từ JSON vàoMcqQuestionsvàMcqChoices. -
tts_irt.py— module helper thuần-Python (được thêm để phục vụ unit test) chứairt_probvàitem_informationsao cho tests có thể chạy độc lập. -
requirements.txt— phụ thuộc tối thiểu. -
tests/— chứa unit tests:tests/test_irt.py— test hàm IRT thuần.tests/test_estimate_theta.py— test fallback củaestimate_theta(không import trực tiếp toàn bộ module service; test dùng AST để load hàm một cách an toàn).
dbo.McqQuestions— cột cần:Id,Content,AssignmentId,ParamA,ParamB,ParamC.dbo.McqChoices—Id,Content,IsCorrect,McqQuestionId.dbo.UserAbilities—UserId,CourseId,Theta,LastUpdate.dbo.CAT_Logs— lưu lịch sử từng phản hồi cùng ThetaBefore/After.dbo.CAT_Results— lưu kết quả khi submit.
Lưu ý: cat_service_api.py sẽ tự tạo các bảng CAT_Logs, UserAbilities, CAT_Results nếu chưa tồn tại (hàm ensure_tables).
- Tạo virtualenv và kích hoạt:
python -m venv .venv
.\.venv\Scripts\Activate.ps1- Cài dependencies:
pip install -r requirements.txt- Chỉnh chuỗi kết nối SQL Server (nếu cần):
- Mở
cat_service_api.pyvà cập nhậtDB_CONNcho phù hợp (hoặc sửacat_service_sqlserver_auto.pynếu dùng script mô phỏng). Hiện tại code có chuỗi mẫu dùng Windows Authentication hoặc UID/PWD cứng — khuyến nghị tách ra biến môi trường trước khi deploy.
- Khởi động service:
# từ thư mục dự án
python cat_service_api.pyService sẽ in log và lắng nghe trên 0.0.0.0:5000 mặc định.
- Import câu hỏi (nếu cần):
python add_question_DB.py- Lấy câu hỏi tiếp theo:
POST /api/cat/next-question
{
"user_id": "<user-guid>",
"course_id": "<course-guid>",
"assignment_id": "<assignment-guid>",
"answered_questions": ["qid1", "qid2"],
"last_response": [1],
"current_theta": 0.0
}- Submit bài:
POST /api/cat/submit
{
"user_id": "<user-guid>",
"course_id": "<course-guid>",
"assignment_id": "<assignment-guid>",
"answered_questions": ["qid1","qid2","qid3"],
"responses": [1,0,1],
"smoothing_alpha": 0.2
}Tài liệu này giải thích kiến thức chính về CAT, cách hệ thống trong repository hoạt động, cách chạy/test và các mẹo để cải thiện "độ chính xác" (tức là sự hợp lý của ước lượng năng lực và độ ổn định thống kê).
Nội dung chính:
- Kiến thức IRT & 3PL (a, b, c)
- Thuật toán chọn item (information, exposure control)
- Ước lượng năng lực (MLE / MAP / EAP / numerical search)
- Kiểm thử dữ liệu (JSON/CSV) và cách chạy
eval_items.pyđể đánh giá item - Công cụ mô phỏng (scripts) và hướng dẫn chạy trên Windows (PowerShell)
-
IRT 3PL: xác suất thí sinh đúng một item được mô tả bởi hàm 3PL:
$$P(\theta) = c + \frac{1-c}{1 + e^{-a(\theta - b)}}$$ - a (discrimination): độ phân biệt của item
- b (difficulty): vị trí khả năng (theta) tại đó P ≈ (1+c)/2
- c (guessing): xác suất đoán đúng khi theta rất thấp
-
Fisher information cho item i tại theta:
$$I_i(\theta) = \frac{[P'_i(\theta)]^2}{P_i(\theta) (1 - P_i(\theta))}$$ Việc lựa chọn item dựa trên thông tin (max information) giúp thu thập nhiều thông tin nhất về θ hiện tại.
-
cat_service_api.py— Flask API endpoint để lấy câu hỏi tiếp theo (/api/cat/next-question) và submit bài (/api/cat/submit).- Thứ tự xử lý khi client gọi
next-question:- Tải item pool (từ DB hoặc file JSON tạm thời).
- Ước lượng
thetahiện tại (MAP/MLE/EAP hoặc fallback heuristic nếu ít dữ liệu). - Tính thông tin Fisher cho từng item chưa được trả lời ở
thetahiện tại. - Áp dụng cơ chế kiểm soát (loại bỏ items bị quá lạm dụng, content balancing).
- Chọn top-K theo thông tin rồi random 1 item trong top-K (randomization giảm exposure).
- Trả về item (kèm
temp_thetavà meta để client render).
- Thứ tự xử lý khi client gọi
-
eval_items.py— công cụ offline để đánh giá quality của item bank bằng dữ liệu phản hồi (CSV). Sinh raitem_stats.csv,distractors.json,corr_report.json. -
scripts/generate_3pl_responses.py(tạo mẫu 3PL responses) vàscripts/generate_sim_responses.py(mẫu đơn giản) — tiện để test pipeline và tính các chỉ số.
-
cat_service_api.py— service chính (Flask). Chứa:- Hàm IRT (3PL) và hàm tính Fisher information.
estimate_theta(...)(dùng numerical search hoặc fallback)- Lưu log và kết quả vào DB (bảng
CAT_Logs,CAT_Results,UserAbilitiesđược tự tạo nếu cần).
-
eval_items.py— đánh giá offline: chấp nhận--responses(CSV) và--bank(bank JSON) và xuất report. Dùng để kiểm tra p-value, point-biserial, Cronbach alpha và tương quan giữa params và stats. -
tests/— unit tests nhỏ:tests/test_irt.py— kiểm tra hàm 3PL và item information.tests/test_validate_data.py— (đã thêm) kiểm tra tính hợp lệ các file JSON trongdata/(tải được, schema cơ bản, trả lời nằm trong options, id duy nhất,...).
McqQuestions/dbo.McqQuestions: Id, Content, AssignmentId, ParamA, ParamB, ParamCMcqChoices/dbo.McqChoices: Id, Content, IsCorrect, McqQuestionIdUserAbilities: UserId, CourseId, Theta, LastUpdateCAT_Logs: lưu từng phản hồi kèm ThetaBefore/AfterCAT_Results: kết quả khi submit
cat_service_api.py có helper ensure_tables() để tự tạo bảng tối thiểu khi cần.
- Tạo virtualenv và cài phụ thuộc (một lần):
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -U pip
python -m pip install -r requirements.txt- Kiểm tra nhanh các test pytest:
python -m pytest -q- Kiểm tra/validate dữ liệu JSON trong
data/(test đã thêm):
python -m pytest tests/test_validate_data.py::test_data_files_found -q
python -m pytest tests/test_validate_data.py -q- Chạy
eval_items.pyđể đánh giá bank với responses CSV:
python eval_items.py --responses data\simulated_responses_3pl.csv --bank data\Java_Course_150_questions.json --out data\eval_java_3plOutputs: item_stats.csv, distractors.json, corr_report.json trong folder --out.
- Khởi chạy service (nếu muốn chạy API):
# trong venv
python cat_service_api.pyEndpoints (JSON):
POST /api/cat/next-question— payload: user_id, course_id, assignment_id, answered_questions, last_response, current_thetaPOST /api/cat/submit— payload: user_id, course_id, assignment_id, answered_questions, responses, smoothing_alpha
- Hiểu ý nghĩa "độ chính xác":
- Cronbach alpha: chỉ báo độ nhất quán nội bộ (classical), cao khi thí sinh có biến thiên năng lực và item phân biệt tốt.
- Correlation a vs point-biserial: kỳ vọng dương (a cao -> discrimination cao -> point-biserial lớn).
- Correlation b vs p-value: kỳ vọng âm (b lớn -> item khó -> p-value thấp).
- Vì sao ban đầu bạn thấy độ chính xác thấp?
- Nếu bạn tạo responses ngẫu nhiên với p cố định (không phụ thuộc theta), không có biến thiên giữa người => Cronbach thấp.
- Cách cải thiện (đã làm và gợi ý thêm):
- Dùng mô phỏng 3PL (đã thêm
scripts/generate_3pl_responses.py) để tạo responses phụ thuộc theta và item params — điều này tạo ra dữ liệu thực tế hơn và các thống kê khớp với IRT. - Tăng kích thước mẫu (n respondents) để ước lượng p và r_pb ổn định hơn.
- Kiểm tra item params: loại bỏ/cải biên item có
param_aquá nhỏ (ví dụ a < 0.3) hoặcparam_cquá lớn (ví dụ c > 0.3) nếu không mong muốn. - Cân bằng độ khó (b) trong bank — nếu tất cả item quá dễ hoặc quá khó, ước lượng năng lực kém.
- Sử dụng exposure control: randomize trong top-K, áp thêm quy tắc tối đa tần suất 1 item.
- Thu thập dữ liệu thực tế để calibrate lại a/b/c bằng package IRT (Python/R). Mô phỏng chỉ giúp kiểm tra pipeline.
-
item_stats.csv:p_value: tỷ lệ thí sinh đúng itempoint_biserial: tương quan giữa item và tổng điểm (loại bỏ item đó)flags:too_hard,too_easy,low_discriminationhoặcok— dùng để lọc/điều chỉnh item
-
distractors.json: nếu responses là letter-coded, chứa tần suất lựa chọn từng lựa chọn theo cả tổng và nhóm trên/dưới. -
corr_report.json: các tương quan a vs r_pb, b vs p — dùng để kiểm tra độ khớp giữa params mô phỏng/ước lượng và tham số đã gán.
tests/test_validate_data.py— kiểm tra schema JSON trongdata/.scripts/generate_sim_responses.py— tạo responses nhị phân đơn giản.scripts/generate_3pl_responses.py— tạo responses theo 3PL (theta~N(0,1)). Dùng để kiểm tra pipeline và cải thiện các chỉ số thống kê.
- Nếu
pytestkhông chạy: càipytestvào virtualenv:python -m pip install pytest. - Nếu
eval_items.pybáo không tìm được items: kiểm tra header CSV hoặc dùng positional columns (CSV không cần header nhưng mapping sẽ theo vị trí). - Nếu service cố kết nối DB thất bại: chỉnh
DB_CONNhoặc chạy service ở chế độ giả lập (đọc bank từ file JSON) để debug luồng logic trước khi kết nối DB thật.
- Thu thập một bộ dữ liệu thật (responses thực) và chạy
eval_items.pyđể calibrate lại a/b/c bằng thư viện IRT chuyên dụng. - Thêm chức năng MAP/EAP chính xác trong
estimate_theta(hiện tại repo dùng numerical search + fallback). Góipyirthoặc gọi Rmirtcó thể giúp. - Thêm logging chi tiết khi chọn item để phân tích exposure và content balancing.
- Nếu cần phân tích distractor, tạo responses letter-coded (mô phỏng hoặc thu thập thực) và chạy
eval_items.pyđể sinhdistractors.json.
Nếu bạn muốn, tôi có thể: (a) thêm ví dụ chạy dùng letter-coded responses, (b) mở data/eval_java_3pl/item_stats.csv và tóm tắt top flagged items, hoặc (c) bổ sung hướng dẫn calibrate a/b/c bằng một script nhỏ.