Spaces:
Running
Running
| # ============================================================ | |
| # 📄 الملف: scripts/prepare_data.py | |
| # 🎯 الغرض: تنظيف البيانات الخام وبناء النص المُدمج (يُشغّل مرة واحدة). | |
| # | |
| # يقابل خلية "تنظيف البيانات" في النوتبوك. يأخذ ملف البيانات | |
| # الخام (lexicalentries.csv) ويقوم بـ: | |
| # 1. حذف الصفوف بدون تعريف (definition). | |
| # 2. إزالة التكرار حسب sense_id. | |
| # 3. تنظيف خفيف للنصوص (مسافات فقط — مع الحفاظ على التشكيل). | |
| # 4. دمج (الكلمة + التعريف فقط) مع حذف التشكيل في عمود combined_text. | |
| # 5. حفظ النتيجة في data/processed/data.csv. | |
| # | |
| # طريقة التشغيل (من داخل مجلد backend): | |
| # python scripts/prepare_data.py | |
| # ============================================================ | |
| import re | |
| import sys | |
| from pathlib import Path | |
| import pandas as pd | |
| # نضيف مجلد backend للمسار عشان نقدر نستورد config | |
| sys.path.append(str(Path(__file__).resolve().parent.parent)) | |
| import config | |
| from app.text_utils import strip_diacritics | |
| def clean_text(text: str) -> str: | |
| """تنظيف خفيف: توحيد المسافات الزائدة فقط (يحافظ على التشكيل والهمزات).""" | |
| if not isinstance(text, str): | |
| return "" | |
| return re.sub(r"\s+", " ", text).strip() | |
| def build_combined_text(row) -> str: | |
| """دمج الكلمة مع تعريفها فقط (بدون المثال) للـ embedding، مع حذف التشكيل. | |
| الصيغة: "الكلمة: [الكلمة] التعريف: [التعريف]" """ | |
| lemma = strip_diacritics(str(row.get("lemma", "") or "").strip()) | |
| definition = strip_diacritics(str(row.get("definition", "") or "").strip()) | |
| return f"الكلمة: {lemma} التعريف: {definition}" | |
| def main(): | |
| if not config.RAW_DATA_PATH.exists(): | |
| raise FileNotFoundError( | |
| f"❌ ملف البيانات الخام غير موجود: {config.RAW_DATA_PATH}\n" | |
| "ضع ملف الـ CSV في data/raw/ باسم lexicalentries.csv" | |
| ) | |
| print(f"📂 قراءة البيانات من: {config.RAW_DATA_PATH}") | |
| df = pd.read_csv(config.RAW_DATA_PATH) | |
| print(f"📊 عدد الصفوف الأصلية: {len(df)}") | |
| # 1) حذف الصفوف بدون تعريف | |
| df = df.dropna(subset=["definition"]).copy() | |
| df = df[df["definition"].astype(str).str.strip() != ""] | |
| # 2) إزالة التكرار حسب sense_id | |
| df = df.drop_duplicates(subset=["sense_id"]).reset_index(drop=True) | |
| # 3) تنظيف خفيف للأعمدة النصّية | |
| for col in config.TEXT_COLUMNS: | |
| if col in df.columns: | |
| df[col] = df[col].apply(clean_text) | |
| # 4) بناء النص المُدمج | |
| df["combined_text"] = df.apply(build_combined_text, axis=1) | |
| # 5) الحفظ | |
| config.PROCESSED_DATA_PATH.parent.mkdir(parents=True, exist_ok=True) | |
| df.to_csv(config.PROCESSED_DATA_PATH, index=False, encoding="utf-8-sig") | |
| print(f"✅ بعد التنظيف: {len(df)} سجل") | |
| print(f"💾 حُفظ في: {config.PROCESSED_DATA_PATH}") | |
| print("\n🔎 عينة من النص المُدمج:") | |
| for t in df["combined_text"].head(3): | |
| print(" •", t) | |
| if __name__ == "__main__": | |
| main() | |