Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 31 additions & 31 deletions examples/relational/relbench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,41 @@ python main.py --dataset=rel-f1 --task=driver-dnf

- `--num_estimators`: Number of estimators (default: `1`).
- `--context_size`: Maximum number of context rows (default: `10_000`).
- `--context_mode`: Context selection strategy, either `latest` or `random` (default: `latest`).
- `--context_mode`: Context selection strategy, either `last` or `rnd` (default: `last`).
- `--num_neighbors`: The number of neighbors to sample for each hop (default: `[16, 16]`).
- `--text`: Include text embeddings from the task entity table.
- `--text_dim`: Final text embedding dimension after PCA (default: `64`).
- `--num_lags`: The number of lag targets to use as additional input (default: `20`).
- `--text_dim`: Text embedding dimension after PCA for the entity table (default: `0`).

## Results

Optimal hyperparameters found via the [RelArena-α](../../../benchmark/relational/relarena) evaluation protocol, using 8 estimators:

| Dataset | Task | Val AUROC | Test AUROC | Size | Mode | Neighbors | Text Model | Text Dim |
| :----------- | :---------------- | --------: | ---------: | ----: | :------- | ---------: | :---------- | -------: |
| `rel-amazon` | `user-churn` | 0.6935 | 0.6947 | `20K` | `latest` | `[8, 8]` | | |
| `rel-amazon` | `item-churn` | 0.8215 | 0.8254 | `20K` | `latest` | `[32, 32]` | | |
| `rel-avito` | `user-visits` | 0.6956 | 0.6711 | `20K` | `latest` | `[32, 32]` | | |
| `rel-avito` | `user-clicks` | 0.6369 | 0.6824 | `20K` | `latest` | `[32, 32]` | | |
| `rel-event` | `user-repeat` | 0.7330 | 0.8090 | `1K` | `random` | `[4, 4]` | | |
| `rel-event` | `user-ignore` | 0.8467 | 0.8380 | `2K` | `latest` | `[16, 16]` | | |
| `rel-f1` | `driver-dnf` | 0.7937 | 0.8418 | `2K` | `latest` | `[4, 4]` | | |
| `rel-f1` | `driver-top3` | 0.8816 | 0.9077 | `1K` | `random` | `[4, 4]` | | |
| `rel-hm` | `user-churn` | 0.7036 | 0.6992 | `20K` | `latest` | `[1, 1]` | | |
| `rel-stack` | `user-engagement` | 0.9001 | 0.9019 | `20K` | `random` | `[8, 8]` | `mini`[^1] | `32` |
| `rel-stack` | `user-badge` | 0.8932 | 0.8809 | `20K` | `random` | `[8, 8]` | `mpnet`[^2] | `64` |
| `rel-trial` | `study-outcome` | 0.6636 | 0.7393 | `20K` | `latest` | `[8, 8]` | `mini`[^1] | `32` |

| Dataset | Task | Val nMAE | Test nMAE | Size | Mode | Neighbors | Text Model | Text Dim |
| :----------- | :---------------- | -------: | --------: | ----: | :------- | ---------: | :--------- | -------: |
| `rel-amazon` | `user-ltv` | 21.60 | 25.01 | `20K` | `random` | `[64, 64]` | | |
| `rel-amazon` | `item-ltv` | 7.38 | 7.56 | `20K` | `random` | `[]` | | |
| `rel-avito` | `ad-ctr` | 32.40 | 32.95 | `2K` | `latest` | `[64, 64]` | | |
| `rel-event` | `user-attendance` | 31.25 | 31.70 | `20K` | `random` | `[64, 64]` | | |
| `rel-f1` | `driver-position` | 44.63 | 43.55 | `20K` | `latest` | `[8, 8]` | | |
| `rel-hm` | `item-sales` | 9.81 | 8.00 | `20K` | `random` | `[]` | | |
| `rel-stack` | `post-votes` | 11.36 | 12.49 | `20K` | `random` | `[]` | | |
| `rel-trial` | `study-adverse` | 10.21 | 9.42 | `20K` | `latest` | `[]` | `mini`[^1] | `32` |
| `rel-trial` | `site-success` | 87.90 | 84.31 | `10K` | `latest` | `[8, 8]` | `mini`[^1] | `32` |
Optimal hyperparameters found via the [RelArena-α](../../../benchmark/relational/relarena) evaluation protocol, using 8 estimators and 20 lag targets:

| Dataset | Task | Val AUROC | Test AUROC | Size | Mode | Neighbors | Text Dim | Text Model |
| :----------- | :---------------- | --------: | ---------: | ----: | :----- | ---------: | -------: | :---------- |
| `rel-amazon` | `user-churn` | 69.35 | 69.47 | `20K` | `last` | `[8, 8]` | `0` | |
| `rel-amazon` | `item-churn` | 82.15 | 82.54 | `20K` | `last` | `[32, 32]` | `0` | |
| `rel-avito` | `user-visits` | 69.56 | 67.11 | `20K` | `last` | `[32, 32]` | `0` | |
| `rel-avito` | `user-clicks` | 63.69 | 68.24 | `20K` | `last` | `[32, 32]` | `0` | |
| `rel-event` | `user-repeat` | 73.30 | 80.90 | `1K` | `rnd` | `[4, 4]` | `0` | |
| `rel-event` | `user-ignore` | 84.67 | 83.80 | `2K` | `last` | `[16, 16]` | `0` | |
| `rel-f1` | `driver-dnf` | 79.37 | 84.18 | `2K` | `last` | `[4, 4]` | `0` | |
| `rel-f1` | `driver-top3` | 88.16 | 90.77 | `1K` | `rnd` | `[4, 4]` | `0` | |
| `rel-hm` | `user-churn` | 70.36 | 69.92 | `20K` | `last` | `[1, 1]` | `0` | |
| `rel-stack` | `user-engagement` | 90.01 | 90.19 | `20K` | `rnd` | `[8, 8]` | `32` | `mini`[^1] |
| `rel-stack` | `user-badge` | 89.32 | 88.09 | `20K` | `rnd` | `[8, 8]` | `64` | `mpnet`[^2] |
| `rel-trial` | `study-outcome` | 66.36 | 73.93 | `20K` | `last` | `[8, 8]` | `32` | `mini`[^1] |

| Dataset | Task | Val nMAE | Test nMAE | Size | Mode | Neighbors | Text Dim | Text Model |
| :----------- | :---------------- | -------: | --------: | ----: | :----- | ---------: | -------: | :--------- |
| `rel-amazon` | `user-ltv` | 21.60 | 25.01 | `20K` | `rnd` | `[64, 64]` | `0` | |
| `rel-amazon` | `item-ltv` | 7.38 | 7.56 | `20K` | `rnd` | `[]` | `0` | |
| `rel-avito` | `ad-ctr` | 32.40 | 32.95 | `2K` | `last` | `[64, 64]` | `0` | |
| `rel-event` | `user-attendance` | 31.25 | 31.70 | `20K` | `rnd` | `[64, 64]` | `0` | |
| `rel-f1` | `driver-position` | 44.63 | 43.55 | `20K` | `last` | `[8, 8]` | `0` | |
| `rel-hm` | `item-sales` | 9.81 | 8.00 | `20K` | `rnd` | `[]` | `0` | |
| `rel-stack` | `post-votes` | 11.36 | 12.49 | `20K` | `rnd` | `[]` | `0` | |
| `rel-trial` | `study-adverse` | 10.21 | 9.42 | `20K` | `last` | `[]` | `32` | `mini`[^1] |
| `rel-trial` | `site-success` | 87.90 | 84.31 | `10K` | `last` | `[8, 8]` | `32` | `mini`[^1] |

[^1]: `sentence-transformers/all-MiniLM-L6-v2`

Expand Down
47 changes: 47 additions & 0 deletions examples/relational/relbench/lag_target.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

import pandas as pd
import relbench


def add_lag_target(
df: pd.DataFrame,
task: relbench.base.EntityTask,
num_lags: int,
) -> pd.DataFrame:
r"""Add lag target features to the task table."""
df = df.copy()
right = df.sort_values(task.time_col)
left = pd.DataFrame(
{
task.entity_col: df[task.entity_col],
"__lookup_time__": df[task.time_col],
"__row__": range(len(df)),
}
)
for lag in range(1, num_lags + 1):
column = f"{task.target_col}_lag_{lag}"
if task.task_type == relbench.base.TaskType.REGRESSION:
df[column] = float("NaN")
else:
df[column] = pd.Series(pd.NA, index=df.index, dtype="object")

merged = pd.merge_asof(
left.sort_values("__lookup_time__"),
right,
by=task.entity_col,
left_on="__lookup_time__",
right_on=task.time_col,
direction="backward",
allow_exact_matches=False,
)
mask = merged[task.time_col].notna()
rows = merged.loc[mask, "__row__"].to_numpy()
df.loc[rows, column] = merged.loc[mask, task.target_col].to_numpy()

# Find the next lag strictly before the previous observation.
left = merged.loc[mask, [task.entity_col, "__row__", task.time_col]]
left = left.rename(columns={task.time_col: "__lookup_time__"})

return df
Loading
Loading