Skinalyze / app.py
Code0ut's picture
Update app.py
81e5ff8 verified
Raw
History Blame
5.79 kB
import os
import json
import re
import numpy as np
import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
import torch
from torch.nn.functional import cosine_similarity
from sentence_transformers import SentenceTransformer
import gradio as gr
# ---------------------
# 1. Download NLTK Data
# ---------------------
nltk.download('punkt')
nltk.download('stopwords')
nltk.download('wordnet')
# ---------------------
# 2. Load Dataset
# ---------------------
dataset_path = "dataset.json"
if not os.path.exists(dataset_path):
raise FileNotFoundError(f"{dataset_path} not found. Please ensure the file is in the current directory.")
with open(dataset.json, "r") as f:
data = json.load(f)
# Convert dataset into a dictionary: disease name -> details
disease_data = {d["name"]: d for d in data["diseases"]}
print("Sample Disease (Acne):")
print(json.dumps(disease_data.get("Acne", {}), indent=2))
# ---------------------
# 3. Advanced Preprocessing Functions
# ---------------------
lemmatizer = WordNetLemmatizer()
stop_words = set(stopwords.words('english'))
# Mapping for common medical synonyms to standardize terminology
medical_synonyms = {
"itchy": "itch",
"pruritic": "itch",
"rash": "eruption",
"redness": "red",
"swollen": "swelling",
"bumps": "lesion"
}
def advanced_preprocess_text(text):
# Lowercase and remove unwanted characters (retain only letters and spaces)
text = text.lower()
text = re.sub(r'[^a-zA-Z\s]', ' ', text)
tokens = word_tokenize(text)
# Replace tokens using the medical synonym mapping
tokens = [medical_synonyms.get(token, token) for token in tokens]
# Remove stopwords and lemmatize
tokens = [lemmatizer.lemmatize(token) for token in tokens if token not in stop_words]
return " ".join(tokens)
# ---------------------
# 4. Prepare Disease Descriptions & Embeddings Using BERT
# ---------------------
# For each disease, combine symptoms, causes, cure, and home remedies into a detailed description.
disease_names = []
disease_descriptions = []
for disease_name, details in disease_data.items():
disease_names.append(disease_name)
description = ""
if "symptoms" in details:
description += "Symptoms: " + " ".join(details["symptoms"]) + ". "
if "causes" in details:
description += "Causes: " + " ".join(details["causes"]) + ". "
if "cure" in details:
description += "Cure: " + " ".join(details["cure"]) + ". "
if "home_remedies" in details:
description += "Home Remedies: " + " ".join(details["home_remedies"]) + ". "
processed_desc = advanced_preprocess_text(description)
disease_descriptions.append(processed_desc)
# Initialize SentenceTransformer (BERT-based model)
bert_model = SentenceTransformer('all-MiniLM-L6-v2')
# Compute embeddings for each disease description (as torch tensors)
disease_embeddings = bert_model.encode(disease_descriptions, convert_to_tensor=True)
print("Computed disease embeddings for", len(disease_embeddings), "diseases.")
# ---------------------
# 5. Detailed User Input Collection
# ---------------------
def get_detailed_user_input(primary_symptom, location, associated_symptoms, duration, severity, additional_info):
# Combine all responses into one detailed description.
combined_input = " ".join([primary_symptom, location, associated_symptoms, duration, severity, additional_info])
return combined_input
# ---------------------
# 6. Chatbot Prediction Function Using BERT Similarity
# ---------------------
def chatbot_response(user_input):
processed_input = advanced_preprocess_text(user_input)
user_embedding = bert_model.encode(processed_input, convert_to_tensor=True)
similarities = cosine_similarity(user_embedding, disease_embeddings)
best_match_idx = torch.argmax(similarities).item()
predicted_disease = disease_names[best_match_idx]
return predicted_disease
# ---------------------
# 7. Gradio Chatbot Function
# ---------------------
def gradio_chatbot(primary_symptom, location, associated_symptoms, duration, severity, additional_info):
detailed_input = get_detailed_user_input(primary_symptom, location, associated_symptoms, duration, severity, additional_info)
predicted = chatbot_response(detailed_input)
details = disease_data.get(predicted, {})
causes = ", ".join(details.get("causes", ["Not available"]))
cure = ", ".join(details.get("cure", ["Not available"]))
home_remedies = ", ".join(details.get("home_remedies", ["Not available"]))
response = (f"🩺 **Predicted Disease:** {predicted}\n\n"
f"**Causes:** {causes}\n\n"
f"**Cure:** {cure}\n\n"
f"**Home Remedies:** {home_remedies}")
return response
# ---------------------
# 8. Gradio Interface Setup
# ---------------------
iface = gr.Interface(
fn=gradio_chatbot,
inputs=[
gr.Textbox(label="1. Primary Symptom", placeholder="e.g., itching, rash"),
gr.Textbox(label="2. Location on Body", placeholder="e.g., face, arms"),
gr.Textbox(label="3. Associated Symptoms", placeholder="e.g., swelling, redness"),
gr.Textbox(label="4. Duration", placeholder="e.g., 2 days, 1 week"),
gr.Textbox(label="5. Severity (scale 1-10)", placeholder="e.g., 5"),
gr.Textbox(label="6. Additional Observations", placeholder="e.g., recent exposure, diet changes")
],
outputs="markdown",
title="Advanced Skin Disease AI Chatbot",
description="Answer a few questions about your symptoms and get a predicted skin disease along with recommended solutions."
)
# ---------------------
# 9. Launch the Gradio App on Hugging Face Spaces
# ---------------------
iface.launch()