Yakk99's picture
Upload folder using huggingface_hub
1b2a5c1 verified
Raw
History Blame Contribute Delete
4.68 kB
"""Build the final training/eval datasets.
Stage 1 β€” repair: replace each accepted truncated abstract with its
recovered text, normalized to the corpus format (the corpus strips all
punctuation except periods; sentence-final periods are free-standing ' . '
tokens; intra-token periods like '94.5' survive). The transform is
validated against every accepted pair by comparing the normalized recovered
prefix to the corpus text we already hold.
Stage 2 β€” titles: prepend the paper title, `<title> | <abstract>`, applied
identically to every split.
Usage: python build_datasets.py
Inputs: data/raw/*, data/external/{recovered_*,pii_title_cache.jsonl,*_with_pii.csv}
Outputs: data/recovered/{train,train_expanded,val,test}[_titled].csv
"""
import json
import re
import unicodedata
from difflib import SequenceMatcher
from pathlib import Path
import pandas as pd
REPO = Path(__file__).resolve().parent.parent
EXT = REPO / "data/external"
OUT = REPO / "data/recovered"
DASHES = "β€β€‘β€’β€“β€”β€•βˆ’"
SECTION_HEADERS = re.compile(
r"\b(BACKGROUND|METHODS?|RESULTS?|CONCLUSIONS?|OBJECTIVES?|PURPOSE"
r"|INTRODUCTION|RATIONALE|AIMS?|DISCUSSION|MATERIALS|SIGNIFICANCE"
r"|FINDINGS|INTERPRETATION|SETTING|DESIGN|PARTICIPANTS|MEASUREMENTS"
r"|LIMITATIONS|IMPLICATIONS|HYPOTHESIS|UNLABELLED|IMPORTANCE"
r"|EXPOSURES?|OUTCOMES?)(\s+AND\s+[A-Z]{4,})?\b[:.]?")
def strip_to_corpus_format(text):
t = unicodedata.normalize("NFKC", str(text))
t = SECTION_HEADERS.sub("", t)
t = t.replace("!", ".").replace("?", ".")
t = re.sub(r"(?<=\S)\.(?=\S)", "\x00", t)
t = t.replace(".", " . ").replace("\x00", ".")
t = t.replace("-", " ")
for d in DASHES:
t = t.replace(d, "")
t = re.sub(r"[^A-Za-z0-9. ]", "", t)
return " ".join(t.split())
def validate_transform():
scores = []
for split in ("train", "val", "test"):
rec = pd.read_csv(EXT / f"recovered_{split}.csv")
for _, r in rec[rec["accepted"]].iterrows():
a = str(r["Abstract"]).split()[:-2]
b = strip_to_corpus_format(r["RecoveredAbstract"]).split()[: len(a) + 20]
m = SequenceMatcher(None, a, b, autojunk=False)
scores.append(sum(bl.size for bl in m.get_matching_blocks()) / max(len(a), 1))
mean = sum(scores) / len(scores)
print(f"transform validation: {len(scores)} pairs, mean token agreement {mean:.4f}")
assert mean >= 0.90, "transform does not reproduce corpus format"
def load_titles():
titles = {}
for line in (EXT / "pii_title_cache.jsonl").read_text().splitlines():
try:
r = json.loads(line)
if r.get("title"):
titles[r["pii"]] = r["title"]
except (json.JSONDecodeError, KeyError):
continue
return titles
def clean_title(raw):
t = strip_to_corpus_format(raw)
while t.endswith(" ."):
t = t[:-2].rstrip()
return t
def main():
validate_transform()
OUT.mkdir(exist_ok=True)
titles = load_titles()
repl = {}
for split in ("train", "val", "test"):
rec = pd.read_csv(EXT / f"recovered_{split}.csv")
acc = rec[rec["accepted"]]
for pii, a in zip(acc["PII"], acc["RecoveredAbstract"]):
repl[pii] = strip_to_corpus_format(a)
extra = EXT / "recovered_expanded_extra.csv"
if extra.exists():
rec = pd.read_csv(extra)
acc = rec[rec["accepted"]]
for pii, a in zip(acc["PII"], acc["RecoveredAbstract"]):
repl[pii] = strip_to_corpus_format(a)
pii_by_split = {
s: dict(zip(*(lambda d: (d["Filename"], d["PII"]))(
pd.read_csv(EXT / f"{s}_with_pii.csv"))))
for s in ("train", "val", "test")
}
for name in ("train", "val", "test", "train_expanded"):
df = pd.read_csv(REPO / f"data/raw/{name}.csv")
piis = (df["PaperID"] if name == "train_expanded"
else df["Filename"].map(pii_by_split[name.replace("_expanded", "")]))
df["Abstract"] = [repl.get(p, a) for p, a in zip(piis, df["Abstract"])]
df.to_csv(OUT / f"{name}.csv", index=False)
titled = []
for pii, ab in zip(piis, df["Abstract"]):
t = titles.get(pii)
titled.append(f"{clean_title(t)} | {ab}" if t else str(ab))
df_t = df.copy()
df_t["Abstract"] = titled
df_t.to_csv(OUT / f"{name}_titled.csv", index=False)
trunc = (~df["Abstract"].astype(str).str.rstrip().str.endswith(".")).mean()
print(f"{name}: {len(df)} rows, residual truncation {trunc:.1%}, "
f"titled variant written")
return 0
if __name__ == "__main__":
raise SystemExit(main())