PragmaticPete commited on
Commit
ddd6cae
·
verified ·
1 Parent(s): d1dcced

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +99 -0
app.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # File: app.py
2
+
3
+ import gradio as gr
4
+ import pandas as pd
5
+ import io
6
+ import zipfile
7
+ import matplotlib.pyplot as plt
8
+ import seaborn as sns
9
+ from logic.care_gap_engine import evaluate_care_gaps
10
+ from logic.financial_model import estimate_financial_recovery
11
+ from logic.nlp_report import generate_patient_summary
12
+ from logic.exporter import export_to_docx_and_zip
13
+
14
+ CONFIG = {
15
+ "base_rate": 9500,
16
+ "care_gap_rules": {
17
+ "Breast Cancer Screening": {"gender": "F", "min_age": 50, "max_age": 74, "interval_days": 730},
18
+ "Colorectal Cancer Screening": {"min_age": 50, "max_age": 75, "interval_days": 365*10},
19
+ "Blood Pressure Control": {"bp_threshold": 140},
20
+ "Follow-Up Care": {},
21
+ "Readmission Risk": {}
22
+ },
23
+ "sdoh_modifiers": [
24
+ "Housing_Instability", "Food_Insecurity", "Transportation_Access", "Health_Literacy"
25
+ ]
26
+ }
27
+
28
+ def run_analysis(file, tone, gap_filter, custom_prompt):
29
+ df = pd.read_csv(file.name)
30
+ df.fillna("", inplace=True)
31
+
32
+ care_gaps = evaluate_care_gaps(df, CONFIG)
33
+ financials = estimate_financial_recovery(care_gaps, df, CONFIG['base_rate'], CONFIG['sdoh_modifiers'])
34
+ merged = care_gaps.merge(financials, on="patient_id")
35
+
36
+ if gap_filter:
37
+ merged = merged[merged['care_gaps'].apply(lambda gaps: gap_filter in gaps)]
38
+
39
+ summaries = {}
40
+ for _, row in merged.iterrows():
41
+ summaries[row['patient_id']] = generate_patient_summary(row, tone, custom_prompt)
42
+
43
+ zip_bytes, file_names = export_to_docx_and_zip(merged, summaries)
44
+
45
+ # Risk score graph
46
+ plt.figure(figsize=(8, 4))
47
+ plt.hist(merged['risk_score'], bins=10)
48
+ plt.title("Risk Score Distribution")
49
+ plt.xlabel("Risk Score")
50
+ plt.ylabel("Number of Patients")
51
+ plt.tight_layout()
52
+ plt.savefig("risk_score_plot.png")
53
+
54
+ # Gap frequency bar chart
55
+ gap_freq = {}
56
+ for gaps in merged['care_gaps']:
57
+ for g in gaps:
58
+ gap_freq[g] = gap_freq.get(g, 0) + 1
59
+ gap_df = pd.DataFrame(list(gap_freq.items()), columns=["Gap", "Count"])
60
+ plt.figure(figsize=(10, 5))
61
+ sns.barplot(x="Count", y="Gap", data=gap_df.sort_values(by="Count", ascending=False))
62
+ plt.title("Care Gap Frequency")
63
+ plt.tight_layout()
64
+ plt.savefig("care_gap_freq.png")
65
+
66
+ # Top 10 revenue opportunities
67
+ top10 = merged.sort_values(by="projected_gain", ascending=False).head(10)
68
+ top10_chart_path = "top10_revenue.png"
69
+ plt.figure(figsize=(10, 5))
70
+ sns.barplot(x="projected_gain", y="patient_id", data=top10)
71
+ plt.title("Top 10 Patients by Projected Gain")
72
+ plt.xlabel("Projected Revenue Recovery ($)")
73
+ plt.ylabel("Patient ID")
74
+ plt.tight_layout()
75
+ plt.savefig(top10_chart_path)
76
+
77
+ return merged, zip_bytes, "risk_score_plot.png", "care_gap_freq.png", top10_chart_path
78
+
79
+ iface = gr.Interface(
80
+ fn=run_analysis,
81
+ inputs=[
82
+ gr.File(label="Upload Patient CSV"),
83
+ gr.Dropdown(choices=["clinical", "executive", "casual"], label="Report Tone", value="executive"),
84
+ gr.Textbox(label="Filter by Care Gap (e.g. 'Breast Cancer Screening')", value=""),
85
+ gr.Textbox(label="Custom Prompt Override (optional)", value="")
86
+ ],
87
+ outputs=[
88
+ gr.Dataframe(label="Care Gap & Financial Report"),
89
+ gr.File(label="Download All Reports as ZIP"),
90
+ gr.Image(label="Risk Score Distribution"),
91
+ gr.Image(label="Care Gap Frequency"),
92
+ gr.Image(label="Top 10 Revenue Opportunities")
93
+ ],
94
+ title="AI Medicare Advantage Analyzer",
95
+ description="Upload a patient dataset, evaluate CMS care gaps and SDOH risk, forecast financial recovery, and generate NLP summaries with LLMs."
96
+ )
97
+
98
+ if __name__ == "__main__":
99
+ iface.launch()