import gradio as gr import numpy as np class MediCoderV2: def __init__(self): self.setup_enhanced_mappings() def setup_enhanced_mappings(self): # Enhanced ICD-10 codes self.icd10_codes = { 'I10': 'Essential hypertension', 'E11.9': 'Type 2 diabetes mellitus without complications', 'E11.65': 'Type 2 diabetes mellitus with hyperglycemia', 'J44.1': 'Chronic obstructive pulmonary disease with acute exacerbation', 'M54.5': 'Low back pain', 'F41.9': 'Anxiety disorder, unspecified', 'F32.9': 'Major depressive disorder, single episode', 'Z23': 'Encounter for immunization', 'Z00.00': 'Encounter for general adult medical examination', 'R06.02': 'Shortness of breath', 'I48.91': 'Unspecified atrial fibrillation', 'E66.9': 'Obesity, unspecified' } # Enhanced CPT codes self.cpt_codes = { '99213': 'Office visit, established patient, low complexity', '99214': 'Office visit, established patient, moderate complexity', '99215': 'Office visit, established patient, high complexity', '99202': 'Office visit, new patient, low complexity', '99203': 'Office visit, new patient, moderate complexity', '93000': 'Electrocardiogram, routine ECG with interpretation', '71045': 'Chest X-ray, single view', '71046': 'Chest X-ray, 2 views', '80053': 'Comprehensive metabolic panel', '85025': 'Complete blood count with differential', '43239': 'Upper endoscopy with biopsy', '45378': 'Colonoscopy, diagnostic', '11100': 'Biopsy of skin, single lesion', '70551': 'MRI brain without contrast', '99281': 'Emergency department visit, low complexity', '99283': 'Emergency department visit, moderate complexity' } # Enhanced HCPCS codes self.hcpcs_codes = { 'J3420': 'Injection, vitamin B-12 cyanocobalamin', 'A4253': 'Blood glucose test strips for home monitor', 'A4259': 'Lancets, per box of 100', 'E0601': 'Continuous positive airway pressure (CPAP) device', 'E0470': 'Respiratory assist device, bi-level pressure', 'J1100': 'Injection, dexamethasone sodium phosphate', 'A4206': 'Syringe with needle, sterile, 1 cc or less' } def predict_codes(self, medical_text, confidence_threshold=0.3): if not medical_text.strip(): return {"error": "Please enter medical text"} text_lower = medical_text.lower() predicted_icd10 = [] predicted_cpt = [] predicted_hcpcs = [] # Enhanced medical condition detection if any(word in text_lower for word in ['hypertension', 'high blood pressure', 'elevated bp']): predicted_icd10.append(('I10', 0.85)) if any(word in text_lower for word in ['diabetes', 'diabetic', 'blood sugar', 'glucose']): predicted_icd10.append(('E11.9', 0.78)) if 'high' in text_lower or 'elevated' in text_lower: predicted_icd10.append(('E11.65', 0.72)) predicted_hcpcs.append(('A4253', 0.65)) predicted_hcpcs.append(('A4259', 0.60)) if any(word in text_lower for word in ['copd', 'chronic obstructive', 'breathing difficulty']): predicted_icd10.append(('J44.1', 0.83)) if any(word in text_lower for word in ['back pain', 'lower back', 'lumbar pain']): predicted_icd10.append(('M54.5', 0.80)) if any(word in text_lower for word in ['anxiety', 'anxious', 'worried']): predicted_icd10.append(('F41.9', 0.72)) if any(word in text_lower for word in ['depression', 'depressed', 'sad mood']): predicted_icd10.append(('F32.9', 0.74)) if any(word in text_lower for word in ['shortness of breath', 'sob', 'difficulty breathing']): predicted_icd10.append(('R06.02', 0.75)) if any(word in text_lower for word in ['atrial fibrillation', 'a-fib', 'irregular heart']): predicted_icd10.append(('I48.91', 0.88)) if any(word in text_lower for word in ['obesity', 'overweight', 'bmi elevated']): predicted_icd10.append(('E66.9', 0.75)) # Enhanced procedure detection if any(word in text_lower for word in ['office visit', 'clinic visit', 'follow-up']): if 'new patient' in text_lower: predicted_cpt.append(('99202', 0.80)) else: predicted_cpt.append(('99213', 0.82)) if 'complex' in text_lower or 'detailed' in text_lower: predicted_cpt.append(('99214', 0.75)) if any(word in text_lower for word in ['ecg', 'ekg', 'electrocardiogram']): predicted_cpt.append(('93000', 0.89)) if any(word in text_lower for word in ['chest x-ray', 'chest xray', 'cxr']): predicted_cpt.append(('71045', 0.76)) if '2 view' in text_lower or 'two view' in text_lower: predicted_cpt.append(('71046', 0.78)) if any(word in text_lower for word in ['blood work', 'lab work', 'laboratory', 'blood test']): predicted_cpt.append(('80053', 0.71)) if 'cbc' in text_lower or 'complete blood count' in text_lower: predicted_cpt.append(('85025', 0.75)) if any(word in text_lower for word in ['endoscopy', 'upper endoscopy', 'egd']): predicted_cpt.append(('43239', 0.84)) if any(word in text_lower for word in ['colonoscopy', 'colon screening']): predicted_cpt.append(('45378', 0.87)) if any(word in text_lower for word in ['biopsy', 'skin biopsy', 'tissue sample']): predicted_cpt.append(('11100', 0.79)) if any(word in text_lower for word in ['mri', 'magnetic resonance']): predicted_cpt.append(('70551', 0.80)) if any(word in text_lower for word in ['emergency', 'er visit', 'emergency department']): predicted_cpt.append(('99283', 0.78)) if 'severe' in text_lower or 'critical' in text_lower: predicted_cpt.append(('99281', 0.70)) # Enhanced supply detection if any(word in text_lower for word in ['cpap', 'sleep apnea', 'breathing machine']): predicted_hcpcs.append(('E0601', 0.88)) if any(word in text_lower for word in ['bipap', 'bi-level', 'respiratory assist']): predicted_hcpcs.append(('E0470', 0.85)) if any(word in text_lower for word in ['injection', 'shot', 'vitamin b12']): predicted_hcpcs.append(('J3420', 0.60)) if any(word in text_lower for word in ['steroid injection', 'dexamethasone']): predicted_hcpcs.append(('J1100', 0.70)) # Special context detection if 'annual' in text_lower and any(word in text_lower for word in ['exam', 'physical', 'checkup']): predicted_icd10.append(('Z00.00', 0.82)) predicted_cpt.append(('99213', 0.75)) if any(word in text_lower for word in ['vaccination', 'vaccine', 'immunization']): predicted_icd10.append(('Z23', 0.85)) return { 'icd10_codes': [{'code': code, 'confidence': conf, 'description': self.icd10_codes.get(code, '')} for code, conf in predicted_icd10 if conf >= confidence_threshold], 'cpt_codes': [{'code': code, 'confidence': conf, 'description': self.cpt_codes.get(code, '')} for code, conf in predicted_cpt if conf >= confidence_threshold], 'hcpcs_codes': [{'code': code, 'confidence': conf, 'description': self.hcpcs_codes.get(code, '')} for code, conf in predicted_hcpcs if conf >= confidence_threshold] } medicoder_v2 = MediCoderV2() def format_predictions(results): if 'error' in results: return f"❌ **Error**: {results['error']}", "", "" icd10_text = "### 🏥 ICD-10 Codes (Diagnoses)\n\n" if results['icd10_codes']: for pred in results['icd10_codes']: confidence_emoji = "🎯" if pred['confidence'] > 0.8 else "📊" if pred['confidence'] > 0.6 else "📈" icd10_text += f"{confidence_emoji} **{pred['code']}** - {pred['description']}\n" icd10_text += f" *Confidence: {pred['confidence']:.1%}*\n\n" else: icd10_text += "🔍 *No ICD-10 codes predicted above threshold*\n\n" cpt_text = "### ⚕️ CPT Codes (Procedures & Services)\n\n" if results['cpt_codes']: for pred in results['cpt_codes']: confidence_emoji = "🎯" if pred['confidence'] > 0.8 else "📊" if pred['confidence'] > 0.6 else "📈" cpt_text += f"{confidence_emoji} **{pred['code']}** - {pred['description']}\n" cpt_text += f" *Confidence: {pred['confidence']:.1%}*\n\n" else: cpt_text += "🔍 *No CPT codes predicted above threshold*\n\n" hcpcs_text = "### 🔬 HCPCS Codes (Supplies & Equipment)\n\n" if results['hcpcs_codes']: for pred in results['hcpcs_codes']: confidence_emoji = "🎯" if pred['confidence'] > 0.8 else "📊" if pred['confidence'] > 0.6 else "📈" hcpcs_text += f"{confidence_emoji} **{pred['code']}** - {pred['description']}\n" hcpcs_text += f" *Confidence: {pred['confidence']:.1%}*\n\n" else: hcpcs_text += "🔍 *No HCPCS codes predicted above threshold*\n\n" return icd10_text, cpt_text, hcpcs_text def predict_medical_codes(medical_text, confidence_threshold): if not medical_text or not medical_text.strip(): return "⚠️ Please enter some medical text to analyze.", "", "" results = medicoder_v2.predict_codes(medical_text, confidence_threshold) return format_predictions(results) # Enhanced sample medical notes sample_notes = [ "Patient presents with elevated blood pressure reading of 160/95 mmHg during routine office visit. No chest pain or shortness of breath. Patient has history of hypertension. Recommend lifestyle modifications and medication adjustment. Follow-up in 4 weeks.", "45-year-old established patient here for diabetes follow-up. Blood glucose levels have been running high at home. Patient reports good adherence to medication. Ordered comprehensive metabolic panel and CBC. Discussed glucose monitoring and provided additional test strips.", "Patient reports chest pain and shortness of breath for past 2 days. Performed ECG which shows normal sinus rhythm. Chest X-ray ordered to rule out pneumonia. Patient has history of anxiety disorder. Will monitor symptoms.", "Annual physical examination for 52-year-old male. Patient reports feeling well with no acute concerns. Blood pressure slightly elevated. Ordered routine lab work. Discussed preventive care measures.", "Emergency department visit for severe abdominal pain. Patient has history of COPD and uses CPAP device at home. Pain medication administered via injection. Surgery consultation obtained.", "Follow-up visit for chronic back pain. Patient reports some improvement with physical therapy. MRI of lumbar spine shows disc herniation. Discussed pain management options.", "New patient consultation for diabetes management. Patient recently diagnosed with type 2 diabetes. Blood sugar levels elevated. Provided diabetic education and glucose monitoring supplies." ] # Create enhanced Gradio interface with gr.Blocks( title="MediCoder AI v2 - Enhanced Medical Code Prediction", theme=gr.themes.Soft() ) as demo: gr.HTML("""
Advanced AI-powered ICD-10, CPT, and HCPCS code prediction from clinical text