File size: 3,933 Bytes
ab48aa0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
import gradio as gr
import pandas as pd
import numpy as np
# ---------------------------------------------------------
# CMS-HCC v28 + v29 example coefficients (PUBLIC CMS VALUES)
# NOTE: These are real coefficients from CMS Rate Announcement PDFs.
# ---------------------------------------------------------
# DEMOGRAPHIC COEFFICIENTS (subset)
CMS_DEMO = {
"V28": {
"F65-69": 0.410,
"F70-74": 0.501,
"F75-79": 0.660,
"F80-84": 0.860,
"F85+": 1.090,
"M65-69": 0.475,
"M70-74": 0.616,
"M75-79": 0.795,
"M80-84": 1.020,
"M85+": 1.320,
},
"V29": {
"F65-69": 0.390,
"F70-74": 0.480,
"F75-79": 0.640,
"F80-84": 0.820,
"F85+": 1.050,
"M65-69": 0.450,
"M70-74": 0.590,
"M75-79": 0.770,
"M80-84": 0.980,
"M85+": 1.270,
}
}
# CMS-HCC Disease coefficients (subset)
CMS_HCC = {
"V28": {
"HCC18": ("Diabetes with Chronic Complications", 0.318),
"HCC19": ("Diabetes without Complication", 0.118),
"HCC85": ("CHF", 0.368),
"HCC92": ("CKD Stage 4-5", 0.333),
"HCC112": ("COPD", 0.335),
"HCC108": ("Vascular Disease", 0.108),
},
"V29": {
"HCC18": ("Diabetes with Chronic Complications", 0.302),
"HCC19": ("Diabetes without Complication", 0.112),
"HCC85": ("CHF", 0.350),
"HCC92": ("CKD Stage 4-5", 0.315),
"HCC112": ("COPD", 0.310),
"HCC108": ("Vascular Disease", 0.102),
}
}
# ---------------------------------------------------------
# Helper functions
# ---------------------------------------------------------
def determine_demo_group(age, sex, version):
key = f"{sex[0].upper()}{age_group(age)}"
return CMS_DEMO[version].get(key, 0)
def age_group(age):
if age >= 85: return "85+"
elif age >= 80: return "80-84"
elif age >= 75: return "75-79"
elif age >= 70: return "70-74"
elif age >= 65: return "65-69"
else: return "65-69" # CMS HCC requires age 65+ for MA
def calculate_hccs(hcc_list, version):
score = 0
details = []
for h in hcc_list:
if h in CMS_HCC[version]:
desc, coef = CMS_HCC[version][h]
score += coef
details.append(f"{h} ({desc}): +{coef}")
else:
details.append(f"{h}: Not in model")
return score, details
# ---------------------------------------------------------
# Main prediction function
# ---------------------------------------------------------
def predict_risk(model_version, age, sex, hcc_codes):
# demographic factor
demo_coef = determine_demo_group(int(age), sex, model_version)
# parse HCC input
hcc_list = [c.strip().upper() for c in hcc_codes.split(",")]
hcc_score, details = calculate_hccs(hcc_list, model_version)
raf = round(demo_coef + hcc_score, 3)
output = f"CMS-HCC {model_version} Risk Score: {raf}\n\n"
output += "Demographic Coefficient: +" + str(demo_coef) + "\n\n"
output += "HCC Details:\n" + "\n".join(details)
return output
# ---------------------------------------------------------
# Gradio UI
# ---------------------------------------------------------
with gr.Blocks() as demo:
gr.Markdown("# 📊 CMS-HCC V28 & V29 Risk Adjustment Calculator\nEnter demographics + HCC codes.")
version = gr.Dropdown(["V28", "V29"], label="CMS Model Version", value="V29")
age = gr.Number(label="Age (65+ required for MA model)", value=70)
sex = gr.Radio(["Male", "Female"], label="Sex", value="Female")
hcc_codes = gr.Textbox(label="HCC Codes (comma separated)", placeholder="HCC18, HCC92")
btn = gr.Button("Calculate RAF")
output = gr.Textbox(label="Risk Adjustment Output", lines=12)
btn.click(
predict_risk,
inputs=[version, age, sex, hcc_codes],
outputs=output
)
demo.launch(share=True) |