code: def marginal_score(
      entity_relation_batch: torch.LongTensor,
      per_entity: Optional[scipy.sparse.csr_matrix],
      per_relation: Optional[scipy.sparse.csr_matrix],
      num_entities: int,
  ) -> torch.FloatTensor:
      """Shared code for computing entity scores from marginals."""
      batch_size = entity_relation_batch.shape[0]
  
      # base case
      if per_entity is None and per_relation is None:
          return torch.full(
              size=(batch_size, num_entities),
              fill_value=1 / num_entities,
          )
  
      e, r = entity_relation_batch.cpu().numpy().T
  
      if per_relation is not None and per_entity is None:
          scores = per_relation[r]
      elif per_relation is None and per_entity is not None:
          scores = per_entity[e]
      elif per_relation is not None and per_entity is not None:
          e_score = per_entity[e]
          r_score = per_relation[r]
          scores = e_score.multiply(r_score)
          scores = sklearn_normalize(scores, norm="l1", axis=1)
      else:
          raise AssertionError  # for mypy
  
      # note: we need to work with dense arrays only to comply with returning torch tensors. Otherwise, we could
      # stay sparse here, with a potential of a huge memory benefit on large datasets!
      return torch.from_numpy(scores.todense())
  
file_path: pykeen/src/pykeen/models/baseline/utils.py
imports: from typing import Optional, Tuple
  import numpy
  import scipy.sparse
  import torch
  from sklearn.preprocessing import normalize
  from ...triples import CoreTriplesFactory
  from ...triples.leakage import jaccard_similarity_scipy, triples_factory_to_sparse_matrices
label_desc: Use image node_id 2 for calling a global function with example usage: marginal_score(entity_relation_batch, per_entity, per_relation, num_entities) and returns: torch, torch