انتقل إلى المحتوى الرئيسي

الوحدة 4 — Word2Vec وGloVe وهندسة المعنى

قدَّمت الوحدة السابقة قيدًا رئيسًا لـTF-IDF: كلمتان مترادفتان تُعامَلان كأنّهما لا صلة بينهما. Word2Vec الذي طرحه توماس ميكولوف وزملاؤه في 2013 كان جوابًا صادمًا آنذاك: كلّ كلمة تصبح متّجهًا كثيفًا في فضاء بأبعاد عدّة مئات، والمسافات في هذا الفضاء تعكس القرابة الدلالية. ما كان قبل ذلك «مصفوفة متناثرة تراوغ فيها كلّ كلمة» صار «سحابة نقاط منظّمة».

سنستأنف جسم مراجعاتنا العربية لنُدرّب تضميناتنا الخاصّة، ونرى ماذا تعرف، وما تُنتِج من تحيّزات لن يعرف نموذج التصنيف أنّه ورثها.

الفرضية التوزيعية

كلّ ما تفعله Word2Vec وGloVe وأمثالهما ينبني على مقولة قديمة لعالم اللسانيات جون فيرث: «تعرف الكلمة بجيرانها». إذا ظهرت كلمة منتج عادةً بجوار شراء وسعر وجودة، وظهرت كلمة سلعة بجوار الجيران أنفسهم تقريبًا، فمن المعقول أن يكون معناهما قريبًا.

الفرضية التوزيعية تحوّل السؤال الفلسفي «ما معنى كلمة؟» إلى مسألة إحصائية: ما التوزيع الشرطي للكلمات التي تظهر في محيطها؟ Word2Vec لا يفعل شيئًا آخر: يتعلّم متّجهًا لكلّ كلمة بحيث يكون هذا المتّجه قادرًا على التنبّؤ بمتّجهات الجيران.

Skip-gram وCBOW: هيكلان لهدف واحد

يقترح Word2Vec طريقتين عكسيّتين للتعلّم.

CBOW (Continuous Bag of Words): تُقدَّم إلى الشبكة سياق (بضع كلمات على اليمين واليسار)، ويُطلب منها التنبّؤ بالكلمة المركزية. مثلًا من المنتج ... جدا سأشتريه، على النموذج أن يقول جيد.

Skip-gram: تُقدَّم الكلمة المركزية، ويُطلب من النموذج التنبّؤ بكلمات السياق كلّها. من جيد، على النموذج أن يعطي احتمالًا كبيرًا لـالمنتج وجدا وسأشتريه.

Skip-gram أثقل من CBOW (يُنتج أمثلة أكثر لكلّ نصّ)، لكنّه يشتغل أفضل على الكلمات النادرة، وهي حال معظم أسماء العلامات التجارية في مراجعاتنا. هو الاختيار الافتراضي للجُسُم الحرّة الطويلة.

الشبكة نفسها بسيطة صادمًا: طبقة تضمين ذات dd بُعدًا (d=300d = 300 نموذجيًّا)، ثمّ طبقة إسقاط على المفردات، ثمّ سوفت‌ماكس. الكلمة تصبح متّجهها المتعلَّم في الطبقة الأولى.

المشكلة المكلفة: سوفت‌ماكس على 100 000 كلمة

الهدف الرسمي لـSkip-gram هو تعظيم احتمال p(contextcenter)p(\text{context} \mid \text{center}). وحساب هذا الاحتمال يحتاج سوفت‌ماكس فوق مفردات كاملة، غالبًا V=100000V = 100\,000 كلمة أو أكثر.

p(wcwo)=exp(vwcvwo)k=1Vexp(vkvwo)p(w_c \mid w_o) = \frac{\exp(v_{w_c}^\top v_{w_o})}{\sum_{k=1}^{V} \exp(v_k^\top v_{w_o})}

المقام يجب حسابه لكلّ مثال تدريب. على جسم من 100 مليون كلمة، هذا يعني مليارات العمليات لكلّ حقبة، بعضها على GPU يتجاوز اليوم.

الحلّ الأناقة يقدّمه أخذ العيّنات السلبية (negative sampling): بدل حساب المقام كاملًا، نتظاهر بأنّ المسألة تصنيف ثنائي. لكلّ زوج حقيقي (كلمة مركزية، كلمة سياق موجودة فعلًا)، نأخذ عيّنة من kk كلمات عشوائية من المفردات (سلبية عمومًا)، ونطلب من النموذج التمييز.

logσ(vcvo)+i=1kEwiPn[logσ(vcvwi)]\log \sigma(v_c^\top v_o) + \sum_{i=1}^{k} \mathbb{E}_{w_i \sim P_n} [\log \sigma(-v_c^\top v_{w_i})]

يُختصر بذلك حساب المقام إلى kk كلمات (k=5k = 5 إلى 2020 عمليًّا)، والزمن ينهار من أيّام إلى ساعات.

تدريب على مراجعاتنا

مكتبة gensim تجعل التدريب بسيطًا. جسم من 10 000 مراجعة صغير جدًّا للتضمينات (يفضَّل عدّة ملايين جملة)، لكنّه كافٍ لعرض المبدأ.

from gensim.models import Word2Vec

# jamil مراجعات مقطّعة إلى قوائم كلمات
jamil = [
["المنتج", "رائع", "جدا", "سأشتري", "مرة", "أخرى"],
["التوصيل", "بطيء", "لكن", "المنتج", "ممتاز"],
# ... 10000 مراجعة معالجة
]

model = Word2Vec(
sentences=jamil,
vector_size=200, # حجم المتّجه
window=5, # نصف عرض السياق
min_count=5, # نتجاهل كلمات ظهرت أقلّ من 5 مرات
negative=10, # عدد العيّنات السلبية
sg=1, # 1 = Skip-gram، 0 = CBOW
workers=4,
epochs=10,
)

print(model.wv.most_similar("رائع", topn=5))
# على جسم كبير: [('ممتاز', 0.87), ('جيد', 0.79), ('أنصح', 0.76), ...]

بعد التدريب، model.wv يعرض متّجهًا لكلّ كلمة تجاوزت الحدّ الأدنى للتكرار. المسافة المستعمَلة عادة هي التشابه الجيبي (cosine similarity):

sim(u,v)=uvuv\text{sim}(u, v) = \frac{u \cdot v}{\|u\| \, \|v\|}

قيمته بين -1 و1، حيث 1 يعني اتّجاهًا متطابقًا (متكافئان دلاليًّا نموذجيًّا).

GloVe: طريق مختلف إلى النتيجة نفسها

GloVe (Global Vectors) قدّمته جامعة ستانفورد في 2014. فكرته مختلفة عن Word2Vec: بدل تعظيم احتمال محلّي على كلّ زوج، يبني أوّلًا مصفوفة تواقع عامّة لكلّ الجسم (XijX_{ij} = عدد ظهور الكلمة jj في سياق الكلمة ii)، ثمّ يبحث عن متّجهات تجعل حاصل ضربها القياسي يقارب لوغاريتم هذا العدد:

vivj+bi+bjlogXijv_i^\top v_j + b_i + b_j \approx \log X_{ij}

النتيجة قريبة عمليًّا من Word2Vec، أحيانًا أفضل قليلًا على مهامّ التشابه. ميزتها أنّها تستغلّ الإحصاء العامّ مرّة واحدة، بينما Skip-gram يمرّ على الجسم كلّه عدّة مرّات.

للعربية، المتوفّر جاهزًا يشمل نماذج AraVec (Word2Vec على تويتر وويكيبيديا العربيّتَين) وتضمينات fastText الرسمية على 157 لغة. fastText يضيف ابتكارًا مفيدًا: كلّ كلمة مجموع من متّجهات وحداتها الجزئية على مستوى الأحرف. هذا يعالج الكلمات المجهولة (نبني متّجهها من أحرفها)، ويلتقط تشابهات الاشتقاق الغنيّة في العربية.

التشبيهات المتّجهية والأسطورة المؤسِّسة

النتيجة التي أشعلت اهتمام المجال ب Word2Vec: التشبيهات تُحلّ بعملية جمع وطرح.

v(king)v(man)+v(woman)v(queen)v(\text{king}) - v(\text{man}) + v(\text{woman}) \approx v(\text{queen})

جميل، وذائع. وأقلّ صحّة ممّا يُقال. الدراسات اللاحقة أثبتت أنّ الحلّ يُحصَّل غالبًا بفرض أنّ الجواب لا يمكن أن يكون واحدًا من الكلمات الثلاث الداخلة في الحساب. اِرْفَع هذا القيد يعُد النموذج إلى الكلمة الأصلية في نصف الحالات.

يبقى للجاذبية الرياضية معنى محدود: بعض العلاقات (مذكّر/مؤنّث، مفرد/جمع، دولة/عاصمة) موجودة بالفعل بوضوح في الفضاء. لكنّها ليست تنبّؤات ذكيّة، بل أنماط إحصائية شديدة الانتشار في الجسم. الاختبار الحقيقي هو ما تفعله التضمينات لاحقًا في تصنيف أو استرجاع، لا مسليّات التشبيه.

التحيّزات المُرمَّزة في التضمينات

نتيجة أخطر بكثير: التضمينات تتعلّم من الجسم كلّ ما فيه من تحيّزات إنسانية.

v(doctor)v(man)+v(woman)v(nurse)v(\text{doctor}) - v(\text{man}) + v(\text{woman}) \approx v(\text{nurse})

هذا ليس خطأ خوارزميّ. الجسم الذي دُرِّب عليه Word2Vec يظهر فيه الأطبّاء ذكورًا والممرّضات إناثًا أكثر. النموذج يعلَم هذا التوزيع بأمانة تامّة. ثمّ يورّثه إلى كلّ نموذج يستعمل هذه التضمينات كطبقة إدخال، من فرز السير الذاتية إلى تصنيف نصوص.

على العربية، فقد رُصدت في AraVec وأمثالها تحيّزات مماثلة تتعلّق بالجنس، والدين، والقومية. الحلول التقنية موجودة (débiasing) لكنّها جزئية. الحلّ الحقيقي يبدأ من اختيار الجسم، ومن أن يكون فريق النشر واعيًا بأنّ نموذجه سيقرّر أشياء ينبغي ألّا تُقرَّر إحصائيًّا.

التضمينات المدرَّبة على تويتر ليست حياديّة

تدريب Word2Vec على تويتر يعطي متّجهات ممتازة لتقاط اللغة الشائعة، لكنّه يكرّس أيضًا كلّ ما في تويتر من عنصرية وتنميط. قبل استعمال تضمينات جاهزة في مسار إنتاج، اعتَبِر مصدرها كأنّه بيانات تدريب: افحصه، وقِس تحيّزاته على قوائم اختبار معيارية، ووثّق ما تجد.

اختبر تضميناتك بأسئلة القرابة بدل أسئلة التشبيه

لتقييم جودة تضميناتك على مجالك، اطبع قائمة أقرب 10 كلمات لعشر كلمات مفتاحية من مجالك (أسماء منتجات، صفات، أخطاء شائعة). القائمة الصالحة تعرض مرادفات وأخطاء إملاء وصيغًا نحوية للكلمة. القائمة الرديئة تعرض كلمات مشوّشة أو من مجال آخر — علامة أنّ الجسم أو الحدّ الأدنى min_count يحتاج مراجعة.

في الخلاصة

  • الفرضية التوزيعية تجعل معنى الكلمة قابلًا للتعلّم من جيرانها: هذا هو أساس Word2Vec وGloVe وكلّ ما جاء بعدها.
  • Skip-gram يتنبّأ بالسياق من الكلمة، وCBOW يتنبّأ بالكلمة من السياق؛ أخذ العيّنات السلبية يجعل التدريب عمليًّا بتحويل المسألة إلى تصنيف ثنائي.
  • GloVe يبني تضميناته من مصفوفة التواقع العامّة بدل التحسين على أزواج محلّية؛ والنتيجتان قريبتان عمليًّا.
  • التشبيهات المتّجهية أقلّ سحرًا ممّا يُقال، لكنّ التحيّزات المتعلّمة حقيقية جدًّا وتنتقل صامتة إلى كلّ نموذج يستعمل هذه التضمينات.

الوحدة التالية: التضمينات السياقية، حيث تصير الكلمة الواحدة متّجهات مختلفة حسب الجملة، فتُحلّ مشكلة تعدّد المعنى.