اختيار المشكلة
درس 1 من 3
1اختيار المشكلة
الصورة الكبيرةالمشروع الختامي يبدأ بشخص لا بنموذج. تختار شخصًا تعرفه، صاحب متجر أو معلّمًا أو موظّف دعم، وتجد مشكلة يعيشها كل أسبوع، ثم تكتب قبل أي سطر كود رقمًا يحدّد النجاح: ما الدقة، أو كم دقيقة توفّر، أو ما نسبة الحالات التي يحلّها النظام وحده. وتكتب معه ما لن تبنيه، لأن المشاريع الختامية تموت من اتساع النطاق لا من صعوبته.
ماذا تشاهد في الرسم: نفس الدقة 80%، ومداها يضيق كلما كبرت المجموعة: 34 نقطة على عشرين مثالًا، و16 على مئة، و5 على ألف. الخط المتقطّع عند المئة هو الحد الأدنى للمشروع الختامي.
خارطة هذا الجزء
المفاهيم بالترتيب، اضغط أيًّا منها للقفز إليه:
طريقان إلى نفس الفكرة
المشروع الختامي يبدأ بشخص حقيقي تعرفه ومشكلة يعاني منها، لا بتقنية تريد تجربتها. وقبل أن تكتب سطرًا، تكتب كيف ستعرف أنك نجحت: رقم واضح مثل «يجيب صحيحًا عن 8 من كل 10 أسئلة».
تحدد المستخدم والمشكلة والبيانات المتاحة والقيود (الخصوصية والتكلفة والزمن)، ومعيار نجاح رقمي ومجموعة تقييم أولية وخط أساس بسيط. وتضيّق النطاق حتى يُنجز في المدة، وتكتب ما هو خارج النطاق صراحة.
قبل أن تبدأ
🧭تأطير المسألة
تعرف كيف تحوّل حاجة غامضة إلى مهمة بمدخل ومخرج ومقياس.
📏المقاييس
تعرف الدقة والدقة الإيجابية والاستدعاء، ومتى يكون أحدها أهم من الآخر.
الفكرة الجوهرية
قبل أي سطر كود تكتب أربعة أشياء بالترتيب: من المستخدم، وما معيار النجاح، وما خط الأساس الذي تتجاوزه، وما الذي لن تبنيه.
1المستخدم: شخص باسمه
ابدأ من شخص حقيقي تعرفه وتستطيع أن تجلس معه ساعة، لا من «المستخدمين عمومًا». اعرف ماذا يفعل اليوم بدون نظامك وكم يستغرق.
انظر إلى الرسم: نورة صاحبة متجر تقرأ رسائل الدعم بيدها، و40% منها سؤال واحد يتكرّر.
هذه مشكلة تعيشها كل أسبوع، ولها رقم تقيسه: الوقت الذي يضيع. هذا ما يجعلها مشكلة تستحق أسابيع من العمل.
2معيار النجاح قبل الكود
اكتب المعيار بلغة المستخدم أولًا: «النظام يردّ وحده على نصف رسائل الشحن، ولا يخطئ في أكثر من رسالة من كل عشرين». ثم ترجمه إلى مقياس تحسبه.
انظر إلى الرسم: تغطية 50% بدقة 95% على فئة الشحن.
الترجمة تكشف ما لم تفكّر فيه: هنا الدقة أهم من التغطية، لأن ردًّا خاطئًا على عميل أسوأ من عدم الرد.
وتقيسه على مئة حالة حقيقية على الأقل من الشهر الماضي، يصنّفها المستخدم بنفسه، ثم تجمّدها قبل أن تبني.
3خط الأساس الذي تتجاوزه
رقم نموذجك لا معنى له وحده. قارنه بأبسط حل ممكن، فإن لم يتجاوزه فالحل البسيط أرخص وأسرع وأسهل في الشرح.
عشرون رسالة دعم حقيقية من متجر صغير، صنّفها صاحب المتجر بنفسه. قبل أي نموذج، جرّب أبسط حلّين: أن تقول دائمًا الفئة الأكثر شيوعًا، وقاعدة كلمات مفتاحية كتبتها في عشر دقائق.
from collections import Counter
# 20 real support messages from a small shop, labelled by the owner
messages = [
("وين طلبي؟ صار له أسبوع", "shipping"),
("كم سعر التوصيل للرياض؟", "shipping"),
("الشحنة متأخرة ومحد يرد", "shipping"),
("متى يوصل الطلب لجدة؟", "shipping"),
("رقم التتبع ما يشتغل", "shipping"),
("المندوب ما اتصل علي", "shipping"),
("هل التوصيل مجاني فوق ٢٠٠؟", "shipping"),
("طلبت من عشرة أيام وما وصل شي", "shipping"),
("أبي أرجع المنتج", "returns"),
("كيف أستبدل المقاس؟", "returns"),
("المنتج ما عجبني أبي فلوسي", "returns"),
("ابغى استرجاع المبلغ", "returns"),
("المنتج وصل مكسور", "damaged"),
("الكرتون مفتوح والقطعة ناقصة", "damaged"),
("اللون غير اللي في الصورة وفيه خدش", "damaged"),
("هل عندكم مقاس أكبر؟", "product"),
("القماش قطن ولا بوليستر؟", "product"),
("متى ينزل اللون الأسود؟", "product"),
("هل يناسب الغسالة؟", "product"),
("فيه ضمان على الجهاز؟", "product"),
]
labels = [label for _, label in messages]
majority, count = Counter(labels).most_common(1)[0]
print(f"majority baseline: always '{majority}' -> {count / len(labels):.0%}")
def keyword_rule(text):
if any(w in text for w in ["طلب", "التوصيل", "الشحن", "يوصل"]):
return "shipping"
if any(w in text for w in ["أرجع", "استرجاع", "أستبدل"]):
return "returns"
if any(w in text for w in ["مكسور", "ناقصة", "خدش"]):
return "damaged"
return "product"
wrong = [(t, y, keyword_rule(t)) for t, y in messages if keyword_rule(t) != y]
print(f"keyword rule: {1 - len(wrong) / len(messages):.0%}")
for text, truth, guess in wrong:
print(f" missed: {text} (truth {truth}, rule said {guess})")
قاعدة من عشرة أسطر وصلت 85%، وهذا رقم متفائل لأنك كتبتها وأنت ترى نفس الرسائل. ومع ذلك فهو الخط الذي يجب أن يتجاوزه نموذجك على رسائل جديدة، وإلا فالقاعدة أرخص وأسرع وأسهل في الشرح. وانظر للأخطاء الثلاثة: كلها لغة لم تتوقّعها القاعدة («التتبع»، «المندوب»، «فلوسي»). هذا هو المكان الذي قد يضيف فيه النموذج قيمة فعلًا.
4أصغر نطاق، وما لن تبنيه
المشاريع الختامية تموت من النطاق لا من الصعوبة. اختر مهمة واحدة يجرّبها المستخدم كاملة في أسبوعين، لا خمس مهام نصف منجزة.
ثم اكتب كل ذلك في صفحة واحدة، ومعها قائمة بالأشياء المغرية التي تؤجّلها عمدًا.
صفحة واحدة تكتبها قبل الكود وتُريها للمستخدم ليوافق عليها. هذا قالب مملوء لمثال المتجر.
# Scope: shipping replies for <shop name>
User: Noura, owner, answers ~60 support messages a day by hand
Today: ~2 hours a day; 40% of messages are "where is my order?"
Task: classify incoming messages; for shipping status questions,
draft a reply with the tracking status for Noura to send
Success bar: on 150 held-out real messages labelled by Noura:
- shipping precision >= 95% (a wrong draft costs her trust)
- drafts accepted without edits >= 60%
- beats the keyword rule (85% on the dev messages) on new data
Baseline: keyword rule, written and measured first
Data: last month's messages, phone numbers and emails removed
before they leave Noura's laptop
Not building: login, other message channels, returns, refunds,
automatic sending without Noura's click, an app
Deadline: first usable version in 2 weeks, stranger test in week 4
كل سطر قابل للفحص لاحقًا. «دقة 95%» رقم تقيسه، و«60% بلا تعديل» تسأل عنه نورة بعد أسبوع، و«لا إرسال آلي» قرار يحمي المستخدم ويقلّل مخاطرتك. وقائمة «لن أبني» هي ما ستعود إليه كل مرة تغريك ميزة جديدة.
كيف يعمل، خطوة بخطوة: كيف تكتب وثيقة النطاق قبل الكود
تختار شخصًا حقيقيًّا باسمه، وتعرف ماذا يفعل اليوم بدون نظامك وكم يستغرق.
تكتب معيار النجاح بلغته أولًا، ثم تترجمه إلى مقياس تحسبه.
تطلب منه مئة حالة حقيقية على الأقل يكتب إجاباتها بنفسه، وتقيس عليها خطًّا أساسيًّا بسيطًا.
تكتب قائمة ما لن تبنيه، وترسل الوثيقة للمستخدم بتاريخ قبل أي تدريب.
أعمق قليلًا
بيانات التقييم تأتي من المستخدم نفسه، لا منك. اطلب منه مئة حالة حقيقية من الشهر الماضي، وأن يكتب لكل منها الإجابة الصحيحة بنفسه. وإن كانت البيانات تحتوي معلومات شخصية، اتّفق معه من البداية على ما يُحذف وأين تُحفظ. وجمّد هذه المجموعة قبل أن تبدأ البناء، فلا تضيف إليها ولا تحذف منها لتحسّن رقمك.
| صياغة ضعيفة | صياغة قابلة للبناء |
|---|---|
| «مساعد ذكي لخدمة العملاء» | «تصنيف رسائل الشحن والرد الآلي على حالة الطلب، بدقة 95% على 50% منها» |
| «تحليل مشاعر التغريدات» | «تنبيه مسؤول الحساب بالشكاوى خلال ساعة، لا يفوته أكثر من شكوى من كل عشر» |
| «تلخيص المستندات» | «ملخّص من خمسة أسطر لعقود الإيجار يختصر وقت المراجعة من 20 دقيقة إلى 5، ولا يحذف أي رقم مالي» |
مثال محلول
قبل أن تكتب معيار النجاح، تحتاج أن تعرف كم مثالًا تحتاج لتقيسه. «دقة 80%» على عشرين مثالًا ليست رقمًا، بل مدى واسع جدًّا. هذا الكود يحسب المدى الحقيقي لنفس الدقة على مجموعات تقييم بأحجام مختلفة.
١. كم مثالًا يكفي؟
import math
def wilson(correct, n, z=1.96):
p = correct / n
centre = (p + z * z / (2 * n)) / (1 + z * z / n)
half = z * math.sqrt(p * (1 - p) / n + z * z / (4 * n * n)) / (1 + z * z / n)
return centre - half, centre + half
# the same 80% accuracy, measured on eval sets of different sizes
for n in [20, 50, 100, 300, 1000]:
low, high = wilson(round(0.8 * n), n)
print(f"n={n:5}: 80% means somewhere in {low:.0%} .. {high:.0%} (width {high - low:.0%})")
على عشرين مثالًا، 80% تعني أي شيء بين 58% و92%، أي أن نظامًا ضعيفًا ونظامًا ممتازًا قد يعطيان نفس الرقم. على مئة مثال يضيق المدى إلى 16 نقطة، وعلى ثلاثمئة إلى 9. القاعدة العملية للمشروع الختامي: مئة مثال على الأقل في مجموعة التقييم، وثلاثمئة إن أردت أن تفرّق بين نسختين متقاربتين.
جرّب بلا كود
خرافة مقابل حقيقة
| الخرافة | الحقيقة |
|---|---|
| ابدأ بتقنية تريد تجربتها ثم ابحث عن مشكلة. | النتيجة نظام معقّد يحلّ مشكلة لا يعيشها أحد. ابدأ من شخص ومشكلة واختر أبسط تقنية تحلّها. |
| عشرون مثالًا تكفي لمعرفة دقة النظام. | على عشرين مثالًا تعني 80% أي شيء بين 58% و92%، فالنظام الضعيف والممتاز يعطيان نفس الرقم. |
| القاعدة البسيطة لا تستحق القياس. | قاعدة كلمات من عشرة أسطر بلغت 85% في المثال. هذا هو الحد الذي يجب أن يتجاوزه نموذجك، وإلا فالقاعدة أرخص وأوضح. |
جرّب بنفسك
نظامك حقّق 85% على 20 مثالًا، ونظام زميلك 80% على 20 مثالًا آخر. ماذا تستنتج؟
على 20 مثالًا، 80% تعني ما بين 58% و92%. فرق خمس نقاط داخل هذا المدى ضجيج. ومقارنة نظامين تحتاج نفس مجموعة التقييم وحجمًا أكبر.
قاعدة كلمات مفتاحية حقّقت 85%، ونموذجك 86% على نفس المجموعة. ما القرار المعقول؟
نقطة واحدة ضمن الضجيج لا تبرّر تكلفة النموذج وصعوبة شرحه وصيانته. النموذج يستحق مكانه حين يتجاوز خط الأساس بفارق واضح، أو يحلّ فئة تفشل فيها القاعدة تمامًا.
بطاقات مراجعة سريعة
تحقق من فهمك
صديقك يقول: «سأبني نموذجًا يصنّف رسائل العملاء، وسأعرف أنه نجح حين يبدو جيدًا». ما الذي ينقصه؟
أربعة أشياء: مستخدم محدّد يعيش المشكلة، ومعيار رقمي مكتوب قبل البناء، ومجموعة تقييم حقيقية بحجم يكفي (مئة مثال على الأقل) صنّفها المستخدم، وخط أساس بسيط مثل قاعدة كلمات مفتاحية. «يبدو جيدًا» ليس معيارًا، لأنه سيبدو جيدًا دائمًا لمن بناه.
لماذا تُعدّ دقة قاعدة الكلمات 85% على رسائل المتجر العشرين متفائلة؟
لأنها كُتبت وأنت تنظر إلى نفس الرسائل، فاخترت كلماتها لتناسبها. رقمها الصادق يأتي من رسائل جديدة لم ترها.
مصادر هذا الدرس
مرتّبة بالنوع. ابدأ بالتوثيق الرسمي إذا تبي المرجع الدقيق، وبالمقال أو الفيديو إذا تبي الشرح أولًا.
توثيق رسمي1
خلّصت الدرس؟
سجّل الدخول ليُحفظ تقدّمك.