Repository: pykeen/pykeen
Issue: Embeddings for unseen nodes

Hi

I recently trained an InductiveNodePieceGNN model and now want to generate embeddings for unseen nodes. To do this, I added a few new triples to the existing data and used the code below to retrieve the embeddings. Could you kindly confirm if this approach is correct, or if there’s anything I might be overlooking? Your feedback would be greatly appreciated.

```python
import torch

from pykeen.triples.triples_factory import TriplesFactory

model = torch.load("trained_model_final.pkl", map_location=torch.device("cpu"))
triples_test = TriplesFactory.from_labeled_triples(data.values, create_inverse_triples=True)
entity_ids = torch.as_tensor(triples_test.entities_to_ids(["5378239", "5493276"]))
model.create_entity_representation_for_new_triples(triples_test)(indices=entity_ids).detach().numpy()
```

Hi @febsonthomas ,

(I reduced you code example a bit by removing some imports you did not use in the snippet).

Your code snippet looks mostly correct, but you need to make sure that the relation IDs in this new triples factory are the same as the ones you used to train the model, otherwise the IDs may not match.

To achieve this, you can simply pass the `relation_to_id` from your training triples factory to 
```python
triples_test = TriplesFactory.from_labeled_triples(
    data.values,
    create_inverse_triples=True,
    relation_to_id=training.relation_to_id,  # <- this is new
)
```


Hi @mberr,

Thank you for your prompt response! This was very helpful. 

1. Could you also confirm if using relation_to_id alone would suffice, or should I include entity_to_id as well? After training, the new dataset will contain both the previously trained triples and new ones.
2. Does hpo pipeline supports InductiveNodePieceGNN model?
3. Can you confirm the difference in both the functions:
     3.1  **loaded_model.entity_representations(indices=entity_ids)**  : to get the embeddings of the nodes used for training?
     3.2  **loaded_model.create_entity_representation_for_new_triples(triples_test)(indices=entity_ids).detach().numpy()** : to get the embeddings for unseen nodes.






> Could you also confirm if using relation_to_id alone would suffice, or should I include entity_to_id as well? After training, the new dataset will contain both the previously trained triples and new ones.

`relation_to_id` should suffice. You need that one to be the same such that the relation tokenizer uses the correct ids. Since the model is inductive, it does not make use of entity IDs.

> Does hpo pipeline supports InductiveNodePieceGNN model?

I am not 100% sure, but I think it might support it, as it uses `pipeline` under the hood, and `pipeline` *should* support inductive models, too.

If it does not, it might be relatively straight forward to set up your own HPO script, e.g., using [optuna](https://optuna.org/) like we do in our `hpo_pipeline`, and adjust the trial evaluation to call you existing training script.

> Can you confirm the difference in both the functions:
3.1 loaded_model.entity_representations(indices=entity_ids) : to get the embeddings of the nodes used for training?
3.2 loaded_model.create_entity_representation_for_new_triples(triples_test)(indices=entity_ids).detach().numpy() : to get the embeddings for unseen nodes.

That depends on your choice of `entity_ids`. They are not necessarily aligned between the two entity representations. The fact that the may differ is the key distinction of inductive representations compared to transductive ones. If you create the triples factories from labeled triples, you can use the respective `TriplesFactory`s `entity_to_id` to get a mapping from (string) entity identifiers to the respective numeric ids, and match the shared entities via their string entity identifier.

Hi @mberr , I want to restrict the relation while evaluating the model. I tried using OGBEvaluator(), but I get 

```
ValueError: <pykeen.evaluation.ogb_evaluator.OGBEvaluator object at 0x7f28950b5630> does not support any of {restrict_relations_to, restrict_entities_to, additional_filter_triples, do_time_consuming_checks, pre_filtered_triples}
```

Any thoughts on this?

Hi @mberr , looks like there is a bug with inductive link prediction. After training the model, I look for number of unique embeddings and I get a number, lets say 27843. When I rerun the same code the second time it throws 48. Any idea why this could happen?