# Buggy code
def __init__(
    self,
    triples_factory: TriplesFactory,
    minimum_frequency: Optional[float] = None,
    symmetric: bool = True,
    use_tqdm: bool = True,
    use_multiprocessing: bool = False,
):
    """Index the inverse frequencies and the inverse relations in the triples factory.

    :param triples_factory: The triples factory to index.
    :param minimum_frequency: The minimum overlap between two relations' triples to consider them as inverses. The
     default value, 0.97, is taken from `Toutanova and Chen (2015) <https://www.aclweb.org/anthology/W15-4007/>`_,
     who originally described the generation of FB15k-237.
    """
    self.triples_factory = triples_factory
    if minimum_frequency is None:
        minimum_frequency = 0.97
    self.minimum_frequency = minimum_frequency

    if use_multiprocessing:
        use_tqdm = False

    self.candidate_duplicate_relations = get_candidate_duplicate_relations(
        triples_factory=self.triples_factory,
        minimum_frequency=self.minimum_frequency,
        symmetric=symmetric,
        use_tqdm=use_tqdm,
        use_multiprocessing=use_multiprocessing,
    )
    logger.info(
        f"identified {len(self.candidate_duplicate_relations)} candidate duplicate relationships"
        f" at similarity > {self.minimum_frequency} in {self.triples_factory}.",
    )
    self.duplicate_relations_to_delete = {
        r for r, _ in self.candidate_duplicate_relations
    }

    self.candidate_inverse_relations = get_candidate_inverse_relations(
        triples_factory=self.triples_factory,
        minimum_frequency=self.minimum_frequency,
        symmetric=symmetric,
        use_tqdm=use_tqdm,
        use_multiprocessing=use_multiprocessing,
    )
    logger.info(
        f"identified {len(self.candidate_inverse_relations)} candidate inverse pairs"
        f" at similarity > {self.minimum_frequency} in {self.triples_factory}",
    )

    if symmetric:
        self.inverses = dict(
            tuple(sorted(k)) for k in self.candidate_inverse_relations.keys()
        )
        self.inverse_relations_to_delete = set(self.inverses.values())
    else:
        self.mutual_inverse = set()
        self.not_mutual_inverse = set()
        for r1, r2 in self.candidate_inverse_relations:
            if (r2, r1) in self.candidate_inverse_relations:
                self.mutual_inverse.add((r1, r2))
            else:
                self.not_mutual_inverse.add((r1, r2))
        logger.info(
            f"{len(self.mutual_inverse)} are mutual inverse ({len(self.mutual_inverse) // 2}"
            f" relations) and {len(self.not_mutual_inverse)} non-mutual inverse.",
        )

        # basically take all candidates
        self.inverses = dict(self.candidate_inverse_relations.keys())
        self.inverse_relations_to_delete = prioritize_mapping(
            self.candidate_inverse_relations
        )

    logger.info(
        f"identified {len(self.inverse_relations_to_delete)} from {self.triples_factory} to delete"
    )


# Traceback (KeyError)
Traceback (most recent call last):
File "/Users/cthoyt/dev/pykeen/scratch/tst.py", line 49, in <module>
main()
File "/Users/cthoyt/dev/pykeen/scratch/tst.py", line 36, in main
testing.new_with_restriction(relations=evaluation_relation_whitelist)
File "/Users/cthoyt/dev/pykeen/src/pykeen/triples/triples_factory.py", line 641, in new_with_restriction
relations = list(relations) + list(map(self.relation_to_inverse.__getitem__, relations))
KeyError: 'accusation_inverse'

# Fixed code
def __init__(
    self,
    triples_factory: TriplesFactory,
    minimum_frequency: Optional[float] = None,
    symmetric: bool = True,
):
    """Index the inverse frequencies and the inverse relations in the triples factory.

    :param triples_factory: The triples factory to index.
    :param minimum_frequency: The minimum overlap between two relations' triples to consider them as inverses. The
     default value, 0.97, is taken from `Toutanova and Chen (2015) <https://www.aclweb.org/anthology/W15-4007/>`_,
     who originally described the generation of FB15k-237.
    """
    self.triples_factory = triples_factory
    if minimum_frequency is None:
        minimum_frequency = 0.97
    self.minimum_frequency = minimum_frequency

    # compute similarities
    if symmetric:
        rel, inv = triples_factory_to_sparse_matrices(triples_factory=triples_factory)
        self.candidate_duplicate_relations = get_candidate_pairs(
            a=rel, threshold=self.minimum_frequency
        )
        self.candidate_inverse_relations = get_candidate_pairs(
            a=rel, b=inv, threshold=self.minimum_frequency
        )
    else:
        raise NotImplementedError
    logger.info(
        f"identified {len(self.candidate_duplicate_relations)} candidate duplicate relationships"
        f" at similarity > {self.minimum_frequency} in {self.triples_factory}.",
    )
    logger.info(
        f"identified {len(self.candidate_inverse_relations)} candidate inverse pairs"
        f" at similarity > {self.minimum_frequency} in {self.triples_factory}",
    )
    self.candidates = set(self.candidate_duplicate_relations).union(
        self.candidate_inverse_relations
    )
    sizes = dict(zip(*triples_factory.mapped_triples[:, 1].unique(return_counts=True)))
    self.relations_to_delete = _select_by_most_pairs(
        components=_get_connected_components(
            pairs=((a, b) for (s, a, b) in self.candidates if (a != b))
        ),
        size=sizes,
    )
    logger.info(
        f"identified {len(self.candidates)} from {self.triples_factory} to delete"
    )