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,187 @@
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 DistMult(Recommender):
20
+ def __init__(
21
+ self,
22
+ config: dict,
23
+ embedding_dim: int = 50,
24
+ entity_initializer=None,
25
+ entity_constrainer=None,
26
+ relation_initializer=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.entity_constrainer = entity_constrainer
39
+ self.relation_initializer = relation_initializer
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 = "DistMult based model + cosine similarity"
52
+ text += f";embedding_dim={self.embedding_dim};entity_initializer={self.entity_initializer};entity_constrainer={self.entity_constrainer};relation_initializer={self.relation_initializer};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="DistMult",
117
+ model_kwargs=dict(
118
+ embedding_dim=self.embedding_dim,
119
+ entity_initializer=self.entity_initializer,
120
+ entity_constrainer=self.entity_constrainer,
121
+ relation_initializer=self.relation_initializer,
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
+ if len(users_no_embedding) > 0:
162
+ users_embeddings = np.concatenate((users_embeddings, np.zeros((len(users_no_embedding), self.embedding_dim), dtype=users_embeddings.dtype)), axis=0)
163
+ users = users + users_no_embedding
164
+
165
+ if len(items_no_embedding) > 0:
166
+ items_embeddings = np.concatenate((items_embeddings, np.zeros((len(items_no_embedding), self.embedding_dim), dtype=items_embeddings.dtype)), axis=0)
167
+ items = items + items_no_embedding
168
+
169
+ for index, user in enumerate(users):
170
+ self._embedding[user] = users_embeddings[index]
171
+
172
+ for index, item in enumerate(items):
173
+ self._embedding[item] = items_embeddings[index]
174
+
175
+ def _get_n_neighbors(self, users, items, top_k):
176
+ n_neighbors = 0
177
+ if self.all_recs:
178
+ n_neighbors = len(items)
179
+ else:
180
+ max_recs = 0
181
+ for user in users:
182
+ rated_items = self.G_train.get_user_rated_items(user)
183
+ if len(rated_items) > max_recs:
184
+ max_recs = len(rated_items)
185
+ n_neighbors = min(max_recs + top_k, len(items))
186
+
187
+ return n_neighbors
File without changes
@@ -0,0 +1,159 @@
1
+ from framework.dataloader.graph.node import UserNode, ItemNode
2
+ from ...recommender import Recommender
3
+
4
+ from ...model2class import model2class
5
+
6
+ from sklearn.neighbors import NearestNeighbors
7
+ from sentence_transformers import SentenceTransformer
8
+
9
+ import numpy as np
10
+ import pandas as pd
11
+ import random
12
+ import importlib
13
+
14
+ from tqdm import tqdm
15
+ from copy import deepcopy
16
+
17
+ import os
18
+ os.environ["TOKENIZERS_PARALLELISM"] = "false"
19
+
20
+ """
21
+ Recommender base class
22
+ """
23
+
24
+ class EPHEN(Recommender):
25
+ def __init__(
26
+ self,
27
+ config: dict,
28
+ embedding_model: str = "sentence-transformers/distiluse-base-multilingual-cased-v2",
29
+ embedding_model_kwargs: dict = None,
30
+ embed_with: str = "movie_title", # 'graph' for graph embedding model or column for text embedding model
31
+ iterations: int = 30,
32
+ mi: float = 0.85,
33
+ all_recs: bool = False,
34
+ ):
35
+ super().__init__(config)
36
+ self.embedding_model = embedding_model
37
+ self.embedding_model_kwargs = embedding_model_kwargs
38
+ self.embed_with = embed_with
39
+ self.iterations = iterations
40
+ self.mi = mi
41
+ self.all_recs = all_recs
42
+ self._embedding = {}
43
+
44
+ def name(self):
45
+ text = "EPHEN based model + cosine similarity"
46
+ text += f";embedding_model={self.embedding_model};embedding_model_kwargs={self.embedding_model_kwargs};embed_with={self.embed_with};iterations={self.iterations};mi={self.mi}."
47
+ return text
48
+
49
+ def train(self, G_train, ratings_train):
50
+ self.G_train = G_train
51
+ self.ratings_train = ratings_train
52
+ self.fit()
53
+
54
+ def get_recommendations(self, k: int = 5):
55
+ # Set doesnt guarantee the order of set elements
56
+ users = list(self.G_train.get_user_nodes())
57
+ items = list(self.G_train.get_item_nodes())
58
+
59
+ users_embeddings = np.array([self._embedding[user] for user in users])
60
+ items_embeddings = np.array([self._embedding[item] for item in items])
61
+
62
+ n_neighbors = self._get_n_neighbors(users, items, k)
63
+ knn = NearestNeighbors(n_neighbors=n_neighbors, metric='cosine')
64
+ knn.fit(items_embeddings)
65
+ rec_indices = knn.kneighbors(users_embeddings, return_distance=False)
66
+
67
+ recommendations = {}
68
+ for user_idx, user in enumerate(users):
69
+ rated_items = self.G_train.get_user_rated_items(user)
70
+ recs = []
71
+ for item_idx in rec_indices[user_idx]:
72
+ item = items[item_idx]
73
+ if item not in rated_items:
74
+ recs.append(item)
75
+ if not self.all_recs and len(recs) == k:
76
+ break
77
+
78
+ recommendations[user] = recs
79
+
80
+ return recommendations
81
+
82
+ def get_user_recommendation(self, user: UserNode, k: int = 5):
83
+ raise NotImplementedError(
84
+ "Override get_user_recommendation() for your model subclass."
85
+ )
86
+
87
+ def fit(self):
88
+ if self.embed_with == "graph":
89
+ self._generate_graph_init_embeddings()
90
+ else:
91
+ self._generate_text_init_embeddings()
92
+ self._regularization()
93
+
94
+ def _get_n_neighbors(self, users, items, top_k):
95
+ n_neighbors = 0
96
+ if self.all_recs:
97
+ n_neighbors = len(items)
98
+ else:
99
+ max_recs = 0
100
+ for user in users:
101
+ rated_items = self.G_train.get_user_rated_items(user)
102
+ if len(rated_items) > max_recs:
103
+ max_recs = len(rated_items)
104
+ n_neighbors = min(max_recs + top_k, len(items))
105
+
106
+ return n_neighbors
107
+
108
+ def _generate_text_init_embeddings(self):
109
+ model = SentenceTransformer(self.embedding_model)
110
+ item_properties = pd.DataFrame(self.G_train.get_item_property_edges())
111
+ filtered_properties = item_properties[1][item_properties[1].apply(lambda x: x.get_property_type() == self.embed_with)].reset_index(drop=True)
112
+ self.init_embeddings = {}
113
+ for property in tqdm(filtered_properties):
114
+ self.init_embeddings[property] = model.encode(property.id)
115
+
116
+ def _generate_graph_init_embeddings(self):
117
+ module_name = f'framework.recommender.models.{model2class[self.embedding_model]["submodule"]}'
118
+ class_name = model2class[self.embedding_model]['class']
119
+
120
+ model = getattr(importlib.import_module(module_name), class_name)
121
+ model = model(self.embedding_model_kwargs['config'], **self.embedding_model_kwargs['parameters'])
122
+
123
+ model.train(self.G_train, self.ratings_train)
124
+
125
+ self.init_embeddings = model._embedding
126
+
127
+ def _regularization(self):
128
+ dim = len(self.init_embeddings[list(self.init_embeddings.keys())[0]])
129
+ self._embedding = deepcopy(self.init_embeddings)
130
+ for node in self.G_train.nodes():
131
+ if node not in self._embedding:
132
+ self._embedding[node] = np.array([0.0] * dim)
133
+ nodes = list(self.G_train.nodes())
134
+ pbar = tqdm(range(0, self.iterations))
135
+ for iteration in pbar:
136
+ random.shuffle(nodes)
137
+ energy = 0.0
138
+ for node in nodes:
139
+ f_new = np.array([0.0] * dim)
140
+ f_old = np.array(self._embedding[node])
141
+ sum_w = 0.0
142
+ for neighbor in self.G_train.neighbors(node):
143
+ w = 1.0
144
+ if 'weight' in self.G_train[node][neighbor]:
145
+ w = self.G_train[node][neighbor]['weight']
146
+ w /= np.sqrt(self.G_train.degree[neighbor])
147
+ f_new = f_new + w * f_old
148
+ sum_w = sum_w + w
149
+ if sum_w == 0.0:
150
+ sum_w = 1.0
151
+ f_new /= sum_w
152
+ self._embedding[node] = f_new
153
+ if node in self.init_embeddings:
154
+ self._embedding[node] = self.init_embeddings[node] * \
155
+ self.mi + self._embedding[node] * (1.0 - self.mi)
156
+ energy = energy + np.linalg.norm(f_new-f_old)
157
+ iteration = iteration + 1
158
+ message = f"Iteration {iteration} | Energy = {energy}"
159
+ pbar.set_description(message)
File without changes
@@ -0,0 +1,184 @@
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 RESCAL(Recommender):
20
+ def __init__(
21
+ self,
22
+ config: dict,
23
+ embedding_dim: int = 50,
24
+ entity_initializer=None,
25
+ relation_initializer=None,
26
+ regularizer=None,
27
+ regularizer_kwargs=None,
28
+ epochs: int = 5,
29
+ seed: int = 42,
30
+ evaluation_fallback: bool = True,
31
+ all_recs: bool = False,
32
+ triples: str = "all",
33
+ ):
34
+ super().__init__(config)
35
+ self.embedding_dim = embedding_dim
36
+ self.entity_initializer = entity_initializer
37
+ self.relation_initializer = relation_initializer
38
+ self.regularizer = regularizer
39
+ self.regularizer_kwargs = regularizer_kwargs
40
+ self.epochs = epochs
41
+ self.seed = seed
42
+ self.evaluation_fallback = evaluation_fallback
43
+ self.all_recs = all_recs
44
+ self.triples = triples
45
+ self._triples = None
46
+ self._embedding = {}
47
+
48
+ def name(self):
49
+ text = "RESCAL based model + cosine similarity"
50
+ text += f";embedding_dim={self.embedding_dim};entity_initializer={self.entity_initializer};relation_initializer={self.relation_initializer};regularizer={self.regularizer};epochs={self.epochs};seed={self.seed};triples={self.triples}"
51
+ return text
52
+
53
+ def train(self, G_train, ratings_train):
54
+ self.G_train = G_train
55
+ if self.triples == "all":
56
+ self._triples = G_train.get_all_triples()
57
+ elif self.triples == "ratings":
58
+ self._triples = G_train.get_ratings_triples()
59
+ self.fit()
60
+
61
+ def get_recommendations(self, k: int = 5) -> t.Dict[UserNode, t.List[ItemNode]]:
62
+ """
63
+ :param k: cutoff recommendation (int)
64
+ :return dict of recommendations for each user
65
+ of type {user1: [item1, item2]}
66
+ """
67
+ users = list(self.G_train.get_user_nodes())
68
+ items = list(self.G_train.get_item_nodes())
69
+
70
+ users_embeddings = np.array([self._embedding[user] for user in users])
71
+ items_embeddings = np.array([self._embedding[item] for item in items])
72
+
73
+ n_neighbors = self._get_n_neighbors(users, items, k)
74
+ knn = NearestNeighbors(n_neighbors=n_neighbors, metric="cosine")
75
+ knn.fit(items_embeddings)
76
+ rec_indices = knn.kneighbors(users_embeddings, return_distance=False)
77
+
78
+ recommendations = {}
79
+ for user_idx, user in enumerate(users):
80
+ rated_items = self.G_train.get_user_rated_items(user)
81
+ recs = []
82
+ for item_idx in rec_indices[user_idx]:
83
+ item = items[item_idx]
84
+ if item not in rated_items:
85
+ recs.append(item)
86
+ if not self.all_recs and len(recs) == k:
87
+ break
88
+
89
+ recommendations[user] = recs
90
+
91
+ return recommendations
92
+
93
+ def get_user_recommendation(self, user: UserNode, k: int = 5):
94
+ raise NotImplementedError(
95
+ "Override get_user_recommendation() for your model subclass."
96
+ )
97
+
98
+ def fit(self):
99
+ triples = TriplesFactory.from_labeled_triples(
100
+ self._triples[["head", "relation", "tail"]].values,
101
+ create_inverse_triples=False,
102
+ entity_to_id=None,
103
+ relation_to_id=None,
104
+ compact_id=False,
105
+ filter_out_candidate_inverse_relations=True,
106
+ metadata=None,
107
+ )
108
+
109
+ dataset = Dataset.from_tf(triples, ratios=[0.95, 0.05, 0.0])
110
+ entity_to_id = dataset.entity_to_id
111
+
112
+ result = pipeline(
113
+ dataset=dataset,
114
+ model="RESCAL",
115
+ model_kwargs=dict(
116
+ embedding_dim=self.embedding_dim,
117
+ entity_initializer=self.entity_initializer,
118
+ relation_initializer=self.relation_initializer,
119
+ regularizer=self.regularizer,
120
+ regularizer_kwargs=self.regularizer_kwargs,
121
+ ),
122
+ epochs = self.epochs,
123
+ random_seed = self.seed,
124
+ evaluation_fallback = self.evaluation_fallback,
125
+ )
126
+ model = result.model
127
+
128
+ users_iter = self.G_train.get_user_nodes()
129
+ items_iter = self.G_train.get_item_nodes()
130
+
131
+ users = list(users_iter)
132
+ items = list(items_iter)
133
+
134
+ # deal with entities that might have not been embedded
135
+ users_indices, users_no_embedding = [], []
136
+ for user in users_iter:
137
+ try:
138
+ users_indices.append(entity_to_id[user.__str__()])
139
+ except:
140
+ users_no_embedding.append(user)
141
+ users.remove(user)
142
+ continue
143
+ users_indices = torch.LongTensor(users_indices)
144
+
145
+ items_indices, items_no_embedding = [], []
146
+ for item in items_iter:
147
+ try:
148
+ items_indices.append(entity_to_id[item.__str__()])
149
+ except:
150
+ items_no_embedding.append(item)
151
+ items.remove(item)
152
+ continue
153
+ items_indices = torch.LongTensor(items_indices)
154
+
155
+ users_embeddings = (model.entity_representations[0](indices=users_indices).detach().cpu().numpy())
156
+ items_embeddings = (model.entity_representations[0](indices=items_indices).detach().cpu().numpy())
157
+
158
+ if len(users_no_embedding) > 0:
159
+ users_embeddings = np.concatenate((users_embeddings, np.zeros((len(users_no_embedding), self.embedding_dim), dtype=users_embeddings.dtype)), axis=0)
160
+ users = users + users_no_embedding
161
+
162
+ if len(items_no_embedding) > 0:
163
+ items_embeddings = np.concatenate((items_embeddings, np.zeros((len(items_no_embedding), self.embedding_dim), dtype=items_embeddings.dtype)), axis=0)
164
+ items = items + items_no_embedding
165
+
166
+ for index, user in enumerate(users):
167
+ self._embedding[user] = users_embeddings[index]
168
+
169
+ for index, item in enumerate(items):
170
+ self._embedding[item] = items_embeddings[index]
171
+
172
+ def _get_n_neighbors(self, users, items, top_k):
173
+ n_neighbors = 0
174
+ if self.all_recs:
175
+ n_neighbors = len(items)
176
+ else:
177
+ max_recs = 0
178
+ for user in users:
179
+ rated_items = self.G_train.get_user_rated_items(user)
180
+ if len(rated_items) > max_recs:
181
+ max_recs = len(rated_items)
182
+ n_neighbors = min(max_recs + top_k, len(items))
183
+
184
+ return n_neighbors
File without changes