Spaces:
Runtime error
Runtime error
File size: 7,317 Bytes
7014076 |
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 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
import gradio as gr
import time
from collections import defaultdict
import spacy
# Load the symptom-to-disease mapping
symptom_data = {
"Shortness of breath": {
"questions": [
"Do you also have chest pain?",
"Do you feel fatigued often?",
"Have you noticed swelling in your legs?"
],
"diseases": ["Atelectasis", "Emphysema", "Edema"],
"weights_yes": [30, 30, 40],
"weights_no": [10, 20, 30]
},
"Persistent cough": {
"questions": [
"Is your cough dry or with mucus?",
"Do you experience fever?",
"Do you have difficulty breathing?"
],
"diseases": ["Pneumonia", "Fibrosis", "Infiltration"],
"weights_yes": [35, 30, 35],
"weights_no": [10, 15, 20]
},
"Sharp chest pain": {
"questions": [
"Does it worsen with deep breaths?",
"Do you feel lightheaded?",
"Have you had recent trauma or surgery?"
],
"diseases": ["Pneumothorax", "Effusion", "Cardiomegaly"],
"weights_yes": [40, 30, 30],
"weights_no": [15, 20, 25]
},
"Fatigue & swelling": {
"questions": [
"Do you feel breathless when lying down?",
"Have you gained weight suddenly?",
"Do you experience irregular heartbeat?"
],
"diseases": ["Edema", "Cardiomegaly"],
"weights_yes": [50, 30, 20],
"weights_no": [20, 15, 15]
},
"Chronic wheezing": {
"questions": [
"Do you have a history of smoking?",
"Do you feel tightness in your chest?",
"Do you have frequent lung infections?"
],
"diseases": ["Emphysema", "Fibrosis"],
"weights_yes": [40, 30, 30],
"weights_no": [15, 25, 20]
}
}
# Load spaCy model for NLP
nlp = spacy.load("en_core_web_lg")
# Function to extract key symptom from user input
def extract_symptom(user_input):
# Define the symptoms that the chatbot recognizes
known_symptoms = list(symptom_data.keys())
# Process the input with spaCy NLP model
user_doc = nlp(user_input.lower())
# Check if any of the known symptoms are in the user input
for symptom in known_symptoms:
if symptom.lower() in user_input.lower():
return symptom
# If no direct match, use similarity to find the closest symptom
similarities = {}
for symptom in known_symptoms:
symptom_doc = nlp(symptom.lower())
similarity = user_doc.similarity(symptom_doc)
similarities[symptom] = similarity
# Return the symptom with the highest similarity
return max(similarities, key=similarities.get)
# Mapping of unrecognized symptoms to similar known ones
synonym_mapping = {
"chest pain": "Sharp chest pain",
"pain in chest": "Sharp chest pain",
"wheezing": "Chronic wheezing",
"cough": "Persistent cough",
"shortness of breath": "Shortness of breath",
"fatigue": "Fatigue & swelling"
}
# Global variables to track user state
user_state = {}
def chatbot(user_input):
if "state" not in user_state:
user_state["state"] = "greet"
if user_state["state"] == "greet":
user_state["state"] = "ask_symptom"
return "Hello! I'm a medical AI assistant. Please describe your primary symptom."
elif user_state["state"] == "ask_symptom":
# Check if the symptom contains any synonym or keyword
matched_symptom = None
for synonym, recognized_symptom in synonym_mapping.items():
if synonym in user_input.lower():
matched_symptom = recognized_symptom
break
# If no synonym found, extract the symptom using NLP
if not matched_symptom:
matched_symptom = extract_symptom(user_input)
# If the symptom is recognized, proceed to the next step
if matched_symptom not in symptom_data:
user_state["state"] = "ask_feeling"
return "I'm sorry, I don't recognize that symptom. How do you feel?"
user_state["symptom"] = matched_symptom
user_state["state"] = "ask_duration"
return "How long have you been experiencing this symptom? (Less than a week / More than a week)"
elif user_state["state"] == "ask_feeling":
# If the symptom is not recognized, ask how they feel
return "Can you describe your symptoms in more detail?"
elif user_state["state"] == "ask_duration":
if user_input.lower() == "less than a week":
user_state.clear()
return "It might be a temporary issue. Please monitor your symptoms and consult a doctor if they persist."
elif user_input.lower() == "more than a week":
user_state["state"] = "follow_up"
user_state["current_question"] = 0
user_state["disease_scores"] = defaultdict(int)
return symptom_data[user_state["symptom"]]["questions"][0]
else:
return "Please respond with 'Less than a week' or 'More than a week'."
elif user_state["state"] == "follow_up":
symptom = user_state["symptom"]
question_index = user_state["current_question"]
# Update probabilities
if user_input.lower() == "yes":
for i, disease in enumerate(symptom_data[symptom]["diseases"]):
user_state["disease_scores"][disease] += symptom_data[symptom]["weights_yes"][i]
else:
for i, disease in enumerate(symptom_data[symptom]["diseases"]):
user_state["disease_scores"][disease] += symptom_data[symptom]["weights_no"][i]
# Move to the next question or finish
user_state["current_question"] += 1
if user_state["current_question"] < len(symptom_data[symptom]["questions"]):
return symptom_data[symptom]["questions"][user_state["current_question"]]
# Final diagnosis
probable_disease = max(user_state["disease_scores"], key=user_state["disease_scores"].get)
user_state.clear()
return f"Based on your symptoms, the most likely condition is: {probable_disease}. Please consult a doctor for confirmation."
# Gradio Chatbot UI with improved features
with gr.Blocks() as demo:
gr.Markdown("# Conversational Image Recognition Assistant: AI-Powered X-ray Diagnosis for Healthcare")
chatbot_ui = gr.Chatbot()
user_input = gr.Textbox(placeholder="Enter your response...", label="Your Message")
submit = gr.Button("Send")
clear_chat = gr.Button("Clear Chat")
def respond(user_message, history):
history.append((user_message, "Thinking...")) # Show thinking message
yield history, "" # Immediate update
time.sleep(1.5) # Simulate processing delay
bot_response = chatbot(user_message)
history[-1] = (user_message, bot_response) # Update with real response
yield history, ""
submit.click(respond, [user_input, chatbot_ui], [chatbot_ui, user_input])
user_input.submit(respond, [user_input, chatbot_ui], [chatbot_ui, user_input])
clear_chat.click(lambda: ([], ""), outputs=[chatbot_ui, user_input])
demo.launch()
|