diff --git a/CAT/model/IRT.py b/CAT/model/IRT.py index 3ec5f78..1a9e2f3 100644 --- a/CAT/model/IRT.py +++ b/CAT/model/IRT.py @@ -6,16 +6,11 @@ import torch.nn as nn import numpy as np import torch.utils.data as data +from math import exp as exp from sklearn.metrics import roc_auc_score -try: - # for python module - from .abstract_model import AbstractModel - from ..dataset import AdapTestDataset, TrainDataset, Dataset -except (ImportError, SystemError): # pragma: no cover - # for python script - from abstract_model import AbstractModel - from dataset import AdapTestDataset, TrainDataset, Dataset +from CAT.model.abstract_model import AbstractModel +from CAT.dataset import AdapTestDataset, TrainDataset, Dataset class IRT(nn.Module): @@ -41,10 +36,6 @@ def forward(self, student_ids, question_ids): pred = torch.sigmoid(pred) return pred - def get_knowledge_status(self, stu_ids): - stu_emb = self.theta(stu_ids) - return stu_emb.data - class IRTModel(AbstractModel): @@ -181,4 +172,20 @@ def get_beta(self, question_id): return self.model.beta.weight.data.numpy()[question_id] def get_theta(self, student_id): - return self.model.theta.weight.data.numpy()[student_id] \ No newline at end of file + return self.model.theta.weight.data.numpy()[student_id] + + def get_iif(self, student_id, question_id): + device = self.config['device'] + sid = torch.LongTensor([student_id]).to(device) + qid = torch.LongTensor([question_id]).to(device) + theta = self.model.theta(sid).clone().detach().requires_grad_(True) + alpha = self.model.alpha(qid).clone().detach() + beta = self.model.beta(qid).clone().detach() + pred = (alpha * theta).sum(dim=1, keepdim=True) + beta + pred = torch.sigmoid(pred) + pred.backward() + pred = pred.data.numpy()[0][0] + grad = theta.grad.data.numpy()[0][0] + return grad ** 2 / (pred * (1 - pred)) + + diff --git a/CAT/model/abstract_model.py b/CAT/model/abstract_model.py index 17123cd..36b61e8 100644 --- a/CAT/model/abstract_model.py +++ b/CAT/model/abstract_model.py @@ -1,10 +1,5 @@ from abc import ABC, abstractmethod -try: - # for python module - from ..dataset import AdapTestDataset, TrainDataset, Dataset -except (ImportError, SystemError): # pragma: no cover - # for python script - from dataset import AdapTestDataset, TrainDataset, Dataset +from CAT.dataset import AdapTestDataset, TrainDataset, Dataset class AbstractModel(ABC): diff --git a/CAT/strategy/MFI_strategy.py b/CAT/strategy/MFI_strategy.py new file mode 100644 index 0000000..1cfedaf --- /dev/null +++ b/CAT/strategy/MFI_strategy.py @@ -0,0 +1,31 @@ +import numpy as np + +from CAT.strategy.abstract_strategy import AbstractStrategy +from CAT.model import AbstractModel +from CAT.dataset import AdapTestDataset + + +class MFIStrategy(AbstractStrategy): + + def __init__(self): + super().__init__() + + @property + def name(self): + return 'Maximum Fisher Information Strategy' + + def adaptest_select(self, model: AbstractModel, adaptest_data: AdapTestDataset): + assert hasattr(model, 'get_theta'), \ + 'the models must implement get_theta method' + assert hasattr(model, 'get_iif'), \ + 'the models must implement get_iif method' + selection = {} + for sid in range(adaptest_data.num_students): + theta = model.get_theta(sid) + untested_questions = np.array(list(adaptest_data.untested[sid])) + untested_iif = [] + for qid in untested_questions: + untested_iif.append(model.get_iif(sid, qid)) + j = np.argmax(untested_iif) + selection[sid] = untested_questions[j] + return selection \ No newline at end of file diff --git a/CAT/strategy/__init__.py b/CAT/strategy/__init__.py index a368902..7a3aed6 100644 --- a/CAT/strategy/__init__.py +++ b/CAT/strategy/__init__.py @@ -1,2 +1,3 @@ from .abstract_strategy import AbstractStrategy -from .random_strategy import RandomStrategy \ No newline at end of file +from .random_strategy import RandomStrategy +from .MFI_strategy import MFIStrategy \ No newline at end of file diff --git a/CAT/strategy/random_strategy.py b/CAT/strategy/random_strategy.py index af34a82..b779335 100644 --- a/CAT/strategy/random_strategy.py +++ b/CAT/strategy/random_strategy.py @@ -1,15 +1,8 @@ import numpy as np -try: - # for python module - from .abstract_strategy import AbstractStrategy - from ..model import AbstractModel - from ..dataset import AdapTestDataset -except (ImportError, SystemError): # pragma: no cover - # for python script - from abstract_strategy import AbstractStrategy - from model import AbstractModel - from dataset import AdapTestDataset +from CAT.strategy.abstract_strategy import AbstractStrategy +from CAT.model import AbstractModel +from CAT.dataset import AdapTestDataset class RandomStrategy(AbstractStrategy):