{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c4afa19c",
   "metadata": {},
   "source": [
    "# مشروع تصنيف النصوص باستخدام تقنيات المعالجة اللغوية والـ Machine Learning\n",
    "### إعداد الطالبة: رباب\n",
    "### تاريخ التسليم: قبل 25-8-2025"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3380bb81",
   "metadata": {},
   "outputs": [],
   "source": [
    "# استيراد المكتبات الأساسية\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import re\n",
    "import nltk\n",
    "from sklearn.model_selection import train_test_split, GridSearchCV\n",
    "from sklearn.feature_extraction.text import TfidfVectorizer\n",
    "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, classification_report, confusion_matrix\n",
    "from sklearn.ensemble import RandomForestClassifier\n",
    "from imblearn.over_sampling import RandomOverSampler, SMOTE\n",
    "from imblearn.under_sampling import RandomUnderSampler\n",
    "from nltk.corpus import stopwords\n",
    "from nltk.tokenize import word_tokenize\n",
    "from nltk.stem import PorterStemmer\n",
    "from collections import Counter\n",
    "\n",
    "# تحميل موارد NLTK\n",
    "nltk.download('punkt')\n",
    "nltk.download('stopwords')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e69e7c2d",
   "metadata": {},
   "outputs": [],
   "source": [
    "# قراءة البيانات\n",
    "df = pd.read_csv(\"unbalanceddataset (1).csv\")\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "85112cf0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# المعالجة المسبقة للنصوص\n",
    "stemmer = PorterStemmer()\n",
    "stop_words = set(stopwords.words('english'))\n",
    "\n",
    "def preprocess_text(text):\n",
    "    text = text.lower()\n",
    "    text = re.sub(r'http\\S+|www\\.\\S+', '', text)\n",
    "    text = re.sub(r'<.*?>', '', text)\n",
    "    text = re.sub(r'[^a-zA-Z\\s]', '', text)\n",
    "    tokens = word_tokenize(text)\n",
    "    tokens = [word for word in tokens if word not in stop_words]\n",
    "    stemmed_tokens = [stemmer.stem(word) for word in tokens]\n",
    "    return ' '.join(stemmed_tokens)\n",
    "\n",
    "df[\"clean_text\"] = df[\"text\"].apply(preprocess_text)\n",
    "df.dropna(inplace=True)\n",
    "df[[\"text\", \"clean_text\", \"sentiment\"]].head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "669ebfdb",
   "metadata": {},
   "outputs": [],
   "source": [
    "# تقسيم البيانات\n",
    "X = df['clean_text']\n",
    "y = df['sentiment']\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state=42)\n",
    "\n",
    "# تحويل النصوص إلى تمثيل رقمي باستخدام TF-IDF\n",
    "vectorizer = TfidfVectorizer()\n",
    "X_train_vec = vectorizer.fit_transform(X_train)\n",
    "X_test_vec = vectorizer.transform(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5c33d082",
   "metadata": {},
   "outputs": [],
   "source": [
    "# دالة تقييم النموذج\n",
    "def evaluate_model(name, y_true, y_pred):\n",
    "    print(f\"\\nModel: {name}\")\n",
    "    print(\"Accuracy:\", accuracy_score(y_true, y_pred))\n",
    "    print(\"Precision:\", precision_score(y_true, y_pred, average='weighted'))\n",
    "    print(\"Recall:\", recall_score(y_true, y_pred, average='weighted'))\n",
    "    print(\"F1 Score:\", f1_score(y_true, y_pred, average='weighted'))\n",
    "    print(\"Classification Report:\\n\", classification_report(y_true, y_pred))\n",
    "    print(\"Confusion Matrix:\\n\", confusion_matrix(y_true, y_pred))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "886c6262",
   "metadata": {},
   "outputs": [],
   "source": [
    "# تدريب نموذج Random Forest مع GridSearchCV\n",
    "def train_rf_with_gridsearch(X_train_vec, y_train, X_test_vec, y_test):\n",
    "    param_grid = {\n",
    "        'n_estimators': [100, 200, 300],\n",
    "        'max_depth': [None, 10, 20]\n",
    "    }\n",
    "    model = RandomForestClassifier(random_state=42)\n",
    "    grid = GridSearchCV(model, param_grid, cv=5, scoring='accuracy', n_jobs=-1)\n",
    "    grid.fit(X_train_vec, y_train)\n",
    "    best_model = grid.best_estimator_\n",
    "    y_pred = best_model.predict(X_test_vec)\n",
    "    evaluate_model(\"RandomForestClassifier\", y_test, y_pred)\n",
    "    print(\"Best Parameters:\", grid.best_params_)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "04004c0a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# تجربة على البيانات الأصلية\n",
    "print(\"📊 Original Dataset Results:\")\n",
    "train_rf_with_gridsearch(X_train_vec, y_train, X_test_vec, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c4e8cb16",
   "metadata": {},
   "outputs": [],
   "source": [
    "# تجربة بعد RandomOverSampling\n",
    "ros = RandomOverSampler(random_state=42)\n",
    "X_ros, y_ros = ros.fit_resample(X_train_vec, y_train)\n",
    "print(\"\\n🔄 After RandomOverSampler:\", Counter(y_ros))\n",
    "train_rf_with_gridsearch(X_ros, y_ros, X_test_vec, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fbe40cca",
   "metadata": {},
   "outputs": [],
   "source": [
    "# تجربة بعد RandomUnderSampling\n",
    "rus = RandomUnderSampler(random_state=42)\n",
    "X_rus, y_rus = rus.fit_resample(X_train_vec, y_train)\n",
    "print(\"\\n🔽 After RandomUnderSampler:\", Counter(y_rus))\n",
    "train_rf_with_gridsearch(X_rus, y_rus, X_test_vec, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cab927c7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# تجربة بعد SMOTE\n",
    "smote = SMOTE(random_state=42)\n",
    "X_smote, y_smote = smote.fit_resample(X_train_vec, y_train)\n",
    "print(\"\\n🧬 After SMOTE:\", Counter(y_smote))\n",
    "train_rf_with_gridsearch(X_smote, y_smote, X_test_vec, y_test)"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 5
}
