Spaces:
Runtime error
Runtime error
| # app.py - نسخه کاملاً اصلاح شده | |
| import pandas as pd | |
| import numpy as np | |
| import gradio as gr | |
| import pickle | |
| import warnings | |
| import os | |
| warnings.filterwarnings('ignore') | |
| print("🚀 در حال راهاندازی سیستم بررسی نظرات...") | |
| # ============ 1. بارگذاری دادهها ============ | |
| try: | |
| if os.path.exists('rew.csv'): | |
| df = pd.read_csv('rew.csv') | |
| print(f"✅ دادههای واقعی بارگذاری شد: {len(df)} نمونه") | |
| else: | |
| df = pd.DataFrame({ | |
| 'des': ['محصول خوبی بود', 'کیفیت پایین'], | |
| 'pos': [2, 1], | |
| 'neg': [1, 3], | |
| 'score': [4, 2] | |
| }) | |
| print("⚠️ از دادههای نمونه استفاده میشود") | |
| except Exception as e: | |
| print(f"❌ خطا در بارگذاری دادهها: {e}") | |
| df = pd.DataFrame({ | |
| 'des': ['محصول خوبی بود', 'کیفیت پایین'], | |
| 'pos': [2, 1], | |
| 'neg': [1, 3], | |
| 'score': [4, 2] | |
| }) | |
| # ============ 2. بارگذاری مدل BERT ============ | |
| try: | |
| from transformers import pipeline | |
| sen = pipeline('sentiment-analysis', | |
| model='HooshvareLab/bert-fa-base-uncased-sentiment-snappfood', | |
| device=-1) | |
| print("✅ مدل BERT بارگذاری شد") | |
| except Exception as e: | |
| print(f"⚠️ مدل BERT بارگذاری نشد: {e}") | |
| sen = None | |
| # ============ 3. بارگذاری یا آموزش مدل Logistic Regression ============ | |
| try: | |
| if os.path.exists('trained_model.pkl'): | |
| with open('trained_model.pkl', 'rb') as f: | |
| model = pickle.load(f) | |
| print("✅ مدل Logistic Regression بارگذاری شد") | |
| else: | |
| raise FileNotFoundError("مدل ذخیره شده یافت نشد") | |
| except: | |
| print("⚠️ آموزش مدل جدید...") | |
| from sklearn.linear_model import LogisticRegression | |
| model = LogisticRegression(random_state=42, max_iter=1000) | |
| # دادههای آموزش | |
| X_train = [[1, 2, 1], [0, 1, 3], [1, 3, 1], [0, 2, 2], [1, 2, 2]] | |
| y_train = [1, 0, 1, 0, 1] | |
| model.fit(X_train, y_train) | |
| # ذخیره مدل | |
| with open('trained_model.pkl', 'wb') as f: | |
| pickle.dump(model, f) | |
| print("✅ مدل جدید آموزش و ذخیره شد") | |
| # ============ 4. تابع تحلیل احساس ============ | |
| def analyze_sentiment(text): | |
| """تحلیل احساس متن""" | |
| if not text or not text.strip(): | |
| return "📝 منتظر متن..." | |
| try: | |
| if sen is not None: | |
| result = sen(text[:200])[0] | |
| label = result['label'] | |
| conf = result['score'] | |
| return f"{'😊 مثبت' if label == 'HAPPY' else '😞 منفی'} (اطمینان: {conf:.1%})" | |
| else: | |
| text_low = text.lower() | |
| pos_words = ['عالی', 'خوب', 'ممتاز', 'عالیه', 'خوبه', 'قشنگ'] | |
| neg_words = ['بد', 'ضعیف', 'خراب', 'بدم', 'بدیه', 'ناراضی'] | |
| pos_count = sum(1 for w in pos_words if w in text_low) | |
| neg_count = sum(1 for w in neg_words if w in text_low) | |
| if pos_count > neg_count: | |
| return f"😊 مثبت ({pos_count} کلمه مثبت)" | |
| elif neg_count > pos_count: | |
| return f"😞 منفی ({neg_count} کلمه منفی)" | |
| else: | |
| return "😐 خنثی" | |
| except Exception as e: | |
| return f"⚠️ خطا در تحلیل: {str(e)}" | |
| # ============ 5. تابع اصلی پیشبینی ============ | |
| def predict(review, strengths, weaknesses, rating): | |
| """پیشبینی و تصمیمگیری نهایی""" | |
| try: | |
| # تحلیل احساس متن | |
| if sen is not None and review.strip(): | |
| try: | |
| sent_result = sen(review[:300])[0] | |
| des = 1 if sent_result['label'] == 'HAPPY' else 0 | |
| sentiment_label = sent_result['label'] | |
| sentiment_conf = sent_result['score'] | |
| except: | |
| des = 1 if len(review) > 10 else 0 | |
| sentiment_label = "مثبت" if des == 1 else "منفی" | |
| sentiment_conf = 0.5 | |
| else: | |
| des = 1 if len(review) > 10 else 0 | |
| sentiment_label = "مثبت" if des == 1 else "منفی" | |
| sentiment_conf = 0.5 | |
| # پیشبینی با مدل Logistic Regression | |
| features = np.array([[des, strengths, weaknesses]]) | |
| pred = model.predict(features)[0] | |
| pred_proba = model.predict_proba(features)[0] | |
| # تصمیمگیری نهایی (طبق منطق اصلی شما) | |
| if pred == 1 and rating >= 3: | |
| result = "✅ نظر شما ثبت شد" | |
| color = "green" | |
| icon = "✅" | |
| elif pred == 1 and rating < 3: | |
| result = "❌ لطفاً امتیاز مناسب بدهید. نظر شما ثبت نشد." | |
| color = "red" | |
| icon = "❌" | |
| elif pred == 0 and rating < 3: | |
| result = "✅ نظر شما ثبت شد" | |
| color = "green" | |
| icon = "✅" | |
| else: # pred == 0 and rating >= 3 | |
| result = "❌ لطفاً امتیاز مناسب بدهید. نظر شما ثبت نشد." | |
| color = "red" | |
| icon = "❌" | |
| # ساخت گزارش HTML | |
| report = f""" | |
| <div style='border: 2px solid {color}; padding: 20px; border-radius: 10px; margin: 15px;'> | |
| <h3 style='color: {color}; text-align: center;'>{icon} {result}</h3> | |
| <hr style='border: 1px solid #ddd; margin: 15px 0;'> | |
| <h4 style='color: #333;'>📊 جزئیات تحلیل:</h4> | |
| <table style='width: 100%; border-collapse: collapse; font-size: 14px;'> | |
| <tr style='border-bottom: 1px solid #eee;'> | |
| <td style='padding: 10px; width: 40%;'><b>📝 نظر شما:</b></td> | |
| <td style='padding: 10px;'>{review[:80]}{'...' if len(review) > 80 else ''}</td> | |
| </tr> | |
| <tr style='border-bottom: 1px solid #eee;'> | |
| <td style='padding: 10px;'><b>😊 تحلیل احساس:</b></td> | |
| <td style='padding: 10px;'>{'مثبت 😊' if des == 1 else 'منفی 😞'} ({sentiment_conf:.1%})</td> | |
| </tr> | |
| <tr style='border-bottom: 1px solid #eee;'> | |
| <td style='padding: 10px;'><b>🔺 نقاط قوت:</b></td> | |
| <td style='padding: 10px;'>{strengths} از ۳</td> | |
| </tr> | |
| <tr style='border-bottom: 1px solid #eee;'> | |
| <td style='padding: 10px;'><b>🔻 نقاط ضعف:</b></td> | |
| <td style='padding: 10px;'>{weaknesses} از ۳</td> | |
| </tr> | |
| <tr style='border-bottom: 1px solid #eee;'> | |
| <td style='padding: 10px;'><b>⭐ امتیاز:</b></td> | |
| <td style='padding: 10px;'>{rating} از ۵</td> | |
| </tr> | |
| <tr style='border-bottom: 1px solid #eee;'> | |
| <td style='padding: 10px;'><b>🤖 تصمیم مدل:</b></td> | |
| <td style='padding: 10px;'>{'تایید ✅' if pred == 1 else 'رد ❌'}</td> | |
| </tr> | |
| <tr> | |
| <td style='padding: 10px;'><b>📈 اطمینان مدل:</b></td> | |
| <td style='padding: 10px;'>{pred_proba[max(pred, 0)]:.1%}</td> | |
| </tr> | |
| </table> | |
| <div style='margin-top: 20px; padding: 12px; background-color: #f8f9fa; border-radius: 8px;'> | |
| <p style='margin: 0; font-size: 13px; color: #666;'> | |
| <b>📋 نکته:</b> این سیستم بر اساس {len(df)} نظر آموزش دیده است. | |
| ترکیب احساس متن، نقاط قوت/ضعف و امتیاز در تصمیمگیری تأثیر دارد. | |
| </p> | |
| </div> | |
| </div> | |
| """ | |
| return report | |
| except Exception as e: | |
| return f""" | |
| <div style='border: 2px solid orange; padding: 20px; border-radius: 10px;'> | |
| <h3 style='color: orange;'>⚠️ خطا در پردازش</h3> | |
| <p>خطای زیر رخ داد:</p> | |
| <pre style='background-color: #f8f9fa; padding: 10px; border-radius: 5px; font-size: 12px;'>{str(e)}</pre> | |
| <p style='margin-top: 10px;'>لطفاً دوباره تلاش کنید.</p> | |
| </div> | |
| """ | |
| # ============ 6. ساخت رابط کاربری Gradio ============ | |
| with gr.Blocks(title="سیستم بررسی نظرات مشتریان", theme=gr.themes.Soft()) as demo: | |
| # عنوان اصلی | |
| gr.Markdown(""" | |
| # 🛍️ سیستم بررسی و ثبت نظرات مشتریان | |
| نظر خود را وارد کنید تا سیستم هوشمند ما آن را تحلیل و تأیید کند. | |
| """) | |
| # ردیف اول: ورودی متن | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| # کادر متن | |
| text_input = gr.Textbox( | |
| label="👤 نظر خود را بنویسید", | |
| placeholder="مثال: کیفیت این محصول عالیه اما قیمتش کمی بالاست...", | |
| lines=4, | |
| max_lines=6 | |
| ) | |
| # نمایش تحلیل احساس | |
| sentiment_display = gr.Textbox( | |
| label="📊 تحلیل لحظهای احساس", | |
| interactive=False, | |
| value="📝 منتظر نظر شما هستیم..." | |
| ) | |
| # اتصال تغییرات متن به تحلیل احساس | |
| text_input.change( | |
| fn=analyze_sentiment, | |
| inputs=text_input, | |
| outputs=sentiment_display | |
| ) | |
| with gr.Column(scale=1): | |
| # اطلاعات سیستم | |
| gr.Markdown(f""" | |
| ### 📊 اطلاعات سیستم | |
| • دادههای آموزشی: {len(df)} نظر | |
| • مدل احساسسنجی: {'فعال ✅' if sen else 'غیرفعال ⚠️'} | |
| • مدل تصمیمگیری: Logistic Regression | |
| • آخرین بروزرسانی: هماکنون | |
| """) | |
| # ردیف دوم: تنظیمات | |
| with gr.Row(): | |
| with gr.Column(): | |
| strengths = gr.Slider( | |
| minimum=1, | |
| maximum=3, | |
| value=2, | |
| step=1, | |
| label="🔺 تعداد نقاط قوت", | |
| info="از ۱ تا ۳" | |
| ) | |
| with gr.Column(): | |
| weaknesses = gr.Slider( | |
| minimum=1, | |
| maximum=3, | |
| value=1, | |
| step=1, | |
| label="🔻 تعداد نقاط ضعف", | |
| info="از ۱ تا ۳" | |
| ) | |
| with gr.Column(): | |
| rating = gr.Radio( | |
| choices=[("۱ ستاره ⭐", 1), ("۲ ستاره ⭐⭐", 2), ("۳ ستاره ⭐⭐⭐", 3), | |
| ("۴ ستاره ⭐⭐⭐⭐", 4), ("۵ ستاره ⭐⭐⭐⭐⭐", 5)], | |
| value=3, | |
| label="⭐ امتیاز کلی محصول", | |
| info="از ۱ (خیلی بد) تا ۵ (عالی)" | |
| ) | |
| # دکمه ثبت | |
| with gr.Row(): | |
| submit_btn = gr.Button( | |
| "📝 ارسال و تحلیل نظر", | |
| variant="primary", | |
| size="lg", | |
| scale=2 | |
| ) | |
| # خروجی | |
| with gr.Row(): | |
| output_display = gr.HTML( | |
| label="🎯 نتیجه نهایی", | |
| value="<div style='text-align: center; color: #888; padding: 40px; font-size: 16px;'>نتیجه تحلیل نظر شما اینجا نمایش داده خواهد شد...</div>" | |
| ) | |
| # اتصال دکمه | |
| submit_btn.click( | |
| fn=predict, | |
| inputs=[text_input, strengths, weaknesses, rating], | |
| outputs=output_display | |
| ) | |
| # مثالهای آماده | |
| with gr.Accordion("📋 کلیک کنید برای تست سریع (مثالهای آماده)", open=False): | |
| examples = [ | |
| ["این محصول واقعاً عالیه! کیفیت ساخت فوقالعاده و بستهبندی شیکی داره.", 3, 1, 5], | |
| ["نسبت به قیمتش کیفیت پایینی داره و زود خراب شد.", 1, 3, 2], | |
| ["قیمت مناسبه اما رنگش با عکس فرق داره.", 2, 2, 3], | |
| ["بدترین خرید عمرم! اصلاً کار نمیکنه.", 1, 3, 1], | |
| ["ارزش پولش رو داره، عملکرد خوبیه.", 2, 1, 4] | |
| ] | |
| gr.Examples( | |
| examples=examples, | |
| inputs=[text_input, strengths, weaknesses, rating], | |
| outputs=output_display, | |
| fn=predict, | |
| label="برای تست سریع روی یک مثال کلیک کنید" | |
| ) | |
| # راهنمای پایین صفحه | |
| with gr.Accordion("📖 راهنمای استفاده", open=False): | |
| gr.Markdown(""" | |
| ### نحوه استفاده: | |
| 1. نظر خود را بنویسید: دیدگاه صادقانه خود را در مورد محصول وارد کنید. | |
| 2. نقاط قوت و ضعف را مشخص کنید: تعداد نقاط مثبت و منفی محصول را انتخاب کنید. | |
| 3. امتیاز دهید: از ۱ تا ۵ به محصول امتیاز دهید. | |
| 4. ثبت کنید: دکمه "ارسال و تحلیل نظر" را بفشارید. | |
| ### منطق سیستم: | |
| - سیستم ابتدا احساس متن شما را با مدل BERT فارسی تحلیل میکند. | |
| - سپس با مدل Logistic Regression و بر اساس احساس متن، نقاط قوت/ضعف و امتیاز تصمیم میگیرد. | |
| - اگر مدل نظر را تأیید کند و امتیاز مناسب باشد، نظر ثبت میشود. | |
| ### رنگهای نتیجه: | |
| - ✅ سبز: نظر شما با موفقیت ثبت شد. | |
| - ❌ قرمز: نیاز به اصلاح دارد (معمولاً مشکل از امتیاز است). | |
| """) | |
| # ============ 7. اجرای برنامه ============ | |
| if name == "main": | |
| print("\n" + "="*60) | |
| print("✅ سیستم آماده است!") | |
| print(f"📊 تعداد دادههای آموزشی: {len(df)}") | |
| print(f"🤖 مدل احساسسنجی: {'فعال' if sen else 'غیرفعال'}") | |
| print(f"🧠 مدل Logistic Regression: فعال") | |
| print("🌐 در حال راهاندازی رابط کاربری...") | |
| print("="*60 + "\n") | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| share=False, | |
| debug=False, | |
| show_error=True | |
| ) |