physician_comparison.py 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import xarray as xr
  2. from utils.config import config
  3. import pathlib as pl
  4. import numpy as np
  5. import pandas as pd
  6. import matplotlib.pyplot as plt
  7. import os
  8. # This code compares the confidence of the model outputs with the physician ratings
  9. adni_data = pd.read_csv(config["analysis"]["adni_path"])
  10. plots_dir = (
  11. pl.Path("../output") / pl.Path(config["analysis"]["evaluation_name"]) / "plots"
  12. )
  13. plots_dir.mkdir(parents=True, exist_ok=True)
  14. physician_ratings = adni_data[
  15. "DXCONFID (1=uncertain, 2= mild, 3= moderate, 4=high confidence) "
  16. ].to_numpy(dtype=str)
  17. image_ids = adni_data["Image Data ID"].to_numpy(dtype=str)
  18. physician_ratings = np.strings.strip(physician_ratings)
  19. image_ids = np.strings.strip(image_ids)
  20. # Filter to only include ratings where it is not "na" or only spaces
  21. valid_indices = np.where(physician_ratings != "na")[0]
  22. valid_indices = valid_indices[physician_ratings[valid_indices] != ""]
  23. physician_ratings = physician_ratings[valid_indices].astype(int)
  24. csv_img_ids = image_ids[valid_indices].astype(int)
  25. # Load the evaluation results
  26. os.chdir(pl.Path(__file__).parent)
  27. model_dataset_path = pl.Path("../model_evaluations") / pl.Path(
  28. config["analysis"]["evaluation_name"].strip()
  29. ).with_suffix(".nc")
  30. print(f"Loading evaluation results from {model_dataset_path}")
  31. array = xr.open_dataset(model_dataset_path) # type: ignore
  32. # This dataset includes two dataarrays: 'img_id' and 'predictions' that we will use to determine the model confidence for each image ID
  33. eval_img_ids = array["img_id"]
  34. predictions = array["predictions"]
  35. # Average across models to get the mean confidence for each image (taking the higher confidence between the two classes)
  36. model_confidences = predictions.mean(dim="model").max(dim="img_class").values
  37. # Find the shared image IDs between the model evaluation and the physician ratings
  38. shared_img_ids, model_indices, csv_indices = np.intersect1d(
  39. eval_img_ids.values, csv_img_ids, return_indices=True
  40. )
  41. # Get the corresponding physician ratings and model confidences for the shared image IDs
  42. shared_physician_ratings = physician_ratings[csv_indices]
  43. shared_model_confidences = model_confidences[model_indices]
  44. # Print distribution of ratings for shared samples
  45. print("Distribution of Physician Ratings for Shared Samples:"),
  46. (unique, counts) = np.unique(shared_physician_ratings, return_counts=True)
  47. distribution = dict(zip(unique, counts))
  48. for rating in range(1, 5):
  49. count = distribution.get(rating, 0)
  50. print(f" Rating {rating}: {count} samples")
  51. # Graph the model confidence vs physician ratings using a violin plot
  52. plt.figure(figsize=(10, 6))
  53. plt.boxplot(
  54. [
  55. shared_model_confidences[shared_physician_ratings == rating]
  56. for rating in range(1, 5)
  57. ],
  58. positions=[1, 2, 3, 4],
  59. widths=0.6,
  60. )
  61. plt.xticks([1, 2, 3, 4], ["1 (Uncertain)", "2 (Mild)", "3 (Moderate)", "4 (High)"])
  62. plt.xlabel("Physician Confidence Rating")
  63. plt.ylabel("Model Confidence")
  64. plt.title("Model Confidence vs Physician Confidence Ratings")
  65. plt.grid(axis="y")
  66. plt.savefig(plots_dir / "model_confidence_vs_physician_ratings_boxplot.png")
  67. plt.close()