relbench 2.1.0__tar.gz → 2.1.2__tar.gz

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 (51) hide show
  1. {relbench-2.1.0 → relbench-2.1.2}/PKG-INFO +48 -23
  2. {relbench-2.1.0 → relbench-2.1.2}/README.md +46 -22
  3. {relbench-2.1.0 → relbench-2.1.2}/pyproject.toml +2 -1
  4. {relbench-2.1.0 → relbench-2.1.2}/relbench/base/table.py +5 -0
  5. {relbench-2.1.0 → relbench-2.1.2}/relbench/base/task_autocomplete.py +2 -4
  6. {relbench-2.1.0 → relbench-2.1.2}/relbench/base/task_recommendation.py +3 -0
  7. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/__init__.py +23 -8
  8. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/dbinfer.py +12 -1
  9. relbench-2.1.2/relbench/datasets/hashes.json +38 -0
  10. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/mimic.py +16 -1
  11. relbench-2.1.2/relbench/datasets/tgb.py +75 -0
  12. {relbench-2.1.0 → relbench-2.1.2}/relbench/modeling/loader.py +5 -2
  13. {relbench-2.1.0 → relbench-2.1.2}/relbench/modeling/nn.py +68 -1
  14. {relbench-2.1.0 → relbench-2.1.2}/relbench/modeling/utils.py +16 -6
  15. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/__init__.py +94 -47
  16. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/amazon.py +14 -28
  17. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/arxiv.py +8 -16
  18. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/avito.py +8 -16
  19. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/dbinfer.py +38 -3
  20. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/event.py +6 -12
  21. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/f1.py +8 -16
  22. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/hashes.json +47 -3
  23. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/hm.py +6 -12
  24. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/mimic.py +8 -4
  25. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/ratebeer.py +14 -28
  26. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/stack.py +10 -20
  27. relbench-2.1.2/relbench/tasks/tgb.py +627 -0
  28. {relbench-2.1.0 → relbench-2.1.2}/relbench/tasks/trial.py +10 -20
  29. relbench-2.1.0/relbench/datasets/hashes.json +0 -20
  30. {relbench-2.1.0 → relbench-2.1.2}/LICENSE +0 -0
  31. {relbench-2.1.0 → relbench-2.1.2}/relbench/__init__.py +0 -0
  32. {relbench-2.1.0 → relbench-2.1.2}/relbench/base/__init__.py +0 -0
  33. {relbench-2.1.0 → relbench-2.1.2}/relbench/base/database.py +0 -0
  34. {relbench-2.1.0 → relbench-2.1.2}/relbench/base/dataset.py +0 -0
  35. {relbench-2.1.0 → relbench-2.1.2}/relbench/base/task_base.py +0 -0
  36. {relbench-2.1.0 → relbench-2.1.2}/relbench/base/task_entity.py +0 -0
  37. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/amazon.py +0 -0
  38. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/arxiv.py +0 -0
  39. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/avito.py +0 -0
  40. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/event.py +0 -0
  41. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/f1.py +0 -0
  42. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/fake.py +0 -0
  43. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/hm.py +0 -0
  44. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/ratebeer.py +0 -0
  45. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/salt.py +0 -0
  46. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/stack.py +0 -0
  47. {relbench-2.1.0 → relbench-2.1.2}/relbench/datasets/trial.py +0 -0
  48. {relbench-2.1.0 → relbench-2.1.2}/relbench/metrics.py +0 -0
  49. {relbench-2.1.0 → relbench-2.1.2}/relbench/modeling/__init__.py +0 -0
  50. {relbench-2.1.0 → relbench-2.1.2}/relbench/modeling/graph.py +0 -0
  51. {relbench-2.1.0 → relbench-2.1.2}/relbench/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: relbench
3
- Version: 2.1.0
3
+ Version: 2.1.2
4
4
  Summary: RelBench: Relational Deep Learning Benchmark
5
5
  Keywords:
6
6
  Author-email: RelBench Team <relbench@cs.stanford.edu>
@@ -18,6 +18,7 @@ Requires-Dist: typing-extensions
18
18
  Requires-Dist: datasets
19
19
  Requires-Dist: redelex ; extra == "ctu"
20
20
  Requires-Dist: dbinfer-relbench-adapter ; extra == "dbinfer"
21
+ Requires-Dist: db-dtypes ; extra == "dbinfer"
21
22
  Requires-Dist: pre-commit ; extra == "dev"
22
23
  Requires-Dist: sentence-transformers ; extra == "example"
23
24
  Requires-Dist: pytorch_frame[full] ; extra == "example"
@@ -48,7 +49,7 @@ Provides-Extra: test
48
49
 
49
50
 
50
51
  <!-- [<img align="center" src="https://relbench.stanford.edu/img/favicon.png" width="20px" /> -->
51
- [**Website**](https://relbench.stanford.edu) | [**Position Paper**](https://proceedings.mlr.press/v235/fey24a.html) | [**Benchmark Paper**](https://arxiv.org/abs/2407.20060) | [**Mailing List**](https://groups.google.com/forum/#!forum/relbench/join)
52
+ [**Website**](https://relbench.stanford.edu) | [**Position Paper**](https://proceedings.mlr.press/v235/fey24a.html) | [**RelBench v1 Paper**](https://arxiv.org/abs/2407.20060) | [**RelBench v2 Paper**](https://arxiv.org/abs/2602.12606) | [**Mailing List**](https://groups.google.com/forum/#!forum/relbench/join)
52
53
 
53
54
  # News
54
55
 
@@ -124,7 +125,30 @@ pip install relbench
124
125
 
125
126
  This will allow usage of the core RelBench data and task loading functionality.
126
127
 
127
- <details markdown="1"><summary>Including CTU datasets</summary>
128
+
129
+ To additionally use `relbench.modeling`, which requires [PyTorch](https://pytorch.org/), [PyTorch Geometric](https://github.com/pyg-team/pytorch_geometric) and [PyTorch Frame](https://github.com/pyg-team/pytorch-frame), install these dependencies manually or do:
130
+
131
+ ```bash
132
+ pip install relbench[full]
133
+ ```
134
+
135
+
136
+ For the scripts in the `examples` directory, use:
137
+ ```bash
138
+ pip install relbench[example]
139
+ ```
140
+
141
+ Then, to run a script:
142
+ ```bash
143
+ git clone https://github.com/snap-stanford/relbench
144
+ cd relbench/examples
145
+ python gnn_entity.py --dataset rel-f1 --task driver-position
146
+ ```
147
+
148
+
149
+ ## Using External Integrations
150
+
151
+ **Using CTU datasets**
128
152
 
129
153
  To use datasets from the CTU repository, use:
130
154
  ```bash
@@ -133,7 +157,7 @@ pip install relbench[ctu]
133
157
 
134
158
  If you use the CTU datasets in your work, please cite [ReDeLEx](https://github.com/jakubpeleska/redelex) as below:
135
159
 
136
- ```
160
+ ```bibtex
137
161
  @misc{peleska2025redelex,
138
162
  title={REDELEX: A Framework for Relational Deep Learning Exploration},
139
163
  author={Jakub Peleška and Gustav Šír},
@@ -145,9 +169,9 @@ If you use the CTU datasets in your work, please cite [ReDeLEx](https://github.c
145
169
  }
146
170
  ```
147
171
 
148
- </details>
149
172
 
150
- <details markdown="1"><summary>Including 4DBInfer datasets</summary>
173
+
174
+ **Using 4DBInfer datasets**
151
175
 
152
176
  To use datasets from the 4DBInfer repository, use:
153
177
  ```bash
@@ -155,7 +179,7 @@ pip install relbench[dbinfer]
155
179
  ```
156
180
 
157
181
  If you use the 4DBInfer datasets in your work, please cite [4DBInfer](https://github.com/awslabs/multi-table-benchmark) as below:
158
- ```
182
+ ```bibtex
159
183
  @article{dbinfer,
160
184
  title={4DBInfer: A 4D Benchmarking Toolbox for Graph-Centric Predictive Modeling on Relational DBs},
161
185
  author={Wang, Minjie and Gan, Quan and Wipf, David and Cai, Zhenkun and Li, Ning and Tang, Jianheng and Zhang, Yanlin and Zhang, Zizhao and Mao, Zunyao and Song, Yakun and Wang, Yanbo and Li, Jiahang and Zhang, Han and Yang, Guang and Qin, Xiao and Lei, Chuan and Zhang, Muhan and Zhang, Weinan and Faloutsos, Christos and Zhang, Zheng},
@@ -164,28 +188,29 @@ If you use the 4DBInfer datasets in your work, please cite [4DBInfer](https://gi
164
188
  }
165
189
  ```
166
190
 
167
- </details>
168
- <br>
169
-
191
+ **Using TGB datasets**
170
192
 
171
- To additionally use `relbench.modeling`, which requires [PyTorch](https://pytorch.org/), [PyTorch Geometric](https://github.com/pyg-team/pytorch_geometric) and [PyTorch Frame](https://github.com/pyg-team/pytorch-frame), install these dependencies manually or do:
193
+ [TGB](https://tgb.complexdatalab.com/) datasets and tasks can be loaded in the RelBench format, and they cover bipartite link prediction (`tgbl-*`), heterogeneous link prediction (`thgl-*`), and node property prediction (`tgbn-*`). See `relbench/tasks/tgb.py` for the official TGB evaluation protocols (one-vs-many MRR / Hits@10 for link prediction, NDCG@10 for node property prediction). Standard RelBench style evaluation works as it is.
172
194
 
173
- ```bash
174
- pip install relbench[full]
195
+ If you use the TGB datasets in your work, please cite [TGB](https://tgb.complexdatalab.com/) as below:
196
+ ```bibtex
197
+ @article{huang2023temporal,
198
+ title={Temporal graph benchmark for machine learning on temporal graphs},
199
+ author={Huang, Shenyang and Poursafaei, Farimah and Danovitch, Jacob and Fey, Matthias and Hu, Weihua and Rossi, Emanuele and Leskovec, Jure and Bronstein, Michael and Rabusseau, Guillaume and Rabbany, Reihaneh},
200
+ journal={Advances in Neural Information Processing Systems},
201
+ year={2023}
202
+ }
175
203
  ```
176
204
 
177
-
178
- For the scripts in the `examples` directory, use:
179
- ```bash
180
- pip install relbench[example]
205
+ ```bibtex
206
+ @article{huang2024tgb2,
207
+ title={TGB 2.0: A Benchmark for Learning on Temporal Knowledge Graphs and Heterogeneous Graphs},
208
+ author={Gastinger, Julia and Huang, Shenyang and Galkin, Mikhail and Loghmani, Erfan and Parviz, Ali and Poursafaei, Farimah and Danovitch, Jacob and Rossi, Emanuele and Koutis, Ioannis and Stuckenschmidt, Heiner and Rabbany, Reihaneh and Rabusseau, Guillaume},
209
+ journal={Advances in Neural Information Processing Systems},
210
+ year={2024}
211
+ }
181
212
  ```
182
213
 
183
- Then, to run a script:
184
- ```bash
185
- git clone https://github.com/snap-stanford/relbench
186
- cd relbench/examples
187
- python gnn_entity.py --dataset rel-f1 --task driver-position
188
- ```
189
214
 
190
215
 
191
216
  # Package Usage
@@ -12,7 +12,7 @@
12
12
 
13
13
 
14
14
  <!-- [<img align="center" src="https://relbench.stanford.edu/img/favicon.png" width="20px" /> -->
15
- [**Website**](https://relbench.stanford.edu) | [**Position Paper**](https://proceedings.mlr.press/v235/fey24a.html) | [**Benchmark Paper**](https://arxiv.org/abs/2407.20060) | [**Mailing List**](https://groups.google.com/forum/#!forum/relbench/join)
15
+ [**Website**](https://relbench.stanford.edu) | [**Position Paper**](https://proceedings.mlr.press/v235/fey24a.html) | [**RelBench v1 Paper**](https://arxiv.org/abs/2407.20060) | [**RelBench v2 Paper**](https://arxiv.org/abs/2602.12606) | [**Mailing List**](https://groups.google.com/forum/#!forum/relbench/join)
16
16
 
17
17
  # News
18
18
 
@@ -88,7 +88,30 @@ pip install relbench
88
88
 
89
89
  This will allow usage of the core RelBench data and task loading functionality.
90
90
 
91
- <details markdown="1"><summary>Including CTU datasets</summary>
91
+
92
+ To additionally use `relbench.modeling`, which requires [PyTorch](https://pytorch.org/), [PyTorch Geometric](https://github.com/pyg-team/pytorch_geometric) and [PyTorch Frame](https://github.com/pyg-team/pytorch-frame), install these dependencies manually or do:
93
+
94
+ ```bash
95
+ pip install relbench[full]
96
+ ```
97
+
98
+
99
+ For the scripts in the `examples` directory, use:
100
+ ```bash
101
+ pip install relbench[example]
102
+ ```
103
+
104
+ Then, to run a script:
105
+ ```bash
106
+ git clone https://github.com/snap-stanford/relbench
107
+ cd relbench/examples
108
+ python gnn_entity.py --dataset rel-f1 --task driver-position
109
+ ```
110
+
111
+
112
+ ## Using External Integrations
113
+
114
+ **Using CTU datasets**
92
115
 
93
116
  To use datasets from the CTU repository, use:
94
117
  ```bash
@@ -97,7 +120,7 @@ pip install relbench[ctu]
97
120
 
98
121
  If you use the CTU datasets in your work, please cite [ReDeLEx](https://github.com/jakubpeleska/redelex) as below:
99
122
 
100
- ```
123
+ ```bibtex
101
124
  @misc{peleska2025redelex,
102
125
  title={REDELEX: A Framework for Relational Deep Learning Exploration},
103
126
  author={Jakub Peleška and Gustav Šír},
@@ -109,9 +132,9 @@ If you use the CTU datasets in your work, please cite [ReDeLEx](https://github.c
109
132
  }
110
133
  ```
111
134
 
112
- </details>
113
135
 
114
- <details markdown="1"><summary>Including 4DBInfer datasets</summary>
136
+
137
+ **Using 4DBInfer datasets**
115
138
 
116
139
  To use datasets from the 4DBInfer repository, use:
117
140
  ```bash
@@ -119,7 +142,7 @@ pip install relbench[dbinfer]
119
142
  ```
120
143
 
121
144
  If you use the 4DBInfer datasets in your work, please cite [4DBInfer](https://github.com/awslabs/multi-table-benchmark) as below:
122
- ```
145
+ ```bibtex
123
146
  @article{dbinfer,
124
147
  title={4DBInfer: A 4D Benchmarking Toolbox for Graph-Centric Predictive Modeling on Relational DBs},
125
148
  author={Wang, Minjie and Gan, Quan and Wipf, David and Cai, Zhenkun and Li, Ning and Tang, Jianheng and Zhang, Yanlin and Zhang, Zizhao and Mao, Zunyao and Song, Yakun and Wang, Yanbo and Li, Jiahang and Zhang, Han and Yang, Guang and Qin, Xiao and Lei, Chuan and Zhang, Muhan and Zhang, Weinan and Faloutsos, Christos and Zhang, Zheng},
@@ -128,28 +151,29 @@ If you use the 4DBInfer datasets in your work, please cite [4DBInfer](https://gi
128
151
  }
129
152
  ```
130
153
 
131
- </details>
132
- <br>
133
-
154
+ **Using TGB datasets**
134
155
 
135
- To additionally use `relbench.modeling`, which requires [PyTorch](https://pytorch.org/), [PyTorch Geometric](https://github.com/pyg-team/pytorch_geometric) and [PyTorch Frame](https://github.com/pyg-team/pytorch-frame), install these dependencies manually or do:
156
+ [TGB](https://tgb.complexdatalab.com/) datasets and tasks can be loaded in the RelBench format, and they cover bipartite link prediction (`tgbl-*`), heterogeneous link prediction (`thgl-*`), and node property prediction (`tgbn-*`). See `relbench/tasks/tgb.py` for the official TGB evaluation protocols (one-vs-many MRR / Hits@10 for link prediction, NDCG@10 for node property prediction). Standard RelBench style evaluation works as it is.
136
157
 
137
- ```bash
138
- pip install relbench[full]
158
+ If you use the TGB datasets in your work, please cite [TGB](https://tgb.complexdatalab.com/) as below:
159
+ ```bibtex
160
+ @article{huang2023temporal,
161
+ title={Temporal graph benchmark for machine learning on temporal graphs},
162
+ author={Huang, Shenyang and Poursafaei, Farimah and Danovitch, Jacob and Fey, Matthias and Hu, Weihua and Rossi, Emanuele and Leskovec, Jure and Bronstein, Michael and Rabusseau, Guillaume and Rabbany, Reihaneh},
163
+ journal={Advances in Neural Information Processing Systems},
164
+ year={2023}
165
+ }
139
166
  ```
140
167
 
141
-
142
- For the scripts in the `examples` directory, use:
143
- ```bash
144
- pip install relbench[example]
168
+ ```bibtex
169
+ @article{huang2024tgb2,
170
+ title={TGB 2.0: A Benchmark for Learning on Temporal Knowledge Graphs and Heterogeneous Graphs},
171
+ author={Gastinger, Julia and Huang, Shenyang and Galkin, Mikhail and Loghmani, Erfan and Parviz, Ali and Poursafaei, Farimah and Danovitch, Jacob and Rossi, Emanuele and Koutis, Ioannis and Stuckenschmidt, Heiner and Rabbany, Reihaneh and Rabusseau, Guillaume},
172
+ journal={Advances in Neural Information Processing Systems},
173
+ year={2024}
174
+ }
145
175
  ```
146
176
 
147
- Then, to run a script:
148
- ```bash
149
- git clone https://github.com/snap-stanford/relbench
150
- cd relbench/examples
151
- python gnn_entity.py --dataset rel-f1 --task driver-position
152
- ```
153
177
 
154
178
 
155
179
  # Package Usage
@@ -4,7 +4,7 @@ build-backend = "flit_core.buildapi"
4
4
 
5
5
  [project]
6
6
  name = "relbench"
7
- version = "2.1.0"
7
+ version = "2.1.2"
8
8
  description = "RelBench: Relational Deep Learning Benchmark"
9
9
  authors = [{name = "RelBench Team", email = "relbench@cs.stanford.edu"}]
10
10
  readme = "README.md"
@@ -44,6 +44,7 @@ dev=[
44
44
  ]
45
45
  dbinfer=[
46
46
  "dbinfer-relbench-adapter",
47
+ "db-dtypes",
47
48
  ]
48
49
  ctu=[
49
50
  "redelex",
@@ -84,6 +84,11 @@ class Table:
84
84
  # Read the Parquet file using pyarrow
85
85
  table = pa.parquet.read_table(path)
86
86
  df = table.to_pandas()
87
+ # DuckDB currently cannot ingest pandas StringDtype columns reliably.
88
+ # Convert them to plain object dtype on load.
89
+ for col in df.columns:
90
+ if isinstance(df[col].dtype, pd.StringDtype):
91
+ df[col] = df[col].astype(object)
87
92
 
88
93
  # Extract metadata
89
94
  metadata_bytes = table.schema.metadata
@@ -173,8 +173,7 @@ class AutoCompleteTask(EntityTask):
173
173
  min_timestamp = timestamp_df["timestamp"].min()
174
174
  max_timestamp = timestamp_df["timestamp"].max()
175
175
 
176
- df = duckdb.sql(
177
- f"""
176
+ df = duckdb.sql(f"""
178
177
  SELECT
179
178
  entity_table.{self.time_col},
180
179
  entity_table.{entity_col},
@@ -188,8 +187,7 @@ class AutoCompleteTask(EntityTask):
188
187
  WHERE
189
188
  entity_table.{self.time_col} > '{min_timestamp}' AND
190
189
  entity_table.{self.time_col} <= '{max_timestamp}'
191
- """
192
- ).df()
190
+ """).df()
193
191
 
194
192
  if self.task_type == TaskType.MULTICLASS_CLASSIFICATION:
195
193
  df[self.target_col] = self.transform_target(df[self.target_col])
@@ -83,6 +83,9 @@ class RecommendationTask(BaseTask):
83
83
  f"{pred.shape} given."
84
84
  )
85
85
 
86
+ if len(target_table) == 0:
87
+ return {fn.__name__: float("nan") for fn in metrics}
88
+
86
89
  pred_isin_list = []
87
90
  dst_count_list = []
88
91
  for true_dst_nodes, pred_dst_nodes in zip(
@@ -18,6 +18,7 @@ from relbench.datasets import (
18
18
  ratebeer,
19
19
  salt,
20
20
  stack,
21
+ tgb,
21
22
  trial,
22
23
  )
23
24
  from relbench.utils import get_relbench_cache_dir
@@ -70,15 +71,8 @@ def download_dataset(name: str) -> None:
70
71
  The downloaded database will be automatically picked up by the dataset object, when
71
72
  `dataset.get_db()` is called.
72
73
  """
73
- if name.startswith("dbinfer-"):
74
- print(
75
- f"Dataset '{name}' is derived from 4DBInfer and must be generated "
76
- "locally; skipping download."
77
- )
78
- return
79
74
 
80
75
  if name == "rel-mimic":
81
- print("Downloading Mimic dataset...")
82
76
  from relbench.datasets.mimic import verify_mimic_access
83
77
 
84
78
  verify_mimic_access()
@@ -126,6 +120,8 @@ def get_dataset(name: str, download=True) -> Dataset:
126
120
  if name == "rel-mimic":
127
121
  from relbench.datasets import mimic
128
122
 
123
+ mimic.verify_mimic_access()
124
+
129
125
  cls, args, kwargs = (
130
126
  mimic.MimicDataset,
131
127
  (),
@@ -150,10 +146,29 @@ register_dataset("rel-arxiv", arxiv.ArxivDataset)
150
146
  register_dataset("rel-salt", salt.SALTDataset)
151
147
  register_dataset("rel-ratebeer", ratebeer.RateBeerDataset)
152
148
  register_dataset("dbinfer-avs", dbinfer.DBInferAVSDataset)
153
- register_dataset("dbinfer-mag", dbinfer.DBInferMAGDataset)
149
+ # register_dataset("dbinfer-mag", dbinfer.DBInferMAGDataset) # Experimental dataset: dbinfer-mag
154
150
  register_dataset("dbinfer-diginetica", dbinfer.DBInferDigineticaDataset)
155
151
  register_dataset("dbinfer-retailrocket", dbinfer.DBInferRetailRocketDataset)
156
152
  register_dataset("dbinfer-seznam", dbinfer.DBInferSeznamDataset)
157
153
  register_dataset("dbinfer-amazon", dbinfer.DBInferAmazonDataset)
158
154
  register_dataset("dbinfer-stackexchange", dbinfer.DBInferStackExchangeDataset)
159
155
  register_dataset("dbinfer-outbrain-small", dbinfer.DBInferOutbrainSmallDataset)
156
+
157
+ # Temporal Graph Benchmark (TGB)
158
+ register_dataset("tgbl-wiki", tgb.TGBDataset, tgb_name="tgbl-wiki")
159
+ register_dataset("tgbl-wiki-v2", tgb.TGBDataset, tgb_name="tgbl-wiki-v2")
160
+ register_dataset("tgbl-review", tgb.TGBDataset, tgb_name="tgbl-review")
161
+ register_dataset("tgbl-review-v2", tgb.TGBDataset, tgb_name="tgbl-review-v2")
162
+ register_dataset("tgbl-coin", tgb.TGBDataset, tgb_name="tgbl-coin")
163
+ register_dataset("tgbl-comment", tgb.TGBDataset, tgb_name="tgbl-comment")
164
+ register_dataset("tgbl-flight", tgb.TGBDataset, tgb_name="tgbl-flight")
165
+
166
+ register_dataset("thgl-software", tgb.TGBDataset, tgb_name="thgl-software")
167
+ register_dataset("thgl-forum", tgb.TGBDataset, tgb_name="thgl-forum")
168
+ register_dataset("thgl-github", tgb.TGBDataset, tgb_name="thgl-github")
169
+ register_dataset("thgl-myket", tgb.TGBDataset, tgb_name="thgl-myket")
170
+
171
+ register_dataset("tgbn-trade", tgb.TGBDataset, tgb_name="tgbn-trade")
172
+ register_dataset("tgbn-genre", tgb.TGBDataset, tgb_name="tgbn-genre")
173
+ register_dataset("tgbn-reddit", tgb.TGBDataset, tgb_name="tgbn-reddit")
174
+ register_dataset("tgbn-token", tgb.TGBDataset, tgb_name="tgbn-token")
@@ -38,7 +38,18 @@ class DBInferDatasetBase(Dataset):
38
38
  self._adapter_cache_dir = adapter_cache_dir
39
39
 
40
40
  def _load_dataset_adapter(self):
41
- from dbinfer_relbench_adapter.loader import load_dbinfer_data
41
+ try:
42
+ from dbinfer_relbench_adapter.loader import load_dbinfer_data
43
+ except ImportError:
44
+ raise ImportError(
45
+ "dbinfer-relbench-adapter is not installed. "
46
+ "Please install it with:\n"
47
+ " pip install dbinfer-relbench-adapter\n"
48
+ " pip install dgl --force-reinstall -f https://data.dgl.ai/wheels/torch-2.3/cu121/repo.html\n"
49
+ "Note: dgl may conflict with other dependencies. We recommend building "
50
+ "dbinfer datasets in a separate virtual environment and using the cached "
51
+ "datasets in your main working environment."
52
+ ) from None
42
53
 
43
54
  dataset_adapter, _ = load_dbinfer_data(
44
55
  dataset_name=self.dbinfer_name,
@@ -0,0 +1,38 @@
1
+ {
2
+ "rel-trial/db.zip": "9fb5ba14f7cbca8115f3dfe0800415f98d6ddc15561e56c35ee614da6b89552a",
3
+ "rel-avito/db.zip": "274e692295027a753063b9201815a9d2dea94d4cda968be81be936f546d77058",
4
+ "rel-stack/db.zip": "5a97bf65a926529143e96f6413b2b0550ca55c01247f85156bfb999ee903e94e",
5
+ "rel-f1/db.zip": "ec31a4e1bc2b2f9c36c05fcd3dfe2a40a506f335dc51ce79c3ec8bb40feb1482",
6
+ "rel-hm/db.zip": "3fb2aa3c978cc388aa81f43f9404fed329b502104ff58f3ee435959ab95e7029",
7
+ "rel-event/db.zip": "2593477065e1090af0258c07769ec22f40dad01f035613ccf35258b924d8b066",
8
+ "rel-amazon/db.zip": "db71c7701b892a4eb7481ff04d14d25465795501dba3a5931aabee9930805efe",
9
+ "rel-salt/db.zip": "fca91ab7d9e37646dcf1cb0007cc4229e9b23ef3c85f3c9e578d0f3fcb167001",
10
+ "rel-mimic/db.zip": "b41c6fa39e9d37b8e1e66f8311eb44622c79ea1644ee2cce280fc731d8366bbb",
11
+ "rel-arxiv/db.zip": "b7db1bc1aa17a6d79e0cf102fe3f258920a610f58ad8f8891169676fc120bc5c",
12
+ "rel-ratebeer/db.zip": "49afdf23a8b464dc0e54731a3782b51e53f3acee93dae0aa6d968cfbd9caa4be",
13
+ "dbinfer-amazon/db.zip": "0d9291bf880b5afa232b711a462ed7522a94a0ef5c141699ee8a2687dbbf0d08",
14
+ "dbinfer-avs/db.zip": "84295768a283c3c9ee0dbb25eb1c47d6d3f2c1956b523e7361f086fcf6664a93",
15
+ "dbinfer-diginetica/db.zip": "396e2aeb88cc616672b3b0d88a02dc13829c81b855edc3e668f7f2dbad3b96f0",
16
+ "dbinfer-outbrain-small/db.zip": "d186a71fc534bcac4299c616110805a997fa56fd16c15110d02e1c8eb3975210",
17
+ "dbinfer-retailrocket/db.zip": "6dbe83488e11c0d159b4592aa4cff57f6fa22b9f4bbf4ae38d0388d536897d75",
18
+ "dbinfer-seznam/db.zip": "77314bf874dc495e8a4a61f2dc5f12982bbec3c5b6b7af5555e9a2bb587154d9",
19
+ "dbinfer-stackexchange/db.zip": "4c8b8ac38b56d57bc2ead3c12be1237b69cae76062ed3f176fc02ad327a84d19",
20
+
21
+ "tgbl-coin/db.zip": "6de3b62bcfc59bb18ff8de0614ce5cbcf21179ad56cb58920d25ade32ec43e00",
22
+ "tgbl-comment/db.zip": "4eb41776954efa2cb06cdb64e093b182335b8683e60236a6645cf4bcd83597be",
23
+ "tgbl-flight/db.zip": "e82646893a45be6c5312e5dc1a774c08d929ecb9eb309c0ad9fdec6dae3b156a",
24
+ "tgbl-review/db.zip": "63b405aafd8092cbda297694e649329ca806ccc3c49c8e6f53eb4a3c19075091",
25
+ "tgbl-review-v2/db.zip": "a5f1a7a9661a700ebb1a3b43df74037853ad3bd6ed54c74342045d2dc8448bc2",
26
+ "tgbl-wiki/db.zip": "ad7b55d1d7b7125c06588db0b8cbebe87c629a95a6c9a911369f89aca9dffdc9",
27
+ "tgbl-wiki-v2/db.zip": "5eb56f8e459405e3b554ce56585903c80038d84a99ca4333b00ce32c8c7a38f1",
28
+
29
+ "tgbn-genre/db.zip": "e46aecc28315ca9872117817ce65bc1f4d00ed261ab6d35038a84bcf0ebab7bf",
30
+ "tgbn-reddit/db.zip": "bc444f5cbaf7004ef7c6c8f98ae12ae72e8427ccc9710e96e46b0fc156cc952e",
31
+ "tgbn-token/db.zip": "44a0f90a62642b8054ef1fbee35c862a67e5d0cec92f08b8fd44c503e0986be8",
32
+ "tgbn-trade/db.zip": "8a983ae6281ea058dc8d84f6ce339d2dacf0ae9bb98bb82cca3fed54ec3fe370",
33
+
34
+ "thgl-forum/db.zip": "fdb20c1afc542e8026b85df850b5e8a539694c182eb4530924fad65964461256",
35
+ "thgl-github/db.zip": "f69c1d49779a4dbead101e7325447854c8890982d254efb2b722117819ba8304",
36
+ "thgl-myket/db.zip": "67a3af25553ceabe8a7eff8906c2213bd82e932cdaeb48ffa326b39d30e0f0cf",
37
+ "thgl-software/db.zip": "35816ef6a07be2291349f081814e18b498a2e46e006ed21be36fdb1a8a0eb90d"
38
+ }
@@ -26,6 +26,15 @@ def verify_mimic_access() -> None:
26
26
  except Exception as e:
27
27
  raise RuntimeError(
28
28
  f"\nACCESS FAILED - BigQuery credential check encountered an error: {e}"
29
+ "\n\nTo gain access to MIMIC-IV via RelBench:"
30
+ "\n 1. Request access at https://physionet.org/content/mimiciv/"
31
+ "\n and complete the 'Request access using Google BigQuery' step."
32
+ "\n 2. Install the Google Cloud SDK: https://cloud.google.com/sdk/docs/install"
33
+ "\n 3. Authenticate: gcloud auth application-default login"
34
+ "\n 4. Set quota project: gcloud auth application-default set-quota-project YOUR_PROJECT_ID"
35
+ "\n 5. Export your project ID: export PROJECT_ID=YOUR_PROJECT_ID"
36
+ "\n 6. If credentials are not at the default path, set:"
37
+ "\n export GOOGLE_APPLICATION_CREDENTIALS=/path/to/application_default_credentials.json"
29
38
  )
30
39
 
31
40
 
@@ -74,7 +83,9 @@ def convert_dtypes(df: pd.DataFrame) -> pd.DataFrame:
74
83
  or "time" in col.lower()
75
84
  ):
76
85
  try:
77
- df[col] = pd.to_datetime(df[col], errors="coerce")
86
+ df[col] = pd.to_datetime(df[col], errors="coerce").astype(
87
+ "datetime64[ns]"
88
+ )
78
89
  except Exception:
79
90
  print("WARNING ")
80
91
  pass
@@ -111,6 +122,10 @@ class MimicDataset(Dataset):
111
122
  The dataset is anchored around ICU stays (`icustays`) and patients (`patients`) and constructs all other
112
123
  tables with respect to these entities.
113
124
 
125
+ Note: MIMIC-IV applies date shifting for patient privacy. Timestamps are offset by a
126
+ random amount (typically decades) while preserving relative ordering. Expect dates
127
+ in the 2110-2200 range rather than the original 2008-2012 collection period.
128
+
114
129
  If certain parameters are not provided, default values will be used.
115
130
 
116
131
  Parameters:
@@ -0,0 +1,75 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from pathlib import Path
5
+ from typing import Optional
6
+
7
+ import pandas as pd
8
+
9
+ from relbench.base import Database, Dataset
10
+
11
+
12
+ @dataclass(frozen=True)
13
+ class TGBCutoffs:
14
+ val_timestamp_s: int
15
+ test_timestamp_s: int
16
+
17
+
18
+ _TGB_CUTOFFS: dict[str, TGBCutoffs] = {
19
+ "tgbl-wiki": TGBCutoffs(val_timestamp_s=1862653, test_timestamp_s=2218300),
20
+ "tgbl-wiki-v2": TGBCutoffs(val_timestamp_s=1862653, test_timestamp_s=2218300),
21
+ "tgbl-review": TGBCutoffs(val_timestamp_s=1464912000, test_timestamp_s=1488844800),
22
+ "tgbl-review-v2": TGBCutoffs(
23
+ val_timestamp_s=1464912000, test_timestamp_s=1488844800
24
+ ),
25
+ "tgbl-coin": TGBCutoffs(val_timestamp_s=1662096249, test_timestamp_s=1664482319),
26
+ "tgbl-comment": TGBCutoffs(val_timestamp_s=1282869285, test_timestamp_s=1288838725),
27
+ "tgbl-flight": TGBCutoffs(val_timestamp_s=1638162000, test_timestamp_s=1653796800),
28
+ "thgl-software": TGBCutoffs(
29
+ val_timestamp_s=1706003880, test_timestamp_s=1706315669
30
+ ),
31
+ "thgl-forum": TGBCutoffs(val_timestamp_s=1390426563, test_timestamp_s=1390838358),
32
+ "thgl-github": TGBCutoffs(val_timestamp_s=1711075987, test_timestamp_s=1711482874),
33
+ "thgl-myket": TGBCutoffs(val_timestamp_s=1603724860, test_timestamp_s=1606341312),
34
+ "tgbn-trade": TGBCutoffs(val_timestamp_s=1262304000, test_timestamp_s=1388534400),
35
+ "tgbn-genre": TGBCutoffs(val_timestamp_s=1216427762, test_timestamp_s=1230448684),
36
+ "tgbn-reddit": TGBCutoffs(val_timestamp_s=1279485233, test_timestamp_s=1286653871),
37
+ "tgbn-token": TGBCutoffs(val_timestamp_s=1522889022, test_timestamp_s=1525386888),
38
+ }
39
+
40
+
41
+ class TGBDataset(Dataset):
42
+ r"""Temporal Graph Benchmark (TGB) datasets exported to RelBench format."""
43
+
44
+ url = "https://tgb.complexdatalab.com/"
45
+
46
+ def __init__(self, *, tgb_name: str, cache_dir: Optional[str] = None) -> None:
47
+ if tgb_name not in _TGB_CUTOFFS:
48
+ raise ValueError(
49
+ f"Unknown tgb_name='{tgb_name}'. Known keys: {sorted(_TGB_CUTOFFS.keys())}"
50
+ )
51
+ self.tgb_name = str(tgb_name)
52
+
53
+ cutoffs = _TGB_CUTOFFS[self.tgb_name]
54
+ self.val_timestamp = pd.to_datetime(
55
+ int(cutoffs.val_timestamp_s), unit="s", utc=True
56
+ )
57
+ self.test_timestamp = pd.to_datetime(
58
+ int(cutoffs.test_timestamp_s), unit="s", utc=True
59
+ )
60
+
61
+ super().__init__(cache_dir=cache_dir)
62
+
63
+ def make_db(self) -> Database:
64
+ if self.cache_dir is None:
65
+ raise RuntimeError("TGBDataset requires cache_dir to locate the cached db.")
66
+
67
+ db_dir = Path(self.cache_dir) / "db"
68
+ if db_dir.exists() and any(db_dir.glob("*.parquet")):
69
+ return Database.load(db_dir)
70
+
71
+ raise RuntimeError(
72
+ f"TGB dataset '{self.tgb_name}' not found at {db_dir}. "
73
+ "This dataset is distributed as a pre-built RelBench database (db.zip). "
74
+ "Please run `download_dataset(...)` or place `db/*.parquet` in the cache directory."
75
+ )
@@ -8,7 +8,7 @@ from torch_geometric.data import Data, FeatureStore, GraphStore, HeteroData
8
8
  from torch_geometric.loader import NodeLoader
9
9
  from torch_geometric.sampler import NeighborSampler, NodeSamplerInput
10
10
  from torch_geometric.sampler.base import SubgraphType
11
- from torch_geometric.typing import EdgeType, NodeType, OptTensor
11
+ from torch_geometric.typing import WITH_PYG_LIB, EdgeType, NodeType, OptTensor
12
12
 
13
13
 
14
14
  def batched_arange(count: Tensor) -> Tuple[Tensor, Tensor]:
@@ -201,7 +201,10 @@ class LinkNeighborLoader(DataLoader):
201
201
  data,
202
202
  num_neighbors=num_neighbors,
203
203
  subgraph_type=subgraph_type,
204
- disjoint=True,
204
+ # PyG only supports `disjoint=True` sampling with `pyg-lib`
205
+ # (as of torch_geometric==2.7.*). Fall back to `disjoint=False` to
206
+ # keep RelBench functional in environments without `pyg-lib`.
207
+ disjoint=WITH_PYG_LIB,
205
208
  temporal_strategy=temporal_strategy,
206
209
  time_attr=time_attr,
207
210
  share_memory=kwargs.get("num_workers", 0) > 0,
@@ -5,7 +5,13 @@ import torch_frame
5
5
  from torch import Tensor
6
6
  from torch_frame.data.stats import StatType
7
7
  from torch_frame.nn.models import ResNet
8
- from torch_geometric.nn import HeteroConv, LayerNorm, PositionalEncoding, SAGEConv
8
+ from torch_geometric.nn import (
9
+ GATv2Conv,
10
+ HeteroConv,
11
+ LayerNorm,
12
+ PositionalEncoding,
13
+ SAGEConv,
14
+ )
9
15
  from torch_geometric.typing import EdgeType, NodeType
10
16
 
11
17
 
@@ -171,3 +177,64 @@ class HeteroGraphSAGE(torch.nn.Module):
171
177
  x_dict = {key: x.relu() for key, x in x_dict.items()}
172
178
 
173
179
  return x_dict
180
+
181
+
182
+ class HeteroGAT(torch.nn.Module):
183
+ def __init__(
184
+ self,
185
+ node_types: List[NodeType],
186
+ edge_types: List[EdgeType],
187
+ channels: int,
188
+ heads: int = 4,
189
+ num_layers: int = 2,
190
+ dropout: float = 0.0,
191
+ ):
192
+ super().__init__()
193
+ self.channels = int(channels)
194
+ self.heads = int(heads)
195
+ self.dropout = float(dropout)
196
+
197
+ self.convs = torch.nn.ModuleList()
198
+ for _ in range(num_layers):
199
+ conv = HeteroConv(
200
+ {
201
+ edge_type: GATv2Conv(
202
+ (channels, channels),
203
+ channels,
204
+ heads=heads,
205
+ concat=False,
206
+ dropout=dropout,
207
+ add_self_loops=False,
208
+ )
209
+ for edge_type in edge_types
210
+ },
211
+ aggr="sum",
212
+ )
213
+ self.convs.append(conv)
214
+
215
+ self.norms = torch.nn.ModuleList()
216
+ for _ in range(num_layers):
217
+ norm_dict = torch.nn.ModuleDict()
218
+ for node_type in node_types:
219
+ norm_dict[node_type] = LayerNorm(channels, mode="node")
220
+ self.norms.append(norm_dict)
221
+
222
+ def reset_parameters(self):
223
+ for conv in self.convs:
224
+ conv.reset_parameters()
225
+ for norm_dict in self.norms:
226
+ for norm in norm_dict.values():
227
+ norm.reset_parameters()
228
+
229
+ def forward(
230
+ self,
231
+ x_dict: Dict[NodeType, Tensor],
232
+ edge_index_dict: Dict[NodeType, Tensor],
233
+ num_sampled_nodes_dict: Optional[Dict[NodeType, List[int]]] = None,
234
+ num_sampled_edges_dict: Optional[Dict[EdgeType, List[int]]] = None,
235
+ ) -> Dict[NodeType, Tensor]:
236
+ for _, (conv, norm_dict) in enumerate(zip(self.convs, self.norms)):
237
+ x_dict = conv(x_dict, edge_index_dict)
238
+ x_dict = {key: norm_dict[key](x) for key, x in x_dict.items()}
239
+ x_dict = {key: x.relu() for key, x in x_dict.items()}
240
+ return x_dict