def construct_pos_neg_samples(
            self, labels: List, ent_id2ent: Dict, ent_id2ent_tag: Dict, doc: List, stat_rel: Dict, neg_samples: str,
    ) -> Tuple[List, Dict]:
        """
        Transforms the relevant information into an entry of the DocRED reader output. The entities between which
        the relation is hold will serve as an annotation for positive samples, while all other entity pairs will be
        used to construct the negative samples.

        Args:
            labels: information about relation found in a document (whole labels list of the original DocRED)
            ent_id2ent: a dictionary {entity id: [entity mentions' positions]}
            stat_rel: a dictionary with relation statistics (will be updated)
            neg_samples: amount of negative samples that are to be generated
            ent_id2ent_tag: a dictionary {entity id: entity NER tag}
            doc: list of all tokens of the document
        Returns:
            a tuple with list of all doc tokens, entity information (positions & NER tags) and relation.
        """

        num_pos_samples, num_neg_samples = 0, 0

        data_samples = []
        rel_triples = {}
        for label_info in labels:
            entity1_id, entity2_id = label_info["h"], label_info["t"]
            if (entity1_id, entity2_id) in rel_triples:
                rel_triples[(entity1_id, entity2_id)].append(self.rel2id[label_info['r']])
            else:
                rel_triples[(entity1_id, entity2_id)] = [self.rel2id[label_info['r']]]

        # the one hot encoding of the negative label
        neg_label_one_hot = self.label_to_one_hot([self.rel2id[self.negative_label]])

        # iterate over all entities
        for (ent1, ent2) in itertools.permutations(ent_id2ent, 2):

            # if there is a relation hold between entities, save them (and a corresponding sample) as positive one
            if (ent1, ent2) in rel_triples:
                num_pos_samples += 1
                labels = rel_triples[(ent1, ent2)]
                label_one_hot = self.label_to_one_hot(labels)
                data_samples.append(
                    self.generate_data_sample(doc, ent1, ent2, label_one_hot, ent_id2ent, ent_id2ent_tag)
                )
                self.stat["POS_REL"] += 1

                for label in labels:
                    rel_name = self.relid2rel[self.id2rel[label]]
                    stat_rel[rel_name] += 1

            else:
                if not neg_samples:         # if no negative samples should be generated, skip
                    continue

                # if there is no relation hold between entities, save them (and a corresponding sample) as negative one
                if neg_samples == "equal" and num_neg_samples < num_pos_samples:
                    num_neg_samples += 1
                    data_samples.append(
                        self.generate_data_sample(doc, ent1, ent2, neg_label_one_hot, ent_id2ent, ent_id2ent_tag)
                    )
                    self.stat["NEG_REL"] += 1

                elif neg_samples == "twice" and num_neg_samples < 2 * num_pos_samples:
                    num_neg_samples += 1
                    data_samples.append(
                        self.generate_data_sample(doc, ent1, ent2, neg_label_one_hot, ent_id2ent, ent_id2ent_tag)
                    )
                    self.stat["NEG_REL"] += 1

                elif neg_samples == "thrice" and num_neg_samples < 3 * num_pos_samples:
                    num_neg_samples += 1
                    data_samples.append(
                        self.generate_data_sample(doc, ent1, ent2, neg_label_one_hot, ent_id2ent, ent_id2ent_tag)
                    )
                    self.stat["NEG_REL"] += 1

        return data_samples, stat_rel

        Transforms the relevant information into an entry of the DocRED reader output. The entities between which
        the relation is hold will serve as an annotation for positive samples, while all other entity pairs will be
        used to construct the negative samples.

        Args:
            labels: information about relation found in a document (whole labels list of the original DocRED)
            ent_id2ent: a dictionary {entity id: [entity mentions' positions]}
            stat_rel: a dictionary with relation statistics (will be updated)
            neg_samples: amount of negative samples that are to be generated
            ent_id2ent_tag: a dictionary {entity id: entity NER tag}
            doc: list of all tokens of the document
        Returns:
            a tuple with list of all doc tokens, entity information (positions & NER tags) and relation.
        
deeppavlov/dataset_readers/docred_reader.py