Medical-Chatbot / app.py
sahar0's picture
Update app.py
cad9404 verified
from flask import Flask, render_template, request, jsonify
import json
import numpy as np
import nltk
from nltk.stem import PorterStemmer
# استيراد مكتبات التنسرفلو للتدريب
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Input
from tensorflow.keras.optimizers import Adam
import random
import os
# ========================================================
# 1. إعداد NLTK (تحميل ملفات اللغة)
# ========================================================
nltk_data_path = os.path.join(os.getcwd(), 'nltk_data')
if not os.path.exists(nltk_data_path):
os.makedirs(nltk_data_path, exist_ok=True)
nltk.data.path.append(nltk_data_path)
print("Downloading NLTK data...")
nltk.download('punkt', download_dir=nltk_data_path, quiet=True)
nltk.download('wordnet', download_dir=nltk_data_path, quiet=True)
nltk.download('punkt_tab', download_dir=nltk_data_path, quiet=True)
nltk.download('omw-1.4', download_dir=nltk_data_path, quiet=True)
print("✅ NLTK data downloaded.")
# ========================================================
# 2. دالة التدريب (Train on Startup)
# ========================================================
stemmer = PorterStemmer()
ignore_words = ['?', '!', '.', ',']
def train_model():
print("🔄 Starting training on server...")
try:
with open('intents.json', 'r', encoding='utf-8') as file:
data = json.load(file)
except Exception as e:
print(f"🛑 Error reading intents.json: {e}")
return None, None, None, None
words = []
classes = []
documents = []
for intent in data['intents']:
tag = intent['tag']
if tag not in classes:
classes.append(tag)
for pattern in intent['patterns']:
w = nltk.word_tokenize(pattern)
words.extend(w)
documents.append((w, tag))
words = [stemmer.stem(w.lower()) for w in words if w not in ignore_words]
words = sorted(list(set(words)))
classes = sorted(list(set(classes)))
training_data = []
output_empty = [0] * len(classes)
for doc in documents:
bag = []
pattern_words = [stemmer.stem(word.lower()) for word in doc[0]]
for w in words:
bag.append(1) if w in pattern_words else bag.append(0)
output_row = list(output_empty)
output_row[classes.index(doc[1])] = 1
training_data.append([np.array(bag), np.array(output_row)])
random.shuffle(training_data)
train_x = np.array([item[0] for item in training_data])
train_y = np.array([item[1] for item in training_data])
# بناء النموذج
model = Sequential()
model.add(Input(shape=(len(train_x[0]),)))
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(len(train_y[0]), activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.01), metrics=['accuracy'])
# التدريب
model.fit(train_x, train_y, epochs=200, batch_size=5, verbose=0)
print("✅ Training completed successfully on server.")
return model, words, classes, data
# ========================================================
# 3. تشغيل التطبيق
# ========================================================
app = Flask(__name__)
# بدء التدريب فور التشغيل
model, words, classes, intents = train_model()
def clean_up_sentence(sentence):
sentence_words = nltk.word_tokenize(sentence)
sentence_words = [stemmer.stem(word.lower()) for word in sentence_words if word not in ignore_words]
return sentence_words
def bag_of_words(sentence, words):
sentence_words = clean_up_sentence(sentence)
bag = [0] * len(words)
for s in sentence_words:
for i, w in enumerate(words):
if w == s:
bag[i] = 1
return np.array(bag)
def predict_class(sentence):
if model is None: return []
bow = bag_of_words(sentence, words)
res = model.predict(np.array([bow]), verbose=0)[0]
ERROR_THRESHOLD = 0.25
results = [[i, r] for i, r in enumerate(res) if r > ERROR_THRESHOLD]
results.sort(key=lambda x: x[1], reverse=True)
return_list = []
for r in results:
return_list.append({"intent": classes[r[0]], "probability": str(r[1])})
return return_list
def get_response(ints, intents_json):
if not ints:
return "I'm sorry, I didn't understand that."
tag = ints[0]['intent']
list_of_intents = intents_json['intents']
for i in list_of_intents:
if i['tag'] == tag:
result = random.choice(i['responses'])
break
else:
result = "I'm sorry, I don't have a response for that."
return result
# --- Routes ---
@app.route("/")
def home():
return render_template("index.html")
@app.route("/get_response", methods=["POST"])
def chatbot_response():
try:
msg = request.json.get('msg')
if msg:
ints = predict_class(msg)
res = get_response(ints, intents)
return jsonify({"response": res})
else:
return jsonify({"response": "Empty message"})
except Exception as e:
return jsonify({"response": f"Error: {str(e)}"})
if __name__ == "__main__":
# تشغيل السيرفر على المنفذ 7860
app.run(host='0.0.0.0', port=7860)