IRT models

class irtorch.models.BaseIRTModel(latent_variables: int, item_categories: list[int], mc_correct: list[int] | None = None)

Bases: ABC, Module

Abstract base class for Item Response Theory models. All IRT models should inherit from this class.

Parameters
  • latent_variables (int) – The number of latent variables.

  • item_categories (list[int]) – A list of the number of response categories for each item.

  • mc_correct (list[int], optional) – A list of the correct response category for each multiple choice item. (default is None)

add_scale_transformation(scale: Scale) None

Add a scale transformation to the model. The rescaling instance should inherit from irtorch.rescale.Scale.

detach_scale_transformations() None

Remove a scale transformation from the model.

property evaluate

Various methods for IRT model evaluation as described in irtorch.Evaluator.

Returns

An instance of the irtorch.Evaluator class.

Return type

Evaluation

expected_item_score_gradients(theta: Tensor, rescale_by_item_score: bool = True, rescale: bool = True) Tensor

Computes expected item score gradients for each item \(j\) with respect to the latent variable(s) \(\mathbf{\theta}\).

Parameters
  • theta (torch.Tensor) – A 2D tensor with theta scores from the population of interest. Each row represents one respondent, and each column represents a latent variable.

  • rescale_by_item_score (bool, optional) – Whether to rescale the expected items scores to have a max of one by dividing by the max item score. (default is True)

  • rescale (bool, optional) – Whether to compute the gradients on the rescaled scale if it exists. Only possible for scale transformations for which gradients are available. (default is True)

Returns

A 3D tensor with the expected item score gradients. Dimensions are (theta rows, items, latent_variables).

Return type

torch.Tensor

Notes

When rescale is True, the gradients are computed on the transformed scale using the Jacobian of the transformation. Let \(\mathbf{\theta} = f(\mathbf{\theta}^*)\) be the transformed theta scores (original scores being \(\mathbf{\theta}^*\)) with Jacobian \(\mathbf{J}_f\) and Jacobian inverse \(\mathbf{J}^{-1}_f\). We know that \(\nabla_{\boldsymbol{\theta}} \mathbb{E}(X_j|\boldsymbol{\theta})=\nabla_{\boldsymbol{\theta}^*} \mathbb{E}(X_j|\boldsymbol{\theta}^*) \mathbf{J}^{-1}_f\) by the chain rule. Thus we can rewrite as follows:

\[\begin{split}\begin{aligned} \nabla_{\boldsymbol{\theta}} \mathbb{E}(X_j|\boldsymbol{\theta})\mathbf{J}_f &=\nabla_{\boldsymbol{\theta}^*} \mathbb{E}(X_j|\boldsymbol{\theta}^*) \mathbf{J}^{-1}_f\mathbf{J}_f \\ \left(\nabla_{\boldsymbol{\theta}} \mathbb{E}(X_j|\boldsymbol{\theta})\mathbf{J}_f\right)^{T} &=\left(\nabla_{\boldsymbol{\theta}^*} \mathbb{E}(X_j|\boldsymbol{\theta}^*) \mathbf{I}\right)^{T}\\ \mathbf{J}_f^{T}\nabla_{\boldsymbol{\theta}} \mathbb{E}(X_j|\boldsymbol{\theta})^T &=\nabla_{\boldsymbol{\theta}^*} \mathbb{E}(X_j|\boldsymbol{\theta}^*)^{T}. \end{aligned}\end{split}\]

The last line gives us a linear equation that is solved using torch.linalg.solve to get \(\nabla_{\boldsymbol{\theta}} \mathbb{E}(X_j|\boldsymbol{\theta})\). This is more efficient as computing \(\mathbf{J}^{-1}_f\) is not needed.

expected_scores(theta: Tensor, return_item_scores: bool = True) Tensor

Computes the model expected item scores/test scores for each respondent (row in theta).

Parameters
  • theta (torch.Tensor) – A 2D tensor with theta scores. Each row represents one respondent, and each column represents a latent variable.

  • return_item_scores (bool, optional) – Whether to return the expected item scores. If False, returns the expected sum scores (default is True)

Returns

A tensor with the expected scores for each respondent.

Return type

torch.Tensor

fit(train_data: torch.Tensor, algorithm: BaseIRTAlgorithm, **kwargs) None

Train the model.

Parameters
  • train_data (torch.Tensor) – The training data. Item responses should be coded 0, 1, … and missing responses coded as nan or -1.

  • algorithm (BaseIRTAlgorithm) – The algorithm to use for training the model. Needs to inherit irtorch.estimation_algorithms.BaseIRTAlgorithm

  • **kwargs – Additional keyword arguments to pass to the algorithm’s fit method.

abstract forward(theta) Tensor

Forward pass of the model. PyTorch requires this method to be implemented in subclasses of nn.Module.

Parameters

theta (torch.Tensor) – Input tensor.

Returns

Output tensor.

Return type

torch.Tensor

information(theta: Tensor, item: bool = True, degrees: list[int] = None, rescale: bool = True) Tensor

Calculate the Fisher information matrix (FIM) for the theta scores (or the information in the direction supplied by degrees).

Parameters
  • theta (torch.Tensor) – A 2D tensor containing latent variable theta scores for which to compute the information. Each column represents one latent variable.

  • item (bool, optional) – Whether to compute the information for each item (True) or for the test as a whole (False). (default is True)

  • degrees (list[int], optional) – For multidimensional models. A list of angles in degrees between 0 and 90, one for each latent variable. Specifies the direction in which to compute the information. (default is None and returns the full FIM)

  • rescale (bool, optional) – Whether to compute information on the rescaled scale if it exists. Only possible for scale transformations for which gradients are available. (default is True)

Returns

A tensor with the information for each theta score. Dimensions are:

  • By default: (theta rows, items, FIM rows, FIM columns).

  • If degrees are specified: (theta rows, items).

  • If item is False: (theta rows, FIM rows, FIM columns).

  • If degrees are specified and item is False: (theta rows).

Return type

torch.Tensor

Notes

In the context of IRT, the Fisher information matrix measures the amount of information that a test taker’s responses \(X\) carries about the latent variable(s) \(\mathbf{\theta}\). It is defined as:

\[I(\mathbf{\theta}) = \mathbb{E}_{X|\mathbf{\theta}}\left[ \left(\nabla_{\mathbf{\theta}} \ell(\mathbf{\theta}|X) \right) \left(\nabla_{\mathbf{\theta}} \ell(\mathbf{\theta}|X) \right)^T \right] = -\mathbb{E}_{X|\mathbf{\theta}}\left[\left(\nabla_{\mathbf{\theta}}^2 \ell(\mathbf{\theta}|X) \right)\right]\]

Where:

  • \(I(\mathbf{\theta})\) is the Fisher Information Matrix.

  • \(\ell(\mathbf{\theta}|X)\) is the log-likelihood of \(\mathbf{\theta}\), given the latent variable vector \(X\).

  • \(\nabla_{\mathbf{\theta}} \ell(\mathbf{\theta}|X)\) is the gradient vector of the log-likelihood with respect to \(\mathbf{\theta}\).

  • \(\nabla_{\mathbf{\theta}}^2 \ell(\mathbf{\theta}|X)\) is the Hessian matrix (the second derivatives of the log-likelihood with respect to \(\mathbf{\theta}\)).

For additional details, see Chang et al. [4].

inverse_transform_theta(transformed_theta: Tensor) Tensor

Reverse transformed latent variables to their original theta scale.

Parameters

transformed_theta (torch.Tensor) – A 2D tensor containing transformed theta scores. Each column represents one latent variable.

Returns

A 2D tensor containing original theta scores. Each column represents one latent variable.

Return type

torch.Tensor

item_probabilities(theta: Tensor) Tensor

Returns the probabilities for each possible response for all items.

Parameters

theta (torch.Tensor) – A 2D tensor. Rows are respondents and latent variables are columns.

Returns

3D tensor with dimensions (respondents, items, item categories)

Return type

torch.Tensor

item_theta_relationship_directions(theta: Tensor) Tensor

Get the directions of the relationships between each item and latent variable for a fitted model.

Parameters

theta (torch.Tensor) – A 2D tensor with latent theta scores from the population of interest. Each row represents one respondent, and each column represents a latent variable.

Returns

A 2D tensor with the relationships between the items and latent variables. Items are rows and latent variables are columns.

Return type

torch.Tensor

latent_scores(data: Tensor, standard_errors: bool = False, theta_estimation: str = 'ML', lbfgs_learning_rate: float = 0.2, eap_theta_integration_points: int = None, device: str = 'cpu', rescale: bool = True)

Returns the latent scores \(\mathbf{\theta}\) for the provided test data using encoder the neural network (NN), maximum likelihood (ML), expected a posteriori (EAP) or maximum a posteriori (MAP). ML and MAP uses the LBFGS algorithm. EAP and MAP are not recommended for non-variational autoencoder models as there is nothing pulling the latent distribution towards a normal. EAP for models with more than three factors is not recommended since the integration grid becomes huge.

Parameters
  • data (torch.Tensor) – A 2D tensor with test data. Each row represents one respondent, each column an item.

  • standard_errors (bool, optional) – Whether to return standard errors for the latent scores. (default is False)

  • theta_estimation (str, optional) – Method used to obtain the theta scores. Can be β€˜NN’, β€˜ML’, β€˜EAP’ or β€˜MAP’ for neural network, maximum likelihood, expected a posteriori or maximum a posteriori respectively. (default is β€˜ML’)

  • device (str, optional) – The device to use for computation. Can be β€˜cpu’ or β€˜cuda’. (default is β€œcuda” if available else β€œcpu”)

  • lbfgs_learning_rate (float, optional) – For ML and MAP. The learning rate to use for the LBFGS optimizer. Try lowering this if your loss runs rampant. (default is 0.2)

  • eap_theta_integration_points (int, optional) – For EAP. The number of integration points for each latent variable. (default is β€˜None’ and uses a function of the number of latent variables)

  • rescale (bool, optional) – Whether to compute the latent scores on the rescaled scale if it exists. (default is True)

Returns

A 2D tensor of latent scores, with latent variables as columns. If standard_errors is True, returns a tuple with the latent scores and the standard errors.

Return type

torch.Tensor or tuple[torch.Tensor, torch.Tensor]

load_model(path: str) None

Loads the model from a file. The initialized model should have the same structure and hyperparameter settings as the fitted model that is being loaded (e.g., the same number of latent variables).

Parameters

path (str) – Where to load fitted model from.

log_likelihood(data: Tensor, output: Tensor, missing_mask: Tensor = None, loss_reduction: str = 'sum') Tensor

Compute the log likelihood of the data given the model. This is equivalent to the negative cross entropy loss.

Parameters
  • data (torch.Tensor) – A 2D tensor with test data. Columns are items and rows are respondents

  • output (torch.Tensor) – A 2D tensor with output. Columns are item response categories and rows are respondents

  • missing_mask (torch.Tensor, optional) – A 2D tensor with missing data mask. (default is None)

  • loss_reduction (str, optional) – The reduction argument for torch.nn.functional.cross_entropy(). (default is β€˜sum’)

Returns

The log likelihood.

Return type

torch.Tensor

property plot

Methods for IRT model plotting. An instance of irtorch.Plotter.

Returns

An instance of the irtorch.Plotter class.

Return type

Plotter

population_difficulty(theta: Tensor = None) Tensor

The average population difficulty for each item. Ranges from 0 to 1.

Calculated as the average proportion of item points missing for each item as:

\[\int_{\mathbf{\theta}}\left[ 1 - \frac{\mathbb{E}(x_j|\mathbf{\theta})}{\text{max}_j}\right]f(\mathbf{\theta})d\mathbf{\theta} \approx \frac{1}{N} \sum_{i=1}^{N} \left[1 - \frac{\mathbb{E}(x_j|\mathbf{\hat{\theta}}_i)}{\text{max}_j}\right]\]

where:

  • \(f(\mathbf{\theta})\) is the probability density function of the latent variables.

  • \(\mathbf{\theta}\) is a vector of latent variables.

  • \(\mathbb{E}(x_j|\mathbf{\theta})\) is the expected score on item \(j\) given \(\mathbf{\theta}\).

  • \(\text{max}_j\) is the maximum score on item \(j\).

  • \(N\) is the sample size and \(\mathbf{\hat{\theta}}_i\) is the estimated \(\mathbf{\theta}\) for respondent \(i\).

Parameters

theta (torch.Tensor, optional) – A 2D tensor with latent variable theta scores from the population of interest. Each row represents one respondent, and each column represents a latent variable. If not provided, assumes a standard normal distribution. (default is None)

Returns

A 1D tensor with the difficulty for each item.

Return type

torch.Tensor

population_discrimination(theta: Tensor = None, item_overall: bool = False, standard_normal_covariance: bool = True, rescale: bool = True, **kwargs) Tensor

The average population discrimination for each item. Relatively large values means that an item is good at distinguishing between higher and lower ability respondents for the population supplied by the theta argument.

Calculated as the average gradients of the expected item scores with respect to the latent variables scaled by the maximum item scores.

For each latent dimension, this is calculated as:

\[\int_{\mathbf{\theta}}\left[ \frac{\nabla_{\mathbf{\theta}}\mathbb{E}(x_j|\mathbf{\theta})}{\text{max}_j}\right]f(\mathbf{\theta})d\mathbf{\theta} \approx \frac{1}{N} \sum_{i=1}^{N} \left[\frac{\nabla_{\mathbf{\theta}}\mathbb{E}(x_j|\mathbf{\hat{\theta}}_i)}{\text{max}_j}\right]\]

If item_overall is True, the scalar population discrimination is returned using a covariance-weighted gradient norm:

\[\int_{\mathbf{\theta}} \frac{\sqrt{\nabla_{\mathbf{\theta}}\mathbb{E}(x_j|\mathbf{\theta})^{\top}\,\boldsymbol{\Sigma}_\theta\,\nabla_{\mathbf{\theta}}\mathbb{E}(x_j|\mathbf{\theta})}}{\text{max}_j} f(\mathbf{\theta}) d\mathbf{\theta} \approx \frac{1}{N} \sum_{i=1}^{N} \frac{\sqrt{\nabla_{\mathbf{\theta}}\mathbb{E}(x_j|\mathbf{\hat{\theta}}_i)^{\top}\,\boldsymbol{\Sigma}_\theta\,\nabla_{\mathbf{\theta}}\mathbb{E}(x_j|\mathbf{\hat{\theta}}_i)}}{\text{max}_j}\]

where:

  • \(f(\mathbf{\theta})\) is the probability density function of the latent variables.

  • \(\mathbf{\theta}\) is a vector of latent variables.

  • \(\mathbb{E}(x_j|\mathbf{\theta})\) is the expected score on item \(j\) given \(\mathbf{\theta}\).

  • \(\text{max}_j\) is the maximum score on item \(j\).

  • \(N\) is the sample size and \(\mathbf{\hat{\theta}}_i\) is the estimated \(\mathbf{\theta}\) for respondent \(i\).

  • \(\boldsymbol{\Sigma}_\theta\) is the covariance matrix of the latent trait vector under the population distribution. When standard_normal_covariance is True, this is the identity matrix \(\mathbf{I}\). Otherwise it is estimated empirically from the supplied theta. Weighting by \(\boldsymbol{\Sigma}_\theta\) gives more weight to directions where the population varies more and less weight to directions where it varies little.

Parameters
  • theta (torch.Tensor, optional) – A 2D tensor with latent variable theta scores from the population of interest. Each row represents one respondent, and each column represents a latent variable. If not provided, assumes a standard normal distribution. (default is None)

  • item_overall (bool, optional) – If True, calculates the scalar population discrimination using a covariance-weighted gradient norm, returning one scalar per item. If False, returns the discrimination separated by latent dimension. (default is False)

  • standard_normal_covariance (bool, optional) – Only used when item_overall is True. If True, uses the identity matrix as \(\boldsymbol{\Sigma}_\theta\), corresponding to a standard normal population. If False, estimates \(\boldsymbol{\Sigma}_\theta\) empirically from the supplied theta. (default is True)

  • rescale (bool, optional) – Whether to compute the gradients on the rescaled scale if it exists. Only possible for scale transformations for which gradients are available. (default is True)

  • **kwargs – Additional keyword arguments to pass to the expected_item_score_gradients method.

Returns

A tensor with the average expected item score gradients. If item_overall is True, this is a 1D tensor summarizing discrimination for each item (length items). If False, this is a 2D tensor with discrimination by latent variable (dimensions (items, latent_variables)).

Return type

torch.Tensor

probabilities_from_output(output: Tensor) Tensor

Compute probabilities from the output tensor from the forward method.

Parameters

output (torch.Tensor) – Output tensor from the forward pass.

Returns

3D tensor with dimensions (respondents, items, item categories)

Return type

torch.Tensor

probability_gradients(theta: Tensor, rescale: bool = True) Tensor

Calculate the gradients of the item response probabilities with respect to the theta scores.

Parameters
  • theta (torch.Tensor) – A 2D tensor containing latent variable theta scores. Each column represents one latent variable.

  • rescale (bool, optional) – Whether to compute the gradients on the rescaled scale if it exists. Only possible for scale transformations for which gradients are available. (default is True)

Returns

A torch tensor with the gradients for each theta score. Dimensions are (theta rows, items, item categories, latent variables).

Return type

torch.Tensor

Notes

When rescale is True, the gradients are computed on the transformed scale using the Jacobian of the transformation. See notes for expected_item_score_gradients() for more details as the method is the same.

sample_test_data(theta: Tensor) Tensor

Sample test data for the provided theta scores.

Parameters

theta (torch.Tensor) – The latent scores.

Returns

The sampled test data.

Return type

torch.Tensor

save_model(path: str) None

Save the fitted model.

Parameters

path (str) – Where to save fitted model.

theta_transform_jacobian(theta: Tensor) Tensor

Compute the Jacobian matrix of the scale transformations for each row in the input theta scores.

Parameters

theta (torch.Tensor) – A 2D tensor containing latent variable theta scores. Each column represents one latent variable.

Returns

A torch tensor with the gradients for each theta score. Dimensions are (theta rows, latent variables, latent variables) where the last two are the jacobians.

Return type

torch.Tensor

transform_theta(theta: Tensor) Tensor

Transform the latent variables using the scale transformation(s).

Parameters

theta (torch.Tensor) – A 2D tensor containing latent variable theta scores. Each column represents one latent variable.

Returns

A 2D tensor containing transformed theta scores. Each column represents one latent variable.

Return type

torch.Tensor

class irtorch.models.OneParameterLogistic(data: Tensor = None, items: int = None)

Bases: BaseIRTModel

One parametric logistic (1PL) IRT model, also known as the Rasch model [11]. This model is only available for unidimensional latent variables.

Parameters
  • data (torch.Tensor, optional) – A 2D torch tensor with test data. Used to automatically compute the number of items. Columns are items and rows are respondents. (default is None)

  • items (int) – Number of items.

Notes

For an item \(j\), the model defines the probability for responding correctly as:

\[\frac{ \exp(\theta + d_j) }{ 1+\exp(\theta + d_j) },\]

where:

  • \(\theta\) is the latent variable.

  • \(d_j\) is the bias term for item \(j\).

Examples

>>> from irtorch.models import OneParameterLogistic
>>> from irtorch.estimation_algorithms import MML
>>> from irtorch.load_dataset import swedish_sat_binary
>>> # Use quantitative part of the SAT data
>>> data = swedish_sat_binary()[:, :80]
>>> model = OneParameterLogistic(items=80)
>>> model.fit(train_data=data, algorithm=MML())
forward(theta: Tensor) Tensor

Forward pass of the model.

Parameters

theta (torch.Tensor) – 2D tensor with latent variables. Rows are respondents and latent variables are columns.

Returns

output – 2D tensor. Rows are respondents and columns are item category logits.

Return type

torch.Tensor

item_parameters() DataFrame

Get the item parameters for a fitted model.

Returns

A dataframe with the item parameters.

Return type

pd.DataFrame

item_theta_relationship_directions(theta: Tensor = None) Tensor

Get the relationship directions between each item and latent variable for a fitted model.

Parameters

theta (torch.Tensor, optional) – Not needed for this model. (default is None)

Returns

A 2D tensor with the relationships between the items and latent variables. Items are rows and latent variables are columns.

Return type

torch.Tensor

class irtorch.models.TwoParameterLogistic(data: Tensor = None, latent_variables: int = 1, items: int = None, item_theta_relationships: Tensor = None)

Bases: BaseIRTModel

Two parametric logistic (2PL) IRT model [1].

Parameters
  • data (torch.Tensor, optional) – A 2D torch tensor with test data. Used to automatically compute the number of items. Columns are items and rows are respondents. (default is None)

  • latent_variables (int) – Number of latent variables.

  • items (int) – Number of items.

  • item_theta_relationships (torch.Tensor, optional) – A boolean tensor of shape (items, latent_variables). If specified, the model will have connections between latent dimensions and items where the tensor is True. If left out, all latent variables and items are related (Default: None)

Notes

For an item \(j\), the model defines the probability for responding correctly as:

\[\frac{ \exp(\mathbf{a}_j^\top \mathbf{\theta} + d_j) }{ 1+\exp(\mathbf{a}_j^\top \mathbf{\theta} + d_j) },\]

where:

  • \(\mathbf{\theta}\) is a vector of latent variables.

  • \(\mathbf{a}_j\) is a vector of weights for item \(j\).

  • \(d_j\) is the bias term for item \(j\).

Examples

>>> from irtorch.models import TwoParameterLogistic
>>> from irtorch.estimation_algorithms import MML
>>> from irtorch.load_dataset import swedish_sat_binary
>>> # Use quantitative part of the SAT data
>>> data = swedish_sat_binary()[:, :80]
>>> model = TwoParameterLogistic(items=80)
>>> model.fit(train_data=data, algorithm=MML())
forward(theta: Tensor) Tensor

Forward pass of the model.

Parameters

theta (torch.Tensor) – 2D tensor with latent variables. Rows are respondents and latent variables are columns.

Returns

output – 2D tensor. Rows are respondents and columns are item category logits.

Return type

torch.Tensor

item_parameters(irt_format=False) DataFrame

Get the item parameters for a fitted model.

Parameters

irt_format (bool, optional) – Only for unidimensional models. Whether to return the item parameters in traditional IRT format. Otherwise returns weights and biases. (default is False)

Returns

A dataframe with the item parameters.

Return type

pd.DataFrame

item_theta_relationship_directions(theta: Tensor = None) Tensor

Get the relationship directions between each item and latent variable for a fitted model.

Parameters

theta (torch.Tensor, optional) – Not needed for this model. (default is None)

Returns

A 2D tensor with the relationships between the items and latent variables. Items are rows and latent variables are columns.

Return type

torch.Tensor

class irtorch.models.ThreeParameterLogistic(data: Tensor = None, latent_variables: int = 1, items: int = None, item_theta_relationships: Tensor = None)

Bases: BaseIRTModel

Three parametric logistic (3PL) IRT model [1]. Note that parameter estimation for this model is currently very unstable.

Parameters
  • data (torch.Tensor, optional) – A 2D torch tensor with test data. Used to automatically compute the number of items. Columns are items and rows are respondents. (default is None)

  • latent_variables (int) – Number of latent variables.

  • items (int) – Number of items.

  • item_theta_relationships (torch.Tensor, optional) – A boolean tensor of shape (items, latent_variables). If specified, the model will have connections between latent dimensions and items where the tensor is True. If left out, all latent variables and items are related (Default: None)

Notes

For an item \(j\), the model defines the probability for responding correctly as:

\[c_j+(1-c_j) \frac{ \exp(\mathbf{a}_j^\top \mathbf{\theta} + d_j) }{ 1+\exp(\mathbf{a}_j^\top \mathbf{\theta} + d_j) },\]

where:

  • \(\mathbf{\theta}\) is a vector of latent variables.

  • \(\mathbf{a}_j\) is a vector of weights for item \(j\).

  • \(d_j\) is the bias term for item \(j\).

  • \(c_j\) is the probability of guessing correctly on item \(j\).

Examples

>>> from irtorch.models import ThreeParameterLogistic
>>> from irtorch.estimation_algorithms import MML
>>> from irtorch.load_dataset import swedish_sat_binary
>>> # Use quantitative part of the SAT data
>>> data = swedish_sat_binary()[:, :80]
>>> model = ThreeParameterLogistic(items=80)
>>> model.fit(train_data=data, algorithm=MML())
forward(theta: Tensor) Tensor

Forward pass of the model.

Parameters

theta (torch.Tensor) – 2D tensor with latent variables. Rows are respondents and latent variables are columns.

Returns

output – 2D tensor. Rows are respondents and columns are probabilities.

Return type

torch.Tensor

item_parameters(irt_format=False) DataFrame

Get the item parameters for a fitted model.

Parameters

irt_format (bool, optional) – Only for unidimensional models. Whether to return the item parameters in traditional IRT format. Otherwise returns weights and biases. (default is False)

Returns

A dataframe with the item parameters.

Return type

pd.DataFrame

item_theta_relationship_directions(theta: Tensor = None) Tensor

Get the relationship directions between each item and latent variable for a fitted model.

Parameters

theta (torch.Tensor, optional) – Not needed for this model. (default is None)

Returns

A 2D tensor with the relationships between the items and latent variables. Items are rows and latent variables are columns.

Return type

torch.Tensor

log_likelihood(data: Tensor, output: Tensor, missing_mask: Tensor = None, loss_reduction: str = 'sum') Tensor

Compute the log likelihood.

Parameters
  • data (torch.Tensor) – A 2D tensor with test data. Columns are items and rows are respondents

  • output (torch.Tensor) – A 2D tensor with output. Columns are item response categories and rows are respondents

  • missing_mask (torch.Tensor, optional) – A 2D tensor with missing data mask. (default is None)

  • loss_reduction (str, optional) – The reduction argument. (default is β€˜sum’)

Returns

The log likelihood.

Return type

torch.Tensor

probabilities_from_output(output: Tensor) Tensor

Compute probabilities from the output tensor from the forward method.

Parameters

output (torch.Tensor) – Output tensor from the forward pass.

Returns

3D tensor with dimensions (respondents, items, item categories)

Return type

torch.Tensor

class irtorch.models.GeneralizedPartialCredit(data: Tensor = None, latent_variables: int = 1, item_categories: list[int] = None, item_theta_relationships: Tensor = None)

Bases: BaseIRTModel

Generalized Partial Credit IRT model [10].

Parameters
  • data (torch.Tensor, optional) – A 2D torch tensor with test data. Used to automatically compute item_categories. Columns are items and rows are respondents. (default is None)

  • latent_variables (int) – Number of latent variables.

  • item_categories (list[int]) – Number of categories for each item. One integer for each item. Missing responses excluded.

  • item_theta_relationships (torch.Tensor, optional) – A boolean tensor of shape (items, latent_variables). If specified, the model will have connections between latent dimensions and items where the tensor is True. If left out, all latent variables and items are related (Default: None)

Notes

For an item \(j\) with \(m=0, 1, 2, \ldots, M_j\) possible item scores, the model defines the probability for responding with a score of \(x\) as follows:

\[\begin{split}P(X_j=x | \mathbf{\theta}) = \begin{cases} \dfrac{1} {1+\sum_{g=1}^{M_i}\exp \left(g\mathbf{a}_{j}^\top \mathbf{\theta} + \sum_{m=1}^gd_{jm}\right)}, & \text{if } x = 0\\ \dfrac{\exp \left( x\mathbf{a}_{j}^\top \mathbf{\theta}+\sum_{m=1}^{x}d_{jm}\right)} {1+\sum_{g=1}^{M_i}\exp \left(g\mathbf{a}_{j}^\top \mathbf{\theta} + \sum_{m=1}^gd_{jm}\right)}, & \text{otherwise} \end{cases}\end{split}\]

where:

  • \(\mathbf{\theta}\) is a vector of latent variables.

  • \(\mathbf{a}_{j}\) is a vector of weights for item \(j\).

  • \(d_{jm}\) is the bias term for item \(j\) and score \(m\).

Examples

>>> from irtorch.models import GeneralizedPartialCredit
>>> from irtorch.estimation_algorithms import MML
>>> from irtorch.load_dataset import swedish_national_mathematics_1
>>> data = swedish_national_mathematics_1()
>>> model = GeneralizedPartialCredit(data)
>>> model.fit(train_data=data, algorithm=MML())
forward(theta: Tensor) Tensor

Forward pass of the model.

Parameters

theta (torch.Tensor) – 2D tensor with latent variables. Rows are respondents and latent variables are columns.

Returns

output – 2D tensor. Rows are respondents and columns are item score logits.

Return type

torch.Tensor

item_parameters(irt_format=False) DataFrame

Get the item parameters for a fitted model.

Parameters

irt_format (bool, optional) – Only for unidimensional models. Whether to return the item parameters in traditional IRT format. Otherwise returns weights and biases. (default is False)

Returns

A dataframe with the item parameters.

Return type

pd.DataFrame

item_theta_relationship_directions(theta: Tensor = None) Tensor

Get the relationship directions between each item and latent variable for a fitted model.

Parameters

theta (torch.Tensor, optional) – Not needed for this model. (default is None)

Returns

A 2D tensor with the relationships between the items and latent variables. Items are rows and latent variables are columns.

Return type

torch.Tensor

class irtorch.models.GradedResponse(data: Tensor = None, latent_variables: int = 1, item_categories: list[int] = None, item_theta_relationships: Tensor = None)

Bases: BaseIRTModel

Graded response IRT model [13].

Parameters
  • data (torch.Tensor, optional) – A 2D torch tensor with test data. Used to automatically compute item_categories. Columns are items and rows are respondents. (default is None)

  • latent_variables (int) – Number of latent variables.

  • item_categories (list[int]) – Number of categories for each item. One integer for each item. Missing responses excluded.

  • item_theta_relationships (torch.Tensor, optional) – A boolean tensor of shape (items, latent_variables). If specified, the model will have connections between latent dimensions and items where the tensor is True. If left out, all latent variables and items are related (Default: None)

Notes

For an item \(j\) with ordered item scores \(x=0, 1, 2, ...\) the model defines the probability for responding with a score of \(x\) or higher for all \(x>0\) as follows:

\[P(X_j \geq x | \mathbf{\theta}) = \dfrac{\exp \left(\mathbf{a}_{j}^\top \mathbf{\theta} + d_{jx}\right)}{1+\exp \left(\mathbf{a}_{j}^\top \mathbf{\theta} + d_{jx}\right)}\]

where:

  • \(\mathbf{\theta}\) is a vector of latent variables.

  • \(\mathbf{a}_{j}\) is a vector of weights for item \(j\).

  • \(d_{jx}\) is the bias term for item \(j\) and score \(x\).

From here, the probability of responding with a score of \(x\) is calculated as:

\[\begin{split}P(X_j = x | \mathbf{\theta}) = \begin{cases} 1-P(X_j \geq x +1 | \mathbf{\theta}), & \text{if } x = 0\\ P(X_j \geq x | \mathbf{\theta})-P(X_j \geq x+1 | \mathbf{\theta}), & \text{otherwise} \end{cases}\end{split}\]

Examples

>>> from irtorch.models import GradedResponse
>>> from irtorch.estimation_algorithms import MML
>>> from irtorch.load_dataset import swedish_national_mathematics_1
>>> data = swedish_national_mathematics_1()
>>> model = GradedResponse(data)
>>> model.fit(train_data=data, algorithm=MML())
forward(theta: Tensor) Tensor

Forward pass of the model.

Parameters

theta (torch.Tensor) – 2D tensor with latent variables. Rows are respondents and latent variables are columns.

Returns

output – 2D tensor. Rows are respondents and columns are \(\mathbf{a}_{j}^\top \mathbf{\theta} + d_{jx}\).

Return type

torch.Tensor

item_parameters(irt_format=False) DataFrame

Get the item parameters for a fitted model.

Parameters

irt_format (bool, optional) – Only for unidimensional models. Whether to return the item parameters in traditional IRT format. Otherwise returns weights and biases. (default is False)

Returns

A dataframe with the item parameters.

Return type

pd.DataFrame

item_theta_relationship_directions(theta: Tensor = None) Tensor

Get the relationship directions between each item and latent variable for a fitted model.

Parameters

theta (torch.Tensor, optional) – Not needed for this model. (default is None)

Returns

A 2D tensor with the relationships between the items and latent variables. Items are rows and latent variables are columns.

Return type

torch.Tensor

log_likelihood(data: Tensor, output: Tensor, missing_mask: Tensor = None, loss_reduction: str = 'sum') Tensor

Compute the log likelihood.

Parameters
  • data (torch.Tensor) – A 2D tensor with test data. Columns are items and rows are respondents

  • output (torch.Tensor) – A 2D tensor with output. Columns are item response categories and rows are respondents

  • missing_mask (torch.Tensor, optional) – A 2D tensor with missing data mask. (default is None)

  • loss_reduction (str, optional) – The reduction argument. (default is β€˜sum’)

Returns

The log likelihood.

Return type

torch.Tensor

probabilities_from_output(output: Tensor) Tensor

Compute probabilities from the output tensor from the forward method.

Parameters

output (torch.Tensor) – Output tensor from the forward pass.

Returns

3D tensor with dimensions (respondents, items, item categories)

Return type

torch.Tensor

class irtorch.models.NestedLogit(mc_correct: list[int], correct_response_model: BaseIRTModel, incorrect_response_model: str = 'nominal', data: torch.Tensor | None = None, latent_variables: int = 1, item_categories: list[int] | None = None, item_theta_relationships: torch.Tensor | None = None, degree: int = 3, knots: list[float] | None = None)

Bases: BaseIRTModel

Nested logit IRT model for multiple choice items [14]. The original paper uses a 3PL model irtorch.models.ThreeParameterLogistic nested with a nominal response model irtorch.models.NominalResponse. This implementation allows one to choose any IRT model for dichotomously scored items in place of the 3PL, and either a nominal response model or B-splines for the incorrect responses.

Requires the correct response model to be specified in advance. It can also be a previously fitted model.

Parameters
  • mc_correct (list[int]) – Only for multiple choice data. The correct response option for each item.

  • correct_response_model (BaseIRTModel) – A fitted IRT model instance to use for the correct response.

  • incorrect_response_model (str, optional) – The model to use for the incorrect responses. Can be β€˜nominal’ or β€˜bspline’. (Default: β€˜nominal’)

  • data (torch.Tensor, optional) – A 2D torch tensor with test data. Used to automatically compute item_categories. Columns are items and rows are respondents. (default is None)

  • latent_variables (int, optional) – Number of latent variables. (default is 1)

  • item_categories (list[int], optional) – Number of categories for each item. One integer for each item. Missing responses excluded. (default is None)

  • item_theta_relationships (torch.Tensor, optional) – A boolean tensor of shape (items, latent_variables). If specified, the model will have connections between latent dimensions and items where the tensor is True. If left out, all latent variables and items are related (Default: None)

  • degree (int, optional) – The degree of the B-spline basis functions when using the B-spline model for the incorrect responses. (Default: 3)

  • knots (list[float], optional) – The positions of the internal knots (bounds excluded) for the B-spline basis functions when using the B-spline model for the incorrect responses. If not provided, defaults to [-1.7, -0.7, 0, 0.7, 1.7].

Notes

For an item \(j\) with \(m=0, 1, 2, \ldots, M_j\) possible item scores, the model defines the probability for responding with a score of \(x\) as follows:

\[\begin{split}P(X_j=x | \mathbf{\theta}) = \begin{cases} P(X_j=c_j|\mathbf{\theta}), & \text{if } x = c_j\\ (1-P(X_j=c_j|\mathbf{\theta}))P(X_j=x|x\neq c_j, \mathbf{\theta}), & \text{otherwise} \end{cases}\end{split}\]

where:

  • \(\mathbf{\theta}\) is a vector of latent variables.

  • \(c_j\) is the correct response option for item \(j\).

  • \(P(X_j=c_j|\mathbf{\theta})\) is computed using the model supplied as correct_response_model.

  • The conditional probabilities \(P(X_j=x|x\neq c_j, \mathbf{\theta})\) are estimated using either a nominal response model or B-splines.

Examples

>>> from irtorch.models import NestedLogit, ThreeParameterLogistic
>>> from irtorch.estimation_algorithms import MML
>>> from irtorch.load_dataset import swedish_sat_quantitative
>>> data, correct_responses = swedish_sat_quantitative()
>>> model_3pl = ThreeParameterLogistic(items = data.shape[1])
>>> model_nested = NestedLogit(correct_responses, model_3pl, data=data)
>>> model_nested.fit(train_data=data, algorithm=MML())
forward(theta: Tensor) Tensor

Forward pass of the model.

Parameters

theta (torch.Tensor) – 2D tensor with latent variables. Rows are respondents and latent variables are columns.

Returns

output – 2D tensor. Rows are respondents and columns are item category logits.

Return type

torch.Tensor

item_theta_relationship_directions(theta: Tensor = None) Tensor

Get the relationship directions between each item and latent variable for a fitted model.

Parameters

theta (torch.Tensor, optional) – Only needed for NR models. A 2D tensor with latent theta scores from the population of interest. Each row represents one respondent, and each column represents a latent variable.

Returns

A 2D tensor with the relationships between the items and latent variables. Items are rows and latent variables are columns.

Return type

torch.Tensor

log_likelihood(data: Tensor, output: Tensor, missing_mask: Tensor = None, loss_reduction: str = 'sum') Tensor

Compute the log likelihood.

Parameters
  • data (torch.Tensor) – A 2D tensor with test data. Columns are items and rows are respondents

  • output (torch.Tensor) – A 2D tensor with output. Columns are item response categories and rows are respondents

  • missing_mask (torch.Tensor, optional) – A 2D tensor with missing data mask. (default is None)

  • loss_reduction (str, optional) – The reduction argument. (default is β€˜sum’)

Returns

The log likelihood.

Return type

torch.Tensor

probabilities_from_output(output: Tensor) Tensor

Probabilities forwarded from the output tensor from the forward method. For this model, the output is already the probabilities and the method exists for compatibility and consistency between models.

Parameters

output (torch.Tensor) – Output tensor from the forward pass.

Returns

3D tensor with dimensions (respondents, items, item categories)

Return type

torch.Tensor

class irtorch.models.NominalResponse(data: Tensor = None, latent_variables: int = 1, item_categories: list[int] = None, item_theta_relationships: Tensor = None, mc_correct: list[int] = None)

Bases: BaseIRTModel

Nominal response IRT model [2].

Parameters
  • data (torch.Tensor, optional) – A 2D torch tensor with test data. Used to automatically compute item_categories. Columns are items and rows are respondents. (default is None)

  • latent_variables (int, optional) – Number of latent variables. (default is 1)

  • item_categories (list[int], optional) – Number of categories for each item. One integer for each item. Missing responses excluded. (default is None)

  • item_theta_relationships (torch.Tensor, optional) – A boolean tensor of shape (items, latent_variables). If specified, the model will have connections between latent dimensions and items where the tensor is True. If left out, all latent variables and items are related (Default: None)

  • mc_correct (list[int], optional) – Only for multiple choice data. The correct response option for each item. (Default: None)

Notes

For an item \(j\) with \(m=0, 1, 2, \ldots, M_j\) possible item responses/scores, the model defines the probability for responding with a score of \(x\) as follows (selecting response option \(x\) for multiple choice items):

\[P(X_j=x | \mathbf{\theta}) = \frac{ \exp(\mathbf{a}_{jm}^\top \mathbf{\theta} + d_{jm}) }{ \sum_{m=0}^{M_j} \exp(\mathbf{a}_{jm}^\top \mathbf{\theta} + d_{jm}) },\]

where:

  • \(\mathbf{\theta}\) is a vector of latent variables.

  • \(\mathbf{a}_{jm}\) is a vector of weights for item \(j\) and response category \(m\).

  • \(d_{jm}\) is the bias term for item \(j\) and response category \(m\).

The model is fitted with the following constraints of the item parameters for model identifiability:

\[\sum_{m=0}^{M_j} a_{jm} = 0, \quad \sum_{m=0}^{M_j} d_{jm} = 0.\]
forward(theta: Tensor) Tensor

Forward pass of the model.

Parameters

theta (torch.Tensor) – 2D tensor with latent variables. Rows are respondents and latent variables are columns.

Returns

output – 2D tensor. Rows are respondents and columns are item category logits.

Return type

torch.Tensor

item_parameters() DataFrame

Get the item parameters for a fitted model.

Returns

A dataframe with the item parameters.

Return type

pd.DataFrame

item_theta_relationship_directions(theta: Tensor = None) Tensor

Get the relationship directions between each item and latent variable for a fitted model.

Parameters

theta (torch.Tensor, optional) – Only needed for NR models. A 2D tensor with latent theta scores from the population of interest. Each row represents one respondent, and each column represents a latent variable.

Returns

A 2D tensor with the relationships between the items and latent variables. Items are rows and latent variables are columns.

Return type

torch.Tensor

class irtorch.models.MonotoneBSpline(data: Tensor = None, latent_variables: int = 1, item_categories: list[int] = None, knots: list[float] = None, degree: int = 3, separate: str = 'items')

Bases: BaseIRTModel

Monotone B-Spline IRT model for polytomously scored items with ordered responses.

Parameters
  • data (torch.Tensor, optional) – A 2D torch tensor with test data. Used to automatically compute item_categories. Columns are items and rows are respondents. (default is None)

  • latent_variables (int) – Number of latent variables.

  • item_categories (list[int]) – Number of categories for each item. One integer for each item. Missing responses excluded.

  • knots (list[float], optional) – Positions of the internal knots (bounds excluded) for the B-spline basis functions. If not provided, defaults to [-1.7, -0.7, 0, 0.7, 1.7].

  • degree (int, optional) – Degree of the B-spline polynomials. Defaults to 3 (cubic splines).

  • separate (str, optional) – Whether to fit separate latent variable functions for items or item response categories. Can be β€˜items’ or β€˜categories’. Note that β€˜categories’ results in a more flexible model with more parameters. (Default: β€˜items’)

Notes

For an item \(j\) with \(m=0, 1, 2, \ldots, M_j\) possible item responses/scores, the model defines the probability for responding with a score of \(x\) as follows:

\[\begin{split}P(X_j=x | \mathbf{\theta}) = \begin{cases} \dfrac{1} {1+\sum_{g=1}^{M_i}\exp \left(d_{jg}+\sum_{m=1}^g\delta_{jm}(\mathbf{\theta})\right)}, & \text{if } x = 0\\ \dfrac{\exp \left(d_{jx}+\sum_{m=1}^x\delta_{jm}(\mathbf{\theta})\right)} {1+\sum_{g=1}^{M_i}\exp \left(d_{jg}+\sum_{m=1}^g\delta_{jm}(\mathbf{\theta})\right)}, & \text{otherwise} \end{cases}\end{split}\]

where:

  • \(\mathbf{\theta}\) is a vector of latent variables.

  • \(\delta_{jm}(\mathbf{\theta})\) is a monotonic B-spline.

  • \(b_{jm}\) is a bias term.

  • Note that when separate=’items’, \(\delta_{jm}(\mathbf{\theta})\) is the same for all response categories for the same item.

Examples

>>> from irtorch.models import MonotoneBSpline
>>> from irtorch.estimation_algorithms import MML
>>> from irtorch.load_dataset import swedish_national_mathematics_1
>>> data = swedish_national_mathematics_1()
>>> model = MonotoneBSpline(data)
>>> model.fit(train_data=data, algorithm=MML())
forward(theta: Tensor) Tensor

Forward pass of the model.

Parameters

theta (torch.Tensor) – 2D tensor with latent variables. Rows are respondents and latent variables are columns.

Returns

output – 3D tensor (respondents, items, item categories).

Return type

torch.Tensor

item_theta_relationship_directions(*args) Tensor

Get the relationship directions between each item and latent variable for a fitted model.

Returns

A 2D tensor with the relationships between the items and latent variables. Items are rows and latent variables are columns.

Return type

torch.Tensor

precompute_basis(theta: Tensor)

Precompute the B-spline basis functions for the given theta values. Primarily used by certain fitting algorithms.

Parameters

theta (torch.Tensor) – A 2D tensor with latent variables. Rows are respondents and latent variables are columns.

probabilities_from_output(output: Tensor) Tensor

Compute item probabilities from the output tensor.

Parameters

output (torch.Tensor) – Output tensor from the forward pass.

Returns

3D torch tensor with dimensions (respondents, items, item categories).

Return type

torch.Tensor

class irtorch.models.MonotoneNN(data: Tensor = None, latent_variables: int = 1, item_categories: list[int] = None, hidden_dim: list[int] = None, mc_correct: list[int] = None, item_theta_relationships: Tensor = None, separate: str = 'categories', negative_latent_variable_item_relationships: bool = True, use_bounded_activation: bool = True)

Bases: BaseIRTModel

Monotone Neural Network IRT model as introduced by Wallmark et al. [18]. The model is a feedforward neural network separate with monotone functions for each item or item category.

If mc_correct is specified, the latent variable effect for the correct item response is a cumulative sum of the effects for the other possible item responses to ensure monotonicity. This model is also referred to as the Monotone Multiple Choice Neural Network (MMCNN) model.

If mc_correct is not specified, the item response categories are treated as ordered, and the latent variable effect for an item response category is the cumulative sum of the effects for the lower categories.

Parameters
  • data (torch.Tensor, optional) – A 2D torch tensor with test data. Used to automatically compute item_categories. Columns are items and rows are respondents. (default is None)

  • latent_variables (int, optional) – Number of latent variables. (default is 1)

  • item_categories (list[int], optional) – Number of categories for each item. One integer for each item. Missing responses excluded. (default is None)

  • hidden_dim (list[int]) – Number of neurons in each hidden layer. For separate=’items’ or separate=’categories’, each element is the number of neurons for each separate item or category. For separate=’none’, each element is the number of neurons for each layer. Needs to be a multiple of 3 is when use_bounded_activation=True and a multiple of 2 when use_bounded_activation=False.

  • mc_correct (list[int], optional) – For multiple choice tests. The correct response category for each item. (Default: None)

  • separate (str, optional) – Whether to fit separate latent variable functions for items or items categories. Can be β€˜items’ or β€˜categories’. Note that β€˜categories’ results in a more flexible model with more parameters. (Default: β€˜categories’)

  • item_theta_relationships (torch.Tensor, optional) – A boolean tensor of shape (items, latent_variables). If specified, the model will have connections between latent dimensions and items where the tensor is True. If left out, all latent variables and items are related (Default: None)

  • negative_latent_variable_item_relationships (bool, optional) – Whether to allow for negative latent variable item relationships. (Default: True)

  • use_bounded_activation (bool, optional) – Whether to use bounded activation functions. (Default: True)

Notes

For an item \(j\) with \(m=0, 1, 2, \ldots, M_j\) possible item responses/scores, the model defines the probability for responding with a score of \(x\) as follows (selecting response option \(x\) for multiple choice items):

\[P(X_j=x | \mathbf{\theta}) = \frac{ \exp(\delta_{jx}(\mathbf{\theta})) }{ \sum_{m=0}^{M_j} \exp(\delta_{jm}(\mathbf{\theta})) },\]

where:

  • \(\mathbf{\theta}\) is a vector of latent variables.

  • When mc_correct is not specified:
    • \(\delta_{jm}(\mathbf{\theta}) = \sum_{c=0}^{m}\text{monotone}_{jc}(\mathbf{\theta}) + b_{jm}\).

  • When mc_correct is specified:
    • \(\delta_{jm}(\mathbf{\theta}) = \text{monotone}_{jm}(\mathbf{\theta}) + b_{jm}\) for all incorrect response options, and \(\delta_{jm}(\mathbf{\theta}) = \sum_{c=0}^{M_j}\text{monotone}_{jc}(\mathbf{\theta}) + b_{jm}\) for the correct response option.

  • \(\text{monotone}_{jm}(\mathbf{\theta})\) is a monotonic neural network with ELU based activation functions as per Runje and Shankaranarayana [12].

  • Note that when separate=’items’, \(\text{monotone}_{jm}(\mathbf{\theta})\) is the same for all categories for the same item.

Examples

>>> from irtorch.models import MonotoneNN
>>> from irtorch.estimation_algorithms import MML
>>> from irtorch.load_dataset import swedish_national_mathematics_1
>>> data = swedish_national_mathematics_1()
>>> model = MonotoneNN(data)
>>> model.fit(train_data=data, algorithm=MML())
forward(theta: Tensor) Tensor

Forward pass of the model. PyTorch requires this method to be implemented in subclasses of nn.Module.

Parameters

theta (torch.Tensor) – Input tensor.

Returns

Output tensor.

Return type

torch.Tensor

item_theta_relationship_directions(*args) Tensor

Get the relationship directions between each item and latent variable for a fitted model.

Returns

A 2D tensor with the relationships between the items and latent variables. Items are rows and latent variables are columns.

Return type

torch.Tensor

probabilities_from_output(output: Tensor) Tensor

Compute item probabilities from the output tensor.

Parameters

output (torch.Tensor) – Output tensor from the forward pass.

Returns

3D torch tensor with dimensions (respondents, items, item categories).

Return type

torch.Tensor

class irtorch.models.MonotonePolynomial(data: torch.Tensor | None = None, latent_variables: int = 1, item_categories: list[int] | None = None, degree: int = 3, item_theta_relationships: torch.Tensor | None = None, separate: str = 'categories', negative_latent_variable_item_relationships: bool = True)

Bases: BaseIRTModel

Monotonic Polynomial IRT model [8] with monotonic polynomials for each item or item response category.

Parameters
  • data (torch.Tensor, optional) – A 2D torch tensor with test data. Used to automatically compute item_categories. Columns are items and rows are respondents. (default is None)

  • latent_variables (int, optional) – Number of latent variables. (default is 1)

  • item_categories (list[int], optional) – Number of categories for each item. One integer for each item. Missing responses excluded. (default is None)

  • degree (int, optional) – The degree of the monotonic polynomials. (default is 3)

  • separate (str, optional) – Whether to fit separate latent variable functions for items or items categories. Can be β€˜items’ or β€˜categories’. Note that β€˜categories’ results in a more flexible model with more parameters. (Default: β€˜categories’)

  • item_theta_relationships (torch.Tensor, optional) – A boolean tensor of shape (items, latent_variables). If specified, the model will have connections between latent dimensions and items where the tensor is True. If left out, all latent variables and items are related (Default: None)

  • negative_latent_variable_item_relationships (bool, optional) – Whether to allow for negative latent variable item relationships. (Default: True)

Examples

>>> from irtorch.models import MonotonePolynomial
>>> from irtorch.estimation_algorithms import MML
>>> from irtorch.load_dataset import swedish_national_mathematics_1
>>> data = swedish_national_mathematics_1()
>>> model = MonotonePolynomial(data)
>>> model.fit(train_data=data, algorithm=MML())
forward(theta: Tensor) Tensor

Forward pass of the model. PyTorch requires this method to be implemented in subclasses of nn.Module.

Parameters

theta (torch.Tensor) – Input tensor.

Returns

Output tensor.

Return type

torch.Tensor

item_theta_relationship_directions(*args) Tensor

Get the relationship directions between each item and latent variable for a fitted model.

Returns

A 2D tensor with the relationships between the items and latent variables. Items are rows and latent variables are columns.

Return type

torch.Tensor

probabilities_from_output(output: Tensor) Tensor

Compute item probabilities from the output tensor.

Parameters

output (torch.Tensor) – Output tensor from the forward pass.

Returns

3D torch tensor with dimensions (respondents, items, item categories).

Return type

torch.Tensor

class irtorch.models.SurprisalSpline(data: Tensor = None, latent_variables: int = 1, item_categories: list[int] = None, item_theta_relationships: Tensor = None, knots: list[float] = None, degree: int = 3)

Bases: BaseIRTModel

Surprisals (negative logarithm of probabilities) are modeled using monotone cubic B-splines, hence the name. Note that this model requires each latent variable to be positively related to all items. Ordered polytomously scored data is supported.

Parameters
  • data (torch.Tensor, optional) – A 2D torch tensor with test data. Used to automatically compute item_categories. Columns are items and rows are respondents. (default is None)

  • latent_variables (int) – Number of latent variables.

  • item_categories (list[int]) – Number of categories for each item. One integer for each item. Missing responses excluded.

  • item_theta_relationships (torch.Tensor, optional) – Boolean tensor of shape (items, latent_variables) specifying which latent variables affect which items. True indicates a relationship exists.

  • knots (list[float], optional) – Positions of the internal knots (bounds excluded) for the B-spline basis functions. If not provided, defaults to [-1.7, -0.7, 0, 0.7, 1.7].

  • degree (int, optional) – Degree of the B-spline polynomials. Defaults to 3 (cubic splines).

Notes

For an item \(j\) with ordered item scores \(x=0, 1, 2, ..., M_j\) the model defines the probability for responding with a score of \(x\) as follows:

\[P(X_j = x | \mathbf{\theta}) = \left(1-\exp[-S_x(\mathbf{\theta})]\right)\prod^{M_j}_{m=x+1}\exp(-S_m(\mathbf{\theta}))\]

where \(\mathbf{\theta}\) is a vector of latent variables and the \(S_x(\mathbf{\theta})\) functions are surprisals (negative logarithms of probabilities) defined as:

\[\begin{split}S_{M_j}(\mathbf{\theta}) & = -\log P(X_j < M_j | \mathbf{\theta}) \\ S_{M_j-1}(\mathbf{\theta}) & = -\log P(X_j < M_j-1 | X_j < M_j, \mathbf{\theta}) \\ S_{M_j-2}(\mathbf{\theta}) & = -\log P(X_j < M_j-2 | X_j-1 < M_j, \mathbf{\theta}) \\ ... \\ S_{1}(\mathbf{\theta}) & = -\log P(X_j < 1 | X_j < 2, \mathbf{\theta}) \\ S_{0}(\mathbf{\theta}) & = -\infty\end{split}\]

Monotone B-splines are used to model the surprisal functions after transforming the latent variables to the unit interval using the sigmoid function.

Examples

>>> from irtorch.models import SurprisalSpline
>>> from irtorch.estimation_algorithms import MML
>>> from irtorch.load_dataset import swedish_national_mathematics_1
>>> data = swedish_national_mathematics_1()
>>> model = SurprisalSpline(data)
>>> model.fit(train_data=data, algorithm=MML())
forward(theta: Tensor) Tensor

Forward pass of the model.

Parameters

theta (torch.Tensor) – 2D tensor with latent variables. Rows are respondents and latent variables are columns.

Returns

output – 3D tensor of response probabilities with dimensions (respondents, items, item categories)

Return type

torch.Tensor

log_likelihood(data: Tensor, output: Tensor, missing_mask: Tensor = None, loss_reduction: str = 'sum') Tensor

Compute the log likelihood.

Parameters
  • data (torch.Tensor) – A 2D tensor with test data. Columns are items and rows are respondents

  • output (torch.Tensor) – A 2D tensor with output. Columns are item response categories and rows are respondents

  • missing_mask (torch.Tensor, optional) – A 2D tensor with missing data mask. (default is None)

  • loss_reduction (str, optional) – The reduction argument. (default is β€˜sum’)

Returns

The log likelihood.

Return type

torch.Tensor

precompute_basis(theta: Tensor)

Precompute the B-spline basis functions for the given theta values. Primarily used by certain fitting algorithms.

Parameters

theta (torch.Tensor) – A 2D tensor with latent variables. Rows are respondents and latent variables are columns.

probabilities_from_output(output: Tensor) Tensor

Probabilities forwarded from the output tensor from the forward method. For this model, the output is already the probabilities and the method exists for compatibility and consistency between models.

Parameters

output (torch.Tensor) – Output tensor from the forward pass.

Returns

3D tensor with dimensions (respondents, items, item categories)

Return type

torch.Tensor

class irtorch.models.ModelMix(models: list[irtorch.models.base_irt_model.BaseIRTModel])

Bases: BaseIRTModel

A mix of models tied together by a single set of latent variables. This allows for a mix of different IRT models to be used when items have different types or some items don’t fit a single model. Note that the items in the test data must be ordered in the same way as the models are ordered in the list.

Parameters

models (list[BaseIRTModel]) – A list of IRT models to be mixed together.

Examples

Example of fitting a mix of Generalized Partial Credit (GPC) and Monotone Neural Network (MNN) models to the Swedish National Mathematics 2 dataset. The GPC model is used for the first 14 items and MNN for the last 14 items.

>>> from irtorch.models import GeneralizedPartialCredit, MonotoneNN, ModelMix
>>> from irtorch.estimation_algorithms import MML
>>> from irtorch.load_dataset import swedish_national_mathematics_2
>>> data_math = swedish_national_mathematics_2()
>>> gpc = GeneralizedPartialCredit(data=data_math[:, :14])
>>> mnn = MonotoneNN(data = data_math[:, 14:])
>>> mix_model = ModelMix([gpc, mnn])
>>> mix_model.fit(train_data=data_math, algorithm=MML())
forward(theta: Tensor) Tensor

Forward pass of the model.

Parameters

theta (torch.Tensor) – 2D tensor with latent variables. Rows are respondents and latent variables are columns.

Returns

output – 2D tensor. Rows are respondents and columns are item category logits.

Return type

torch.Tensor

item_probabilities(theta: Tensor) Tensor

Returns the probabilities for each possible response for all items.

Parameters

theta (torch.Tensor) – A 2D tensor. Rows are respondents and latent variables are columns.

Returns

3D tensor with dimensions (respondents, items, item categories)

Return type

torch.Tensor

log_likelihood(data: Tensor, output: Tensor, missing_mask: Tensor = None, loss_reduction: str = 'sum') Tensor

Compute the log likelihood of the data given the model. This is equivalent to the negative cross entropy loss.

Parameters
  • data (torch.Tensor) – A 2D tensor with test data. Columns are items and rows are respondents

  • output (torch.Tensor) – A 2D tensor with output. Columns are item response categories and rows are respondents

  • missing_mask (torch.Tensor, optional) – A 2D tensor with missing data mask. (default is None)

  • loss_reduction (str, optional) – For most models, this is the reduction argument for torch.nn.functional.cross_entropy(). (default is β€˜sum’)

Returns

The log likelihood.

Return type

torch.Tensor

probabilities_from_output(output: Tensor) Tensor

Compute probabilities from the output tensor from the forward method.

Parameters

output (torch.Tensor) – Output tensor from the forward pass.

Returns

3D tensor with dimensions (respondents, items, item categories)

Return type

torch.Tensor