FranKGraphBench 0.0.1a0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. FranKGraphBench-0.0.1a0.dist-info/LICENSE +201 -0
  2. FranKGraphBench-0.0.1a0.dist-info/METADATA +189 -0
  3. FranKGraphBench-0.0.1a0.dist-info/RECORD +70 -0
  4. FranKGraphBench-0.0.1a0.dist-info/WHEEL +6 -0
  5. FranKGraphBench-0.0.1a0.dist-info/entry_points.txt +3 -0
  6. FranKGraphBench-0.0.1a0.dist-info/top_level.txt +2 -0
  7. data_integration/__init__.py +47 -0
  8. data_integration/__main__.py +4 -0
  9. data_integration/dataset.py +270 -0
  10. data_integration/dataset2class.py +34 -0
  11. data_integration/datasets/__init__.py +0 -0
  12. data_integration/datasets/amazon.py +140 -0
  13. data_integration/datasets/book-crossing.py +98 -0
  14. data_integration/datasets/douban-movie.py +75 -0
  15. data_integration/datasets/lastfm.py +215 -0
  16. data_integration/datasets/movielens.py +375 -0
  17. data_integration/datasets/steam.py +98 -0
  18. data_integration/datasets/worker.py +31 -0
  19. data_integration/datasets/yelp.py +156 -0
  20. framework/__init__.py +17 -0
  21. framework/__main__.py +4 -0
  22. framework/dataloader/__init__.py +0 -0
  23. framework/dataloader/dataloader.py +52 -0
  24. framework/dataloader/dataset/__init__.py +0 -0
  25. framework/dataloader/dataset/dataset.py +38 -0
  26. framework/dataloader/edge_splitter/__init__.py +0 -0
  27. framework/dataloader/edge_splitter/edge_splitter.py +163 -0
  28. framework/dataloader/graph/__init__.py +0 -0
  29. framework/dataloader/graph/graph.py +314 -0
  30. framework/dataloader/graph/node.py +80 -0
  31. framework/dataloader/preprocess/__init__.py +0 -0
  32. framework/dataloader/preprocess/methods.py +47 -0
  33. framework/evaluator/__init__.py +0 -0
  34. framework/evaluator/metric.py +39 -0
  35. framework/evaluator/metric2class.py +10 -0
  36. framework/evaluator/metrics/__init__.py +0 -0
  37. framework/evaluator/metrics/map.py +33 -0
  38. framework/evaluator/metrics/ndcg.py +49 -0
  39. framework/experiment.py +120 -0
  40. framework/recommender/__init__.py +0 -0
  41. framework/recommender/model2class.py +46 -0
  42. framework/recommender/models/__init__.py +0 -0
  43. framework/recommender/models/complEx/__init__.py +0 -0
  44. framework/recommender/models/complEx/model.py +193 -0
  45. framework/recommender/models/deep_walk_based/__init__.py +0 -0
  46. framework/recommender/models/deep_walk_based/model.py +149 -0
  47. framework/recommender/models/distMult/__init__.py +0 -0
  48. framework/recommender/models/distMult/model.py +187 -0
  49. framework/recommender/models/ePHEN/__init__.py +0 -0
  50. framework/recommender/models/ePHEN/model.py +159 -0
  51. framework/recommender/models/rESCAL/__init__.py +0 -0
  52. framework/recommender/models/rESCAL/model.py +184 -0
  53. framework/recommender/models/rotatE/__init__.py +0 -0
  54. framework/recommender/models/rotatE/model.py +195 -0
  55. framework/recommender/models/transD/__init__.py +0 -0
  56. framework/recommender/models/transD/model.py +190 -0
  57. framework/recommender/models/transE/__init__.py +0 -0
  58. framework/recommender/models/transE/model.py +194 -0
  59. framework/recommender/models/transH/__init__.py +0 -0
  60. framework/recommender/models/transH/model.py +193 -0
  61. framework/recommender/models/transR/__init__.py +0 -0
  62. framework/recommender/models/transR/model.py +190 -0
  63. framework/recommender/models/tuckER/__init__.py +0 -0
  64. framework/recommender/models/tuckER/model.py +199 -0
  65. framework/recommender/recommender.py +32 -0
  66. framework/recommender/utils/__init__.py +0 -0
  67. framework/recommender/utils/walker.py +185 -0
  68. framework/reporter/__init__.py +0 -0
  69. framework/reporter/report.py +101 -0
  70. framework/utils.py +10 -0
@@ -0,0 +1,195 @@
1
+ from framework.dataloader.graph.node import UserNode, ItemNode
2
+ from ...recommender import Recommender
3
+
4
+ from pykeen.pipeline import pipeline
5
+ from pykeen.triples import TriplesFactory
6
+ from pykeen.datasets import Dataset
7
+ from sklearn.neighbors import NearestNeighbors
8
+
9
+
10
+ import numpy as np
11
+ import torch
12
+ import typing as t
13
+
14
+ """
15
+ Recommender base class
16
+ """
17
+
18
+
19
+ class RotatE(Recommender):
20
+ def __init__(
21
+ self,
22
+ config: dict,
23
+ embedding_dim: int = 200,
24
+ entity_initializer=None,
25
+ relation_initializer=None,
26
+ relation_constrainer=None,
27
+ regularizer=None,
28
+ regularizer_kwargs=None,
29
+ epochs: int = 5,
30
+ seed: int = 42,
31
+ evaluation_fallback: bool = True,
32
+ all_recs: bool = False,
33
+ triples: str = "all",
34
+ ):
35
+ super().__init__(config)
36
+ self.embedding_dim = embedding_dim
37
+ self.entity_initializer = entity_initializer
38
+ self.relation_initializer = relation_initializer
39
+ self.relation_constrainer = relation_constrainer
40
+ self.regularizer = regularizer
41
+ self.regularizer_kwargs = regularizer_kwargs
42
+ self.epochs = epochs
43
+ self.seed = seed
44
+ self.evaluation_fallback = evaluation_fallback
45
+ self.all_recs = all_recs
46
+ self.triples = triples
47
+ self._triples = None
48
+ self._embedding = {}
49
+
50
+ def name(self):
51
+ text = "RotatE based model + cosine similarity"
52
+ text += f";embedding_dim={self.embedding_dim};entity_initializer={self.entity_initializer};relation_initializer={self.relation_initializer};relation_constrainer={self.relation_constrainer};regularizer={self.regularizer};epochs={self.epochs};seed={self.seed};triples={self.triples}"
53
+ return text
54
+
55
+ def train(self, G_train, ratings_train):
56
+ self.G_train = G_train
57
+ if self.triples == "all":
58
+ self._triples = G_train.get_all_triples()
59
+ elif self.triples == "ratings":
60
+ self._triples = G_train.get_ratings_triples()
61
+ self.fit()
62
+
63
+ def get_recommendations(self, k: int = 5) -> t.Dict[UserNode, t.List[ItemNode]]:
64
+ """
65
+ :param k: cutoff recommendation (int)
66
+ :return dict of recommendations for each user
67
+ of type {user1: [item1, item2]}
68
+ """
69
+ users = list(self.G_train.get_user_nodes())
70
+ items = list(self.G_train.get_item_nodes())
71
+
72
+ users_embeddings = np.array([self._embedding[user] for user in users])
73
+ items_embeddings = np.array([self._embedding[item] for item in items])
74
+
75
+ n_neighbors = self._get_n_neighbors(users, items, k)
76
+ knn = NearestNeighbors(n_neighbors=n_neighbors, metric="cosine")
77
+ knn.fit(items_embeddings)
78
+ rec_indices = knn.kneighbors(users_embeddings, return_distance=False)
79
+
80
+ recommendations = {}
81
+ for user_idx, user in enumerate(users):
82
+ rated_items = self.G_train.get_user_rated_items(user)
83
+ recs = []
84
+ for item_idx in rec_indices[user_idx]:
85
+ item = items[item_idx]
86
+ if item not in rated_items:
87
+ recs.append(item)
88
+ if not self.all_recs and len(recs) == k:
89
+ break
90
+
91
+ recommendations[user] = recs
92
+
93
+ return recommendations
94
+
95
+ def get_user_recommendation(self, user: UserNode, k: int = 5):
96
+ raise NotImplementedError(
97
+ "Override get_user_recommendation() for your model subclass."
98
+ )
99
+
100
+ def fit(self):
101
+ triples = TriplesFactory.from_labeled_triples(
102
+ self._triples[["head", "relation", "tail"]].values,
103
+ create_inverse_triples=False,
104
+ entity_to_id=None,
105
+ relation_to_id=None,
106
+ compact_id=False,
107
+ filter_out_candidate_inverse_relations=True,
108
+ metadata=None,
109
+ )
110
+
111
+ dataset = Dataset.from_tf(triples, ratios=[0.95, 0.05, 0.0])
112
+ entity_to_id = dataset.entity_to_id
113
+
114
+ result = pipeline(
115
+ dataset=dataset,
116
+ model="RotatE",
117
+ model_kwargs=dict(
118
+ embedding_dim=self.embedding_dim,
119
+ entity_initializer=self.entity_initializer,
120
+ relation_initializer=self.relation_initializer,
121
+ relation_constrainer=self.relation_constrainer,
122
+ regularizer=self.regularizer,
123
+ regularizer_kwargs=self.regularizer_kwargs,
124
+ ),
125
+ epochs = self.epochs,
126
+ random_seed = self.seed,
127
+ evaluation_fallback = self.evaluation_fallback,
128
+ )
129
+ model = result.model
130
+
131
+ users_iter = self.G_train.get_user_nodes()
132
+ items_iter = self.G_train.get_item_nodes()
133
+
134
+ users = list(users_iter)
135
+ items = list(items_iter)
136
+
137
+ # deal with entities that might have not been embedded
138
+ users_indices, users_no_embedding = [], []
139
+ for user in users_iter:
140
+ try:
141
+ users_indices.append(entity_to_id[user.__str__()])
142
+ except:
143
+ users_no_embedding.append(user)
144
+ users.remove(user)
145
+ continue
146
+ users_indices = torch.LongTensor(users_indices)
147
+
148
+ items_indices, items_no_embedding = [], []
149
+ for item in items_iter:
150
+ try:
151
+ items_indices.append(entity_to_id[item.__str__()])
152
+ except:
153
+ items_no_embedding.append(item)
154
+ items.remove(item)
155
+ continue
156
+ items_indices = torch.LongTensor(items_indices)
157
+
158
+ users_embeddings = (model.entity_representations[0](indices=users_indices).detach().cpu().numpy())
159
+ items_embeddings = (model.entity_representations[0](indices=items_indices).detach().cpu().numpy())
160
+
161
+ concat_users_embeddings, concat_items_embeddings = np.zeros((len(users_embeddings), self.embedding_dim*2)), np.zeros((len(items_embeddings), self.embedding_dim*2))
162
+
163
+ # complex data not supported by sklearn
164
+ for index, ue in enumerate(users_embeddings):
165
+ concat_users_embeddings[index] = np.concatenate((np.real(ue), np.imag(ue)))
166
+ for index, ie in enumerate(items_embeddings):
167
+ concat_items_embeddings[index] = np.concatenate((np.real(ie), np.imag(ie)))
168
+
169
+ if len(users_no_embedding) > 0:
170
+ concat_users_embeddings = np.concatenate((concat_users_embeddings, np.zeros((len(users_no_embedding), self.embedding_dim*2), dtype=concat_users_embeddings.dtype)), axis=0)
171
+ users = users + users_no_embedding
172
+
173
+ if len(items_no_embedding) > 0:
174
+ concat_items_embeddings = np.concatenate((concat_items_embeddings, np.zeros((len(items_no_embedding), self.embedding_dim*2), dtype=concat_items_embeddings.dtype)), axis=0)
175
+ items = items + items_no_embedding
176
+
177
+ for index, user in enumerate(users):
178
+ self._embedding[user] = concat_users_embeddings[index]
179
+
180
+ for index, item in enumerate(items):
181
+ self._embedding[item] = concat_items_embeddings[index]
182
+
183
+ def _get_n_neighbors(self, users, items, top_k):
184
+ n_neighbors = 0
185
+ if self.all_recs:
186
+ n_neighbors = len(items)
187
+ else:
188
+ max_recs = 0
189
+ for user in users:
190
+ rated_items = self.G_train.get_user_rated_items(user)
191
+ if len(rated_items) > max_recs:
192
+ max_recs = len(rated_items)
193
+ n_neighbors = min(max_recs + top_k, len(items))
194
+
195
+ return n_neighbors
File without changes
@@ -0,0 +1,190 @@
1
+ from framework.dataloader.graph.node import UserNode, ItemNode
2
+ from ...recommender import Recommender
3
+
4
+ from pykeen.pipeline import pipeline
5
+ from pykeen.triples import TriplesFactory
6
+ from pykeen.datasets import Dataset
7
+ from sklearn.neighbors import NearestNeighbors
8
+
9
+
10
+ import numpy as np
11
+ import torch
12
+ import typing as t
13
+
14
+ """
15
+ Recommender base class
16
+ """
17
+
18
+
19
+ class TransD(Recommender):
20
+ def __init__(
21
+ self,
22
+ config: dict,
23
+ embedding_dim: int = 50,
24
+ relation_dim = None,
25
+ interaction_kwargs = None,
26
+ entity_initializer=None,
27
+ entity_constrainer=None,
28
+ relation_initializer=None,
29
+ relation_constrainer=None,
30
+ epochs: int = 5,
31
+ seed: int = 42,
32
+ evaluation_fallback: bool = True,
33
+ all_recs: bool = False,
34
+ triples: str = "all",
35
+ ):
36
+ super().__init__(config)
37
+ self.embedding_dim = embedding_dim
38
+ self.relation_dim = relation_dim
39
+ self.interaction_kwargs = interaction_kwargs
40
+ self.entity_initializer = entity_initializer
41
+ self.entity_constrainer = entity_constrainer
42
+ self.relation_initializer = relation_initializer
43
+ self.relation_constrainer = relation_constrainer
44
+ self.epochs = epochs
45
+ self.seed = seed
46
+ self.evaluation_fallback = evaluation_fallback
47
+ self.all_recs = all_recs
48
+ self.triples = triples
49
+ self._triples = None
50
+ self._embedding = {}
51
+
52
+ def name(self):
53
+ text = "TransD based model + cosine similarity"
54
+ text += f";embedding_dim={self.embedding_dim};relation_dim={self.relation_dim};entity_initializer={self.entity_initializer};entity_constrainer={self.entity_constrainer};relation_initializer={self.relation_initializer};relation_constrainer={self.relation_constrainer};epochs={self.epochs};seed={self.seed};triples={self.triples}"
55
+ return text
56
+
57
+ def train(self, G_train, ratings_train):
58
+ self.G_train = G_train
59
+ if self.triples == "all":
60
+ self._triples = G_train.get_all_triples()
61
+ elif self.triples == "ratings":
62
+ self._triples = G_train.get_ratings_triples()
63
+ self.fit()
64
+
65
+ def get_recommendations(self, k: int = 5) -> t.Dict[UserNode, t.List[ItemNode]]:
66
+ """
67
+ :param k: cutoff recommendation (int)
68
+ :return dict of recommendations for each user
69
+ of type {user1: [item1, item2]}
70
+ """
71
+ users = list(self.G_train.get_user_nodes())
72
+ items = list(self.G_train.get_item_nodes())
73
+
74
+ users_embeddings = np.array([self._embedding[user] for user in users])
75
+ items_embeddings = np.array([self._embedding[item] for item in items])
76
+
77
+ n_neighbors = self._get_n_neighbors(users, items, k)
78
+ knn = NearestNeighbors(n_neighbors=n_neighbors, metric="cosine")
79
+ knn.fit(items_embeddings)
80
+ rec_indices = knn.kneighbors(users_embeddings, return_distance=False)
81
+
82
+ recommendations = {}
83
+ for user_idx, user in enumerate(users):
84
+ rated_items = self.G_train.get_user_rated_items(user)
85
+ recs = []
86
+ for item_idx in rec_indices[user_idx]:
87
+ item = items[item_idx]
88
+ if item not in rated_items:
89
+ recs.append(item)
90
+ if not self.all_recs and len(recs) == k:
91
+ break
92
+
93
+ recommendations[user] = recs
94
+
95
+ return recommendations
96
+
97
+ def get_user_recommendation(self, user: UserNode, k: int = 5):
98
+ raise NotImplementedError(
99
+ "Override get_user_recommendation() for your model subclass."
100
+ )
101
+
102
+ def fit(self):
103
+ triples = TriplesFactory.from_labeled_triples(
104
+ self._triples[["head", "relation", "tail"]].values,
105
+ create_inverse_triples=False,
106
+ entity_to_id=None,
107
+ relation_to_id=None,
108
+ compact_id=False,
109
+ filter_out_candidate_inverse_relations=True,
110
+ metadata=None,
111
+ )
112
+
113
+ dataset = Dataset.from_tf(triples, ratios=[0.95, 0.05, 0.0])
114
+ entity_to_id = dataset.entity_to_id
115
+
116
+ result = pipeline(
117
+ dataset=dataset,
118
+ model="TransD",
119
+ model_kwargs=dict(
120
+ embedding_dim=self.embedding_dim,
121
+ relation_dim=self.relation_dim,
122
+ interaction_kwargs=self.interaction_kwargs,
123
+ entity_initializer=self.entity_initializer,
124
+ entity_constrainer=self.entity_constrainer,
125
+ relation_initializer=self.relation_initializer,
126
+ relation_constrainer=self.relation_constrainer,
127
+ ),
128
+ epochs = self.epochs,
129
+ random_seed = self.seed,
130
+ evaluation_fallback = self.evaluation_fallback,
131
+ )
132
+ model = result.model
133
+
134
+ users_iter = self.G_train.get_user_nodes()
135
+ items_iter = self.G_train.get_item_nodes()
136
+
137
+ users = list(users_iter)
138
+ items = list(items_iter)
139
+
140
+ # deal with entities that might have not been embedded
141
+ users_indices, users_no_embedding = [], []
142
+ for user in users_iter:
143
+ try:
144
+ users_indices.append(entity_to_id[user.__str__()])
145
+ except:
146
+ users_no_embedding.append(user)
147
+ users.remove(user)
148
+ continue
149
+ users_indices = torch.LongTensor(users_indices)
150
+
151
+ items_indices, items_no_embedding = [], []
152
+ for item in items_iter:
153
+ try:
154
+ items_indices.append(entity_to_id[item.__str__()])
155
+ except:
156
+ items_no_embedding.append(item)
157
+ items.remove(item)
158
+ continue
159
+ items_indices = torch.LongTensor(items_indices)
160
+
161
+ users_embeddings = (model.entity_representations[0](indices=users_indices).detach().cpu().numpy())
162
+ items_embeddings = (model.entity_representations[0](indices=items_indices).detach().cpu().numpy())
163
+
164
+ if len(users_no_embedding) > 0:
165
+ users_embeddings = np.concatenate((users_embeddings, np.zeros((len(users_no_embedding), self.embedding_dim), dtype=users_embeddings.dtype)), axis=0)
166
+ users = users + users_no_embedding
167
+
168
+ if len(items_no_embedding) > 0:
169
+ items_embeddings = np.concatenate((items_embeddings, np.zeros((len(items_no_embedding), self.embedding_dim), dtype=items_embeddings.dtype)), axis=0)
170
+ items = items + items_no_embedding
171
+
172
+ for index, user in enumerate(users):
173
+ self._embedding[user] = users_embeddings[index]
174
+
175
+ for index, item in enumerate(items):
176
+ self._embedding[item] = items_embeddings[index]
177
+
178
+ def _get_n_neighbors(self, users, items, top_k):
179
+ n_neighbors = 0
180
+ if self.all_recs:
181
+ n_neighbors = len(items)
182
+ else:
183
+ max_recs = 0
184
+ for user in users:
185
+ rated_items = self.G_train.get_user_rated_items(user)
186
+ if len(rated_items) > max_recs:
187
+ max_recs = len(rated_items)
188
+ n_neighbors = min(max_recs + top_k, len(items))
189
+
190
+ return n_neighbors
File without changes
@@ -0,0 +1,194 @@
1
+ from framework.dataloader.graph.node import UserNode, ItemNode
2
+ from ...recommender import Recommender
3
+
4
+ from pykeen.pipeline import pipeline
5
+ from pykeen.triples import TriplesFactory
6
+ from pykeen.datasets import Dataset
7
+ from sklearn.neighbors import NearestNeighbors
8
+
9
+
10
+ import numpy as np
11
+ import torch
12
+ import typing as t
13
+
14
+ """
15
+ Recommender base class
16
+ """
17
+
18
+
19
+ class TransE(Recommender):
20
+ def __init__(
21
+ self,
22
+ config: dict,
23
+ embedding_dim: int = 50,
24
+ scoring_fct_norm: int = 1,
25
+ entity_initializer=None,
26
+ entity_constrainer=None,
27
+ relation_initializer=None,
28
+ relation_constrainer=None,
29
+ regularizer=None,
30
+ regularizer_kwargs=None,
31
+ epochs: int = 5,
32
+ seed: int = 42,
33
+ evaluation_fallback: bool = True,
34
+ all_recs: bool = False,
35
+ triples: str = "all",
36
+ ):
37
+ super().__init__(config)
38
+ self.embedding_dim = embedding_dim
39
+ self.scoring_fct_norm = scoring_fct_norm
40
+ self.entity_initializer = entity_initializer
41
+ self.entity_constrainer = entity_constrainer
42
+ self.relation_initializer = relation_initializer
43
+ self.relation_constrainer = relation_constrainer
44
+ self.regularizer = regularizer
45
+ self.regularizer_kwargs = regularizer_kwargs
46
+ self.epochs = epochs
47
+ self.seed = seed
48
+ self.evaluation_fallback = evaluation_fallback
49
+ self.all_recs = all_recs
50
+ self.triples = triples
51
+ self._triples = None
52
+ self._embedding = {}
53
+
54
+ def name(self):
55
+ text = "TransE based model + cosine similarity"
56
+ text += f";embedding_dim={self.embedding_dim};scoring_fct_norm={self.scoring_fct_norm};entity_initializer={self.entity_initializer};relation_initializer={self.relation_initializer};relation_constrainer={self.relation_constrainer};regularizer={self.regularizer};epochs={self.epochs};seed={self.seed};triples={self.triples}"
57
+ return text
58
+
59
+ def train(self, G_train, ratings_train):
60
+ self.G_train = G_train
61
+ if self.triples == "all":
62
+ self._triples = G_train.get_all_triples()
63
+ elif self.triples == "ratings":
64
+ self._triples = G_train.get_ratings_triples()
65
+ self.fit()
66
+
67
+ def get_recommendations(self, k: int = 5) -> t.Dict[UserNode, t.List[ItemNode]]:
68
+ """
69
+ :param k: cutoff recommendation (int)
70
+ :return dict of recommendations for each user
71
+ of type {user1: [item1, item2]}
72
+ """
73
+
74
+ users = list(self.G_train.get_user_nodes())
75
+ items = list(self.G_train.get_item_nodes())
76
+
77
+ users_embeddings = np.array([self._embedding[user] for user in users])
78
+ items_embeddings = np.array([self._embedding[item] for item in items])
79
+
80
+ n_neighbors = self._get_n_neighbors(users, items, k)
81
+ knn = NearestNeighbors(n_neighbors=n_neighbors, metric="cosine")
82
+ knn.fit(items_embeddings)
83
+ rec_indices = knn.kneighbors(users_embeddings, return_distance=False)
84
+
85
+ recommendations = {}
86
+ for user_idx, user in enumerate(users):
87
+ rated_items = self.G_train.get_user_rated_items(user)
88
+ recs = []
89
+ for item_idx in rec_indices[user_idx]:
90
+ item = items[item_idx]
91
+ if item not in rated_items:
92
+ recs.append(item)
93
+ if not self.all_recs and len(recs) == k:
94
+ break
95
+
96
+ recommendations[user] = recs
97
+
98
+ return recommendations
99
+
100
+ def get_user_recommendation(self, user: UserNode, k: int = 5):
101
+ raise NotImplementedError(
102
+ "Override get_user_recommendation() for your model subclass."
103
+ )
104
+
105
+ def fit(self):
106
+ triples = TriplesFactory.from_labeled_triples(
107
+ self._triples[["head", "relation", "tail"]].values,
108
+ create_inverse_triples=False,
109
+ entity_to_id=None,
110
+ relation_to_id=None,
111
+ compact_id=False,
112
+ filter_out_candidate_inverse_relations=True,
113
+ metadata=None,
114
+ )
115
+
116
+ dataset = Dataset.from_tf(triples, ratios=[0.95, 0.05, 0.0])
117
+ entity_to_id = dataset.entity_to_id
118
+
119
+ result = pipeline(
120
+ dataset=dataset,
121
+ model="TransE",
122
+ model_kwargs=dict(
123
+ embedding_dim=self.embedding_dim,
124
+ scoring_fct_norm=self.scoring_fct_norm,
125
+ entity_initializer=self.entity_initializer,
126
+ entity_constrainer=self.entity_constrainer,
127
+ relation_initializer=self.relation_initializer,
128
+ relation_constrainer=self.relation_constrainer,
129
+ regularizer=self.regularizer,
130
+ regularizer_kwargs=self.regularizer_kwargs,
131
+ ),
132
+ epochs=self.epochs,
133
+ random_seed=self.seed,
134
+ evaluation_fallback=self.evaluation_fallback,
135
+ )
136
+ model = result.model
137
+
138
+ users_iter = self.G_train.get_user_nodes()
139
+ items_iter = self.G_train.get_item_nodes()
140
+
141
+ users = list(users_iter)
142
+ items = list(items_iter)
143
+
144
+ # deal with entities that might have not been embedded
145
+ users_indices, users_no_embedding = [], []
146
+ for user in users_iter:
147
+ try:
148
+ users_indices.append(entity_to_id[user.__str__()])
149
+ except:
150
+ users_no_embedding.append(user)
151
+ users.remove(user)
152
+ continue
153
+ users_indices = torch.LongTensor(users_indices)
154
+
155
+ items_indices, items_no_embedding = [], []
156
+ for item in items_iter:
157
+ try:
158
+ items_indices.append(entity_to_id[item.__str__()])
159
+ except:
160
+ items_no_embedding.append(item)
161
+ items.remove(item)
162
+ continue
163
+ items_indices = torch.LongTensor(items_indices)
164
+
165
+ users_embeddings = (model.entity_representations[0](indices=users_indices).detach().cpu().numpy())
166
+ items_embeddings = (model.entity_representations[0](indices=items_indices).detach().cpu().numpy())
167
+
168
+ if len(users_no_embedding) > 0:
169
+ users_embeddings = np.concatenate((users_embeddings, np.zeros((len(users_no_embedding), self.embedding_dim), dtype=users_embeddings.dtype)), axis=0)
170
+ users = users + users_no_embedding
171
+
172
+ if len(items_no_embedding) > 0:
173
+ items_embeddings = np.concatenate((items_embeddings, np.zeros((len(items_no_embedding), self.embedding_dim), dtype=items_embeddings.dtype)), axis=0)
174
+ items = items + items_no_embedding
175
+
176
+ for index, user in enumerate(users):
177
+ self._embedding[user] = users_embeddings[index]
178
+
179
+ for index, item in enumerate(items):
180
+ self._embedding[item] = items_embeddings[index]
181
+
182
+ def _get_n_neighbors(self, users, items, top_k):
183
+ n_neighbors = 0
184
+ if self.all_recs:
185
+ n_neighbors = len(items)
186
+ else:
187
+ max_recs = 0
188
+ for user in users:
189
+ rated_items = self.G_train.get_user_rated_items(user)
190
+ if len(rated_items) > max_recs:
191
+ max_recs = len(rated_items)
192
+ n_neighbors = min(max_recs + top_k, len(items))
193
+
194
+ return n_neighbors
File without changes