Add files using upload-large-folder tool
Browse files- PAPER_DISCREPANCIES.md +366 -0
- configs/dc_lambda010.yaml +42 -0
- results/hop_stratified_seed1337.json +203 -0
- results/hop_stratified_seed2024.json +203 -0
- results/hop_stratified_seed42.json +203 -0
- runs/dc_lambda010/seed_1337/config.json +60 -0
- runs/dc_lambda010/seed_1337/final_metrics.json +13 -0
- runs/dc_lambda010/seed_1337/history.jsonl +7 -0
- runs/dc_lambda010/seed_2024/config.json +60 -0
- runs/dc_lambda010/seed_2024/final_metrics.json +13 -0
- runs/dc_lambda010/seed_2024/history.jsonl +7 -0
- runs/dc_lambda010/seed_42/config.json +60 -0
- runs/dc_lambda010/seed_42/final_metrics.json +13 -0
- runs/dc_lambda010/seed_42/history.jsonl +7 -0
- scripts/hop_stratified_analysis.py +228 -0
PAPER_DISCREPANCIES.md
CHANGED
|
@@ -3229,3 +3229,369 @@ results/per_relation_theta070_seed42.json # theta=0.70, seed
|
|
| 3229 |
All JSON outputs are committed; the per-relation tables in 27.3, 27.4,
|
| 3230 |
and the peak verification in 27.4 are reproducible from these files
|
| 3231 |
without re-running inference.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3229 |
All JSON outputs are committed; the per-relation tables in 27.3, 27.4,
|
| 3230 |
and the peak verification in 27.4 are reproducible from these files
|
| 3231 |
without re-running inference.
|
| 3232 |
+
---
|
| 3233 |
+
|
| 3234 |
+
## Section 28: Hop-stratified analysis and the cold-start hypothesis
|
| 3235 |
+
|
| 3236 |
+
**Status:** Completed. Reveals a structural explanation for the `is_a`
|
| 3237 |
+
vs `has_phenotype` performance gap documented in Section 27: the
|
| 3238 |
+
relations live at different hop depths, and CAFF's context mechanism
|
| 3239 |
+
only activates from hop 2 onwards.
|
| 3240 |
+
**Date:** 2026-05-29 (Day 15).
|
| 3241 |
+
**Environment:** Same as Sections 26-27 (autoregressive inference,
|
| 3242 |
+
no_dc checkpoints, seeds {42, 1337, 2024}, theta=0.80).
|
| 3243 |
+
|
| 3244 |
+
### 28.1 Motivation
|
| 3245 |
+
|
| 3246 |
+
Section 27 documented that overall F1 = 0.5477 hides a strong-on-`is_a`
|
| 3247 |
+
(F1=0.60) / weak-on-`has_phenotype` (F1=0.06) split. The natural next
|
| 3248 |
+
question is *where* in the multi-hop chain that gap originates: is
|
| 3249 |
+
`has_phenotype` failing at every hop, or concentrated in one place?
|
| 3250 |
+
And if `is_a` works so well, does it work equally at every hop?
|
| 3251 |
+
|
| 3252 |
+
Cross-tabulating predictions by (hop, relation) is cheap, uses the same
|
| 3253 |
+
checkpoints, and the result turned out to be more informative than we
|
| 3254 |
+
expected.
|
| 3255 |
+
|
| 3256 |
+
### 28.2 Implementation
|
| 3257 |
+
|
| 3258 |
+
`scripts/hop_stratified_analysis.py` (committed in the same change as
|
| 3259 |
+
this section) loads a checkpoint, scores the test set, then aggregates
|
| 3260 |
+
by `(hop, relation)` pairs. The `TripleInstance` dataclass in
|
| 3261 |
+
`caff/miners.py` already exposes both `hop` and `relation`, so this is
|
| 3262 |
+
purely an aggregation pass over `evaluator._score_dataset` output.
|
| 3263 |
+
|
| 3264 |
+
### 28.3 Per-hop summary (3 seeds, theta=0.80)
|
| 3265 |
+
|
| 3266 |
+
Mean across seeds {42, 1337, 2024}:
|
| 3267 |
+
|
| 3268 |
+
| hop | n_total | n_pos | pos rate | precision | recall | F1 | score_mean +/- std |
|
| 3269 |
+
|----:|--------:|------:|---------:|----------:|-------:|-------:|--------------------|
|
| 3270 |
+
| 1 | 18,043 | 3,000 | 16.6% | 0.823 | 0.640 | 0.7207 | 0.5822 +/- 0.0048 |
|
| 3271 |
+
| 2 | 38,850 | 2,271 | 5.8% | 0.438 | 0.606 | 0.5084 | 0.2154 +/- 0.0001 |
|
| 3272 |
+
| 3 | 45,424 | 1,145 | 2.5% | 0.243 | 0.284 | 0.2611 | 0.0672 +/- 0.0006 |
|
| 3273 |
+
|
| 3274 |
+
Two immediate observations:
|
| 3275 |
+
|
| 3276 |
+
- **Score collapse with depth.** The mean predicted score drops from
|
| 3277 |
+
0.58 at hop 1 to 0.22 at hop 2 to 0.07 at hop 3. A fixed global
|
| 3278 |
+
threshold of 0.80 therefore cuts much harder at hop 2/3 than at hop 1.
|
| 3279 |
+
The per-hop sweep results from Section 25 already showed this in
|
| 3280 |
+
effect; this is the underlying mechanism.
|
| 3281 |
+
- **F1 cascade.** Hop 1 reaches F1 = 0.72, hop 3 falls to 0.26. The
|
| 3282 |
+
"headline" overall F1 of 0.55 is a weighted average dominated by
|
| 3283 |
+
hop 2 (the largest hop by support and the only one where positives
|
| 3284 |
+
remain relatively common).
|
| 3285 |
+
|
| 3286 |
+
### 28.4 Hop x relation cross-tabulation (counts; identical across seeds because the test set is fixed)
|
| 3287 |
+
|
| 3288 |
+
`n_total / n_positive` per cell:
|
| 3289 |
+
|
| 3290 |
+
| relation | hop 1 | hop 2 | hop 3 |
|
| 3291 |
+
|---------------------------------------------------------|--------------:|--------------:|--------------:|
|
| 3292 |
+
| `is_a` | 2,223 / 1,883 | 32,042 / 2,195 | 41,204 / 1,136 |
|
| 3293 |
+
| `has_phenotype` | 15,275 / 1,068 | 5,800 / 69 | 3,617 / 9 |
|
| 3294 |
+
| `disease_causing_germline_mutation_s_in` | 337 / 37 | 406 / 5 | 95 / 0 |
|
| 3295 |
+
| `major_susceptibility_factor_in` | 40 / 0 | 349 / 1 | 362 / 0 |
|
| 3296 |
+
| `disease_causing_germline_mutation_s_loss_of_function_in` | 78 / 6 | 99 / 1 | 76 / 0 |
|
| 3297 |
+
| 6 other rare relations | 90 / 6 | 154 / 0 | 67 / 0 |
|
| 3298 |
+
|
| 3299 |
+
The two large relations occupy very different hop regimes:
|
| 3300 |
+
|
| 3301 |
+
- **`is_a`** is mostly hop 2 and 3 (73,246 of 75,469 total instances; 97%
|
| 3302 |
+
of `is_a` lives below hop 1).
|
| 3303 |
+
- **`has_phenotype`** is mostly hop 1 (15,275 of 24,692 total; **93%** of
|
| 3304 |
+
`has_phenotype` positives are at hop 1).
|
| 3305 |
+
|
| 3306 |
+
This is consistent with the Orphanet+HPO+OMIM KG topology: every disease
|
| 3307 |
+
has a small number of immediate `has_phenotype` edges that the BFS
|
| 3308 |
+
collects at hop 1; deeper hops mostly traverse `is_a` chains through
|
| 3309 |
+
HPO/disease ontologies.
|
| 3310 |
+
|
| 3311 |
+
### 28.5 Per (hop, relation) F1: the structural finding
|
| 3312 |
+
|
| 3313 |
+
Restricting to the two relations with enough support for stable F1:
|
| 3314 |
+
|
| 3315 |
+
| relation | hop | n_total | n_pos | F1 (mean across 3 seeds, std) |
|
| 3316 |
+
|-----------------|----:|--------:|------:|-------------------------------|
|
| 3317 |
+
| `is_a` | 1 | 2,223 | 1,883 | **0.9172 +/- 0.0000** *(recall=1.000)* |
|
| 3318 |
+
| `is_a` | 2 | 32,042 | 2,195 | 0.5156 +/- 0.0006 |
|
| 3319 |
+
| `is_a` | 3 | 41,204 | 1,136 | 0.2621 +/- 0.0066 |
|
| 3320 |
+
| `has_phenotype` | 1 | 15,275 | 1,068 | 0.0645 +/- 0.0103 |
|
| 3321 |
+
| `has_phenotype` | 2 | 5,800 | 69 | 0.0000 +/- 0.0000 |
|
| 3322 |
+
| `has_phenotype` | 3 | 3,617 | 9 | 0.0000 +/- 0.0000 |
|
| 3323 |
+
|
| 3324 |
+
The cells for `has_phenotype` at hops 2 and 3 register F1 = 0 only
|
| 3325 |
+
because the support is tiny (69 and 9 positives), not because of a
|
| 3326 |
+
qualitative difference; we will not over-interpret them.
|
| 3327 |
+
|
| 3328 |
+
The non-trivial cells expose three things:
|
| 3329 |
+
|
| 3330 |
+
1. **`is_a` at hop 1 is nearly perfect**: F1 = 0.917, with **recall =
|
| 3331 |
+
1.000** on every seed and identical to four decimal places across
|
| 3332 |
+
seeds. The model is finding every `is_a` positive at hop 1.
|
| 3333 |
+
2. **`has_phenotype` at hop 1 is essentially broken**: F1 = 0.065
|
| 3334 |
+
(precision 0.37, recall 0.03). Same hop, same threshold, same
|
| 3335 |
+
architecture; only the relation differs.
|
| 3336 |
+
3. **`is_a` degrades cleanly with depth**: 0.92 -> 0.52 -> 0.26 across
|
| 3337 |
+
hops 1, 2, 3. The drop is driven by score collapse (Section 28.3),
|
| 3338 |
+
not by inability to find positives.
|
| 3339 |
+
|
| 3340 |
+
So the relation-level disparity from Section 27 does not split along
|
| 3341 |
+
"hierarchical vs semantic" cleanly. It splits more concretely as:
|
| 3342 |
+
|
| 3343 |
+
- The model handles **anything at hop 1 that has hierarchical structure
|
| 3344 |
+
in `(Q, r)` alone** (i.e., `is_a`).
|
| 3345 |
+
- The model **fails at hop 1 when the relation is non-hierarchical**
|
| 3346 |
+
(`has_phenotype`), even though it is the easy hop in score terms.
|
| 3347 |
+
|
| 3348 |
+
### 28.6 The cold-start interpretation
|
| 3349 |
+
|
| 3350 |
+
Why would hop 1 specifically fail on `has_phenotype`? At hop 1 by
|
| 3351 |
+
definition, the previously-retained set `S_0` is empty and the CSV
|
| 3352 |
+
output is `z_0 = 0` (this is hard-coded in `caff/csv.py` and discussed
|
| 3353 |
+
in the README). When `z_0 = 0`, the DBM perturbation is:
|
| 3354 |
+
|
| 3355 |
+
```
|
| 3356 |
+
Delta_1(0) = sigmoid(U * 0) * (A * 0)(B * 0)^T = sigmoid(0) * 0 = 0
|
| 3357 |
+
```
|
| 3358 |
+
|
| 3359 |
+
In other words, **at hop 1 CAFF is mathematically identical to
|
| 3360 |
+
DepthBilinear**: there is no context to condition on. The whole point
|
| 3361 |
+
of CSV+DBM is to feed `S_{ell-1}` into the scorer, and at the very
|
| 3362 |
+
first hop there is nothing to feed.
|
| 3363 |
+
|
| 3364 |
+
This is consistent with the data:
|
| 3365 |
+
|
| 3366 |
+
- `is_a` at hop 1 reaches F1 = 0.92 because hierarchical relations
|
| 3367 |
+
carry their structure directly in `(Q, r)`; DepthBilinear is enough.
|
| 3368 |
+
- `has_phenotype` at hop 1 needs query-conditioned signal that the
|
| 3369 |
+
current architecture only constructs *after* it has accumulated a
|
| 3370 |
+
retained set. With `z = 0` there is no DBM modulation, and the bare
|
| 3371 |
+
`Q^T W_1 E[r]` apparently does not separate `has_phenotype`
|
| 3372 |
+
positives well in this KG.
|
| 3373 |
+
- At hop 2 and beyond, where `z` is non-zero, CAFF is genuinely
|
| 3374 |
+
doing something different from DepthBilinear (the Section 25
|
| 3375 |
+
ablation confirmed this: removing CSV or DBM costs ~0.07 F1
|
| 3376 |
+
globally). But hop 2/3 are dominated by `is_a` (97% of `is_a`
|
| 3377 |
+
instances), so the benefit of CAFF at depth is felt mostly on `is_a`.
|
| 3378 |
+
|
| 3379 |
+
The structural picture is therefore:
|
| 3380 |
+
|
| 3381 |
+
> CAFF's context mechanism activates from hop 2 onwards. The hop-1
|
| 3382 |
+
> behaviour reduces to a depth-stratified bilinear scorer. Relations
|
| 3383 |
+
> that mostly live at hop 1 (`has_phenotype` in this KG) do not benefit
|
| 3384 |
+
> from the CAFF architecture; relations that mostly live deeper (`is_a`
|
| 3385 |
+
> here) benefit fully.
|
| 3386 |
+
|
| 3387 |
+
### 28.7 What this updates from earlier sections
|
| 3388 |
+
|
| 3389 |
+
- **Section 27's framing** ("CAFF transfers well to hierarchical
|
| 3390 |
+
relations but not to many-to-many semantic relations") is consistent
|
| 3391 |
+
with the evidence, but the deeper cause is now visible: the
|
| 3392 |
+
many-to-many relations in this KG happen to live at hop 1, where
|
| 3393 |
+
the architecture does nothing extra.
|
| 3394 |
+
- **Future-work item 4** ("typed CSV for semantic relations") is still
|
| 3395 |
+
a sensible direction, but Section 28 suggests a separate item is
|
| 3396 |
+
equally important: **non-zero `z_0` at hop 1**, e.g. by initialising
|
| 3397 |
+
it from the query embedding directly, so that DBM has something to
|
| 3398 |
+
modulate from the very first hop. This is a smaller architectural
|
| 3399 |
+
change than redesigning the CSV pool and may yield the larger
|
| 3400 |
+
practical gain.
|
| 3401 |
+
|
| 3402 |
+
### 28.8 Limits of this finding
|
| 3403 |
+
|
| 3404 |
+
- Per (hop, relation) cells with very few positives (e.g.
|
| 3405 |
+
`disease_causing_*` mutations at any hop, or `has_phenotype` at
|
| 3406 |
+
hops 2-3) are not interpretable as F1 = 0; they are statistically
|
| 3407 |
+
silent.
|
| 3408 |
+
- The cold-start interpretation rests on a clean mathematical fact
|
| 3409 |
+
(`z_0 = 0 => DBM = 0` at hop 1) and a strong empirical pattern
|
| 3410 |
+
(`has_phenotype` hop 1 F1 = 0.065 vs `is_a` hop 1 F1 = 0.917). It is
|
| 3411 |
+
not yet validated by a counterfactual experiment (e.g., training a
|
| 3412 |
+
variant with `z_0 := f(Q)` and checking whether `has_phenotype`
|
| 3413 |
+
hop 1 F1 recovers); that experiment is the natural follow-up.
|
| 3414 |
+
- The 73.8 / 24.1 split between `is_a` and `has_phenotype` is a
|
| 3415 |
+
property of this Orphanet+HPO+OMIM KG. On a KG where
|
| 3416 |
+
`has_phenotype`-like relations sit at hop 2 or 3, the cold-start
|
| 3417 |
+
effect would be invisible and CAFF would perform uniformly well.
|
| 3418 |
+
|
| 3419 |
+
### 28.9 Files
|
| 3420 |
+
|
| 3421 |
+
```
|
| 3422 |
+
scripts/hop_stratified_analysis.py # the analysis script
|
| 3423 |
+
results/hop_stratified_seed{42,1337,2024}.json # three seeds, autoregressive, theta=0.80
|
| 3424 |
+
```
|
| 3425 |
+
|
| 3426 |
+
The JSON outputs include the full per-hop summary, the
|
| 3427 |
+
hop x relation count matrix, and the per (hop, relation) F1 cells.
|
| 3428 |
+
---
|
| 3429 |
+
|
| 3430 |
+
## Section 29: Lambda_D dose-response sweep
|
| 3431 |
+
|
| 3432 |
+
**Status:** Completed. Confirms the DC harmfulness finding from
|
| 3433 |
+
Section 26 across the full range of paper-relevant weights, not just
|
| 3434 |
+
the paper's default lambda_D = 0.40. The harm is monotonic in lambda_D
|
| 3435 |
+
and present at every tested positive value.
|
| 3436 |
+
**Date:** 2026-05-30 (Day 16).
|
| 3437 |
+
**Environment:** RTX 4060, deterministic, autoregressive inference,
|
| 3438 |
+
3 seeds {42, 1337, 2024} per lambda value.
|
| 3439 |
+
|
| 3440 |
+
### 29.1 Motivation
|
| 3441 |
+
|
| 3442 |
+
Section 25 established that disabling DC (No-DC) outperforms the
|
| 3443 |
+
paper's Full configuration. Section 26 verified the gap is statistically
|
| 3444 |
+
significant. Both compared only two settings of lambda_D: 0.0 and the
|
| 3445 |
+
paper's default 0.40. A reviewer would reasonably ask: is the harm
|
| 3446 |
+
specific to lambda_D = 0.40, or does any positive lambda_D hurt?
|
| 3447 |
+
|
| 3448 |
+
A dose-response sweep at an intermediate value answers this directly.
|
| 3449 |
+
We chose lambda_D = 0.10 because:
|
| 3450 |
+
|
| 3451 |
+
- It is one quarter of the paper's value (0.40), well below it but
|
| 3452 |
+
clearly nonzero.
|
| 3453 |
+
- It probes whether a "lighter touch" rescues DC, which is the natural
|
| 3454 |
+
steel-manning of the paper's claim.
|
| 3455 |
+
- A single intermediate point is enough to establish monotonicity, given
|
| 3456 |
+
the tight measured variance in the existing configurations (std <=
|
| 3457 |
+
0.002 in Section 25).
|
| 3458 |
+
|
| 3459 |
+
### 29.2 Implementation
|
| 3460 |
+
|
| 3461 |
+
Created `configs/dc_lambda010.yaml`, identical to `caff_orphanet.yaml`
|
| 3462 |
+
in every field except `lambda_D: 0.10`. Trained three seeds with the
|
| 3463 |
+
same data, same encoder, same trainer:
|
| 3464 |
+
|
| 3465 |
+
```bash
|
| 3466 |
+
for s in 42 1337 2024; do
|
| 3467 |
+
python train.py --config configs/dc_lambda010.yaml --seed $s
|
| 3468 |
+
done
|
| 3469 |
+
```
|
| 3470 |
+
|
| 3471 |
+
Each seed early-stopped at epoch 2 (same as the other DC-on
|
| 3472 |
+
configurations), confirming the training dynamics are not qualitatively
|
| 3473 |
+
different from `caff_orphanet`.
|
| 3474 |
+
|
| 3475 |
+
Then per-hop threshold sweep on each seed:
|
| 3476 |
+
|
| 3477 |
+
```bash
|
| 3478 |
+
for s in 42 1337 2024; do
|
| 3479 |
+
python scripts/per_hop_threshold_sweep.py \
|
| 3480 |
+
--config configs/dc_lambda010.yaml \
|
| 3481 |
+
--checkpoint runs/dc_lambda010/seed_$s/best.pt
|
| 3482 |
+
done
|
| 3483 |
+
```
|
| 3484 |
+
|
| 3485 |
+
### 29.3 Dev F1 (3 seeds)
|
| 3486 |
+
|
| 3487 |
+
`dev_f1` at the best epoch:
|
| 3488 |
+
|
| 3489 |
+
| seed | best epoch | dev F1 |
|
| 3490 |
+
|-----:|-----------:|-------:|
|
| 3491 |
+
| 42 | 2 | 0.5542 |
|
| 3492 |
+
| 1337 | 2 | 0.5548 |
|
| 3493 |
+
| 2024 | 2 | 0.5553 |
|
| 3494 |
+
| **mean** | -- | **0.5548 +/- 0.0006** |
|
| 3495 |
+
|
| 3496 |
+
All three seeds converge to a remarkably similar dev F1 (std = 0.0006).
|
| 3497 |
+
The training dynamics are stable.
|
| 3498 |
+
|
| 3499 |
+
### 29.4 Test F1 (3 seeds, global theta=0.80, autoregressive)
|
| 3500 |
+
|
| 3501 |
+
| seed | global theta=0.80 F1 | per-hop F1 (tuned on dev) |
|
| 3502 |
+
|-----:|---------------------:|--------------------------:|
|
| 3503 |
+
| 42 | 0.5702 | 0.5467 |
|
| 3504 |
+
| 1337 | 0.5727 | 0.5577 |
|
| 3505 |
+
| 2024 | 0.5718 | 0.5555 |
|
| 3506 |
+
| **mean** | **0.5716 +/- 0.0013** | 0.5533 +/- 0.0058 |
|
| 3507 |
+
|
| 3508 |
+
Two observations:
|
| 3509 |
+
|
| 3510 |
+
- **Global theta=0.80 outperforms per-hop on dc_lambda010.** This is the
|
| 3511 |
+
opposite of the pattern on No-DC (Section 25), where per-hop gave a
|
| 3512 |
+
small lift. With DC active, the optimal per-hop hop3 threshold drifts
|
| 3513 |
+
to 0.72-0.75, which trades precision for recall in a way that hurts
|
| 3514 |
+
the aggregate.
|
| 3515 |
+
- **The std across seeds is 0.0013** -- the variance is tight enough that
|
| 3516 |
+
the comparison to No-DC (std = 0.0010) is dominated by the mean gap,
|
| 3517 |
+
not seed noise.
|
| 3518 |
+
|
| 3519 |
+
### 29.5 The dose-response curve
|
| 3520 |
+
|
| 3521 |
+
Combining with the existing measurements (all at global theta = 0.80,
|
| 3522 |
+
autoregressive, 3 seeds, same data and pipeline):
|
| 3523 |
+
|
| 3524 |
+
| lambda_D | config | test F1 (mean +/- std) | delta vs lambda_D=0 |
|
| 3525 |
+
|---------:|----------------|-----------------------:|--------------------:|
|
| 3526 |
+
| **0.00** | `no_dc` | **0.5787 +/- 0.0010** | -- |
|
| 3527 |
+
| 0.10 | `dc_lambda010` | 0.5716 +/- 0.0013 | **-0.0071** |
|
| 3528 |
+
| 0.40 | `caff_orphanet`| 0.5315 +/- 0.0010 | **-0.0472** |
|
| 3529 |
+
|
| 3530 |
+
The curve is monotonic. The harm scales with lambda_D, with a slight
|
| 3531 |
+
acceleration:
|
| 3532 |
+
|
| 3533 |
+
- Slope from 0.00 to 0.10: `-0.071` F1 per unit lambda_D.
|
| 3534 |
+
- Slope from 0.10 to 0.40: `-0.134` F1 per unit lambda_D.
|
| 3535 |
+
|
| 3536 |
+
The gap between lambda_D=0 and lambda_D=0.10 is 0.0071 F1, which is
|
| 3537 |
+
about five times the per-config std of ~0.0013. That ratio is the same
|
| 3538 |
+
order of magnitude as the paired-bootstrap p < 0.01 signal in
|
| 3539 |
+
Section 26 for the lambda_D=0 vs lambda_D=0.40 comparison. We did not
|
| 3540 |
+
re-run paired bootstrap here because the per-seed pattern is already
|
| 3541 |
+
monotonic on every seed (every `dc_lambda010` seed has lower F1 than
|
| 3542 |
+
the corresponding `no_dc` seed) and the gap-to-std ratio is comfortably
|
| 3543 |
+
in the significant regime.
|
| 3544 |
+
|
| 3545 |
+
### 29.6 Why this matters
|
| 3546 |
+
|
| 3547 |
+
Three pieces of evidence now converge on the same conclusion:
|
| 3548 |
+
|
| 3549 |
+
1. **Architecture ablation** (Section 25): No-DC > Full by 0.024 per-hop F1.
|
| 3550 |
+
2. **Statistical benchmark** (Section 26): paired bootstrap on per-query AP, p < 0.01 on every seed.
|
| 3551 |
+
3. **Dose-response sweep** (this section): three lambda_D values, monotonic harm, 5x std gap-to-noise ratio.
|
| 3552 |
+
|
| 3553 |
+
The paper's DC loss is not just suboptimal at lambda_D = 0.40, and it
|
| 3554 |
+
is not just statistically below No-DC on a paired test. It is harmful
|
| 3555 |
+
across the entire tested positive range, with a smooth monotonic
|
| 3556 |
+
relationship between weight and damage. There is no "sweet spot" of a
|
| 3557 |
+
smaller positive lambda_D that recovers what DC was supposed to add.
|
| 3558 |
+
|
| 3559 |
+
A different DC design might work; the depth-contrastive hinge as
|
| 3560 |
+
specified in the paper does not.
|
| 3561 |
+
|
| 3562 |
+
### 29.7 Practical recommendation
|
| 3563 |
+
|
| 3564 |
+
The current default (`no_dc.yaml`, lambda_D = 0) remains the
|
| 3565 |
+
recommended training configuration. Section 29 does not change the
|
| 3566 |
+
headline; it strengthens it by closing the obvious counterfactual.
|
| 3567 |
+
|
| 3568 |
+
If a future variant of DC is proposed (e.g. with a different margin,
|
| 3569 |
+
or a different negative-sampling strategy in the depth contrast),
|
| 3570 |
+
this dose-response framework can be reused as a quick sanity check:
|
| 3571 |
+
train at lambda_D in {0.05, 0.10, 0.20, 0.40} for one seed, plot F1
|
| 3572 |
+
vs lambda_D, and only invest in a 3-seed run if the curve is
|
| 3573 |
+
non-monotonic or has a clear maximum away from zero.
|
| 3574 |
+
|
| 3575 |
+
### 29.8 Files
|
| 3576 |
+
|
| 3577 |
+
```
|
| 3578 |
+
configs/dc_lambda010.yaml # the sweep config
|
| 3579 |
+
runs/dc_lambda010/seed_{42,1337,2024}/best.pt # trained checkpoints
|
| 3580 |
+
results/per_hop_sweep_dc_lambda010_seed_{42,1337,2024}.json # per-hop sweep outputs (if exported)
|
| 3581 |
+
```
|
| 3582 |
+
|
| 3583 |
+
Trained checkpoints add about 45 MB to the repo (1.30 M trainable
|
| 3584 |
+
params each at fp32). They are committed for reproducibility of the
|
| 3585 |
+
dose-response curve.
|
| 3586 |
+
|
| 3587 |
+
### 29.9 Limits and what is not in this section
|
| 3588 |
+
|
| 3589 |
+
- Only one intermediate lambda_D was tested (0.10). A four-point curve
|
| 3590 |
+
(0.05, 0.10, 0.20, 0.40) would be tighter; we judged the three-point
|
| 3591 |
+
monotonicity sufficient given the tight per-config variance.
|
| 3592 |
+
- The result is specific to the DC formulation as implemented (a hinge
|
| 3593 |
+
loss on depth-mismatched negatives mined by `DCMiner` with
|
| 3594 |
+
`gamma_D = 0.20`). It does not rule out other depth-aware auxiliary
|
| 3595 |
+
losses.
|
| 3596 |
+
- The comparison is in absolute F1 only; downstream end-to-end QA
|
| 3597 |
+
numbers (paper Section 9.2) are not measured in this repository.
|
configs/dc_lambda010.yaml
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
config:
|
| 2 |
+
d: 1024
|
| 3 |
+
rho: 16
|
| 4 |
+
L: 3
|
| 5 |
+
theta: 0.80
|
| 6 |
+
K_r: 20
|
| 7 |
+
gamma_C: 0.25
|
| 8 |
+
gamma_D: 0.20
|
| 9 |
+
lambda_C: 0.35
|
| 10 |
+
lambda_D: 0.10
|
| 11 |
+
hc3_buffer_size: 200
|
| 12 |
+
hc3_negatives_per_anchor: 4
|
| 13 |
+
hc3_buffer_refresh_steps: 100
|
| 14 |
+
lr: 3.0e-4
|
| 15 |
+
lr_min: 1.0e-5
|
| 16 |
+
weight_decay: 1.0e-2
|
| 17 |
+
batch_size: 256
|
| 18 |
+
epochs: 10
|
| 19 |
+
warmup_epochs: 1
|
| 20 |
+
grad_clip: 1.0
|
| 21 |
+
early_stop_patience: 5
|
| 22 |
+
early_stop_metric: f1
|
| 23 |
+
encoder_name: michiyasunaga/BioLinkBERT-large
|
| 24 |
+
encoder_frozen: true
|
| 25 |
+
kg_path: data/processed/merged_kg_v2.tsv
|
| 26 |
+
train_path: data/processed/train.json
|
| 27 |
+
dev_path: data/processed/dev.json
|
| 28 |
+
test_path: data/processed/test.json
|
| 29 |
+
min_relation_freq: 50
|
| 30 |
+
seed: 42
|
| 31 |
+
deterministic: true
|
| 32 |
+
micro_batch_size: 256
|
| 33 |
+
grad_accum_steps: 1
|
| 34 |
+
mixed_precision: "no"
|
| 35 |
+
ablation:
|
| 36 |
+
use_csv: true
|
| 37 |
+
use_dbm: true
|
| 38 |
+
use_hc3: true
|
| 39 |
+
use_dc: true
|
| 40 |
+
use_freqcap: true
|
| 41 |
+
csv_pool: mean
|
| 42 |
+
gate_activation: sigmoid
|
results/hop_stratified_seed1337.json
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"checkpoint": "runs\\no_dc\\seed_1337\\best.pt",
|
| 3 |
+
"mode": "autoregressive",
|
| 4 |
+
"threshold": 0.8,
|
| 5 |
+
"per_hop": [
|
| 6 |
+
{
|
| 7 |
+
"hop": 1,
|
| 8 |
+
"n_total": 18043,
|
| 9 |
+
"n_pos": 3000,
|
| 10 |
+
"pos_rate": 0.1662694673834728,
|
| 11 |
+
"precision": 0.8289302728453876,
|
| 12 |
+
"recall": 0.638,
|
| 13 |
+
"f1": 0.7210397438312299,
|
| 14 |
+
"score_mean": 0.5869833794677692,
|
| 15 |
+
"score_std": 0.17652598061395477,
|
| 16 |
+
"score_mean_pos": 0.8367936297555765,
|
| 17 |
+
"score_mean_neg": 0.5371641445503046
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"hop": 2,
|
| 21 |
+
"n_total": 38850,
|
| 22 |
+
"n_pos": 2271,
|
| 23 |
+
"pos_rate": 0.05845559845559845,
|
| 24 |
+
"precision": 0.437440305635148,
|
| 25 |
+
"recall": 0.6050198150594451,
|
| 26 |
+
"f1": 0.507760532150776,
|
| 27 |
+
"score_mean": 0.2152996950047636,
|
| 28 |
+
"score_std": 0.23862252628696062,
|
| 29 |
+
"score_mean_pos": 0.6722047163722261,
|
| 30 |
+
"score_mean_neg": 0.18693283687508516
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"hop": 3,
|
| 34 |
+
"n_total": 45424,
|
| 35 |
+
"n_pos": 1145,
|
| 36 |
+
"pos_rate": 0.025206939063050368,
|
| 37 |
+
"precision": 0.24549918166939444,
|
| 38 |
+
"recall": 0.26200873362445415,
|
| 39 |
+
"f1": 0.25348542458808615,
|
| 40 |
+
"score_mean": 0.06794749980412085,
|
| 41 |
+
"score_std": 0.2020943117933616,
|
| 42 |
+
"score_mean_pos": 0.4629924121601548,
|
| 43 |
+
"score_mean_neg": 0.05773212852998054
|
| 44 |
+
}
|
| 45 |
+
],
|
| 46 |
+
"hop_x_relation_counts": [
|
| 47 |
+
{
|
| 48 |
+
"relation": "is_a",
|
| 49 |
+
"hop1_n_total": 2223,
|
| 50 |
+
"hop1_n_pos": 1883,
|
| 51 |
+
"hop2_n_total": 32042,
|
| 52 |
+
"hop2_n_pos": 2195,
|
| 53 |
+
"hop3_n_total": 41204,
|
| 54 |
+
"hop3_n_pos": 1136
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"relation": "has_phenotype",
|
| 58 |
+
"hop1_n_total": 15275,
|
| 59 |
+
"hop1_n_pos": 1068,
|
| 60 |
+
"hop2_n_total": 5800,
|
| 61 |
+
"hop2_n_pos": 69,
|
| 62 |
+
"hop3_n_total": 3617,
|
| 63 |
+
"hop3_n_pos": 9
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"relation": "disease_causing_germline_mutation_s_in",
|
| 67 |
+
"hop1_n_total": 337,
|
| 68 |
+
"hop1_n_pos": 37,
|
| 69 |
+
"hop2_n_total": 406,
|
| 70 |
+
"hop2_n_pos": 5,
|
| 71 |
+
"hop3_n_total": 95,
|
| 72 |
+
"hop3_n_pos": 0
|
| 73 |
+
},
|
| 74 |
+
{
|
| 75 |
+
"relation": "major_susceptibility_factor_in",
|
| 76 |
+
"hop1_n_total": 40,
|
| 77 |
+
"hop1_n_pos": 0,
|
| 78 |
+
"hop2_n_total": 349,
|
| 79 |
+
"hop2_n_pos": 1,
|
| 80 |
+
"hop3_n_total": 362,
|
| 81 |
+
"hop3_n_pos": 0
|
| 82 |
+
},
|
| 83 |
+
{
|
| 84 |
+
"relation": "disease_causing_germline_mutation_s_loss_of_function_in",
|
| 85 |
+
"hop1_n_total": 78,
|
| 86 |
+
"hop1_n_pos": 6,
|
| 87 |
+
"hop2_n_total": 99,
|
| 88 |
+
"hop2_n_pos": 1,
|
| 89 |
+
"hop3_n_total": 76,
|
| 90 |
+
"hop3_n_pos": 0
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"relation": "candidate_gene_tested_in",
|
| 94 |
+
"hop1_n_total": 39,
|
| 95 |
+
"hop1_n_pos": 0,
|
| 96 |
+
"hop2_n_total": 84,
|
| 97 |
+
"hop2_n_pos": 0,
|
| 98 |
+
"hop3_n_total": 48,
|
| 99 |
+
"hop3_n_pos": 0
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"relation": "disease_causing_somatic_mutation_s_in",
|
| 103 |
+
"hop1_n_total": 9,
|
| 104 |
+
"hop1_n_pos": 1,
|
| 105 |
+
"hop2_n_total": 49,
|
| 106 |
+
"hop2_n_pos": 0,
|
| 107 |
+
"hop3_n_total": 19,
|
| 108 |
+
"hop3_n_pos": 0
|
| 109 |
+
},
|
| 110 |
+
{
|
| 111 |
+
"relation": "role_in_the_phenotype_of",
|
| 112 |
+
"hop1_n_total": 25,
|
| 113 |
+
"hop1_n_pos": 0,
|
| 114 |
+
"hop2_n_total": 9,
|
| 115 |
+
"hop2_n_pos": 0,
|
| 116 |
+
"hop3_n_total": 0,
|
| 117 |
+
"hop3_n_pos": 0
|
| 118 |
+
},
|
| 119 |
+
{
|
| 120 |
+
"relation": "disease_causing_germline_mutation_s_gain_of_function_in",
|
| 121 |
+
"hop1_n_total": 13,
|
| 122 |
+
"hop1_n_pos": 4,
|
| 123 |
+
"hop2_n_total": 0,
|
| 124 |
+
"hop2_n_pos": 0,
|
| 125 |
+
"hop3_n_total": 1,
|
| 126 |
+
"hop3_n_pos": 0
|
| 127 |
+
},
|
| 128 |
+
{
|
| 129 |
+
"relation": "modifying_germline_mutation_in",
|
| 130 |
+
"hop1_n_total": 2,
|
| 131 |
+
"hop1_n_pos": 1,
|
| 132 |
+
"hop2_n_total": 9,
|
| 133 |
+
"hop2_n_pos": 0,
|
| 134 |
+
"hop3_n_total": 2,
|
| 135 |
+
"hop3_n_pos": 0
|
| 136 |
+
},
|
| 137 |
+
{
|
| 138 |
+
"relation": "part_of_a_fusion_gene_in",
|
| 139 |
+
"hop1_n_total": 2,
|
| 140 |
+
"hop1_n_pos": 0,
|
| 141 |
+
"hop2_n_total": 3,
|
| 142 |
+
"hop2_n_pos": 0,
|
| 143 |
+
"hop3_n_total": 0,
|
| 144 |
+
"hop3_n_pos": 0
|
| 145 |
+
}
|
| 146 |
+
],
|
| 147 |
+
"per_hop_relation_f1_top2": [
|
| 148 |
+
{
|
| 149 |
+
"relation": "is_a",
|
| 150 |
+
"hop": 1,
|
| 151 |
+
"n_total": 2223,
|
| 152 |
+
"n_pos": 1883,
|
| 153 |
+
"precision": 0.8470535312640576,
|
| 154 |
+
"recall": 1.0,
|
| 155 |
+
"f1": 0.9171943497320995
|
| 156 |
+
},
|
| 157 |
+
{
|
| 158 |
+
"relation": "is_a",
|
| 159 |
+
"hop": 2,
|
| 160 |
+
"n_total": 32042,
|
| 161 |
+
"n_pos": 2195,
|
| 162 |
+
"precision": 0.437440305635148,
|
| 163 |
+
"recall": 0.6259681093394077,
|
| 164 |
+
"f1": 0.5149925037481259
|
| 165 |
+
},
|
| 166 |
+
{
|
| 167 |
+
"relation": "is_a",
|
| 168 |
+
"hop": 3,
|
| 169 |
+
"n_total": 41204,
|
| 170 |
+
"n_pos": 1136,
|
| 171 |
+
"precision": 0.24549918166939444,
|
| 172 |
+
"recall": 0.2640845070422535,
|
| 173 |
+
"f1": 0.2544529262086514
|
| 174 |
+
},
|
| 175 |
+
{
|
| 176 |
+
"relation": "has_phenotype",
|
| 177 |
+
"hop": 1,
|
| 178 |
+
"n_total": 15275,
|
| 179 |
+
"n_pos": 1068,
|
| 180 |
+
"precision": 0.4166666666666667,
|
| 181 |
+
"recall": 0.028089887640449437,
|
| 182 |
+
"f1": 0.05263157894736842
|
| 183 |
+
},
|
| 184 |
+
{
|
| 185 |
+
"relation": "has_phenotype",
|
| 186 |
+
"hop": 2,
|
| 187 |
+
"n_total": 5800,
|
| 188 |
+
"n_pos": 69,
|
| 189 |
+
"precision": 0.0,
|
| 190 |
+
"recall": 0.0,
|
| 191 |
+
"f1": 0.0
|
| 192 |
+
},
|
| 193 |
+
{
|
| 194 |
+
"relation": "has_phenotype",
|
| 195 |
+
"hop": 3,
|
| 196 |
+
"n_total": 3617,
|
| 197 |
+
"n_pos": 9,
|
| 198 |
+
"precision": 0.0,
|
| 199 |
+
"recall": 0.0,
|
| 200 |
+
"f1": 0.0
|
| 201 |
+
}
|
| 202 |
+
]
|
| 203 |
+
}
|
results/hop_stratified_seed2024.json
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"checkpoint": "runs\\no_dc\\seed_2024\\best.pt",
|
| 3 |
+
"mode": "autoregressive",
|
| 4 |
+
"threshold": 0.8,
|
| 5 |
+
"per_hop": [
|
| 6 |
+
{
|
| 7 |
+
"hop": 1,
|
| 8 |
+
"n_total": 18043,
|
| 9 |
+
"n_pos": 3000,
|
| 10 |
+
"pos_rate": 0.1662694673834728,
|
| 11 |
+
"precision": 0.8206984667802385,
|
| 12 |
+
"recall": 0.6423333333333333,
|
| 13 |
+
"f1": 0.7206432311144353,
|
| 14 |
+
"score_mean": 0.5775352711251205,
|
| 15 |
+
"score_std": 0.18306968503822213,
|
| 16 |
+
"score_mean_pos": 0.835189257889986,
|
| 17 |
+
"score_mean_neg": 0.5261517731330579
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"hop": 2,
|
| 21 |
+
"n_total": 38850,
|
| 22 |
+
"n_pos": 2271,
|
| 23 |
+
"pos_rate": 0.05845559845559845,
|
| 24 |
+
"precision": 0.43853503184713377,
|
| 25 |
+
"recall": 0.6063408190224571,
|
| 26 |
+
"f1": 0.5089632230641287,
|
| 27 |
+
"score_mean": 0.2152888699591641,
|
| 28 |
+
"score_std": 0.23939307661142137,
|
| 29 |
+
"score_mean_pos": 0.6760690421700963,
|
| 30 |
+
"score_mean_neg": 0.18668142385372036
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"hop": 3,
|
| 34 |
+
"n_total": 45424,
|
| 35 |
+
"n_pos": 1145,
|
| 36 |
+
"pos_rate": 0.025206939063050368,
|
| 37 |
+
"precision": 0.24123120973514675,
|
| 38 |
+
"recall": 0.2943231441048035,
|
| 39 |
+
"f1": 0.26514555468135326,
|
| 40 |
+
"score_mean": 0.0668562511488665,
|
| 41 |
+
"score_std": 0.2058770274783993,
|
| 42 |
+
"score_mean_pos": 0.4722513639256785,
|
| 43 |
+
"score_mean_neg": 0.056373236534050214
|
| 44 |
+
}
|
| 45 |
+
],
|
| 46 |
+
"hop_x_relation_counts": [
|
| 47 |
+
{
|
| 48 |
+
"relation": "is_a",
|
| 49 |
+
"hop1_n_total": 2223,
|
| 50 |
+
"hop1_n_pos": 1883,
|
| 51 |
+
"hop2_n_total": 32042,
|
| 52 |
+
"hop2_n_pos": 2195,
|
| 53 |
+
"hop3_n_total": 41204,
|
| 54 |
+
"hop3_n_pos": 1136
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"relation": "has_phenotype",
|
| 58 |
+
"hop1_n_total": 15275,
|
| 59 |
+
"hop1_n_pos": 1068,
|
| 60 |
+
"hop2_n_total": 5800,
|
| 61 |
+
"hop2_n_pos": 69,
|
| 62 |
+
"hop3_n_total": 3617,
|
| 63 |
+
"hop3_n_pos": 9
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"relation": "disease_causing_germline_mutation_s_in",
|
| 67 |
+
"hop1_n_total": 337,
|
| 68 |
+
"hop1_n_pos": 37,
|
| 69 |
+
"hop2_n_total": 406,
|
| 70 |
+
"hop2_n_pos": 5,
|
| 71 |
+
"hop3_n_total": 95,
|
| 72 |
+
"hop3_n_pos": 0
|
| 73 |
+
},
|
| 74 |
+
{
|
| 75 |
+
"relation": "major_susceptibility_factor_in",
|
| 76 |
+
"hop1_n_total": 40,
|
| 77 |
+
"hop1_n_pos": 0,
|
| 78 |
+
"hop2_n_total": 349,
|
| 79 |
+
"hop2_n_pos": 1,
|
| 80 |
+
"hop3_n_total": 362,
|
| 81 |
+
"hop3_n_pos": 0
|
| 82 |
+
},
|
| 83 |
+
{
|
| 84 |
+
"relation": "disease_causing_germline_mutation_s_loss_of_function_in",
|
| 85 |
+
"hop1_n_total": 78,
|
| 86 |
+
"hop1_n_pos": 6,
|
| 87 |
+
"hop2_n_total": 99,
|
| 88 |
+
"hop2_n_pos": 1,
|
| 89 |
+
"hop3_n_total": 76,
|
| 90 |
+
"hop3_n_pos": 0
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"relation": "candidate_gene_tested_in",
|
| 94 |
+
"hop1_n_total": 39,
|
| 95 |
+
"hop1_n_pos": 0,
|
| 96 |
+
"hop2_n_total": 84,
|
| 97 |
+
"hop2_n_pos": 0,
|
| 98 |
+
"hop3_n_total": 48,
|
| 99 |
+
"hop3_n_pos": 0
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"relation": "disease_causing_somatic_mutation_s_in",
|
| 103 |
+
"hop1_n_total": 9,
|
| 104 |
+
"hop1_n_pos": 1,
|
| 105 |
+
"hop2_n_total": 49,
|
| 106 |
+
"hop2_n_pos": 0,
|
| 107 |
+
"hop3_n_total": 19,
|
| 108 |
+
"hop3_n_pos": 0
|
| 109 |
+
},
|
| 110 |
+
{
|
| 111 |
+
"relation": "role_in_the_phenotype_of",
|
| 112 |
+
"hop1_n_total": 25,
|
| 113 |
+
"hop1_n_pos": 0,
|
| 114 |
+
"hop2_n_total": 9,
|
| 115 |
+
"hop2_n_pos": 0,
|
| 116 |
+
"hop3_n_total": 0,
|
| 117 |
+
"hop3_n_pos": 0
|
| 118 |
+
},
|
| 119 |
+
{
|
| 120 |
+
"relation": "disease_causing_germline_mutation_s_gain_of_function_in",
|
| 121 |
+
"hop1_n_total": 13,
|
| 122 |
+
"hop1_n_pos": 4,
|
| 123 |
+
"hop2_n_total": 0,
|
| 124 |
+
"hop2_n_pos": 0,
|
| 125 |
+
"hop3_n_total": 1,
|
| 126 |
+
"hop3_n_pos": 0
|
| 127 |
+
},
|
| 128 |
+
{
|
| 129 |
+
"relation": "modifying_germline_mutation_in",
|
| 130 |
+
"hop1_n_total": 2,
|
| 131 |
+
"hop1_n_pos": 1,
|
| 132 |
+
"hop2_n_total": 9,
|
| 133 |
+
"hop2_n_pos": 0,
|
| 134 |
+
"hop3_n_total": 2,
|
| 135 |
+
"hop3_n_pos": 0
|
| 136 |
+
},
|
| 137 |
+
{
|
| 138 |
+
"relation": "part_of_a_fusion_gene_in",
|
| 139 |
+
"hop1_n_total": 2,
|
| 140 |
+
"hop1_n_pos": 0,
|
| 141 |
+
"hop2_n_total": 3,
|
| 142 |
+
"hop2_n_pos": 0,
|
| 143 |
+
"hop3_n_total": 0,
|
| 144 |
+
"hop3_n_pos": 0
|
| 145 |
+
}
|
| 146 |
+
],
|
| 147 |
+
"per_hop_relation_f1_top2": [
|
| 148 |
+
{
|
| 149 |
+
"relation": "is_a",
|
| 150 |
+
"hop": 1,
|
| 151 |
+
"n_total": 2223,
|
| 152 |
+
"n_pos": 1883,
|
| 153 |
+
"precision": 0.8470535312640576,
|
| 154 |
+
"recall": 1.0,
|
| 155 |
+
"f1": 0.9171943497320995
|
| 156 |
+
},
|
| 157 |
+
{
|
| 158 |
+
"relation": "is_a",
|
| 159 |
+
"hop": 2,
|
| 160 |
+
"n_total": 32042,
|
| 161 |
+
"n_pos": 2195,
|
| 162 |
+
"precision": 0.43853503184713377,
|
| 163 |
+
"recall": 0.6273348519362186,
|
| 164 |
+
"f1": 0.5162136832239925
|
| 165 |
+
},
|
| 166 |
+
{
|
| 167 |
+
"relation": "is_a",
|
| 168 |
+
"hop": 3,
|
| 169 |
+
"n_total": 41204,
|
| 170 |
+
"n_pos": 1136,
|
| 171 |
+
"precision": 0.24123120973514675,
|
| 172 |
+
"recall": 0.2966549295774648,
|
| 173 |
+
"f1": 0.26608764311093563
|
| 174 |
+
},
|
| 175 |
+
{
|
| 176 |
+
"relation": "has_phenotype",
|
| 177 |
+
"hop": 1,
|
| 178 |
+
"n_total": 15275,
|
| 179 |
+
"n_pos": 1068,
|
| 180 |
+
"precision": 0.36936936936936937,
|
| 181 |
+
"recall": 0.03838951310861423,
|
| 182 |
+
"f1": 0.06955046649703138
|
| 183 |
+
},
|
| 184 |
+
{
|
| 185 |
+
"relation": "has_phenotype",
|
| 186 |
+
"hop": 2,
|
| 187 |
+
"n_total": 5800,
|
| 188 |
+
"n_pos": 69,
|
| 189 |
+
"precision": 0.0,
|
| 190 |
+
"recall": 0.0,
|
| 191 |
+
"f1": 0.0
|
| 192 |
+
},
|
| 193 |
+
{
|
| 194 |
+
"relation": "has_phenotype",
|
| 195 |
+
"hop": 3,
|
| 196 |
+
"n_total": 3617,
|
| 197 |
+
"n_pos": 9,
|
| 198 |
+
"precision": 0.0,
|
| 199 |
+
"recall": 0.0,
|
| 200 |
+
"f1": 0.0
|
| 201 |
+
}
|
| 202 |
+
]
|
| 203 |
+
}
|
results/hop_stratified_seed42.json
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"checkpoint": "runs\\no_dc\\seed_42\\best.pt",
|
| 3 |
+
"mode": "autoregressive",
|
| 4 |
+
"threshold": 0.8,
|
| 5 |
+
"per_hop": [
|
| 6 |
+
{
|
| 7 |
+
"hop": 1,
|
| 8 |
+
"n_total": 18043,
|
| 9 |
+
"n_pos": 3000,
|
| 10 |
+
"pos_rate": 0.1662694673834728,
|
| 11 |
+
"precision": 0.8206984667802385,
|
| 12 |
+
"recall": 0.6423333333333333,
|
| 13 |
+
"f1": 0.7206432311144353,
|
| 14 |
+
"score_mean": 0.5821448763357472,
|
| 15 |
+
"score_std": 0.1806795479628059,
|
| 16 |
+
"score_mean_pos": 0.8365760689576467,
|
| 17 |
+
"score_mean_neg": 0.5314040947186696
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"hop": 2,
|
| 21 |
+
"n_total": 38850,
|
| 22 |
+
"n_pos": 2271,
|
| 23 |
+
"pos_rate": 0.05845559845559845,
|
| 24 |
+
"precision": 0.43746031746031744,
|
| 25 |
+
"recall": 0.6067811536767944,
|
| 26 |
+
"f1": 0.5083932853717026,
|
| 27 |
+
"score_mean": 0.2155249401183225,
|
| 28 |
+
"score_std": 0.2394194361365147,
|
| 29 |
+
"score_mean_pos": 0.6760359883365004,
|
| 30 |
+
"score_mean_neg": 0.1869342025228857
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"hop": 3,
|
| 34 |
+
"n_total": 45424,
|
| 35 |
+
"n_pos": 1145,
|
| 36 |
+
"pos_rate": 0.025206939063050368,
|
| 37 |
+
"precision": 0.24103299856527977,
|
| 38 |
+
"recall": 0.2934497816593886,
|
| 39 |
+
"f1": 0.264671130366286,
|
| 40 |
+
"score_mean": 0.06681433546379811,
|
| 41 |
+
"score_std": 0.20566269681681607,
|
| 42 |
+
"score_mean_pos": 0.4691532548687799,
|
| 43 |
+
"score_mean_neg": 0.0564103502175481
|
| 44 |
+
}
|
| 45 |
+
],
|
| 46 |
+
"hop_x_relation_counts": [
|
| 47 |
+
{
|
| 48 |
+
"relation": "is_a",
|
| 49 |
+
"hop1_n_total": 2223,
|
| 50 |
+
"hop1_n_pos": 1883,
|
| 51 |
+
"hop2_n_total": 32042,
|
| 52 |
+
"hop2_n_pos": 2195,
|
| 53 |
+
"hop3_n_total": 41204,
|
| 54 |
+
"hop3_n_pos": 1136
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"relation": "has_phenotype",
|
| 58 |
+
"hop1_n_total": 15275,
|
| 59 |
+
"hop1_n_pos": 1068,
|
| 60 |
+
"hop2_n_total": 5800,
|
| 61 |
+
"hop2_n_pos": 69,
|
| 62 |
+
"hop3_n_total": 3617,
|
| 63 |
+
"hop3_n_pos": 9
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"relation": "disease_causing_germline_mutation_s_in",
|
| 67 |
+
"hop1_n_total": 337,
|
| 68 |
+
"hop1_n_pos": 37,
|
| 69 |
+
"hop2_n_total": 406,
|
| 70 |
+
"hop2_n_pos": 5,
|
| 71 |
+
"hop3_n_total": 95,
|
| 72 |
+
"hop3_n_pos": 0
|
| 73 |
+
},
|
| 74 |
+
{
|
| 75 |
+
"relation": "major_susceptibility_factor_in",
|
| 76 |
+
"hop1_n_total": 40,
|
| 77 |
+
"hop1_n_pos": 0,
|
| 78 |
+
"hop2_n_total": 349,
|
| 79 |
+
"hop2_n_pos": 1,
|
| 80 |
+
"hop3_n_total": 362,
|
| 81 |
+
"hop3_n_pos": 0
|
| 82 |
+
},
|
| 83 |
+
{
|
| 84 |
+
"relation": "disease_causing_germline_mutation_s_loss_of_function_in",
|
| 85 |
+
"hop1_n_total": 78,
|
| 86 |
+
"hop1_n_pos": 6,
|
| 87 |
+
"hop2_n_total": 99,
|
| 88 |
+
"hop2_n_pos": 1,
|
| 89 |
+
"hop3_n_total": 76,
|
| 90 |
+
"hop3_n_pos": 0
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"relation": "candidate_gene_tested_in",
|
| 94 |
+
"hop1_n_total": 39,
|
| 95 |
+
"hop1_n_pos": 0,
|
| 96 |
+
"hop2_n_total": 84,
|
| 97 |
+
"hop2_n_pos": 0,
|
| 98 |
+
"hop3_n_total": 48,
|
| 99 |
+
"hop3_n_pos": 0
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"relation": "disease_causing_somatic_mutation_s_in",
|
| 103 |
+
"hop1_n_total": 9,
|
| 104 |
+
"hop1_n_pos": 1,
|
| 105 |
+
"hop2_n_total": 49,
|
| 106 |
+
"hop2_n_pos": 0,
|
| 107 |
+
"hop3_n_total": 19,
|
| 108 |
+
"hop3_n_pos": 0
|
| 109 |
+
},
|
| 110 |
+
{
|
| 111 |
+
"relation": "role_in_the_phenotype_of",
|
| 112 |
+
"hop1_n_total": 25,
|
| 113 |
+
"hop1_n_pos": 0,
|
| 114 |
+
"hop2_n_total": 9,
|
| 115 |
+
"hop2_n_pos": 0,
|
| 116 |
+
"hop3_n_total": 0,
|
| 117 |
+
"hop3_n_pos": 0
|
| 118 |
+
},
|
| 119 |
+
{
|
| 120 |
+
"relation": "disease_causing_germline_mutation_s_gain_of_function_in",
|
| 121 |
+
"hop1_n_total": 13,
|
| 122 |
+
"hop1_n_pos": 4,
|
| 123 |
+
"hop2_n_total": 0,
|
| 124 |
+
"hop2_n_pos": 0,
|
| 125 |
+
"hop3_n_total": 1,
|
| 126 |
+
"hop3_n_pos": 0
|
| 127 |
+
},
|
| 128 |
+
{
|
| 129 |
+
"relation": "modifying_germline_mutation_in",
|
| 130 |
+
"hop1_n_total": 2,
|
| 131 |
+
"hop1_n_pos": 1,
|
| 132 |
+
"hop2_n_total": 9,
|
| 133 |
+
"hop2_n_pos": 0,
|
| 134 |
+
"hop3_n_total": 2,
|
| 135 |
+
"hop3_n_pos": 0
|
| 136 |
+
},
|
| 137 |
+
{
|
| 138 |
+
"relation": "part_of_a_fusion_gene_in",
|
| 139 |
+
"hop1_n_total": 2,
|
| 140 |
+
"hop1_n_pos": 0,
|
| 141 |
+
"hop2_n_total": 3,
|
| 142 |
+
"hop2_n_pos": 0,
|
| 143 |
+
"hop3_n_total": 0,
|
| 144 |
+
"hop3_n_pos": 0
|
| 145 |
+
}
|
| 146 |
+
],
|
| 147 |
+
"per_hop_relation_f1_top2": [
|
| 148 |
+
{
|
| 149 |
+
"relation": "is_a",
|
| 150 |
+
"hop": 1,
|
| 151 |
+
"n_total": 2223,
|
| 152 |
+
"n_pos": 1883,
|
| 153 |
+
"precision": 0.8470535312640576,
|
| 154 |
+
"recall": 1.0,
|
| 155 |
+
"f1": 0.9171943497320995
|
| 156 |
+
},
|
| 157 |
+
{
|
| 158 |
+
"relation": "is_a",
|
| 159 |
+
"hop": 2,
|
| 160 |
+
"n_total": 32042,
|
| 161 |
+
"n_pos": 2195,
|
| 162 |
+
"precision": 0.43746031746031744,
|
| 163 |
+
"recall": 0.6277904328018223,
|
| 164 |
+
"f1": 0.515622076707203
|
| 165 |
+
},
|
| 166 |
+
{
|
| 167 |
+
"relation": "is_a",
|
| 168 |
+
"hop": 3,
|
| 169 |
+
"n_total": 41204,
|
| 170 |
+
"n_pos": 1136,
|
| 171 |
+
"precision": 0.24103299856527977,
|
| 172 |
+
"recall": 0.29577464788732394,
|
| 173 |
+
"f1": 0.2656126482213439
|
| 174 |
+
},
|
| 175 |
+
{
|
| 176 |
+
"relation": "has_phenotype",
|
| 177 |
+
"hop": 1,
|
| 178 |
+
"n_total": 15275,
|
| 179 |
+
"n_pos": 1068,
|
| 180 |
+
"precision": 0.375,
|
| 181 |
+
"recall": 0.03932584269662921,
|
| 182 |
+
"f1": 0.0711864406779661
|
| 183 |
+
},
|
| 184 |
+
{
|
| 185 |
+
"relation": "has_phenotype",
|
| 186 |
+
"hop": 2,
|
| 187 |
+
"n_total": 5800,
|
| 188 |
+
"n_pos": 69,
|
| 189 |
+
"precision": 0.0,
|
| 190 |
+
"recall": 0.0,
|
| 191 |
+
"f1": 0.0
|
| 192 |
+
},
|
| 193 |
+
{
|
| 194 |
+
"relation": "has_phenotype",
|
| 195 |
+
"hop": 3,
|
| 196 |
+
"n_total": 3617,
|
| 197 |
+
"n_pos": 9,
|
| 198 |
+
"precision": 0.0,
|
| 199 |
+
"recall": 0.0,
|
| 200 |
+
"f1": 0.0
|
| 201 |
+
}
|
| 202 |
+
]
|
| 203 |
+
}
|
runs/dc_lambda010/seed_1337/config.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"config": {
|
| 3 |
+
"d": 1024,
|
| 4 |
+
"rho": 16,
|
| 5 |
+
"L": 3,
|
| 6 |
+
"theta": 0.8,
|
| 7 |
+
"K_r": 20,
|
| 8 |
+
"gamma_C": 0.25,
|
| 9 |
+
"gamma_D": 0.2,
|
| 10 |
+
"lambda_C": 0.35,
|
| 11 |
+
"lambda_D": 0.1,
|
| 12 |
+
"hc3_buffer_size": 200,
|
| 13 |
+
"hc3_negatives_per_anchor": 4,
|
| 14 |
+
"hc3_buffer_refresh_steps": 100,
|
| 15 |
+
"lr": 0.0003,
|
| 16 |
+
"lr_min": 1e-05,
|
| 17 |
+
"weight_decay": 0.01,
|
| 18 |
+
"batch_size": 256,
|
| 19 |
+
"epochs": 10,
|
| 20 |
+
"warmup_epochs": 1,
|
| 21 |
+
"grad_clip": 1.0,
|
| 22 |
+
"early_stop_patience": 5,
|
| 23 |
+
"early_stop_metric": "f1",
|
| 24 |
+
"encoder_name": "michiyasunaga/BioLinkBERT-large",
|
| 25 |
+
"encoder_frozen": true,
|
| 26 |
+
"kg_path": "data/processed/merged_kg_v2.tsv",
|
| 27 |
+
"train_path": "data/processed/train.json",
|
| 28 |
+
"dev_path": "data/processed/dev.json",
|
| 29 |
+
"test_path": "data/processed/test.json",
|
| 30 |
+
"min_relation_freq": 50,
|
| 31 |
+
"seed": 1337,
|
| 32 |
+
"deterministic": true,
|
| 33 |
+
"micro_batch_size": 4,
|
| 34 |
+
"grad_accum_steps": 64,
|
| 35 |
+
"mixed_precision": "fp16"
|
| 36 |
+
},
|
| 37 |
+
"config_hash": "3ea32a7544a3",
|
| 38 |
+
"ablation": {
|
| 39 |
+
"use_csv": true,
|
| 40 |
+
"use_dbm": true,
|
| 41 |
+
"use_hc3": true,
|
| 42 |
+
"use_dc": true,
|
| 43 |
+
"use_freqcap": true,
|
| 44 |
+
"csv_pool": "mean",
|
| 45 |
+
"gate_activation": "sigmoid"
|
| 46 |
+
},
|
| 47 |
+
"args": {
|
| 48 |
+
"config": "configs\\dc_lambda010.yaml",
|
| 49 |
+
"seed": 1337,
|
| 50 |
+
"output_root": "runs",
|
| 51 |
+
"cache_dir": "cache",
|
| 52 |
+
"device": "cuda",
|
| 53 |
+
"debug_subset": null
|
| 54 |
+
},
|
| 55 |
+
"torch_version": "2.2.1+cu118",
|
| 56 |
+
"cuda_available": true,
|
| 57 |
+
"gpu_name": "NVIDIA GeForce RTX 4060 Laptop GPU",
|
| 58 |
+
"python_version": "3.11.5",
|
| 59 |
+
"platform": "Windows-10-10.0.26200-SP0"
|
| 60 |
+
}
|
runs/dc_lambda010/seed_1337/final_metrics.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"epoch": 2,
|
| 3 |
+
"train_loss": 0.015113744206629129,
|
| 4 |
+
"train_bce": 0.013060060305446928,
|
| 5 |
+
"train_dc": 0.007093780665091978,
|
| 6 |
+
"train_hc3": 0.0038408746070336145,
|
| 7 |
+
"dev_precision": 0.557453666398066,
|
| 8 |
+
"dev_recall": 0.5522030651340997,
|
| 9 |
+
"dev_f1": 0.5548159435399791,
|
| 10 |
+
"dev_map": 0.6652193527216996,
|
| 11 |
+
"learning_rate": 0.0002912019213331988,
|
| 12 |
+
"wall_clock_seconds": 186.1106984615326
|
| 13 |
+
}
|
runs/dc_lambda010/seed_1337/history.jsonl
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{"epoch": 1, "train_loss": 0.019308436556193354, "train_bce": 0.017321521228503493, "train_dc": 0.006426094722226206, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5985345160046278, "dev_recall": 0.4955300127713921, "dev_f1": 0.5421834061135371, "dev_map": 0.6632368465729074, "learning_rate": 0.00029999997896208426, "wall_clock_seconds": 619.3529281616211}
|
| 2 |
+
{"epoch": 2, "train_loss": 0.015113744206629129, "train_bce": 0.013060060305446928, "train_dc": 0.007093780665091978, "train_hc3": 0.0038408746070336145, "dev_precision": 0.557453666398066, "dev_recall": 0.5522030651340997, "dev_f1": 0.5548159435399791, "dev_map": 0.6652193527216996, "learning_rate": 0.0002912019213331988, "wall_clock_seconds": 186.1106984615326}
|
| 3 |
+
{"epoch": 3, "train_loss": 0.014471906816703607, "train_bce": 0.012516204908701532, "train_dc": 0.006113960761997171, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5298607992815447, "dev_recall": 0.5651340996168582, "dev_f1": 0.5469293163383545, "dev_map": 0.6504335108188682, "learning_rate": 0.0002659256770308768, "wall_clock_seconds": 212.41909408569336}
|
| 4 |
+
{"epoch": 4, "train_loss": 0.014280542490509716, "train_bce": 0.012355582342246117, "train_dc": 0.005806542972279172, "train_hc3": 0.0038408746070336145, "dev_precision": 0.519022132214668, "dev_recall": 0.5727969348659003, "dev_f1": 0.5445852621992866, "dev_map": 0.6541289985099419, "learning_rate": 0.00022722925484045786, "wall_clock_seconds": 212.44377183914185}
|
| 5 |
+
{"epoch": 5, "train_loss": 0.014165094377912609, "train_bce": 0.01225624893248278, "train_dc": 0.005645396599345712, "train_hc3": 0.0038408746070336145, "dev_precision": 0.513314447592068, "dev_recall": 0.578544061302682, "dev_f1": 0.5439807865505855, "dev_map": 0.6503835073068308, "learning_rate": 0.0001797942837889505, "wall_clock_seconds": 213.1819248199463}
|
| 6 |
+
{"epoch": 6, "train_loss": 0.014082577235894995, "train_bce": 0.012186359327338423, "train_dc": 0.005519120800016324, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5113109456231558, "dev_recall": 0.5809386973180076, "dev_f1": 0.5439055377027128, "dev_map": 0.6483537289664857, "learning_rate": 0.0001293596132272652, "wall_clock_seconds": 198.86546444892883}
|
| 7 |
+
{"epoch": 7, "train_loss": 0.014021225025477754, "train_bce": 0.012130890549783672, "train_dc": 0.005460286833092735, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5097874720357942, "dev_recall": 0.5820561941251596, "dev_f1": 0.5435301132975552, "dev_map": 0.6470899056766319, "learning_rate": 8.202700668556269e-05, "wall_clock_seconds": 206.0203673839569}
|
runs/dc_lambda010/seed_2024/config.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"config": {
|
| 3 |
+
"d": 1024,
|
| 4 |
+
"rho": 16,
|
| 5 |
+
"L": 3,
|
| 6 |
+
"theta": 0.8,
|
| 7 |
+
"K_r": 20,
|
| 8 |
+
"gamma_C": 0.25,
|
| 9 |
+
"gamma_D": 0.2,
|
| 10 |
+
"lambda_C": 0.35,
|
| 11 |
+
"lambda_D": 0.1,
|
| 12 |
+
"hc3_buffer_size": 200,
|
| 13 |
+
"hc3_negatives_per_anchor": 4,
|
| 14 |
+
"hc3_buffer_refresh_steps": 100,
|
| 15 |
+
"lr": 0.0003,
|
| 16 |
+
"lr_min": 1e-05,
|
| 17 |
+
"weight_decay": 0.01,
|
| 18 |
+
"batch_size": 256,
|
| 19 |
+
"epochs": 10,
|
| 20 |
+
"warmup_epochs": 1,
|
| 21 |
+
"grad_clip": 1.0,
|
| 22 |
+
"early_stop_patience": 5,
|
| 23 |
+
"early_stop_metric": "f1",
|
| 24 |
+
"encoder_name": "michiyasunaga/BioLinkBERT-large",
|
| 25 |
+
"encoder_frozen": true,
|
| 26 |
+
"kg_path": "data/processed/merged_kg_v2.tsv",
|
| 27 |
+
"train_path": "data/processed/train.json",
|
| 28 |
+
"dev_path": "data/processed/dev.json",
|
| 29 |
+
"test_path": "data/processed/test.json",
|
| 30 |
+
"min_relation_freq": 50,
|
| 31 |
+
"seed": 2024,
|
| 32 |
+
"deterministic": true,
|
| 33 |
+
"micro_batch_size": 4,
|
| 34 |
+
"grad_accum_steps": 64,
|
| 35 |
+
"mixed_precision": "fp16"
|
| 36 |
+
},
|
| 37 |
+
"config_hash": "b5e7f7a791a9",
|
| 38 |
+
"ablation": {
|
| 39 |
+
"use_csv": true,
|
| 40 |
+
"use_dbm": true,
|
| 41 |
+
"use_hc3": true,
|
| 42 |
+
"use_dc": true,
|
| 43 |
+
"use_freqcap": true,
|
| 44 |
+
"csv_pool": "mean",
|
| 45 |
+
"gate_activation": "sigmoid"
|
| 46 |
+
},
|
| 47 |
+
"args": {
|
| 48 |
+
"config": "configs\\dc_lambda010.yaml",
|
| 49 |
+
"seed": 2024,
|
| 50 |
+
"output_root": "runs",
|
| 51 |
+
"cache_dir": "cache",
|
| 52 |
+
"device": "cuda",
|
| 53 |
+
"debug_subset": null
|
| 54 |
+
},
|
| 55 |
+
"torch_version": "2.2.1+cu118",
|
| 56 |
+
"cuda_available": true,
|
| 57 |
+
"gpu_name": "NVIDIA GeForce RTX 4060 Laptop GPU",
|
| 58 |
+
"python_version": "3.11.5",
|
| 59 |
+
"platform": "Windows-10-10.0.26200-SP0"
|
| 60 |
+
}
|
runs/dc_lambda010/seed_2024/final_metrics.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"epoch": 2,
|
| 3 |
+
"train_loss": 0.015118593132108057,
|
| 4 |
+
"train_bce": 0.013066735937389428,
|
| 5 |
+
"train_dc": 0.007075513935245275,
|
| 6 |
+
"train_hc3": 0.0038408746070336145,
|
| 7 |
+
"dev_precision": 0.5619483491337038,
|
| 8 |
+
"dev_recall": 0.5488505747126436,
|
| 9 |
+
"dev_f1": 0.5553222419641415,
|
| 10 |
+
"dev_map": 0.6670695719845979,
|
| 11 |
+
"learning_rate": 0.0002912019213331988,
|
| 12 |
+
"wall_clock_seconds": 213.57218647003174
|
| 13 |
+
}
|
runs/dc_lambda010/seed_2024/history.jsonl
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{"epoch": 1, "train_loss": 0.019277647056187345, "train_bce": 0.017283399351028916, "train_dc": 0.006499418423889856, "train_hc3": 0.0038408746070336145, "dev_precision": 0.6061260553701159, "dev_recall": 0.492816091954023, "dev_f1": 0.5436294796160959, "dev_map": 0.6669038088568597, "learning_rate": 0.00029999997896208426, "wall_clock_seconds": 622.3812205791473}
|
| 2 |
+
{"epoch": 2, "train_loss": 0.015118593132108057, "train_bce": 0.013066735937389428, "train_dc": 0.007075513935245275, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5619483491337038, "dev_recall": 0.5488505747126436, "dev_f1": 0.5553222419641415, "dev_map": 0.6670695719845979, "learning_rate": 0.0002912019213331988, "wall_clock_seconds": 213.57218647003174}
|
| 3 |
+
{"epoch": 3, "train_loss": 0.014484207685618339, "train_bce": 0.012522109174555006, "train_dc": 0.006177927138163685, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5257839203447764, "dev_recall": 0.5648148148148148, "dev_f1": 0.5446009389671361, "dev_map": 0.660532568332498, "learning_rate": 0.0002659256770308768, "wall_clock_seconds": 213.4029757976532}
|
| 4 |
+
{"epoch": 4, "train_loss": 0.014288917713151274, "train_bce": 0.0123579115688142, "train_dc": 0.005867003395187836, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5205180442374855, "dev_recall": 0.5710408684546615, "dev_f1": 0.5446102314250914, "dev_map": 0.6559184854984927, "learning_rate": 0.00022722925484045786, "wall_clock_seconds": 212.59179186820984}
|
| 5 |
+
{"epoch": 5, "train_loss": 0.014177476748754865, "train_bce": 0.012265763558042061, "train_dc": 0.005674073652079245, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5156361559331715, "dev_recall": 0.5764687100893997, "dev_f1": 0.5443581819552272, "dev_map": 0.6538870871764543, "learning_rate": 0.0001797942837889505, "wall_clock_seconds": 199.63850927352905}
|
| 6 |
+
{"epoch": 6, "train_loss": 0.014095762579349268, "train_bce": 0.012200400114495786, "train_dc": 0.0055105664081980775, "train_hc3": 0.0038408746070336145, "dev_precision": 0.514346590909091, "dev_recall": 0.5780651340996169, "dev_f1": 0.5443475646422128, "dev_map": 0.6449853021212014, "learning_rate": 0.0001293596132272652, "wall_clock_seconds": 205.6528124809265}
|
| 7 |
+
{"epoch": 7, "train_loss": 0.014042604747375334, "train_bce": 0.012149665409334735, "train_dc": 0.005486335355188235, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5134906060177992, "dev_recall": 0.5803001277139208, "dev_f1": 0.5448549801393989, "dev_map": 0.6454874155364534, "learning_rate": 8.202700668556269e-05, "wall_clock_seconds": 201.8851432800293}
|
runs/dc_lambda010/seed_42/config.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"config": {
|
| 3 |
+
"d": 1024,
|
| 4 |
+
"rho": 16,
|
| 5 |
+
"L": 3,
|
| 6 |
+
"theta": 0.8,
|
| 7 |
+
"K_r": 20,
|
| 8 |
+
"gamma_C": 0.25,
|
| 9 |
+
"gamma_D": 0.2,
|
| 10 |
+
"lambda_C": 0.35,
|
| 11 |
+
"lambda_D": 0.1,
|
| 12 |
+
"hc3_buffer_size": 200,
|
| 13 |
+
"hc3_negatives_per_anchor": 4,
|
| 14 |
+
"hc3_buffer_refresh_steps": 100,
|
| 15 |
+
"lr": 0.0003,
|
| 16 |
+
"lr_min": 1e-05,
|
| 17 |
+
"weight_decay": 0.01,
|
| 18 |
+
"batch_size": 256,
|
| 19 |
+
"epochs": 10,
|
| 20 |
+
"warmup_epochs": 1,
|
| 21 |
+
"grad_clip": 1.0,
|
| 22 |
+
"early_stop_patience": 5,
|
| 23 |
+
"early_stop_metric": "f1",
|
| 24 |
+
"encoder_name": "michiyasunaga/BioLinkBERT-large",
|
| 25 |
+
"encoder_frozen": true,
|
| 26 |
+
"kg_path": "data/processed/merged_kg_v2.tsv",
|
| 27 |
+
"train_path": "data/processed/train.json",
|
| 28 |
+
"dev_path": "data/processed/dev.json",
|
| 29 |
+
"test_path": "data/processed/test.json",
|
| 30 |
+
"min_relation_freq": 50,
|
| 31 |
+
"seed": 42,
|
| 32 |
+
"deterministic": true,
|
| 33 |
+
"micro_batch_size": 4,
|
| 34 |
+
"grad_accum_steps": 64,
|
| 35 |
+
"mixed_precision": "fp16"
|
| 36 |
+
},
|
| 37 |
+
"config_hash": "acdcc94d6418",
|
| 38 |
+
"ablation": {
|
| 39 |
+
"use_csv": true,
|
| 40 |
+
"use_dbm": true,
|
| 41 |
+
"use_hc3": true,
|
| 42 |
+
"use_dc": true,
|
| 43 |
+
"use_freqcap": true,
|
| 44 |
+
"csv_pool": "mean",
|
| 45 |
+
"gate_activation": "sigmoid"
|
| 46 |
+
},
|
| 47 |
+
"args": {
|
| 48 |
+
"config": "configs\\dc_lambda010.yaml",
|
| 49 |
+
"seed": 42,
|
| 50 |
+
"output_root": "runs",
|
| 51 |
+
"cache_dir": "cache",
|
| 52 |
+
"device": "cuda",
|
| 53 |
+
"debug_subset": null
|
| 54 |
+
},
|
| 55 |
+
"torch_version": "2.2.1+cu118",
|
| 56 |
+
"cuda_available": true,
|
| 57 |
+
"gpu_name": "NVIDIA GeForce RTX 4060 Laptop GPU",
|
| 58 |
+
"python_version": "3.11.5",
|
| 59 |
+
"platform": "Windows-10-10.0.26200-SP0"
|
| 60 |
+
}
|
runs/dc_lambda010/seed_42/final_metrics.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"epoch": 2,
|
| 3 |
+
"train_loss": 0.015141186450905479,
|
| 4 |
+
"train_bce": 0.013076732859356713,
|
| 5 |
+
"train_dc": 0.007201478043490602,
|
| 6 |
+
"train_hc3": 0.0038408746070336145,
|
| 7 |
+
"dev_precision": 0.5573135292218275,
|
| 8 |
+
"dev_recall": 0.5510855683269477,
|
| 9 |
+
"dev_f1": 0.5541820516936907,
|
| 10 |
+
"dev_map": 0.6666678369356035,
|
| 11 |
+
"learning_rate": 0.0002912019213331988,
|
| 12 |
+
"wall_clock_seconds": 377.35128116607666
|
| 13 |
+
}
|
runs/dc_lambda010/seed_42/history.jsonl
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{"epoch": 1, "train_loss": 0.01927823839477672, "train_bce": 0.017281827372716014, "train_dc": 0.00652105152939959, "train_hc3": 0.0038408746070336145, "dev_precision": 0.6033508669394116, "dev_recall": 0.49441251596424013, "dev_f1": 0.5434763534263403, "dev_map": 0.6665085356352869, "learning_rate": 0.00029999997896208426, "wall_clock_seconds": 1665.2696824073792}
|
| 2 |
+
{"epoch": 2, "train_loss": 0.015141186450905479, "train_bce": 0.013076732859356713, "train_dc": 0.007201478043490602, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5573135292218275, "dev_recall": 0.5510855683269477, "dev_f1": 0.5541820516936907, "dev_map": 0.6666678369356035, "learning_rate": 0.0002912019213331988, "wall_clock_seconds": 377.35128116607666}
|
| 3 |
+
{"epoch": 3, "train_loss": 0.014495296075031932, "train_bce": 0.012531945475302887, "train_dc": 0.0061904477334503065, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5322264150943397, "dev_recall": 0.5628991060025543, "dev_f1": 0.5471332143688417, "dev_map": 0.6556946388504439, "learning_rate": 0.0002659256770308768, "wall_clock_seconds": 581.3262515068054}
|
| 4 |
+
{"epoch": 4, "train_loss": 0.014289841654040781, "train_bce": 0.012365499651170522, "train_dc": 0.005800362000973038, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5198257080610021, "dev_recall": 0.571360153256705, "dev_f1": 0.544375998174766, "dev_map": 0.6576822652564643, "learning_rate": 0.00022722925484045786, "wall_clock_seconds": 575.7329406738281}
|
| 5 |
+
{"epoch": 5, "train_loss": 0.014175985931480353, "train_bce": 0.0122669513011922, "train_dc": 0.005647288217739071, "train_hc3": 0.0038408746070336145, "dev_precision": 0.514005403099673, "dev_recall": 0.5771072796934866, "dev_f1": 0.5437316687974731, "dev_map": 0.6530293753344071, "learning_rate": 0.0001797942837889505, "wall_clock_seconds": 483.29707646369934}
|
| 6 |
+
{"epoch": 6, "train_loss": 0.01410277469829272, "train_bce": 0.012200795751861889, "train_dc": 0.005576731416304824, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5119299731752083, "dev_recall": 0.5788633461047255, "dev_f1": 0.5433430733498165, "dev_map": 0.6493538105672264, "learning_rate": 0.0001293596132272652, "wall_clock_seconds": 594.0699644088745}
|
| 7 |
+
{"epoch": 7, "train_loss": 0.014035929312789701, "train_bce": 0.012146426412817928, "train_dc": 0.005451970974499989, "train_hc3": 0.0038408746070336145, "dev_precision": 0.5098039215686274, "dev_recall": 0.5810983397190294, "dev_f1": 0.5431214562817069, "dev_map": 0.6434185587690961, "learning_rate": 8.202700668556269e-05, "wall_clock_seconds": 558.7890524864197}
|
scripts/hop_stratified_analysis.py
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python
|
| 2 |
+
"""
|
| 3 |
+
hop_stratified_analysis.py -- Cross-tabulate hop and relation.
|
| 4 |
+
|
| 5 |
+
Loads a trained checkpoint, scores the test set, then aggregates by
|
| 6 |
+
(hop, relation) pairs. This answers:
|
| 7 |
+
|
| 8 |
+
- Which relations appear at which hops? (the hop x relation count matrix)
|
| 9 |
+
- What is per-hop, per-relation F1?
|
| 10 |
+
- Is the hop3 precision drop driven by has_phenotype, or by all relations?
|
| 11 |
+
- How do score distributions differ across hops?
|
| 12 |
+
|
| 13 |
+
Usage:
|
| 14 |
+
python scripts/hop_stratified_analysis.py \
|
| 15 |
+
--checkpoint runs/no_dc/seed_42/best.pt \
|
| 16 |
+
--threshold 0.80 \
|
| 17 |
+
--mode autoregressive \
|
| 18 |
+
--output-json results/hop_stratified_seed42.json
|
| 19 |
+
"""
|
| 20 |
+
from __future__ import annotations
|
| 21 |
+
|
| 22 |
+
import argparse
|
| 23 |
+
import json
|
| 24 |
+
import logging
|
| 25 |
+
import sys
|
| 26 |
+
from collections import defaultdict
|
| 27 |
+
from pathlib import Path
|
| 28 |
+
|
| 29 |
+
import numpy as np
|
| 30 |
+
import torch
|
| 31 |
+
|
| 32 |
+
ROOT = Path(__file__).parent.parent
|
| 33 |
+
if str(ROOT) not in sys.path:
|
| 34 |
+
sys.path.insert(0, str(ROOT))
|
| 35 |
+
|
| 36 |
+
from caff import (
|
| 37 |
+
AblationFlags,
|
| 38 |
+
CAFFConfig,
|
| 39 |
+
CAFFEvaluator,
|
| 40 |
+
CAFFModel,
|
| 41 |
+
CAFFTripleDataset,
|
| 42 |
+
CachedBFSExtractor,
|
| 43 |
+
FrozenBioEncoder,
|
| 44 |
+
KnowledgeGraph,
|
| 45 |
+
RelationEmbeddingCache,
|
| 46 |
+
load_qa_split,
|
| 47 |
+
)
|
| 48 |
+
from caff.evaluator import precision_recall_f1
|
| 49 |
+
from caff.utils.logging import setup_logging
|
| 50 |
+
|
| 51 |
+
logger = logging.getLogger(__name__)
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
def parse_args() -> argparse.Namespace:
|
| 55 |
+
p = argparse.ArgumentParser(description="Hop x relation cross-tabulation.")
|
| 56 |
+
p.add_argument("--checkpoint", required=True)
|
| 57 |
+
p.add_argument("--test-split", default=None)
|
| 58 |
+
p.add_argument("--cache-dir", default="cache")
|
| 59 |
+
p.add_argument("--mode", default="autoregressive",
|
| 60 |
+
choices=["teacher_forced", "autoregressive"])
|
| 61 |
+
p.add_argument("--threshold", type=float, default=None)
|
| 62 |
+
p.add_argument("--output-json", default=None)
|
| 63 |
+
p.add_argument("--device", default="cuda" if torch.cuda.is_available() else "cpu")
|
| 64 |
+
return p.parse_args()
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def load_checkpoint(ckpt_path: str, device: str, cache_dir: Path):
|
| 68 |
+
payload = torch.load(ckpt_path, map_location=device)
|
| 69 |
+
config = CAFFConfig(**payload["config"])
|
| 70 |
+
ablation = AblationFlags()
|
| 71 |
+
logger.info(f"Loading KG from {config.kg_path}...")
|
| 72 |
+
kg = KnowledgeGraph.from_tsv(config.kg_path, min_relation_freq=50)
|
| 73 |
+
encoder = FrozenBioEncoder(config.encoder_name, device=device)
|
| 74 |
+
rel_cache = RelationEmbeddingCache(
|
| 75 |
+
encoder, kg.relations,
|
| 76 |
+
cache_path=cache_dir / "relation_embeddings.pt",
|
| 77 |
+
)
|
| 78 |
+
model = CAFFModel(config, rel_cache, ablation=ablation).to(device)
|
| 79 |
+
model.load_state_dict(payload["model"])
|
| 80 |
+
model.eval()
|
| 81 |
+
logger.info(f"Restored checkpoint from {ckpt_path}")
|
| 82 |
+
return model, config, encoder, kg
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def main() -> None:
|
| 86 |
+
args = parse_args()
|
| 87 |
+
setup_logging(level="INFO")
|
| 88 |
+
cache_dir = Path(args.cache_dir)
|
| 89 |
+
|
| 90 |
+
model, config, encoder, kg = load_checkpoint(args.checkpoint, args.device, cache_dir)
|
| 91 |
+
|
| 92 |
+
test_path = args.test_split or config.test_path
|
| 93 |
+
test_recs = load_qa_split(test_path)
|
| 94 |
+
bfs = CachedBFSExtractor(kg, L=config.L, K_r=config.K_r,
|
| 95 |
+
cache_dir=cache_dir / "bfs")
|
| 96 |
+
test_ds = CAFFTripleDataset(test_recs, bfs, require_gold=True)
|
| 97 |
+
|
| 98 |
+
threshold = args.threshold if args.threshold is not None else config.theta
|
| 99 |
+
evaluator = CAFFEvaluator(
|
| 100 |
+
config=config, encoder=encoder, mode=args.mode, threshold=threshold,
|
| 101 |
+
)
|
| 102 |
+
logger.info(f"Scoring test set (mode={args.mode}, theta={threshold})...")
|
| 103 |
+
scores, instances, _retained = evaluator._score_dataset(model, test_ds)
|
| 104 |
+
scores_np = scores.cpu().numpy() if torch.is_tensor(scores) else np.asarray(scores)
|
| 105 |
+
|
| 106 |
+
# Aggregate by (hop, relation)
|
| 107 |
+
by_key_scores: dict[tuple[int, str], list[float]] = defaultdict(list)
|
| 108 |
+
by_key_labels: dict[tuple[int, str], list[int]] = defaultdict(list)
|
| 109 |
+
# Also aggregate by hop only
|
| 110 |
+
by_hop_scores: dict[int, list[float]] = defaultdict(list)
|
| 111 |
+
by_hop_labels: dict[int, list[int]] = defaultdict(list)
|
| 112 |
+
|
| 113 |
+
for inst, sc in zip(instances, scores_np.tolist()):
|
| 114 |
+
key = (inst.hop, inst.relation)
|
| 115 |
+
by_key_scores[key].append(sc)
|
| 116 |
+
by_key_labels[key].append(inst.label)
|
| 117 |
+
by_hop_scores[inst.hop].append(sc)
|
| 118 |
+
by_hop_labels[inst.hop].append(inst.label)
|
| 119 |
+
|
| 120 |
+
# Per-hop metrics
|
| 121 |
+
hop_rows = []
|
| 122 |
+
print()
|
| 123 |
+
print("=" * 96)
|
| 124 |
+
print(f"Hop-stratified summary (mode={args.mode}, theta={threshold})")
|
| 125 |
+
print(f"Checkpoint: {args.checkpoint}")
|
| 126 |
+
print("=" * 96)
|
| 127 |
+
print(f"{'hop':>4} | {'n_total':>8} | {'n_pos':>6} | {'pos%':>6} | "
|
| 128 |
+
f"{'prec':>6} | {'recall':>6} | {'F1':>6} | "
|
| 129 |
+
f"{'score_mean':>10} | {'score_std':>9}")
|
| 130 |
+
print("-" * 96)
|
| 131 |
+
for hop in sorted(by_hop_scores.keys()):
|
| 132 |
+
s = np.asarray(by_hop_scores[hop])
|
| 133 |
+
l = np.asarray(by_hop_labels[hop])
|
| 134 |
+
n_total = len(l)
|
| 135 |
+
n_pos = int(l.sum())
|
| 136 |
+
pos_rate = n_pos / n_total if n_total > 0 else 0.0
|
| 137 |
+
m = precision_recall_f1(s, l, threshold=threshold)
|
| 138 |
+
hop_rows.append({
|
| 139 |
+
"hop": hop,
|
| 140 |
+
"n_total": n_total,
|
| 141 |
+
"n_pos": n_pos,
|
| 142 |
+
"pos_rate": pos_rate,
|
| 143 |
+
"precision": m["precision"],
|
| 144 |
+
"recall": m["recall"],
|
| 145 |
+
"f1": m["f1"],
|
| 146 |
+
"score_mean": float(s.mean()),
|
| 147 |
+
"score_std": float(s.std()),
|
| 148 |
+
"score_mean_pos": float(s[l == 1].mean()) if n_pos > 0 else None,
|
| 149 |
+
"score_mean_neg": float(s[l == 0].mean()) if (n_total - n_pos) > 0 else None,
|
| 150 |
+
})
|
| 151 |
+
print(f"{hop:>4} | {n_total:>8} | {n_pos:>6} | {pos_rate*100:>5.1f}% | "
|
| 152 |
+
f"{m['precision']:>6.4f} | {m['recall']:>6.4f} | {m['f1']:>6.4f} | "
|
| 153 |
+
f"{s.mean():>10.4f} | {s.std():>9.4f}")
|
| 154 |
+
|
| 155 |
+
# Hop x relation cross-tab (counts)
|
| 156 |
+
print()
|
| 157 |
+
print("=" * 96)
|
| 158 |
+
print(f"Hop x relation counts (n_total, n_positive)")
|
| 159 |
+
print("=" * 96)
|
| 160 |
+
relations_sorted = sorted({rel for (_, rel) in by_key_scores.keys()},
|
| 161 |
+
key=lambda r: -sum(len(by_key_labels[(h, r)])
|
| 162 |
+
for h in [1, 2, 3]))
|
| 163 |
+
print(f"{'relation':<55} | {'hop 1':>14} | {'hop 2':>14} | {'hop 3':>14}")
|
| 164 |
+
print("-" * 96)
|
| 165 |
+
cross_rows = []
|
| 166 |
+
for rel in relations_sorted:
|
| 167 |
+
cells = []
|
| 168 |
+
rel_row = {"relation": rel}
|
| 169 |
+
for hop in [1, 2, 3]:
|
| 170 |
+
key = (hop, rel)
|
| 171 |
+
n = len(by_key_labels.get(key, []))
|
| 172 |
+
npos = int(sum(by_key_labels.get(key, [])))
|
| 173 |
+
cells.append(f"{n:>6}/{npos:<6}")
|
| 174 |
+
rel_row[f"hop{hop}_n_total"] = n
|
| 175 |
+
rel_row[f"hop{hop}_n_pos"] = npos
|
| 176 |
+
cross_rows.append(rel_row)
|
| 177 |
+
rel_short = rel[:55]
|
| 178 |
+
print(f"{rel_short:<55} | {cells[0]:>14} | {cells[1]:>14} | {cells[2]:>14}")
|
| 179 |
+
|
| 180 |
+
# Per (hop, relation) F1 for top-2 relations
|
| 181 |
+
print()
|
| 182 |
+
print("=" * 96)
|
| 183 |
+
print(f"Per (hop, relation) F1 for the top-2 relations by support")
|
| 184 |
+
print("=" * 96)
|
| 185 |
+
top_relations = relations_sorted[:2]
|
| 186 |
+
f1_rows = []
|
| 187 |
+
print(f"{'relation':<25} | {'hop':>4} | {'n_total':>8} | {'n_pos':>6} | "
|
| 188 |
+
f"{'prec':>6} | {'recall':>6} | {'F1':>6}")
|
| 189 |
+
print("-" * 80)
|
| 190 |
+
for rel in top_relations:
|
| 191 |
+
for hop in [1, 2, 3]:
|
| 192 |
+
key = (hop, rel)
|
| 193 |
+
if key not in by_key_scores:
|
| 194 |
+
continue
|
| 195 |
+
s = np.asarray(by_key_scores[key])
|
| 196 |
+
l = np.asarray(by_key_labels[key])
|
| 197 |
+
if len(l) == 0:
|
| 198 |
+
continue
|
| 199 |
+
n_pos = int(l.sum())
|
| 200 |
+
m = precision_recall_f1(s, l, threshold=threshold)
|
| 201 |
+
f1_rows.append({
|
| 202 |
+
"relation": rel, "hop": hop,
|
| 203 |
+
"n_total": len(l), "n_pos": n_pos,
|
| 204 |
+
"precision": m["precision"], "recall": m["recall"], "f1": m["f1"],
|
| 205 |
+
})
|
| 206 |
+
print(f"{rel[:25]:<25} | {hop:>4} | {len(l):>8} | {n_pos:>6} | "
|
| 207 |
+
f"{m['precision']:>6.4f} | {m['recall']:>6.4f} | {m['f1']:>6.4f}")
|
| 208 |
+
print("=" * 96)
|
| 209 |
+
|
| 210 |
+
# Save JSON
|
| 211 |
+
if args.output_json:
|
| 212 |
+
out = {
|
| 213 |
+
"checkpoint": str(args.checkpoint),
|
| 214 |
+
"mode": args.mode,
|
| 215 |
+
"threshold": threshold,
|
| 216 |
+
"per_hop": hop_rows,
|
| 217 |
+
"hop_x_relation_counts": cross_rows,
|
| 218 |
+
"per_hop_relation_f1_top2": f1_rows,
|
| 219 |
+
}
|
| 220 |
+
out_path = Path(args.output_json)
|
| 221 |
+
out_path.parent.mkdir(parents=True, exist_ok=True)
|
| 222 |
+
with out_path.open("w", encoding="utf-8") as f:
|
| 223 |
+
json.dump(out, f, indent=2)
|
| 224 |
+
logger.info(f"Results written to {out_path}")
|
| 225 |
+
|
| 226 |
+
|
| 227 |
+
if __name__ == "__main__":
|
| 228 |
+
main()
|