Florian Herzog 00f51859e0 Drop non-extractable custodian relation; add per-triple grounded flag
Custodian names (esp. foreign sub-custodians) appear only in structured N-CEN,
never in the prospectus prose, so they are not a valid text->triple target.
Per-fund the custodian object name occurs in only 28% of segments, the weakest
of all relations. Default is now --custodian-scope none.

Every triple now carries a 'grounded' boolean (object name present in the
sample's input text); 80% of triples are grounded across the full build. This
lets training/eval restrict to text-extractable targets.

- build_rdf_dataset.py: annotate_grounding() + grounded flag in samples/stats
- gold rebuilt without custodian (15,739 -> 12,694 edges)
- dataset_description + README updated (custodian dropped, grounding documented)

Reported by thesis author: Citibank custodians in triples for 0001529390 never
appear in that prospectus text.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 10:34:14 +02:00

fund_rdf_data

A relationship-rich finance dataset for text-to-RDF-triple extraction, built from mandatory U.S. SEC fund disclosures. Companion data pipeline to the thesis Magical RDF Triples and how to synthetize them.

Each sample pairs a long natural-language prospectus section (input) with a compact graph of entity-to-entity RDF triples (target) — a fund advised by a manager, distributed by an underwriter, seriesOf a trust, and so on. Unlike Wikidata-derived corpora where text ≈ triples, here the input is ~2050× larger than the output, and the target is a genuine knowledge graph rather than flat attributes. Ground truth comes for free from parallel structured filings (N-CEN), so no model is needed to label the relational edges.

See dataset_description.pdf for the full scientific description (ontology, graph structure, holdings sub-graph, baselines, training use) and data/RDF_DATASET_DESIGN.md for design notes.

Pipeline

The dataset is built by build_rdf_dataset.py in four stages:

# 1. gold  — parse local N-CEN flat files into per-trust gold graphs
python build_rdf_dataset.py gold --custodian-scope primary

# 2. fetch — download all recent full prospectus books per trust from EDGAR
python build_rdf_dataset.py fetch --limit 435 --max-filings 8

# 3. samples — segment prose per fund and join with gold into text->triple samples
python build_rdf_dataset.py samples

# 4. split — trust-level 80/10/10 train/val/test (no cross-split leakage)
python build_rdf_dataset.py split

# or run all four:
python build_rdf_dataset.py all --limit 435

score_baseline.py computes a no-model string-match baseline and scores strong-model predictions against the gold:

python score_baseline.py stringmatch          # no-model lower bound
python score_baseline.py model --pred preds.jsonl

Sample format

Each line of samples.jsonl / train|val|test.jsonl is a JSON record:

field meaning
input_text prospectus prose for the fund (model input)
ontology inferred meta-schema (subject type → predicate → object type)
target_triples structured {s,p,o,grounded} list (grounded = object name appears in input_text)
target_serialized marker form (<triple_start> …) for Models 2/4
target_serialized_plain Turtle-like form, no special tokens, for Models 1/3
cik, series_id, fund, trust_name identifiers
stats input/target sizes, triple count, n_grounded, text:json ratio

Relations

Entity-to-entity edges (gold from N-CEN / Series-Class): seriesOf, advisedBy, subAdvisedBy, transferAgent, administrator, underwrittenBy.

custodian is dropped by default (--custodian-scope none): custodian names — especially foreign sub-custodians — appear only in the structured N-CEN table and in no prose document (the summary prospectus says only "the custodian"), so they are not extractable from text. The primary custodian is named only in the separately-filed SAI (N-1A Part B), which is not part of the input. Use --custodian-scope primary or all to re-include it if you add the SAI as input.

Prose-grounding: every triple carries a grounded flag (object name present in the sample's input). Across the full build ~80 % of triples are grounded (per relation: advisedBy 93 %, seriesOf/subAdvisedBy/administrator 8084 %, transferAgent 72 %, underwrittenBy 62 %). Filter on grounded to train/evaluate only on text-extractable targets.

Holdings edges (holds/issuedBy/domiciledIn, gold from N-PORT) are a planned second track from annual-report (N-CSR) commentary — see the description PDF.

Data sources

All inputs are public SEC filings (EDGAR, DERA data sets). The large raw data (prospectus prose, bulk N-CEN/N-PORT/XBRL downloads) and the generated sample files are git-ignored because they are reproducible from the commands above; only the lightweight structured gold graph (data/rdf_poc/gold_graphs.jsonl) is committed.

Requirements

pip install -r requirements.txt
Description
Code for fund SEC RFID data
Readme MIT 9 MiB
Languages
Python 83.4%
TeX 13%
Shell 3.6%