adaptive-interview-env / training /plot_results.py
Suguna Sri
feat: AdaptiveInterviewEnv v1
47fbb23
Raw
History Blame Contribute Delete
3.18 kB
"""Reward curve and calibration improvement plots.
Usage:
python training/plot_results.py --log_path outputs/rewards.csv --output_dir outputs/
"""
import argparse
import csv
import os
def plot(log_path: str, output_dir: str):
try:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
except ImportError:
print("matplotlib not installed. Skipping plots.")
return
if not os.path.exists(log_path):
print(f"Log file not found: {log_path}")
return
os.makedirs(output_dir, exist_ok=True)
# Read CSV
episodes, mean_rewards, rolling_rewards = [], [], []
cal_scores, imp_scores, con_scores = [], [], []
with open(log_path) as f:
reader = csv.DictReader(f)
for row in reader:
episodes.append(int(row["episode"]))
mean_rewards.append(float(row.get("mean_reward", 0)))
rolling_rewards.append(float(row.get("rolling_mean_reward", 0)))
cal_scores.append(float(row.get("calibration_score", 0)))
imp_scores.append(float(row.get("improvement_signal", 0)))
con_scores.append(float(row.get("consistency_score", 0)))
if not episodes:
print("No data in log file.")
return
# --- Plot 1: Mean reward per episode + rolling mean ---
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(episodes, mean_rewards, alpha=0.4, color="steelblue", label="Episode reward")
ax.plot(episodes, rolling_rewards, color="steelblue", linewidth=2, label="Rolling mean (100 ep)")
ax.set_xlabel("Episode")
ax.set_ylabel("Reward")
ax.set_title("Scorer Reward over Training")
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
out1 = os.path.join(output_dir, "reward_curve.png")
plt.savefig(out1, dpi=150)
plt.close()
print(f"Saved: {out1}")
# --- Plot 2: Per-component reward breakdown ---
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
components = [
(cal_scores, "Calibration Score", "darkorange"),
(imp_scores, "Improvement Signal", "green"),
(con_scores, "Consistency Score", "red"),
]
for ax, (vals, label, color) in zip(axes, components):
# Smooth with rolling window
window = min(20, len(vals))
smoothed = [
sum(vals[max(0, i - window):i + 1]) / min(i + 1, window)
for i in range(len(vals))
]
ax.plot(episodes, vals, alpha=0.3, color=color)
ax.plot(episodes, smoothed, color=color, linewidth=2)
ax.set_xlabel("Episode")
ax.set_ylabel(label)
ax.set_title(label)
ax.grid(True, alpha=0.3)
plt.suptitle("Reward Component Breakdown over Training")
plt.tight_layout()
out2 = os.path.join(output_dir, "reward_components.png")
plt.savefig(out2, dpi=150)
plt.close()
print(f"Saved: {out2}")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--log_path", required=True)
parser.add_argument("--output_dir", default="outputs/")
args = parser.parse_args()
plot(args.log_path, args.output_dir)