Spaces:
Sleeping
Sleeping
| 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 --- | |
| def home(): | |
| return render_template("index.html") | |
| 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) |