AuralGuard / scripts /balance_metadata.py
AyoPrince's picture
Upload folder using huggingface_hub
127b976 verified
Raw History Blame Contribute Delete
2.2 kB
from __future__ import annotations
import argparse
from pathlib import Path
import pandas as pd
REQUIRED_COLUMNS = {"file_path", "binary_label", "attack_type", "start_fake", "end_fake", "dataset", "split"}
def print_counts(df, title):
print("\n" + "=" * 70)
print(title)
print("=" * 70)
print("Rows:", len(df))
print("\nBinary label counts:")
print(df["binary_label"].value_counts().sort_index())
print("\nDataset counts:")
print(df["dataset"].value_counts())
print("\nDataset x label counts:")
print(pd.crosstab(df["dataset"], df["binary_label"]))
def main():
p = argparse.ArgumentParser(description="Balance metadata by keeping all real rows and downsampling fake rows.")
p.add_argument("--input", required=True)
p.add_argument("--out", required=True)
p.add_argument("--fake-multiplier", type=float, default=1.0, help="1.0 means fake count roughly equals real count")
p.add_argument("--cap-wavefake", type=int, default=0)
p.add_argument("--seed", type=int, default=42)
args = p.parse_args()
df = pd.read_csv(args.input, low_memory=False)
df["binary_label"] = df["binary_label"].astype(int)
print_counts(df, "Before balancing")
if args.cap_wavefake > 0:
mask = df["dataset"].astype(str).str.lower() == "wavefake"
wave = df[mask]
other = df[~mask]
if len(wave) > args.cap_wavefake:
wave = wave.sample(n=args.cap_wavefake, random_state=args.seed)
df = pd.concat([other, wave], ignore_index=True)
print_counts(df, f"After WaveFake cap: {args.cap_wavefake}")
real = df[df["binary_label"] == 0]
fake = df[df["binary_label"] == 1]
max_fake = int(len(real) * args.fake_multiplier)
fake = fake.sample(n=min(len(fake), max_fake), random_state=args.seed)
out = pd.concat([real, fake], ignore_index=True).sample(frac=1.0, random_state=args.seed).reset_index(drop=True)
Path(args.out).parent.mkdir(parents=True, exist_ok=True)
out.to_csv(args.out, index=False)
print_counts(out, "After balancing")
print("Saved:", args.out)
if __name__ == "__main__":
main()