Buckets:
| """Produce comprehensive statistics on the current healthy-brain corpus.""" | |
| import pandas as pd | |
| from pathlib import Path | |
| import textwrap | |
| ROOT = Path("/home/MRI-DataSet") | |
| df = pd.read_csv(ROOT / "manifest.csv") | |
| out = [] | |
| out.append("=" * 72) | |
| out.append("HEALTHY-BRAIN TRAINING CORPUS — FINAL SNAPSHOT") | |
| out.append("=" * 72) | |
| out.append(f"Manifest: {ROOT/'manifest.csv'}") | |
| out.append(f"Golden-0-to-25 (primary): {ROOT/'Golden-0-to-25'}/") | |
| out.append(f"Golden-25plus (fine-tune): {ROOT/'Golden-25plus'}/") | |
| out.append("") | |
| # Overall | |
| total = len(df) | |
| healthy = (df["healthy"] == True).sum() | |
| with_age = df["age_years"].notna().sum() | |
| age025 = ((df["age_years"].notna()) & (df["age_years"] < 25)).sum() | |
| age25p = ((df["age_years"].notna()) & (df["age_years"] >= 25)).sum() | |
| no_age = df["age_years"].isna().sum() | |
| out.append(f"Total scans: {total}") | |
| out.append(f"Labelled healthy: {healthy} ({100*healthy/total:.1f}%)") | |
| out.append(f"With known age: {with_age} ({100*with_age/total:.1f}%)") | |
| out.append(f" age < 25 (primary): {age025}") | |
| out.append(f" age >= 25 (pretrain): {age25p}") | |
| out.append(f"Unknown age (to impute): {no_age}") | |
| out.append("") | |
| # Age stats | |
| if with_age: | |
| ages = df["age_years"].dropna() | |
| out.append("Age distribution (years) over dated scans:") | |
| out.append(f" min={ages.min():.1f} median={ages.median():.1f} max={ages.max():.1f}") | |
| out.append(f" mean={ages.mean():.1f} ± {ages.std():.1f}") | |
| out.append("") | |
| # Split breakdown | |
| if "split" in df.columns: | |
| out.append("-" * 72) | |
| out.append("SPLIT BREAKDOWN") | |
| out.append("-" * 72) | |
| for split, grp in df.groupby("split"): | |
| n = len(grp) | |
| h = (grp["healthy"] == True).sum() | |
| ages = grp["age_years"].dropna() | |
| rng = f"{ages.min():.1f}-{ages.max():.1f}" if len(ages) else "n/a" | |
| out.append(f" {split:<28} {n:>5} scans (healthy={h}) range={rng}") | |
| out.append("") | |
| # Per-dataset breakdown | |
| out.append("-" * 72) | |
| out.append("PER-DATASET BREAKDOWN") | |
| out.append("-" * 72) | |
| out.append(f"{'dataset':<28}{'scans':>7}{'healthy':>9}{'age<25':>8}{'age>=25':>9}" | |
| f"{'age range':>18}") | |
| out.append("-" * 72) | |
| for ds, grp in df.groupby("dataset"): | |
| n = len(grp) | |
| h = (grp["healthy"] == True).sum() | |
| a = ((grp["age_years"].notna()) & (grp["age_years"] < 25)).sum() | |
| b = ((grp["age_years"].notna()) & (grp["age_years"] >= 25)).sum() | |
| ages = grp["age_years"].dropna() | |
| if len(ages): | |
| rng = f"{ages.min():.1f}-{ages.max():.1f}" | |
| else: | |
| rng = "n/a" | |
| out.append(f"{ds:<28}{n:>7}{h:>9}{a:>8}{b:>9}{rng:>18}") | |
| out.append("-" * 72) | |
| out.append("") | |
| # Age histogram in 5-year bins | |
| out.append("AGE HISTOGRAM (5-year bins, across all dated scans)") | |
| ages = df["age_years"].dropna() | |
| if len(ages): | |
| max_age = int(ages.max()) + 5 | |
| edges = list(range(0, max_age + 1, 5)) | |
| counts, _ = pd.cut(ages, bins=edges, right=False, include_lowest=True).value_counts(sort=False), None | |
| for interval, n in counts.items(): | |
| bar = "#" * int(40 * n / counts.max()) | |
| out.append(f" [{interval.left:>3}, {interval.right:>3}) {n:>5} {bar}") | |
| out.append("") | |
| # Split targets | |
| out.append("=" * 72) | |
| out.append("TARGET SPLITS FOR TRAINING") | |
| out.append("=" * 72) | |
| out.append("") | |
| out.append(textwrap.dedent(f"""\ | |
| Primary training (0-25 years) : {age025:>5} scans | |
| Pretraining pool (25+ years) : {age25p:>5} scans | |
| Grand total labelled : {age025+age25p:>5} scans | |
| Strategy (per user): | |
| 1. Train EfficientNet-B3 multi-view on Training_0to25/ (pediatric + young adult) | |
| 2. Ablation: pretrain on Training_0to25 + Pretrain_25plus | |
| (full lifespan), then fine-tune on 0-25 | |
| 3. Compare pediatric MAE between the two strategies in thesis | |
| """)) | |
| text = "\n".join(out) | |
| print(text) | |
| (ROOT / "STATISTICS.md").write_text(text) | |
| (ROOT / "STATISTICS.txt").write_text(text) | |
| print(f"\n-> wrote {ROOT/'STATISTICS.md'} and {ROOT/'STATISTICS.txt'}") | |
Xet Storage Details
- Size:
- 4.01 kB
- Xet hash:
- c61df410239417c8715dc22a53f02a9d555c436dc44d1cf6b05e0c0c5fd59df3
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.