sabt-nazar / app.py
aria123123's picture
Update app.py
90233cc verified
# 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
)