File size: 3,428 Bytes
cdc6248
 
 
 
 
 
 
 
 
c62252d
cdc6248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c62252d
cdc6248
 
 
 
 
 
 
 
 
 
c62252d
 
 
 
 
cdc6248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# ============================================================
# 📄 الملف: 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()