Stage 4 of 5المرحلة 4 من 5

Real Projects & Machine Learningالمشاريع الحقيقية وتعلم الآلة

Frame real business problems, use machine learning only where it fits, evaluate it honestly and deliver end-to-end projects.

تحوّل مشكلات العمل الحقيقية إلى مشاريع، وتستخدم تعلم الآلة فقط حيث يناسب، وتقيّمه بأمانة، وتسلّم مشاريع كاملة من البداية للنهاية.

5 units · 22 lessons · Each unit ends with an exit check · Taught in English

5 وحدات · 22 درسًا · كل وحدة تنتهي بتقييم · الدروس بالإنجليزية

U17 · From Business Problem to Data Projectمن مشكلة العمل إلى مشروع بيانات

Stage 4المرحلة 4

Free: the first lesson. The other lessons, the exit brief and the practice files are for Starter and Membership.

مجاني: الدرس الأول. باقي الدروس وتكليف نهاية الوحدة وملفات التمرين لأصحاب باقة البداية والاشتراك.

Download U17 practice files (.zip, 1.0 MB)حمّل ملفات تمرين U17 (zip، 1.0 MB)

Unzip into a short folder such as D:\DWorld on Windows. The zip has only learner files: no answers.

فك الضغط في مجلد قصير مثل D:\DWorld على ويندوز. الملف يحتوي ملفات المتعلم فقط بدون إجابات.

L72 · From Request to Problem Statement: Stakeholders & Decision OwnersL72 · من الطلب إلى بيان المشكلة: أصحاب المصلحة وأصحاب القرار About 2.5 hoursحوالي ساعتين ونصف Freeمجاني

L72 — From Request to Problem Statement: Stakeholders & Decision Owners

Learner file. Answers and model solutions are in a separate instructor-only file. Version: U17 Production v1 · Content date: 21 October 2026. Time estimates are planning estimates until learners have tested them. The code in this lesson was run with Python 3.13.16, pandas 3.0.5 and NumPy 2.5.3 (recorded in D.World's internal Code Test Report); Python 3.13 is the accepted course version. Not run with Python 3.14 or inside JupyterLab.

All businesses are fictional and all data is synthetic.


1. Lesson Identity

Field Value
Title From Request to Problem Statement: Stakeholders & Decision Owners
Stage Stage 4 — Real Projects & Machine Learning
Unit U17 — From Business Problem to Data Project
Lesson ID L72
Skills Request vs problem vs task; stakeholder map (decision owner, users, affected parties, data owners); value at stake; constraints; problem-statement template; questions to ask before data work; scope in and out
Difficulty Intermediate
Estimated time About 2.5 hours (planning estimate, unvalidated)
Assessment level Practice
Prerequisites L66 (decision frames), L65 (audience and decision), L57 (EDA question trees).

Time breakdown (planning estimate): concept and worked example 55 min · guided practice 30 min · independent practice 35 min · knowledge check 10 min · AI 5 min (optional) · workplace task and mini challenge 15 min.

What you need: practice_files (L72_starter.ipynb; u17_data/cedar_lane_u17.db).

The U17 data. cedar_lane_u17.db is a SQLite database for the whole unit, July 2025 to September 2026: customers (sign-up date, region, acquisition channel, whether they use the app), orders (one row per order: date, home delivery or pickup, pickup point, basket value, gross margin), deliveries (home orders: zone, distance, the promised latest delivery time and the actual delivery time) and pickup_visits (pickup-point visits from May 2026: arrival time, minutes waited, whether the customer left without collecting). You will check how good these tables are in L74; in this lesson you only use them to put a number on what is at stake.


2. Learning Objective

By the end of this lesson, you will be able to:

  • rewrite a stakeholder request as a problem statement that names the decision, the decision owner, the stakeholders affected and the value at stake;
  • draw a stakeholder map that separates the decision owner, users, affected parties and data owners;
  • list what is not yet known, as questions to ask before any data work starts.

D.World approved objective (verbatim): Rewrite a stakeholder request as a problem statement that names the decision, the decision owner, the stakeholders affected and the value at stake, and list what is not yet known.


3. Why It Matters

Stage 4 is about real projects, and real projects rarely arrive as clean questions. They arrive as requests: "We need a dashboard for late deliveries." "Use AI to fix our pickup queues." "Can we predict churn?" Each request names a tool (a dashboard, AI, a prediction). None of them says what will be decided, who decides, or what it is worth.

Teams that build what was literally asked often deliver something accurate that nobody acts on. In L66 you framed single decisions. Now you start a whole project, and the first deliverable is not code: it is a problem statement that everyone involved agrees with.

Key principle: a project starts from a decision and its value, not from a tool or a dataset. Write down who decides what, what it is worth, and what you do not know yet, before you touch the data.


4. Concept

import sqlite3

import pandas as pd

con = sqlite3.connect("u17_data/cedar_lane_u17.db")
q = lambda sql: pd.read_sql_query(sql, con)
for t in ["customers", "orders", "deliveries", "pickup_visits"]:
    print(f"{t:<14}", q(f"SELECT COUNT(*) AS n FROM {t}")["n"].iloc[0], "rows")
customers      6007 rows
orders         13694 rows
deliveries     7950 rows
pickup_visits  2522 rows

Part A — Request, problem, task

Level What it says Example at Cedar Lane
Request What someone asks for, often a tool or output "We need a dashboard for late deliveries."
Problem The business situation that must change, and why it matters Late home deliveries may be costing repeat customers and margin; nobody knows which actions would reduce them.
Task A piece of work that helps solve the problem Measure the late rate by slot and distance; estimate the margin at stake.

A request is useful information: it tells you who is worried and about what. But it is not yet a problem statement. Your job is to move from the request to the problem with the person who asked, then plan the tasks.

Part B — The stakeholder map

A stakeholder is anyone who decides, uses, is affected by, or supplies data to the project. Separate four roles:

Role Question it answers Typical people at Cedar Lane
Decision owner Who will decide and be accountable? Head of operations, marketing lead, managing director
Users Who will use the output day to day? Dispatch planners, pickup-point supervisors, the retention team
Affected parties Who feels the consequences without deciding? Customers, couriers, pickup-point staff, finance
Data owners Who holds and can explain the data? The delivery-app team, the queue-system supplier, finance

Two rules: there must be exactly one decision owner for each decision (a committee is not an owner), and affected parties are not optional: customers and staff often carry the cost of a decision they did not make.

Part C — Value at stake, constraints and scope

The value at stake is how much is gained or lost depending on the decision, in money or customers, over a stated period. It does not have to be precise; an order of magnitude with its assumptions is enough to decide whether a project is worth weeks of work.

Start with the size of the problem. How many home deliveries arrive late?

late = q("""
SELECT substr(promised_by, 1, 7) AS month, COUNT(*) AS home_deliveries,
       SUM(delivered_at > promised_by) AS late
FROM deliveries
WHERE promised_by >= '2026-07-01' AND promised_by < '2026-10-01'
GROUP BY 1 ORDER BY 1
""")
late["late_rate"] = (late["late"] / late["home_deliveries"]).round(3)
print(late.to_string(index=False))
  month  home_deliveries  late  late_rate
2026-07              647    78      0.121
2026-08              653    91      0.139
2026-09              691    92      0.133

About one home delivery in seven or eight arrives after the promised time. That is the size of the problem, not yet its value. Value needs a link to money: for example, customers whose first delivery is late may not come back (you will check this in the worked example).

Constraints limit what solutions are possible: time (a decision is needed before the Christmas peak), data (no courier GPS data), privacy (customer addresses must not leave the delivery system), budget (no new staff this year). Scope says what is in and what is out: for example, in = home deliveries in the five regions; out = pickup orders, courier pay.

Part D — The problem-statement template

A good problem statement fits in one paragraph and answers six questions:

  1. Situation: what is happening, with a number.
  2. Decision: what will be decided, by whom (the decision owner), by when.
  3. Options: at least two, including "do nothing" (L66).
  4. Value at stake: money or customers, over a period, with the main assumption.
  5. Affected parties: who else feels the result.
  6. Scope and constraints: what is in, what is out, what limits the solution.

Then add a list of open questions: what you do not know yet and who can answer it. A problem statement that names a tool ("build a dashboard") instead of a decision fails the template.


5. Worked Example

Cedar Lane (fictional), synthetic data. The head of operations writes: "We need a dashboard for late deliveries."

Step 1 — Who is asking, and what are they worried about? Operations is worried about late home deliveries. The dashboard is their idea of a solution, not the problem.

Step 2 — Is lateness linked to value? Compare new customers whose first order was a home delivery that arrived late with those whose first delivery was on time. Use the customers who joined from July 2025 to June 2026 (twelve months), so that everyone has had at least 90 days in which to order again.

first = q("""
WITH f AS (
  SELECT o.customer_id, o.order_id, o.order_date
  FROM orders o JOIN customers c ON c.customer_id = o.customer_id AND o.order_date = c.signup_date
  WHERE o.fulfilment = 'home' AND c.signup_date < '2026-07-01'
)
SELECT f.customer_id,
       MAX(d.delivered_at > d.promised_by) AS first_late,
       (SELECT COUNT(*) FROM orders o2 WHERE o2.customer_id = f.customer_id
          AND o2.order_date > f.order_date AND o2.order_date <= date(f.order_date, '+90 days')) > 0 AS repeat_90d
FROM f JOIN deliveries d ON d.order_id = f.order_id
GROUP BY f.customer_id
""")
print(first.groupby("first_late")["repeat_90d"].agg(customers="size", repeat_rate="mean").round(3))
            customers  repeat_rate
first_late                        
0                2539        0.416
1                 393        0.221

Customers whose first delivery was late came back within 90 days far less often. This is an association, not proof that lateness causes customers to leave (L56): late first deliveries may happen more often in areas where customers order less anyway. But it is enough to say that lateness may be worth money.

Step 3 — Put a rough number on the value at stake.

gap = first.groupby("first_late")["repeat_90d"].mean()
lost_share = gap.loc[0] - gap.loc[1]
late_first_per_year = int(first["first_late"].sum())   # the cohort covers exactly twelve months
margin_90d = q("""
WITH f AS (SELECT customer_id, signup_date FROM customers WHERE signup_date < '2026-07-01')
SELECT AVG(m) AS margin FROM (
  SELECT f.customer_id, SUM(o.gross_margin) AS m FROM f JOIN orders o ON o.customer_id = f.customer_id
  WHERE o.order_date > f.signup_date AND o.order_date <= date(f.signup_date, '+90 days')
  GROUP BY f.customer_id)
""")["margin"].iloc[0]
print(f"repeat-rate gap: {lost_share:.3f}")
print(f"late first deliveries (Jul 2025 - Jun 2026): {late_first_per_year}")
print(f"average 90-day margin of a returning customer: EUR {margin_90d:.2f}")
print(f"upper-bound margin at stake per year: EUR {late_first_per_year * lost_share * margin_90d:,.0f}")
repeat-rate gap: 0.195
late first deliveries (Jul 2025 - Jun 2026): 393
average 90-day margin of a returning customer: EUR 13.99
upper-bound margin at stake per year: EUR 1,072

The calculation multiplies three things: how many first deliveries are late per year, how much less often those customers return, and what a returning customer is worth in the following 90 days. It is an upper bound on one specific loss, the 90-day repeat margin of new customers, because it treats the whole association as if lateness caused it. It is also narrow: it counts only 90 days and only new customers. The honest summary is: "Through lost 90-day repeat purchases from new customers, late first deliveries cost at most about €1,100 of margin a year; the full cost of lateness could be higher once other customers, longer periods and direct costs are counted."

That number is small, and that is a useful result. It already rules out an expensive solution (new routing software, extra vans) justified by repeat purchases alone. It does not end the project, because of what it leaves out: other customers, longer periods and direct costs of lateness (refunds, complaints), which are open questions below. So the value at stake points the project towards cheap options and towards finding the missing costs first.

Step 4 — Stakeholder map.

Role Who
Decision owner Head of operations (decides on delivery changes)
Users Dispatch planners; customer-service leads
Affected parties New customers; couriers (routes, workload); finance (delivery cost)
Data owners Delivery-app team (deliveries); finance (orders margin)

Step 5 — Problem statement.

About 13% of Cedar Lane's home deliveries arrived after the promised time in July–September 2026. New customers whose first delivery was late returned within 90 days much less often than those whose delivery was on time (about 22% vs 42%; an association). The head of operations must decide before the November planning meeting whether to change how first deliveries are scheduled (options: do nothing; add buffer time to first deliveries; prioritise first-time customers in routing). At most about €1,100 a year of repeat-purchase margin is at stake (an upper bound), plus direct costs of lateness not yet known; only low-cost options are justified so far. Couriers, new customers and finance are affected. In scope: home deliveries, all regions. Out of scope: pickup orders, courier pay. Constraint: no courier GPS data; changes must not raise delivery cost per order.

Step 6 — Open questions (and who can answer them):

  1. Is the promised time the end of the slot the customer chose, or a time the courier set? (delivery-app team)
  2. Which actions are actually possible before November? (head of operations)
  3. Does lateness also affect existing customers, or only first orders? (analysis)
  4. What does a late delivery cost directly, beyond repeat purchases (refunds, complaints)? (finance, customer service)
  5. Who would use a dashboard, and which decision would they make with it each day? (dispatch planners)

Notice that the dashboard did not disappear: it may become one task later, if the dispatch planners need it for a daily decision.


6. Visual Explanation

 REQUEST (a tool)          PROBLEM (a decision + its value)                 TASKS (work)
 "dashboard for     ──▶    situation with a number · decision · owner   ──▶  measure late rate
  late deliveries"         options incl. do nothing · value at stake          estimate value at stake
                           affected parties · scope in/out · constraints     answer open questions

 STAKEHOLDER MAP      decision owner (exactly one) │ users │ affected parties │ data owners

 VALUE AT STAKE = (cases per year) × (difference in outcome) × (value per outcome)   → state assumptions; upper bound?

Alt text: A three-stage flow from a request that names a tool, to a problem statement with a situation and number, the decision and its single owner, options including doing nothing, the value at stake, affected parties, scope and constraints, and then to tasks such as measuring the late rate and estimating the value at stake. Below, a stakeholder map lists four roles: one decision owner, users, affected parties and data owners. At the bottom, value at stake is shown as cases per year times the difference in outcome times the value per outcome, with a reminder to state assumptions and whether the figure is an upper bound.


7. Guided Practice

Open L72_starter.ipynb.

  1. Run the setup cell and the late-delivery query. Write the situation sentence for "we need a dashboard for late deliveries" with the late rate for July–September 2026.
  2. Compute the first-delivery repeat comparison and the value-at-stake estimate. Write one sentence that says why it is an upper bound, and one that says what it leaves out.
  3. Fill in the stakeholder map (four roles). Name exactly one decision owner.
  4. Write the problem statement with the six template parts, and a scope line (in / out).
  5. List five open questions and who can answer each one.
  6. Run Restart Kernel and Run All Cells….

8. Independent Practice

Pickup queues. The head of operations sends a new message: "Customers complain about queues at the pickup points. Use AI to fix our pickup queues."

Write, in L72_starter.ipynb (Part 2):

  1. Size of the problem from the data: from pickup_visits, the visits per pickup point, the average wait, the share of visits waiting more than 10 minutes and the number of customers who left without collecting. Note which point and which hours look worst.
  2. A problem statement (120–200 words) using the six template parts. It must name a decision and a value, not a tool ("AI" may appear only as a possible option).
  3. A stakeholder map with the four roles.
  4. The five questions you would ask before starting, each with the person who can answer it.

Hint: think about what "fix" could mean as decisions (staff rota, opening hours, collection slots, moving orders to home delivery) and what a customer who leaves without collecting costs.


9. Knowledge Check — Problem Statements

Q1. "We need a dashboard for late deliveries" is best described as:

  • A) A problem statement with a clear owner and metric
  • B) A task that already names the decision to be made
  • C) A request that names a tool
  • D) A hypothesis about why deliveries are late

Q2. How many decision owners should one decision have?

  • A) Exactly one person, who is accountable for it
  • B) One for each department that the decision affects
  • C) None, because the data should make the decision
  • D) As many as the steering committee has members

Q3. Which person is an affected party (not the decision owner) when operations changes pickup opening hours?

  • A) The head of operations, who makes the decision
  • B) The queue-system supplier who holds the wait data
  • C) The analyst who prepares the evidence
  • D) Pickup-point staff whose shifts change

Q4. Which is the best statement of value at stake?

  • A) "Late deliveries are very bad for our brand and must be reduced as soon as possible."
  • B) "Up to about €X of margin a year may be lost after late first deliveries (an upper bound)."
  • C) "The dashboard will have ten charts, one for each region and courier."
  • D) "13% of deliveries are late, against a target of 10% set last year."

Q5. Why is the value-at-stake estimate in the worked example called an upper bound?

  • A) Because it was computed with SQL instead of a statistical model
  • B) Because it uses too few customers to give a reliable estimate
  • C) Because it treats an association as if lateness caused all of it
  • D) Because margin figures from finance are always overestimated

Q6. Which line belongs in scope?

  • A) "Out of scope: courier pay."
  • B) "The model will use gradient boosting."
  • C) "The head of operations decides."
  • D) "Customers are affected."

Q7. Which is a constraint?

  • A) The late rate is 13%, higher than in the same month last year.
  • B) No courier GPS data is available, and delivery cost per order must not rise.
  • C) Customers return less often after a late first delivery than after an on-time one.
  • D) Dispatch planners will use the output in their weekly planning meeting.

Q8. What should you do with the original request (for example "a dashboard") once you have a problem statement?

  • A) Delete it, because requests from managers are usually wrong
  • B) Build it first, and then write the problem statement around it
  • C) Keep it as a possible task, if a user needs it for a decision
  • D) Replace it with a machine-learning model that predicts lateness

10. AI in Practice (optional, bounded)

Goal: use an AI assistant to brainstorm stakeholders and hidden constraints, then keep only what applies to Cedar Lane.

  1. Ask: "A small online grocery's head of operations says: 'Use AI to fix our pickup queues.' List every stakeholder and every constraint that might matter."
  2. Copy the answer into your notebook. Mark each item C (applies to the Cedar Lane case facts) or G (generic, no evidence in our case).
  3. Add any stakeholder the AI missed.

Boundaries: AI is optional; describe the situation, never paste customer data; the problem statement is yours: AI may suggest, you decide.


11. AI Verification

  1. Case facts: for every item marked C, point to the fact that supports it (a table, a number, a sentence in the request).
  2. Decision, not tool: does your final problem statement name a decision and a value, not "AI" or "a dashboard"?
  3. One owner: did the AI propose a committee or several owners? Reduce it to one.
  4. Write down two suggestions you rejected and why.

12. Business Lens

Projects that start from value, not tools, avoid building things nobody uses. A problem statement is cheap: one paragraph, one meeting. It protects weeks of analysis by making sure the decision owner agrees on what will be decided, what it is worth and what is out of scope. It also gives affected parties (customers, staff, finance) a voice before the work starts, which is when their concerns are cheapest to address.


13. Workplace Task — The Reply to the Requester

Fictional business: Cedar Lane. Write a reply (80–120 words) to the head of operations about the dashboard request. Thank them, restate the problem in one sentence with a number, propose the decision and the options, say what you will deliver first (not the dashboard), and ask the two most important open questions.


14. Mini Challenge — Whose Problem Is It?

Fictional business: Cedar Lane. The marketing lead writes: "Use AI to send personalised offers to every customer who waited too long at a pickup point."

print(q("""
SELECT CASE WHEN CAST(strftime('%H', arrived_at) AS INTEGER) BETWEEN 17 AND 19 THEN 'evening 17-19' ELSE 'other hours' END AS period,
       COUNT(*) AS visits, SUM(wait_minutes > 10) AS waited_over_10
FROM pickup_visits GROUP BY 1
""").to_string(index=False))
       period  visits  waited_over_10
evening 17-19     986             276
  other hours    1536              98
  1. Before writing anything, say who you think the decision owner should be, and why that is not obvious here.
  2. Is this the same problem as the pickup-queue request in Section 8? Explain in two sentences.
  3. Write a one-paragraph problem statement for the marketing request, with its value at stake as a formula (cases × effect × value) and the assumptions you would need.
  4. Write one sentence your team can keep as a rule for requests that start with "use AI to…".

Submit before feedback. No solution is provided here.


15. Resources

Required (about 30 min):

  • AWS Cloud Adoption Framework — Business Perspective: Data science, on starting from business problems with clear value and a measurable metric, and deciding whether ML is needed at all. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/data-science.html (Opened 21 Oct 2026.)

Recommended:

  • AWS Cloud Adoption Framework — Business Perspective: Business insights, on identifying the business decisions that need insights first. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/business-insights.html (Opened 21 Oct 2026.)
  • Cassie Kozyrkov: home page, writing on decision intelligence. https://www.kozyr.com/ (Opened 21 Oct 2026.)

16. Person to Follow / Role Model

Cassie Kozyrkov (mapped by D.World for L72–L74, L90–L92).

  • Verified fact: her home page presents her as a "Decision Intelligence Pioneer" and "Google's First Chief Decision Scientist" (D.World Stage 1 role-model record R01; page opened 21 Oct 2026).
  • Why D.World recommends her: her work starts from the decision and the decision maker, which is exactly where a project charter starts.
  • Honest note: we quote only how her own page presents her.
  • Try this: find one of her pieces about the role of the decision maker. Summarise in one sentence what she says the decision maker must do before the analyst starts.

17. Glossary

Term Meaning in this lesson
Problem statement One paragraph naming the situation (with a number), the decision, its owner and deadline, the options, the value at stake, affected parties, scope and constraints
Stakeholder Anyone who decides, uses, is affected by, or supplies data to a project
Decision owner The single person who will make the decision and be accountable for it
Scope What the project includes and what it explicitly excludes
Constraint A limit on possible solutions (time, data, privacy, budget, rules)
Value at stake How much is gained or lost depending on the decision, with its period and main assumptions
Request What someone asks for, often a tool or an output
Affected party Someone who feels the consequences of a decision without making it
Data owner The person or team who holds the data and can explain how it was recorded

Review: decision frames (L66) · audience and decision (L65) · EDA question trees (L57).


18. Reflection

  1. Think of a request you received at work or study. What decision was behind it?
  2. Who was an affected party in that situation, and were they asked?
  3. Which open question would you always ask first, and why?

19. Next Step

Next: L73 — Hypotheses, Success Metrics & Decision Criteria. You turn the problem statement into testable hypotheses and agree, in numbers, what success looks like before any model is built.


20. Assessment Evidence

Evidence What it shows How it is judged
Pickup-queue problem statement + stakeholder map + questions (Independent Practice) Size from data; decision not tool; one owner; value at stake; affected parties; scope; five questions with who answers Rubric L72-IP
Guided practice (situation, value at stake, map, statement, questions) Template complete; upper bound explained Rubric L72-GP
Knowledge check (Q1–Q8) Request vs problem; owner; affected parties; value; scope; constraints 7 or more of 8 correct
Workplace task and mini challenge Reply to the requester; owner and value for a marketing request Rubrics L72-WT, L72-MC

References

  1. Amazon Web Services. AWS CAF — Business Perspective: Data science. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/data-science.html (AWS-DS, Map R05). Supports: start from business problems with measurable value; decide whether ML is needed.
  2. Amazon Web Services. AWS CAF — Business Perspective: Business insights. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/business-insights.html (AWS-BI, Map R06). Supports: identify decisions first.
  3. Kozyrkov, C. Home page. https://www.kozyr.com/ (KOZYR). Supports: role-model description (R01).
  4. D.World Stage 4 Detailed Lesson Map v0.9 (L72 row). Internal.

L72 — من الطلب إلى بيان المشكلة: أصحاب المصلحة وأصحاب القرار

ملف المتعلّم. الإجابات والحلول النموذجية في ملف منفصل خاص بالمدرّس فقط. الإصدار: U17 Production v1 · تاريخ المحتوى: 21 أكتوبر 2026. تقديرات الوقت تقديرات للتخطيط إلى أن يختبرها المتعلّمون. الكود في هذا الدرس شُغّل باستخدام Python 3.13.16 وpandas 3.0.5 وNumPy 2.5.3 (مسجّلة في تقرير اختبار الكود الداخلي في D.World)؛ وPython 3.13 هو الإصدار المعتمد في الدورة. ولم يُشغَّل باستخدام Python 3.14 ولا داخل JupyterLab.

كل الأنشطة التجارية خيالية، وكل البيانات مصطنعة.


1. بطاقة الدرس

البند القيمة
العنوان من الطلب إلى بيان المشكلة: أصحاب المصلحة وأصحاب القرار
المرحلة المرحلة 4 — مشاريع حقيقية وتعلّم الآلة
الوحدة U17 — من مشكلة العمل إلى مشروع البيانات
رقم الدرس L72
المهارات الطلب مقابل المشكلة مقابل المهمة؛ خريطة أصحاب المصلحة (صاحب القرار، والمستخدمون، والأطراف المتأثرة، وأصحاب البيانات)؛ القيمة المعرّضة للخطر؛ القيود؛ قالب بيان المشكلة؛ أسئلة تُطرح قبل العمل على البيانات؛ ما يدخل في النطاق وما يخرج منه
المستوى متوسط
الوقت المتوقع حوالي ساعتين ونصف (تقدير للتخطيط، غير مُتحقَّق منه)
مستوى التقييم تدريب
المتطلبات السابقة L66 (أطر القرار)، وL65 (الجمهور والقرار)، وL57 (أشجار الأسئلة في التحليل الاستكشافي).

تفصيل الوقت (تقدير للتخطيط):

  • المفهوم والمثال المحلول: 55 دقيقة.
  • التدريب الموجَّه: 30 دقيقة.
  • التدريب المستقل: 35 دقيقة.
  • اختبار الفهم: 10 دقائق.
  • الذكاء الاصطناعي: 5 دقائق (اختياري).
  • مهمة العمل والتحدي القصير: 15 دقيقة.

ما تحتاج إليه: مجلد practice_files (L72_starter.ipynb؛ وu17_data/cedar_lane_u17.db).

بيانات U17. cedar_lane_u17.db قاعدة بيانات SQLite للوحدة كلها، من يوليو 2025 إلى سبتمبر 2026: customers (تاريخ التسجيل، والمنطقة، وقناة الاستقطاب، وهل يستخدم التطبيق)، وorders (صف لكل طلب: التاريخ، والتوصيل للمنزل أو الاستلام، ونقطة الاستلام، وقيمة السلة، وهامش الربح الإجمالي)، وdeliveries (طلبات التوصيل للمنزل: المنطقة الفرعية، والمسافة، وآخر موعد توصيل موعود، وموعد التوصيل الفعلي)، وpickup_visits (زيارات نقاط الاستلام بدءًا من مايو 2026: وقت الوصول، ودقائق الانتظار، وهل غادر العميل دون الاستلام). ستفحص جودة هذه الجداول في L74؛ أما في هذا الدرس فتستخدمها فقط لتضع رقمًا لما هو معرّض للخطر.


2. هدف التعلّم

في نهاية هذا الدرس ستكون قادرًا على أن:

  • تعيد صياغة طلب أحد أصحاب المصلحة في صورة بيان مشكلة يسمّي القرار، وصاحب القرار، وأصحاب المصلحة المتأثرين، والقيمة المعرّضة للخطر؛
  • ترسم خريطة لأصحاب المصلحة تفصل بين صاحب القرار، والمستخدمين، والأطراف المتأثرة، وأصحاب البيانات؛
  • تسرد ما لم يُعرف بعد، في صورة أسئلة تُطرح قبل أن يبدأ أي عمل على البيانات.

الهدف المعتمد من D.World (بنصّه): Rewrite a stakeholder request as a problem statement that names the decision, the decision owner, the stakeholders affected and the value at stake, and list what is not yet known.


3. لماذا يهمّك هذا؟

المرحلة 4 عن المشاريع الحقيقية، والمشاريع الحقيقية نادرًا ما تصل في صورة أسئلة نظيفة. بل تصل في صورة طلبات: "We need a dashboard for late deliveries." "Use AI to fix our pickup queues." "Can we predict churn?" (أي: "نحتاج إلى لوحة متابعة للتوصيلات المتأخرة." "استخدم الذكاء الاصطناعي لحل مشكلة طوابير نقاط الاستلام." "هل نستطيع التنبؤ بتسرّب العملاء؟"). كل طلب يسمّي أداة (لوحة متابعة، ذكاء اصطناعي، تنبؤ). ولا يقول أي منها ما الذي سيُقرَّر، ولا من يقرّر، ولا كم يساوي.

والفرق التي تبني ما طُلب حرفيًا كثيرًا ما تسلّم شيئًا دقيقًا لا يتصرف أحد بناءً عليه. في L66 صغت قرارات منفردة. والآن تبدأ مشروعًا كاملًا، وأول ما تسلّمه ليس كودًا: إنه بيان مشكلة (problem statement) يتفق عليه كل المعنيين.

المبدأ الأساسي: المشروع يبدأ من قرار وقيمته، لا من أداة أو مجموعة بيانات. اكتب من يقرّر ماذا، وكم يساوي ذلك، وما الذي لا تعرفه بعد، قبل أن تلمس البيانات.


4. المفهوم

import sqlite3

import pandas as pd

con = sqlite3.connect("u17_data/cedar_lane_u17.db")
q = lambda sql: pd.read_sql_query(sql, con)
for t in ["customers", "orders", "deliveries", "pickup_visits"]:
    print(f"{t:<14}", q(f"SELECT COUNT(*) AS n FROM {t}")["n"].iloc[0], "rows")
customers      6007 rows
orders         13694 rows
deliveries     7950 rows
pickup_visits  2522 rows

الجزء A — الطلب، والمشكلة، والمهمة

المستوى ماذا يقول مثال في Cedar Lane
الطلب (Request) ما يطلبه شخص ما، وكثيرًا ما يكون أداة أو مُخرَجًا "We need a dashboard for late deliveries." (أي: "نحتاج إلى لوحة متابعة للتوصيلات المتأخرة.")
المشكلة (Problem) وضع العمل الذي يجب أن يتغير، ولماذا يهم قد تكلّفنا التوصيلات المنزلية المتأخرة عملاء متكررين وهامش ربح؛ ولا أحد يعرف أي الإجراءات ستقلّلها.
المهمة (Task) جزء من العمل يساعد على حل المشكلة قياس معدل التأخير حسب الفترة الزمنية والمسافة؛ وتقدير الهامش المعرّض للخطر.

الطلب معلومة مفيدة: فهو يخبرك من القلق وبشأن ماذا. لكنه ليس بيان مشكلة بعد. ومهمتك أن تنتقل من الطلب إلى المشكلة مع الشخص الذي طلب، ثم تخطط المهام.

الجزء B — خريطة أصحاب المصلحة

صاحب المصلحة (stakeholder) هو كل من يقرّر في المشروع، أو يستخدمه، أو يتأثر به، أو يزوّده بالبيانات. افصل بين أربعة أدوار:

الدور السؤال الذي يجيب عنه أشخاص معتادون في Cedar Lane
صاحب القرار (Decision owner) من سيقرّر ويتحمّل المسؤولية؟ رئيس العمليات، ومسؤول التسويق، والمدير العام
المستخدمون (Users) من سيستخدم المُخرَج يومًا بيوم؟ مخطّطو التوزيع، ومشرفو نقاط الاستلام، وفريق الاحتفاظ بالعملاء
الأطراف المتأثرة (Affected parties) من يشعر بالعواقب دون أن يقرّر؟ العملاء، ومندوبو التوصيل، وموظفو نقاط الاستلام، وقسم المالية
أصحاب البيانات (Data owners) من يملك البيانات ويستطيع شرحها؟ فريق تطبيق التوصيل، ومورّد نظام الطوابير، وقسم المالية

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

الجزء C — القيمة المعرّضة للخطر، والقيود، والنطاق

القيمة المعرّضة للخطر (value at stake) هي مقدار ما يُكسب أو يُخسر بحسب القرار، بالمال أو بالعملاء، خلال فترة محددة. ولا يلزم أن تكون دقيقة؛ فيكفي ترتيب حجمها مع افتراضاته لتقرّر هل يستحق المشروع أسابيع من العمل.

ابدأ بحجم المشكلة. كم توصيلة منزلية تصل متأخرة؟

late = q("""
SELECT substr(promised_by, 1, 7) AS month, COUNT(*) AS home_deliveries,
       SUM(delivered_at > promised_by) AS late
FROM deliveries
WHERE promised_by >= '2026-07-01' AND promised_by < '2026-10-01'
GROUP BY 1 ORDER BY 1
""")
late["late_rate"] = (late["late"] / late["home_deliveries"]).round(3)
print(late.to_string(index=False))
  month  home_deliveries  late  late_rate
2026-07              647    78      0.121
2026-08              653    91      0.139
2026-09              691    92      0.133

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

القيود (constraints) تحدّ من الحلول الممكنة: الوقت (القرار مطلوب قبل ذروة عيد الميلاد)، والبيانات (لا توجد بيانات GPS لمندوبي التوصيل)، والخصوصية (يجب ألّا تخرج عناوين العملاء من نظام التوصيل)، والميزانية (لا موظفين جددًا هذا العام). والنطاق (scope) يقول ما يدخل وما يخرج: مثلًا، يدخل = التوصيلات المنزلية في المناطق الخمس؛ ويخرج = طلبات الاستلام، وأجور المندوبين.

الجزء D — قالب بيان المشكلة

بيان المشكلة الجيد يتّسع له فقرة واحدة ويجيب عن ستة أسئلة:

  1. الوضع: ما الذي يحدث، مع رقم.
  2. القرار: ما الذي سيُقرَّر، ومن يقرّره (صاحب القرار)، ومتى.
  3. الخيارات: اثنان على الأقل، منها "عدم فعل شيء" (L66).
  4. القيمة المعرّضة للخطر: مال أو عملاء، خلال فترة، مع الافتراض الرئيسي.
  5. الأطراف المتأثرة: من غيرهم يشعر بالنتيجة.
  6. النطاق والقيود: ما يدخل، وما يخرج، وما يحدّ من الحل.

ثم أضف قائمة بالأسئلة المفتوحة: ما لا تعرفه بعد، ومن يستطيع الإجابة عنه. وبيان المشكلة الذي يسمّي أداة ("build a dashboard"، أي "ابنِ لوحة متابعة") بدلًا من قرار لا يجتاز القالب.


5. مثال محلول

Cedar Lane (خيالية)، بيانات مصطنعة. يكتب رئيس العمليات: "We need a dashboard for late deliveries." (أي: "نحتاج إلى لوحة متابعة للتوصيلات المتأخرة.")

الخطوة 1 — من يسأل، وما الذي يقلقه؟ قسم العمليات قلق من تأخر التوصيلات المنزلية. ولوحة المتابعة هي تصوّره للحل، لا المشكلة.

الخطوة 2 — هل التأخير مرتبط بالقيمة؟ قارن العملاء الجدد الذين كان أول طلب لهم توصيلًا منزليًا وصل متأخرًا بمن وصلت أول توصيلة لهم في موعدها. واستخدم العملاء الذين انضموا من يوليو 2025 إلى يونيو 2026 (اثنا عشر شهرًا)، حتى يكون لكل منهم 90 يومًا على الأقل ليطلب مرة أخرى.

first = q("""
WITH f AS (
  SELECT o.customer_id, o.order_id, o.order_date
  FROM orders o JOIN customers c ON c.customer_id = o.customer_id AND o.order_date = c.signup_date
  WHERE o.fulfilment = 'home' AND c.signup_date < '2026-07-01'
)
SELECT f.customer_id,
       MAX(d.delivered_at > d.promised_by) AS first_late,
       (SELECT COUNT(*) FROM orders o2 WHERE o2.customer_id = f.customer_id
          AND o2.order_date > f.order_date AND o2.order_date <= date(f.order_date, '+90 days')) > 0 AS repeat_90d
FROM f JOIN deliveries d ON d.order_id = f.order_id
GROUP BY f.customer_id
""")
print(first.groupby("first_late")["repeat_90d"].agg(customers="size", repeat_rate="mean").round(3))
            customers  repeat_rate
first_late
0                2539        0.416
1                 393        0.221

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

الخطوة 3 — ضع رقمًا تقريبيًا للقيمة المعرّضة للخطر.

gap = first.groupby("first_late")["repeat_90d"].mean()
lost_share = gap.loc[0] - gap.loc[1]
late_first_per_year = int(first["first_late"].sum())   # the cohort covers exactly twelve months
margin_90d = q("""
WITH f AS (SELECT customer_id, signup_date FROM customers WHERE signup_date < '2026-07-01')
SELECT AVG(m) AS margin FROM (
  SELECT f.customer_id, SUM(o.gross_margin) AS m FROM f JOIN orders o ON o.customer_id = f.customer_id
  WHERE o.order_date > f.signup_date AND o.order_date <= date(f.signup_date, '+90 days')
  GROUP BY f.customer_id)
""")["margin"].iloc[0]
print(f"repeat-rate gap: {lost_share:.3f}")
print(f"late first deliveries (Jul 2025 - Jun 2026): {late_first_per_year}")
print(f"average 90-day margin of a returning customer: EUR {margin_90d:.2f}")
print(f"upper-bound margin at stake per year: EUR {late_first_per_year * lost_share * margin_90d:,.0f}")
repeat-rate gap: 0.195
late first deliveries (Jul 2025 - Jun 2026): 393
average 90-day margin of a returning customer: EUR 13.99
upper-bound margin at stake per year: EUR 1,072

(التعليق في الكود معناه: "المجموعة تغطي اثني عشر شهرًا بالضبط".)

الحساب يضرب ثلاثة أشياء: عدد التوصيلات الأولى المتأخرة في السنة، ومقدار انخفاض عودة هؤلاء العملاء، وقيمة العميل العائد في التسعين يومًا التالية. وهو حد أعلى (upper bound) لخسارة واحدة محددة، هي هامش الشراء المتكرر خلال 90 يومًا للعملاء الجدد، لأنه يعامل الارتباط كله كأن التأخير هو سببه. وهو أيضًا ضيّق: يحسب 90 يومًا فقط والعملاء الجدد فقط. والخلاصة الصادقة هي: "Through lost 90-day repeat purchases from new customers, late first deliveries cost at most about €1,100 of margin a year; the full cost of lateness could be higher once other customers, longer periods and direct costs are counted." (أي: "من خلال المشتريات المتكررة المفقودة خلال 90 يومًا من العملاء الجدد، تكلّف التوصيلات الأولى المتأخرة على الأكثر حوالي 1,100 يورو من الهامش سنويًا؛ وقد تكون التكلفة الكاملة للتأخير أعلى إذا حُسب العملاء الآخرون، والفترات الأطول، والتكاليف المباشرة.")

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

الخطوة 4 — خريطة أصحاب المصلحة.

الدور من
صاحب القرار رئيس العمليات (يقرّر تغييرات التوصيل)
المستخدمون مخطّطو التوزيع؛ ومسؤولو خدمة العملاء
الأطراف المتأثرة العملاء الجدد؛ ومندوبو التوصيل (المسارات، وعبء العمل)؛ وقسم المالية (تكلفة التوصيل)
أصحاب البيانات فريق تطبيق التوصيل (deliveries)؛ وقسم المالية (هامش orders)

الخطوة 5 — بيان المشكلة.

وصلت حوالي 13% من التوصيلات المنزلية في Cedar Lane بعد الموعد الموعود في يوليو–سبتمبر 2026. والعملاء الجدد الذين تأخرت أول توصيلة لهم عادوا خلال 90 يومًا بمعدل أقل بكثير ممن وصلت توصيلتهم في موعدها (حوالي 22% مقابل 42%؛ وهذا ارتباط). ويجب أن يقرّر رئيس العمليات قبل اجتماع التخطيط في نوفمبر هل يغيّر طريقة جدولة التوصيلات الأولى (الخيارات: عدم فعل شيء؛ أو إضافة وقت احتياطي للتوصيلات الأولى؛ أو إعطاء العملاء الجدد أولوية في تخطيط المسارات). والمعرّض للخطر على الأكثر حوالي 1,100 يورو سنويًا من هامش المشتريات المتكررة (حد أعلى)، إضافةً إلى تكاليف مباشرة للتأخير لم تُعرف بعد؛ ولا تُبرَّر حتى الآن إلا الخيارات منخفضة التكلفة. والمتأثرون هم مندوبو التوصيل، والعملاء الجدد، وقسم المالية. داخل النطاق: التوصيلات المنزلية، في كل المناطق. خارج النطاق: طلبات الاستلام، وأجور المندوبين. القيد: لا توجد بيانات GPS للمندوبين؛ ويجب ألّا ترفع التغييرات تكلفة التوصيل لكل طلب.

الخطوة 6 — الأسئلة المفتوحة (ومن يستطيع الإجابة عنها):

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

لاحظ أن لوحة المتابعة لم تختفِ: فقد تصبح مهمة لاحقًا، إذا احتاج إليها مخطّطو التوزيع لقرار يومي.


6. شرح بصري

 REQUEST (a tool)          PROBLEM (a decision + its value)                 TASKS (work)
 "dashboard for     ──▶    situation with a number · decision · owner   ──▶  measure late rate
  late deliveries"         options incl. do nothing · value at stake          estimate value at stake
                           affected parties · scope in/out · constraints     answer open questions

 STAKEHOLDER MAP      decision owner (exactly one) │ users │ affected parties │ data owners

 VALUE AT STAKE = (cases per year) × (difference in outcome) × (value per outcome)   → state assumptions; upper bound?

وصف الرسم: تدفق من ثلاث مراحل: من طلب يسمّي أداة، إلى بيان مشكلة فيه الوضع مع رقم، والقرار وصاحبه الوحيد، والخيارات ومنها عدم فعل شيء، والقيمة المعرّضة للخطر، والأطراف المتأثرة، والنطاق والقيود، ثم إلى مهام مثل قياس معدل التأخير وتقدير القيمة المعرّضة للخطر. وفي الأسفل خريطة أصحاب المصلحة بأدوارها الأربعة: صاحب قرار واحد، والمستخدمون، والأطراف المتأثرة، وأصحاب البيانات. وفي النهاية تظهر القيمة المعرّضة للخطر على أنها عدد الحالات في السنة × الفرق في النتيجة × قيمة كل نتيجة، مع تذكير بذكر الافتراضات وهل الرقم حد أعلى. (نصوص الرسم: REQUEST (a tool) = الطلب (أداة)؛ PROBLEM (a decision + its value) = المشكلة (قرار + قيمته)؛ TASKS (work) = المهام (العمل)؛ situation with a number = الوضع مع رقم؛ decision · owner = القرار · صاحبه؛ options incl. do nothing = الخيارات ومنها عدم فعل شيء؛ value at stake = القيمة المعرّضة للخطر؛ affected parties = الأطراف المتأثرة؛ scope in/out = النطاق داخله/خارجه؛ constraints = القيود؛ measure late rate = قياس معدل التأخير؛ answer open questions = الإجابة عن الأسئلة المفتوحة؛ STAKEHOLDER MAP = خريطة أصحاب المصلحة؛ exactly one = واحد بالضبط؛ users = المستخدمون؛ data owners = أصحاب البيانات؛ cases per year = الحالات في السنة؛ difference in outcome = الفرق في النتيجة؛ value per outcome = قيمة كل نتيجة؛ state assumptions; upper bound? = اذكر الافتراضات؛ هل هو حد أعلى؟)


7. تدريب موجَّه

افتح L72_starter.ipynb.

  1. شغّل خلية التجهيز واستعلام التوصيلات المتأخرة. واكتب جملة الوضع لطلب "we need a dashboard for late deliveries" مع معدل التأخير في يوليو–سبتمبر 2026.
  2. احسب مقارنة العودة حسب التوصيلة الأولى وتقدير القيمة المعرّضة للخطر. واكتب جملة تشرح لماذا هو حد أعلى، وجملة تذكر ما الذي يتركه.
  3. املأ خريطة أصحاب المصلحة (أربعة أدوار). وسمِّ صاحب قرار واحدًا بالضبط.
  4. اكتب بيان المشكلة بأجزاء القالب الستة، وسطرًا للنطاق (داخل / خارج).
  5. اسرد خمسة أسئلة مفتوحة ومن يستطيع الإجابة عن كل منها.
  6. شغّل Restart Kernel and Run All Cells….

8. تدريب مستقل

طوابير نقاط الاستلام. يرسل رئيس العمليات رسالة جديدة: "Customers complain about queues at the pickup points. Use AI to fix our pickup queues." (أي: "العملاء يشتكون من الطوابير في نقاط الاستلام. استخدم الذكاء الاصطناعي لحل مشكلة الطوابير.")

اكتب، في L72_starter.ipynb (الجزء 2):

  1. حجم المشكلة من البيانات: من pickup_visits، الزيارات لكل نقطة استلام، ومتوسط الانتظار، ونسبة الزيارات التي انتظرت أكثر من 10 دقائق، وعدد العملاء الذين غادروا دون استلام. وسجّل أي نقطة وأي ساعات تبدو الأسوأ.
  2. بيان مشكلة (من 120 إلى 200 كلمة) بأجزاء القالب الستة. ويجب أن يسمّي قرارًا وقيمة، لا أداة ("الذكاء الاصطناعي" لا يظهر إلا كخيار محتمل).
  3. خريطة أصحاب المصلحة بأدوارها الأربعة.
  4. الأسئلة الخمسة التي ستطرحها قبل البدء، ومع كل منها الشخص الذي يستطيع الإجابة عنه.

تلميح: فكّر في المعاني الممكنة لكلمة "fix" (حل) في صورة قرارات (جدول مناوبات الموظفين، وساعات العمل، وفترات الاستلام، وتحويل الطلبات إلى التوصيل المنزلي)، وفي تكلفة العميل الذي يغادر دون استلام.


9. اختبار الفهم (Knowledge Check) — بيانات المشكلة

Q1. أفضل وصف لعبارة "We need a dashboard for late deliveries" هو:

  • A) بيان مشكلة له صاحب ومقياس واضحان
  • B) مهمة تسمّي بالفعل القرار المطلوب اتخاذه
  • C) طلب يسمّي أداة
  • D) فرضية عن سبب تأخر التوصيلات

Q2. كم صاحب قرار يجب أن يكون للقرار الواحد؟

  • A) شخص واحد بالضبط، يتحمّل مسؤوليته
  • B) واحد لكل قسم يتأثر بالقرار
  • C) لا أحد، لأن البيانات هي التي يجب أن تقرّر
  • D) بعدد أعضاء اللجنة التوجيهية

Q3. أي شخص هو طرف متأثر (لا صاحب القرار) عندما يغيّر قسم العمليات ساعات عمل نقاط الاستلام؟

  • A) رئيس العمليات، الذي يتخذ القرار
  • B) مورّد نظام الطوابير الذي يملك بيانات الانتظار
  • C) المحلّل الذي يجهّز الأدلة
  • D) موظفو نقاط الاستلام الذين تتغير مناوباتهم

Q4. أي مما يلي أفضل صياغة للقيمة المعرّضة للخطر؟

  • A) "التوصيلات المتأخرة سيئة جدًا لعلامتنا التجارية ويجب تقليلها في أسرع وقت."
  • B) "قد يُفقد ما يصل إلى حوالي X يورو من الهامش سنويًا بعد التوصيلات الأولى المتأخرة (حد أعلى)."
  • C) "ستضم لوحة المتابعة عشرة مخططات، واحدًا لكل منطقة ومندوب."
  • D) "13% من التوصيلات متأخرة، مقابل هدف 10% حُدد العام الماضي."

Q5. لماذا يُسمّى تقدير القيمة المعرّضة للخطر في المثال المحلول حدًّا أعلى؟

  • A) لأنه حُسب بـ SQL بدلًا من نموذج إحصائي
  • B) لأنه يستخدم عددًا قليلًا جدًا من العملاء لا يكفي لتقدير موثوق
  • C) لأنه يعامل الارتباط كأن التأخير سببه كله
  • D) لأن أرقام الهامش من قسم المالية مبالغ فيها دائمًا

Q6. أي سطر ينتمي إلى النطاق؟

  • A) "خارج النطاق: أجور المندوبين."
  • B) "سيستخدم النموذج gradient boosting."
  • C) "رئيس العمليات هو من يقرّر."
  • D) "العملاء متأثرون."

Q7. أي مما يلي قيد؟

  • A) معدل التأخير 13%، وهو أعلى منه في الشهر نفسه من العام الماضي.
  • B) لا تتوفر بيانات GPS للمندوبين، ويجب ألّا ترتفع تكلفة التوصيل لكل طلب.
  • C) يعود العملاء بمعدل أقل بعد توصيلة أولى متأخرة منه بعد توصيلة في موعدها.
  • D) سيستخدم مخطّطو التوزيع المُخرَج في اجتماع التخطيط الأسبوعي.

Q8. ماذا تفعل بالطلب الأصلي (مثل "لوحة متابعة") بعد أن يصبح لديك بيان مشكلة؟

  • A) تحذفه، لأن طلبات المديرين خاطئة في الغالب
  • B) تبنيه أولًا، ثم تكتب بيان المشكلة حوله
  • C) تحتفظ به كمهمة محتملة، إذا احتاج إليه مستخدم لاتخاذ قرار
  • D) تستبدل به نموذج تعلّم آلي يتنبأ بالتأخير

10. الذكاء الاصطناعي في التطبيق (اختياري، وفي حدود)

الهدف: أن تستخدم مساعد ذكاء اصطناعي لتوليد أفكار عن أصحاب المصلحة والقيود الخفية، ثم لا تُبقي إلا ما ينطبق على Cedar Lane.

  1. اسأل:

"A small online grocery's head of operations says: 'Use AI to fix our pickup queues.' List every stakeholder and every constraint that might matter."

وبالعربية: "يقول رئيس العمليات في متجر بقالة إلكتروني صغير: 'استخدم الذكاء الاصطناعي لحل مشكلة طوابير الاستلام.' اذكر كل صاحب مصلحة وكل قيد قد يكون مهمًا."

  1. انسخ الإجابة إلى دفترك. وعلّم كل بند بـ C (ينطبق على وقائع حالة Cedar Lane) أو G (عام، ولا دليل عليه في حالتنا).
  2. أضف أي صاحب مصلحة فاته الذكاء الاصطناعي.

الحدود:

  • استخدام الذكاء الاصطناعي اختياري.
  • صِف الوضع، ولا تلصق بيانات العملاء أبدًا.
  • بيان المشكلة مسؤوليتك: الذكاء الاصطناعي يقترح، وأنت تقرّر.

11. التحقق من مخرجات الذكاء الاصطناعي

  1. وقائع الحالة: لكل بند علّمته بـ C، أشر إلى الواقعة التي تدعمه (جدول، أو رقم، أو جملة في الطلب).
  2. قرار لا أداة: هل يسمّي بيان مشكلتك النهائي قرارًا وقيمة، لا "الذكاء الاصطناعي" أو "لوحة متابعة"؟
  3. صاحب واحد: هل اقترح الذكاء الاصطناعي لجنة أو عدة أصحاب قرار؟ اختصرهم إلى واحد.
  4. دوّن اقتراحين رفضتهما ولماذا.

12. منظور الأعمال

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


13. مهمة عمل — الرد على صاحب الطلب

نشاط خيالي: Cedar Lane. اكتب ردًّا (من 80 إلى 120 كلمة) إلى رئيس العمليات بشأن طلب لوحة المتابعة. اشكره، وأعد صياغة المشكلة في جملة واحدة مع رقم، واقترح القرار والخيارات، وقل ما ستسلّمه أولًا (ليس لوحة المتابعة)، واطرح أهم سؤالين مفتوحين.


14. تحدٍّ قصير — مشكلة من هذه؟

نشاط خيالي: Cedar Lane. يكتب مسؤول التسويق: "Use AI to send personalised offers to every customer who waited too long at a pickup point." (أي: "استخدم الذكاء الاصطناعي لإرسال عروض مخصصة لكل عميل انتظر طويلًا في نقطة استلام.")

print(q("""
SELECT CASE WHEN CAST(strftime('%H', arrived_at) AS INTEGER) BETWEEN 17 AND 19 THEN 'evening 17-19' ELSE 'other hours' END AS period,
       COUNT(*) AS visits, SUM(wait_minutes > 10) AS waited_over_10
FROM pickup_visits GROUP BY 1
""").to_string(index=False))
       period  visits  waited_over_10
evening 17-19     986             276
  other hours    1536              98

(القيمتان في العمود period معناهما: المساء من 17 إلى 19، وباقي الساعات.)

  1. قبل أن تكتب أي شيء، قل من تظن أنه يجب أن يكون صاحب القرار، ولماذا ليس ذلك واضحًا هنا.
  2. هل هذه هي مشكلة طوابير الاستلام نفسها في القسم 8؟ اشرح في جملتين.
  3. اكتب بيان مشكلة من فقرة واحدة لطلب التسويق، مع قيمته المعرّضة للخطر في صورة معادلة (الحالات × الأثر × القيمة) والافتراضات التي ستحتاج إليها.
  4. اكتب جملة واحدة يحتفظ بها فريقك كقاعدة للطلبات التي تبدأ بعبارة "use AI to…" (أي: "استخدم الذكاء الاصطناعي لـ…").

سلّم عملك قبل أن تتلقى الملاحظات. لا يوجد حل منشور هنا.


15. المصادر

مطلوب (حوالي 30 دقيقة):

  • AWS Cloud Adoption Framework — Business Perspective: Data science، عن البدء من مشكلات أعمال لها قيمة واضحة ومقياس قابل للقياس، وعن تقرير هل تعلّم الآلة مطلوب أصلًا. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/data-science.html (فُتح في 21 أكتوبر 2026.)

موصى به:

  • AWS Cloud Adoption Framework — Business Perspective: Business insights، عن تحديد قرارات العمل التي تحتاج إلى رؤى أولًا. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/business-insights.html (فُتح في 21 أكتوبر 2026.)
  • Cassie Kozyrkov: home page، كتاباتها عن ذكاء القرار. https://www.kozyr.com/ (فُتح في 21 أكتوبر 2026.)

16. شخصية تتابعها / قدوة

Cassie Kozyrkov (اختارتها D.World للدروس L72–L74 وL90–L92).

  • حقيقة مُتحقَّق منها: صفحتها الرئيسية تقدّمها بوصفها "Decision Intelligence Pioneer" (رائدة في ذكاء القرار) و"Google's First Chief Decision Scientist" (أول كبيرة علماء القرار في Google) (سجل القدوات في المرحلة 1 من D.World، R01؛ وفُتحت الصفحة في 21 أكتوبر 2026).
  • لماذا توصي بها D.World: عملها يبدأ من القرار ومن صاحب القرار، وهو بالضبط المكان الذي يبدأ منه ميثاق المشروع.
  • ملاحظة صادقة: لا نقتبس إلا الطريقة التي تقدّمها بها صفحتها.
  • جرّب هذا: ابحث عن مقال لها عن دور صاحب القرار. ولخّص في جملة واحدة ما تقول إن على صاحب القرار أن يفعله قبل أن يبدأ المحلّل.

17. المصطلحات

المصطلح معناه في هذا الدرس
بيان المشكلة (Problem statement) فقرة واحدة تسمّي الوضع (مع رقم)، والقرار، وصاحبه وموعده، والخيارات، والقيمة المعرّضة للخطر، والأطراف المتأثرة، والنطاق والقيود
صاحب المصلحة (Stakeholder) كل من يقرّر في المشروع، أو يستخدمه، أو يتأثر به، أو يزوّده بالبيانات
صاحب القرار (Decision owner) الشخص الوحيد الذي سيتخذ القرار ويتحمّل مسؤوليته
النطاق (Scope) ما يشمله المشروع وما يستبعده صراحةً
القيد (Constraint) حدّ على الحلول الممكنة (الوقت، والبيانات، والخصوصية، والميزانية، والقواعد)
القيمة المعرّضة للخطر (Value at stake) مقدار ما يُكسب أو يُخسر بحسب القرار، مع فترته وافتراضاته الرئيسية
الطلب (Request) ما يطلبه شخص ما، وكثيرًا ما يكون أداة أو مُخرَجًا
الطرف المتأثر (Affected party) شخص يشعر بعواقب القرار دون أن يتخذه
صاحب البيانات (Data owner) الشخص أو الفريق الذي يملك البيانات ويستطيع شرح طريقة تسجيلها

للمراجعة: أطر القرار (L66) · الجمهور والقرار (L65) · أشجار الأسئلة في التحليل الاستكشافي (L57).


18. تأمّل

  1. فكّر في طلب تلقيته في العمل أو الدراسة. ما القرار الذي كان وراءه؟
  2. من كان طرفًا متأثرًا في ذلك الموقف، وهل سُئل؟
  3. أي سؤال مفتوح ستطرحه أولًا دائمًا، ولماذا؟

19. الخطوة التالية

التالي: L73 — الفرضيات ومقاييس النجاح ومعايير القرار (Hypotheses, Success Metrics & Decision Criteria). تحوّل بيان المشكلة إلى فرضيات قابلة للاختبار، وتتفق بالأرقام على شكل النجاح قبل بناء أي نموذج.


20. أدلة التقييم

الدليل ماذا يُظهر كيف يُقيَّم
بيان مشكلة طوابير الاستلام + خريطة أصحاب المصلحة + الأسئلة (التدريب المستقل) الحجم من البيانات؛ وقرار لا أداة؛ وصاحب واحد؛ والقيمة المعرّضة للخطر؛ والأطراف المتأثرة؛ والنطاق؛ وخمسة أسئلة مع من يجيب عنها دليل التقييم L72-IP
التدريب الموجَّه (الوضع، والقيمة المعرّضة للخطر، والخريطة، والبيان، والأسئلة) القالب مكتمل؛ والحد الأعلى مشروح دليل التقييم L72-GP
اختبار الفهم (Q1–Q8) الطلب مقابل المشكلة؛ وصاحب القرار؛ والأطراف المتأثرة؛ والقيمة؛ والنطاق؛ والقيود 7 إجابات صحيحة أو أكثر من 8
مهمة العمل والتحدي القصير الرد على صاحب الطلب؛ وصاحب القرار والقيمة لطلب التسويق دليلا التقييم L72-WT وL72-MC

المراجع

  1. Amazon Web Services. AWS CAF — Business Perspective: Data science. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/data-science.html (AWS-DS, Map R05). يدعم: البدء من مشكلات أعمال ذات قيمة قابلة للقياس؛ وتقرير هل تعلّم الآلة مطلوب.
  2. Amazon Web Services. AWS CAF — Business Perspective: Business insights. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/business-insights.html (AWS-BI, Map R06). يدعم: تحديد القرارات أولًا.
  3. Kozyrkov, C. Home page. https://www.kozyr.com/ (KOZYR). يدعم: وصف القدوة (R01).
  4. D.World Stage 4 Detailed Lesson Map v0.9 (صف L72). وثيقة داخلية.
L73 · Hypotheses, Success Metrics & Decision Criteria About 2.5 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

L74 · Data Requirements, Feasibility & the Analysis Plan About 2.5 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

U17 Exit Check — Project Charter Membersللمشتركين

The exit brief is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

تكليف نهاية الوحدة ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

U18 · Machine Learning Foundationsأساسيات تعلم الآلة

Stage 4المرحلة 4

Free: the first lesson. The other lessons, the exit brief and the practice files are for Starter and Membership.

مجاني: الدرس الأول. باقي الدروس وتكليف نهاية الوحدة وملفات التمرين لأصحاب باقة البداية والاشتراك.

Download U18 practice files (.zip, 413 KB)حمّل ملفات تمرين U18 (zip، 413 KB)

Unzip into a short folder such as D:\DWorld on Windows. The zip has only learner files: no answers.

فك الضغط في مجلد قصير مثل D:\DWorld على ويندوز. الملف يحتوي ملفات المتعلم فقط بدون إجابات.

L75 · When Is ML the Right Tool? Tasks, Targets, Features & BaselinesL75 · متى يكون تعلّم الآلة هو الأداة المناسبة؟ المهام، والهدف، والخصائص، ونماذج المقارنة الأساسية About 2.5 hoursحوالي ساعتين ونصف Freeمجاني

L75 — When Is ML the Right Tool? Tasks, Targets, Features & Baselines

Learner file. Answers and model solutions are in a separate instructor-only file. Version: U18 Production v1 · Content date: 25 October 2026. Time estimates are planning estimates until learners have tested them. The code in this lesson was run with Python 3.13.16, pandas 3.0.5 and NumPy 2.5.3 (recorded in D.World's internal Code Test Report); Python 3.13 is the accepted course version. Not run with Python 3.14 or inside JupyterLab.

All businesses are fictional and all data is synthetic.


1. Lesson Identity

Field Value
Title When Is ML the Right Tool? Tasks, Targets, Features & Baselines
Stage Stage 4 — Real Projects & Machine Learning
Unit U18 — Machine Learning Foundations
Lesson ID L75
Skills Supervised (regression, classification) vs unsupervised (clustering); target, features and the prediction moment; what is known at prediction time; rule-based and simple-statistic baselines; DummyRegressor / DummyClassifier as formal baselines; value of a better prediction; when a rule, an analysis or an experiment is enough
Difficulty Intermediate
Estimated time About 2.5 hours (planning estimate, unvalidated)
Assessment level Understanding / Practice
Prerequisites U10 (feature preparation, train/test idea), U13 (distributions, correlation, confounding), U17 (project charters).

Time breakdown (planning estimate): concept and worked example 55 min · guided practice 30 min · independent practice 35 min · knowledge check 10 min · AI 5 min (optional) · workplace task and mini challenge 15 min.

What you need: practice_files (L75_starter.ipynb; u18_data/new_customers.csv, u18_data/deliveries_ml.csv). No new installation in this lesson: scikit-learn is installed in L76.

The U18 data. u18_data/ holds one small synthetic table per task: new_customers.csv (one row per new customer who joined between 1 January and 1 July 2026, with what was known about their first order and whether they did not order again within 60 days), deliveries_ml.csv (one row per home delivery with distance, weekday, zone, slot, items and the hours it took), and further tables introduced in the lessons that use them.


2. Learning Objective

By the end of this lesson, you will be able to:

  • classify a business problem as a regression, classification, clustering or non-ML task;
  • define the target and the features that are known at the prediction moment;
  • specify the baseline a model must beat, and compute its score from data.

D.World approved objective (verbatim): Classify a business problem as a regression, classification, clustering or non-ML task, define the target and features at prediction time, and specify the baseline a model must beat.


3. Why It Matters

U17 ended with charters. Some of them suggested a model; many did not need one. Machine learning (ML) is powerful, but it costs time to build, data to train, and effort to monitor and maintain. It is worth it only when a better prediction changes a decision enough to pay for itself.

Two habits protect you. First, define precisely what is predicted, when, and from what: a model that uses information from the future looks brilliant in a notebook and is useless in practice. Second, write down the baseline first: the simplest prediction anyone could make without ML. If a model cannot beat it by a margin that matters, the project should stop or use the simple rule.

Key principle: before any model, name the task type, the target, the prediction moment and the features known at that moment, and score a simple baseline. ML is the right tool only if beating that baseline changes a decision enough to pay for the model.


4. Concept

import numpy as np
import pandas as pd

cust = pd.read_csv("u18_data/new_customers.csv")
deliv = pd.read_csv("u18_data/deliveries_ml.csv")
print(cust.shape, deliv.shape)
print(cust.columns.tolist())
(5000, 13) (4000, 8)
['customer_id', 'signup_date', 'acq_channel', 'app_user', 'region', 'first_items', 'first_basket', 'first_fulfilment', 'first_delivery_late', 'distance_km', 'app_opens_first_7d', 'second_order_date', 'no_return_60d']

Part A — Kinds of learning task

Task What it predicts or finds Needs a target? Cedar Lane example
Regression (supervised) A number Yes Hours a delivery will take
Classification (supervised) A category, usually yes/no, often with a probability Yes Will this new customer not order again within 60 days?
Clustering (unsupervised) Groups of similar records No Customer segments for the loyalty team
Not ML — — "What was the late rate last month?" (descriptive query); "Does free delivery raise orders?" (experiment, L69)

Supervised learning learns from examples where the answer is known (the target). Unsupervised learning looks for structure without a target. Many questions are neither: a count is a query, a cause needs an experiment, and a fixed business rule may already be good enough.

Part B — Target, features and the prediction moment

The target is what you want to predict (no_return_60d). The features are the inputs. The prediction moment is when the prediction is made in real use, and it decides which features are allowed: only information available at that moment.

For the retention team, the prediction is made the day after a new customer's first order, so that a welcome offer can be sent at once. Check each column against that moment:

known_at = {
    "acq_channel": "sign-up", "app_user": "sign-up", "region": "sign-up",
    "first_items": "first order", "first_basket": "first order", "first_fulfilment": "first order",
    "first_delivery_late": "first order (next day)", "distance_km": "first order",
    "app_opens_first_7d": "days 1-7 AFTER the first order", "second_order_date": "only if they order again",
}
for col, when in known_at.items():
    ok = "AFTER" not in when and "only if" not in when
    print(f"{col:<22} known at: {when:<32} allowed: {ok}")
print(pd.crosstab(cust["second_order_date"].notna(), cust["no_return_60d"]))
acq_channel            known at: sign-up                          allowed: True
app_user               known at: sign-up                          allowed: True
region                 known at: sign-up                          allowed: True
first_items            known at: first order                      allowed: True
first_basket           known at: first order                      allowed: True
first_fulfilment       known at: first order                      allowed: True
first_delivery_late    known at: first order (next day)           allowed: True
distance_km            known at: first order                      allowed: True
app_opens_first_7d     known at: days 1-7 AFTER the first order   allowed: False
second_order_date      known at: only if they order again         allowed: False
no_return_60d         0     1
second_order_date            
False                 0  3086
True               1914     0

second_order_date is filled in exactly for the customers who returned: it is the answer in disguise. app_opens_first_7d is counted during the week after the prediction moment. Both would make a model look excellent and would be impossible to use on the day it must decide. Using them is leakage (L42, L58): information from after the prediction moment leaking into the features.

Part C — Baselines

A baseline model is the simplest honest prediction, and every model must beat it:

Task Simple-statistic baseline Rule baseline
Regression Predict the mean (or median) of the target for everyone Mean by one obvious group (for example by zone)
Classification Predict the most frequent class for everyone One business rule (for example "app users return, others do not")

scikit-learn provides these as formal estimators, DummyRegressor and DummyClassifier (L76). Here, compute them by hand:

y = cust["no_return_60d"]
print("share who do not return:", round(y.mean(), 3))
print("majority-class baseline accuracy:", round(max(y.mean(), 1 - y.mean()), 3))
rule = (cust["app_user"] == 0).astype(int)          # rule: non-app users will not return
print("rule baseline accuracy (non-app users do not return):", round((rule == y).mean(), 3))
share who do not return: 0.617
majority-class baseline accuracy: 0.617
rule baseline accuracy (non-app users do not return): 0.614
h = deliv["delivery_hours"]
print("MAE of predicting the mean for everyone:", round((h - h.mean()).abs().mean(), 3))
zone_mean = deliv.groupby("zone")["delivery_hours"].transform("mean")
print("MAE of predicting the zone mean:", round((h - zone_mean).abs().mean(), 3))
MAE of predicting the mean for everyone: 1.069
MAE of predicting the zone mean: 1.051

Two warnings. These scores are computed on the same rows the means were taken from, which flatters them slightly; L76 evaluates on data the baseline has not seen. And a baseline's score is not the end: what matters is how much better a model must be for the decision to change.

Part D — Is a better prediction worth it?

A prediction has value only through a decision. Ask:

  1. Which decision uses it? (Send a welcome voucher? Promise a delivery window?)
  2. What does a wrong prediction cost, each way? (L66: a voucher wasted on a customer who would return anyway; a customer lost because no voucher was sent.)
  3. How much better than the baseline must the model be for the decision to improve enough to pay for building and maintaining it?
  4. Would a rule, an analysis or an experiment answer it? If the decision is "should we send vouchers at all?", that is an experiment (L69), not a model.

5. Worked Example

Cedar Lane (fictional), synthetic data. The retention team asks: "Can we predict which new customers will not come back within 60 days?"

Step 1 — Task type. Yes/no outcome with known history → supervised classification, ideally with a probability so customers can be ranked (L78).

Step 2 — Prediction moment. The day after the first order (the welcome offer goes out then).

Step 3 — Target. no_return_60d = 1 if the customer places no further order within 60 days of the first order.

Step 4 — Allowed features. Channel, app user, region, first-order items, basket, fulfilment, whether the first delivery was late, distance. Not allowed: app_opens_first_7d (after the moment), second_order_date (the answer).

Step 5 — Baselines. Majority class (predict "will not return" for everyone): accuracy as printed in Part C. Rule baseline (non-app users do not return): printed in Part C; it is no better than the majority class, so one feature alone is not enough. A model is interesting only if it ranks customers better than these, so that vouchers go to those most at risk.

Step 6 — Value of a better prediction. Suppose (assumption from marketing) a €4 voucher brings back one in five of the at-risk customers who receive it, and a returning customer is worth about €14 of margin in the next 90 days (L72). A voucher sent to an at-risk customer is then worth about 0.2 × €14 − €4 = −€1.20 on average: the voucher loses money even when perfectly targeted under these assumptions.

saved_share, margin_back, voucher = 0.20, 14.0, 4.0
for share_at_risk in [1.0, 0.8, 0.62]:      # perfect targeting, a good model, sending to everyone (base rate)
    value = share_at_risk * saved_share * margin_back - voucher
    print(f"share of contacted customers truly at risk {share_at_risk:.2f}: value per voucher EUR {value:.2f}")
share of contacted customers truly at risk 1.00: value per voucher EUR -1.20
share of contacted customers truly at risk 0.80: value per voucher EUR -1.76
share of contacted customers truly at risk 0.62: value per voucher EUR -2.26

Conclusion for the retention team: under these assumptions no model can make this voucher profitable, because the voucher itself is too expensive for what it brings back. The first step is a test of the offer (cheaper voucher, or measure the true response rate, L69), not a model. If the test shows a stronger response, a model becomes worth building to target it, and the majority-class and app-rule baselines are what it must beat.


6. Visual Explanation

 BUSINESS QUESTION ─▶ TASK TYPE   number → regression │ category → classification │ groups → clustering │ count/cause/rule → NOT ML
                         │
                 PREDICTION MOMENT  "the day after the first order"
                         │
   FEATURES known before the moment ✔ channel, app, basket, late first delivery      ✘ app opens days 1-7, second order date (leakage)
                         │
   BASELINE first      regression: mean (or group mean)      classification: majority class (or one rule)
                         │
   VALUE CHECK   better prediction → better decision → worth more than the cost of the model?   no → rule / analysis / experiment

Alt text: A business question is sorted into a task type: a number means regression, a category means classification, groups mean clustering, and a count, a causal question or a fixed rule means no ML. Then the prediction moment is fixed, for example the day after the first order. Features known before that moment are allowed, such as channel, app use, basket and a late first delivery; features from after it, such as app opens in the next seven days or the second order date, are leakage. A baseline comes first: the mean or a group mean for regression, the majority class or a single rule for classification. Finally a value check asks whether a better prediction improves a decision enough to pay for the model; if not, a rule, analysis or experiment is used instead.


7. Guided Practice

Open L75_starter.ipynb.

  1. For the 60-day non-return problem, write the task type, prediction moment and target.
  2. Run the prediction-moment check. Mark every column as allowed or not, and explain the two that are not in one sentence each.
  3. Compute the two classification baselines (majority class and a rule of your own choice) and the two regression baselines for delivery hours (mean and a group mean of your choice).
  4. Recompute the value-per-voucher table with a response of 0.35 instead of 0.20. Does the conclusion change?
  5. Run Restart Kernel and Run All Cells….

8. Independent Practice

Part 1 — Five problems. For each Cedar Lane problem, decide the task type (regression, classification, clustering or not ML), the target (if any), the prediction moment, two allowed features, one feature that would leak, and the baseline:

  1. Estimate how many minutes a pickup order takes to prepare, when the order is placed.
  2. Decide whether an order will be cancelled, at the moment it is placed.
  3. Find groups of loyalty members with similar shopping habits.
  4. Report how many orders each pickup point handled last week.
  5. Find out whether a new checkout design increases conversion.

Part 2 — ML or not for pickup queues. Using your pickup-queue charter from U17, write one paragraph: is ML the right tool for the decision you named? State the baseline (for example "average wait at that point and hour last month"), what a model would have to predict better, and what that improvement would be worth.

Work in L75_starter.ipynb (Part 2). Present Part 1 as a table.


9. Knowledge Check — Is It ML?

Q1. "How many hours will this delivery take?" is which kind of task?

  • A) Clustering
  • B) Classification
  • C) Regression
  • D) Not ML

Q2. "Find groups of customers with similar habits, without a target" is:

  • A) Unsupervised learning (clustering)
  • B) Regression on a habit score per customer
  • C) Classification into loyal and not loyal
  • D) A randomized experiment on the groups

Q3. What is the prediction moment?

  • A) When the model is trained on all of the historical data in the warehouse
  • B) When the data were exported from the sales system for the analysis
  • C) The end of the financial year, when the results are reported to the board
  • D) When the prediction is made in real use, which decides the allowed features

Q4. The prediction is made the day after the first order. Which feature leaks?

  • A) Acquisition channel recorded when the account was opened
  • B) App opens during the seven days after the first order
  • C) Whether the first delivery arrived later than promised
  • D) First basket value, taken from the first order

Q5. What is the standard baseline for a classification task?

  • A) A deep neural network trained on all of the features
  • B) Always predicting the most frequent class
  • C) The best model from last year, retrained on new data
  • D) A random forest with default settings

Q6. A model scores 0.64 accuracy; predicting the most frequent class scores 0.62. What follows?

  • A) The model clearly works, because any gain over a baseline, however small, proves value
  • B) Accuracy is irrelevant for classification tasks, so the comparison tells you nothing at all
  • C) The model adds little over the baseline here; check whether its ranking changes a decision
  • D) The baseline must be wrong, because a model should beat it by much more than that

Q7. "Does free delivery increase orders?" is best answered with:

  • A) A randomized experiment with a control group
  • B) A regression model on historical order data
  • C) Clustering customers by how often they order
  • D) A dashboard of orders before and after

Q8. Under the stated assumptions, a voucher loses money even when sent only to customers who are truly at risk. What does that mean for a targeting model?

  • A) Build a more accurate model, so that fewer vouchers are wasted
  • B) No model can make the offer profitable; change or test the offer first
  • C) Send the voucher to everyone, so that no at-risk customer is missed
  • D) Lower the model's threshold, so that more customers qualify for it

10. AI in Practice (optional, bounded)

Goal: ask an AI assistant to suggest features for a churn target, then check each against the prediction moment.

  1. Ask: "Suggest ten features to predict whether a new online-grocery customer will not order again within 60 days."
  2. For each suggestion, write when it would be known: before or after the day after the first order. Mark the "after" ones as leakage.
  3. Check which suggested features exist in new_customers.csv.

Boundaries: AI is optional; no data in prompts; you decide which features are allowed, by the prediction moment, not by how predictive they sound.


11. AI Verification

  1. Timestamps: for each kept feature, name the column and confirm it is recorded before the prediction moment.
  2. Leak test: for any suggested feature that is in the table, cross-tabulate it with the target; a near-perfect split is a warning.
  3. Baseline: compute the baseline score from the data yourself.
  4. Write down which AI suggestions were leakage.

12. Business Lens

ML costs time and maintenance; it is worth it only when a better prediction changes a decision enough. The value calculation in the worked example took five minutes and showed that the voucher, not the targeting, was the problem. Teams that skip this step often build an accurate model for an offer that loses money. A clear baseline also gives managers a fair yardstick: "the model must beat what we do today by this much".


13. Workplace Task — The "ML or Not" Note

Fictional business: Cedar Lane. The operations lead asks for "an AI model to predict delivery times". Write a note (80–120 words): the task type, prediction moment, target, two allowed features, the baseline and its MAE from the data, and the decision a better prediction would improve.


14. Mini Challenge — The Perfect Feature

Fictional business: Cedar Lane. A colleague reports a churn rule that "beats every baseline easily":

rule = cust["app_opens_first_7d"] <= 1
print("accuracy of 'opens the app at most once in week 1 -> will not return':", round((rule.astype(int) == cust["no_return_60d"]).mean(), 3))
accuracy of 'opens the app at most once in week 1 -> will not return': 0.731
  1. Before reading the number, say what is wrong with this feature for a prediction made the day after the first order.
  2. Could the rule still be useful for a different decision with a later prediction moment? Which one?
  3. Rewrite the colleague's claim so that it is honest.
  4. Write one sentence your team can keep as a rule about features and the prediction moment.

Submit before feedback. No solution is provided here.


15. Resources

Required (about 30 min):

  • scikit-learn: Getting Started (scikit-learn 1.9.1 documentation), on estimators, fit and predict, transformers and evaluation. https://scikit-learn.org/stable/getting_started.html (Opened 25 Oct 2026.)

Recommended:

  • scikit-learn: Metrics and scoring (1.9.1), which notes that dummy estimators give a baseline value of metrics. https://scikit-learn.org/stable/modules/model_evaluation.html (Opened 25 Oct 2026.)
  • DeepLearning.AI, the AI education platform founded by Andrew Ng. https://www.deeplearning.ai/ (Opened 25 Oct 2026.)

16. Person to Follow / Role Model

Andrew Ng (mapped by D.World for L75, L76, L81, L82).

  • Verified fact: listed in the D.World Stage 1 role-model record R03 for AI / ML education; the DeepLearning.AI home page names him as its founder (opened 25 Oct 2026).
  • Why D.World recommends him: he is widely followed for teaching machine learning to beginners, with a practical focus on when and how to apply it.
  • Honest note: we state only the D.World record and what the DeepLearning.AI page says.
  • Try this: find one free DeepLearning.AI resource on framing ML problems. Write one sentence on what it says to do before training a model.

17. Glossary

Term Meaning in this lesson
Supervised learning Learning from examples where the target (answer) is known
Unsupervised learning Finding structure (for example groups) without a target
Regression Predicting a number
Classification Predicting a category, usually with a probability
Target The outcome a supervised model predicts
Feature An input used to make the prediction
Prediction moment The moment in real use when the prediction is made; only information available then may be used
Baseline model The simplest honest prediction (mean, majority class, one rule) that any model must beat
Leakage Using information that would not be available at the prediction moment

Review: feature preparation (L39–L41) · leakage awareness (L42) · baseline forecasts (L70).


18. Reflection

  1. Which prediction in your own work would change a decision, and which would only be interesting?
  2. What is the prediction moment of a forecast you use regularly?
  3. When have you seen a simple rule beat a complicated method?

19. Next Step

Next: L76 — Your First scikit-learn Model. You install scikit-learn, split data into training, validation and test sets, and compare a formal baseline with a first model honestly.


20. Assessment Evidence

Evidence What it shows How it is judged
Task/target/feature/baseline table for five problems + ML-or-not paragraph (Independent Practice) Correct task types incl. non-ML; prediction moments; allowed vs leaking features; baselines; value reasoning Rubric L75-IP
Guided practice (moment check, four baselines, value table) Leaks found; baselines computed; conclusion under a new assumption Rubric L75-GP
Knowledge check (Q1–Q8) Task types; prediction moment; leakage; baselines; ML or not 7 or more of 8 correct
Workplace task and mini challenge ML-or-not note with baseline MAE; leaky "perfect" rule Rubrics L75-WT, L75-MC

References

  1. scikit-learn developers. Getting Started (1.9.1). https://scikit-learn.org/stable/getting_started.html (SK-START). Supports: estimator API, fit/predict.
  2. scikit-learn developers. Metrics and scoring (1.9.1). https://scikit-learn.org/stable/modules/model_evaluation.html (SK-EVAL). Supports: dummy estimators as baselines.
  3. DeepLearning.AI. Home page. https://www.deeplearning.ai/ (DLAI). Supports: role-model record (R03; founder named on the page).
  4. D.World Stage 4 Detailed Lesson Map v0.9 (L75 row). Internal.

L75 — متى يكون تعلّم الآلة هو الأداة المناسبة؟ المهام، والهدف، والخصائص، ونماذج المقارنة الأساسية

ملف المتعلّم. الإجابات والحلول النموذجية في ملف منفصل خاص بالمدرّس فقط. الإصدار: U18 Production v1 · تاريخ المحتوى: 25 أكتوبر 2026. تقديرات الوقت تقديرات للتخطيط إلى أن يختبرها المتعلّمون. الكود في هذا الدرس شُغّل باستخدام Python 3.13.16 وpandas 3.0.5 وNumPy 2.5.3 (مسجّلة في تقرير اختبار الكود الداخلي في D.World)؛ وPython 3.13 هو الإصدار المعتمد في الدورة. ولم يُشغَّل باستخدام Python 3.14 ولا داخل JupyterLab.

كل الأنشطة التجارية خيالية، وكل البيانات مصطنعة.


1. بطاقة الدرس

البند القيمة
العنوان متى يكون تعلّم الآلة هو الأداة المناسبة؟ المهام، والهدف، والخصائص، ونماذج المقارنة الأساسية
المرحلة المرحلة 4 — مشاريع حقيقية وتعلّم الآلة
الوحدة U18 — أساسيات تعلّم الآلة
رقم الدرس L75
المهارات التعلّم الخاضع للإشراف (الانحدار، والتصنيف) مقابل غير الخاضع للإشراف (التجميع)؛ الهدف، والخصائص، ولحظة التنبؤ؛ ما هو معروف وقت التنبؤ؛ نماذج المقارنة الأساسية القائمة على قاعدة أو على إحصاء بسيط؛ DummyRegressor / DummyClassifier كنماذج مقارنة رسمية؛ قيمة التنبؤ الأفضل؛ متى تكفي قاعدة أو تحليل أو تجربة
المستوى متوسط
الوقت المتوقع حوالي ساعتين ونصف (تقدير للتخطيط، غير مُتحقَّق منه)
مستوى التقييم فهم / تدريب
المتطلبات السابقة U10 (تجهيز الخصائص، وفكرة التدريب/الاختبار)، وU13 (التوزيعات، والارتباط، والعوامل المربكة)، وU17 (مواثيق المشاريع).

تفصيل الوقت (تقدير للتخطيط):

  • المفهوم والمثال المحلول: 55 دقيقة.
  • التدريب الموجَّه: 30 دقيقة.
  • التدريب المستقل: 35 دقيقة.
  • اختبار الفهم: 10 دقائق.
  • الذكاء الاصطناعي: 5 دقائق (اختياري).
  • مهمة العمل والتحدي القصير: 15 دقيقة.

ما تحتاج إليه: مجلد practice_files (L75_starter.ipynb؛ وu18_data/new_customers.csv وu18_data/deliveries_ml.csv). لا تثبيت جديد في هذا الدرس: ستثبّت scikit-learn في L76.

بيانات U18. في u18_data/ جدول صغير مصطنع لكل مهمة: new_customers.csv (صف لكل عميل جديد انضم بين 1 يناير و1 يوليو 2026، مع ما كان معروفًا عن طلبه الأول، وهل لم يطلب مرة أخرى خلال 60 يومًا)، وdeliveries_ml.csv (صف لكل توصيل منزلي مع المسافة، ويوم الأسبوع، والمنطقة الفرعية، والفترة الزمنية، وعدد المنتجات، والساعات التي استغرقها)، وجداول أخرى تُقدَّم في الدروس التي تستخدمها.


2. هدف التعلّم

في نهاية هذا الدرس ستكون قادرًا على أن:

  • تصنّف مشكلة العمل: مهمة انحدار، أو تصنيف، أو تجميع، أو مهمة لا تحتاج إلى تعلّم الآلة؛
  • تعرّف الهدف والخصائص المعروفة في لحظة التنبؤ؛
  • تحدّد نموذج المقارنة الأساسي الذي يجب أن يتفوق عليه النموذج، وتحسب درجته من البيانات.

الهدف المعتمد من D.World (بنصّه): Classify a business problem as a regression, classification, clustering or non-ML task, define the target and features at prediction time, and specify the baseline a model must beat.


3. لماذا يهمّك هذا؟

انتهت U17 بمواثيق للمشاريع. بعضها اقترح نموذجًا؛ وكثير منها لم يحتج إلى نموذج. وتعلّم الآلة (machine learning، ML) قوي، لكنه يكلّف وقتًا لبنائه، وبيانات لتدريبه، وجهدًا لمراقبته وصيانته. ولا يستحق ذلك إلا عندما يغيّر التنبؤ الأفضل قرارًا بما يكفي ليغطي تكلفته.

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

المبدأ الأساسي: قبل أي نموذج، سمِّ نوع المهمة، والهدف، ولحظة التنبؤ، والخصائص المعروفة في تلك اللحظة، واحسب درجة نموذج مقارنة بسيط. وتعلّم الآلة هو الأداة المناسبة فقط إذا كان التفوق على ذلك النموذج يغيّر قرارًا بما يكفي لدفع تكلفة النموذج.


4. المفهوم

import numpy as np
import pandas as pd

cust = pd.read_csv("u18_data/new_customers.csv")
deliv = pd.read_csv("u18_data/deliveries_ml.csv")
print(cust.shape, deliv.shape)
print(cust.columns.tolist())
(5000, 13) (4000, 8)
['customer_id', 'signup_date', 'acq_channel', 'app_user', 'region', 'first_items', 'first_basket', 'first_fulfilment', 'first_delivery_late', 'distance_km', 'app_opens_first_7d', 'second_order_date', 'no_return_60d']

الجزء A — أنواع مهام التعلّم

المهمة ماذا تتنبأ به أو تجده تحتاج إلى هدف؟ مثال في Cedar Lane
الانحدار (Regression) (خاضع للإشراف) رقمًا نعم كم ساعة سيستغرق التوصيل
التصنيف (Classification) (خاضع للإشراف) فئة، وغالبًا نعم/لا، وكثيرًا مع احتمال نعم هل لن يطلب هذا العميل الجديد مرة أخرى خلال 60 يومًا؟
التجميع (Clustering) (غير خاضع للإشراف) مجموعات من السجلات المتشابهة لا شرائح عملاء لفريق برنامج الولاء
ليست تعلّم آلة — — "What was the late rate last month?" (أي: "كم كان معدل التأخير الشهر الماضي؟"، استعلام وصفي)؛ "Does free delivery raise orders?" (أي: "هل يزيد التوصيل المجاني الطلبات؟"، تجربة، L69)

التعلّم الخاضع للإشراف (supervised learning) يتعلم من أمثلة إجابتها معروفة (الهدف). والتعلّم غير الخاضع للإشراف (unsupervised learning) يبحث عن بنية دون هدف. وكثير من الأسئلة ليست هذا ولا ذاك: فالعدّ استعلام، والسبب يحتاج إلى تجربة، وقد تكون قاعدة عمل ثابتة جيدة بما يكفي من الأساس.

الجزء B — الهدف، والخصائص، ولحظة التنبؤ

الهدف (target) هو ما تريد التنبؤ به (no_return_60d). والخصائص (features) هي المدخلات. ولحظة التنبؤ (prediction moment) هي الوقت الذي يُجرى فيه التنبؤ في الاستخدام الفعلي، وهي التي تحدد الخصائص المسموح بها: فقط المعلومات المتاحة في تلك اللحظة.

بالنسبة لفريق الاحتفاظ بالعملاء، يُجرى التنبؤ في اليوم التالي لأول طلب للعميل الجديد، حتى يُرسَل عرض ترحيبي فورًا. افحص كل عمود مقابل تلك اللحظة:

known_at = {
    "acq_channel": "sign-up", "app_user": "sign-up", "region": "sign-up",
    "first_items": "first order", "first_basket": "first order", "first_fulfilment": "first order",
    "first_delivery_late": "first order (next day)", "distance_km": "first order",
    "app_opens_first_7d": "days 1-7 AFTER the first order", "second_order_date": "only if they order again",
}
for col, when in known_at.items():
    ok = "AFTER" not in when and "only if" not in when
    print(f"{col:<22} known at: {when:<32} allowed: {ok}")
print(pd.crosstab(cust["second_order_date"].notna(), cust["no_return_60d"]))
acq_channel            known at: sign-up                          allowed: True
app_user               known at: sign-up                          allowed: True
region                 known at: sign-up                          allowed: True
first_items            known at: first order                      allowed: True
first_basket           known at: first order                      allowed: True
first_fulfilment       known at: first order                      allowed: True
first_delivery_late    known at: first order (next day)           allowed: True
distance_km            known at: first order                      allowed: True
app_opens_first_7d     known at: days 1-7 AFTER the first order   allowed: False
second_order_date      known at: only if they order again         allowed: False
no_return_60d         0     1
second_order_date
False                 0  3086
True               1914     0

(أوقات المعرفة في القاموس معناها: sign-up = عند التسجيل؛ first order = عند الطلب الأول؛ first order (next day) = الطلب الأول (اليوم التالي)؛ days 1-7 AFTER the first order = الأيام 1–7 بعد الطلب الأول؛ only if they order again = فقط إذا طلب مرة أخرى.)

العمود second_order_date ممتلئ بالضبط للعملاء الذين عادوا: إنه الإجابة متنكّرة. وapp_opens_first_7d يُحسب خلال الأسبوع الذي يلي لحظة التنبؤ. وكلاهما سيجعل النموذج يبدو ممتازًا، ومن المستحيل استخدامهما في اليوم الذي يجب أن يقرّر فيه. واستخدامهما تسرّب (leakage) (L42 وL58): معلومات من بعد لحظة التنبؤ تتسرب إلى الخصائص.

الجزء C — نماذج المقارنة الأساسية

نموذج المقارنة الأساسي (baseline model) هو أبسط تنبؤ أمين، ويجب أن يتفوق عليه كل نموذج:

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

توفّر scikit-learn هذه النماذج كمقدّرات رسمية، DummyRegressor وDummyClassifier (L76). وهنا احسبها يدويًا:

y = cust["no_return_60d"]
print("share who do not return:", round(y.mean(), 3))
print("majority-class baseline accuracy:", round(max(y.mean(), 1 - y.mean()), 3))
rule = (cust["app_user"] == 0).astype(int)          # rule: non-app users will not return
print("rule baseline accuracy (non-app users do not return):", round((rule == y).mean(), 3))
share who do not return: 0.617
majority-class baseline accuracy: 0.617
rule baseline accuracy (non-app users do not return): 0.614

(التعليق في الكود معناه: "القاعدة: من لا يستخدمون التطبيق لن يعودوا".)

h = deliv["delivery_hours"]
print("MAE of predicting the mean for everyone:", round((h - h.mean()).abs().mean(), 3))
zone_mean = deliv.groupby("zone")["delivery_hours"].transform("mean")
print("MAE of predicting the zone mean:", round((h - zone_mean).abs().mean(), 3))
MAE of predicting the mean for everyone: 1.069
MAE of predicting the zone mean: 1.051

تحذيران. هذه الدرجات محسوبة على الصفوف نفسها التي أُخذت منها المتوسطات، وهذا يجمّلها قليلًا؛ وسيقيّم L76 على بيانات لم يرها نموذج المقارنة. ودرجة نموذج المقارنة ليست النهاية: فالمهم هو كم يجب أن يكون النموذج أفضل حتى يتغير القرار.

الجزء D — هل يستحق التنبؤ الأفضل؟

للتنبؤ قيمة فقط من خلال قرار. اسأل:

  1. أي قرار يستخدمه؟ (هل نرسل قسيمة ترحيب؟ هل نَعِد بفترة توصيل معينة؟)
  2. كم يكلّف التنبؤ الخاطئ، في كل اتجاه؟ (L66: قسيمة مهدرة على عميل كان سيعود على أي حال؛ وعميل فُقد لأنه لم تُرسل له قسيمة.)
  3. كم يجب أن يكون النموذج أفضل من نموذج المقارنة حتى يتحسن القرار بما يكفي لدفع تكلفة بنائه وصيانته؟
  4. هل تجيب عنه قاعدة، أو تحليل، أو تجربة؟ إذا كان القرار "هل نرسل قسائم أصلًا؟"، فهذه تجربة (L69)، لا نموذج.

5. مثال محلول

Cedar Lane (خيالية)، بيانات مصطنعة. يسأل فريق الاحتفاظ بالعملاء: "Can we predict which new customers will not come back within 60 days?" (أي: "هل نستطيع التنبؤ بالعملاء الجدد الذين لن يعودوا خلال 60 يومًا؟")

الخطوة 1 — نوع المهمة. نتيجة نعم/لا مع تاريخ معروف، إذن: تصنيف خاضع للإشراف، ويُفضّل أن يكون مع احتمال حتى يمكن ترتيب العملاء (L78).

الخطوة 2 — لحظة التنبؤ. اليوم التالي للطلب الأول (حين يُرسَل العرض الترحيبي).

الخطوة 3 — الهدف. no_return_60d = 1 إذا لم يقدّم العميل أي طلب آخر خلال 60 يومًا من الطلب الأول.

الخطوة 4 — الخصائص المسموح بها. القناة، واستخدام التطبيق، والمنطقة، وعدد منتجات الطلب الأول، والسلة، وطريقة التنفيذ، وهل تأخرت أول توصيلة، والمسافة. غير مسموح بها: app_opens_first_7d (بعد اللحظة)، وsecond_order_date (الإجابة).

الخطوة 5 — نماذج المقارنة. الفئة الأغلب (التنبؤ بـ "لن يعود" للجميع): الدقة كما طُبعت في الجزء C. ونموذج القاعدة (من لا يستخدمون التطبيق لا يعودون): مطبوع في الجزء C؛ وهو ليس أفضل من الفئة الأغلب، فخاصية واحدة وحدها لا تكفي. والنموذج يكون مثيرًا للاهتمام فقط إذا رتّب العملاء أفضل من ذلك، حتى تذهب القسائم إلى الأكثر عرضة للخطر.

الخطوة 6 — قيمة التنبؤ الأفضل. افترض (افتراض من قسم التسويق) أن قسيمة بقيمة 4 يورو تعيد واحدًا من كل خمسة من العملاء المعرّضين للخطر الذين يتلقونها، وأن العميل العائد يساوي حوالي 14 يورو من الهامش في التسعين يومًا التالية (L72). إذن القسيمة المرسلة إلى عميل معرّض للخطر تساوي في المتوسط حوالي 0.2 × 14 يورو − 4 يورو = −1.20 يورو: القسيمة تخسر مالًا حتى مع استهداف مثالي في ظل هذه الافتراضات.

saved_share, margin_back, voucher = 0.20, 14.0, 4.0
for share_at_risk in [1.0, 0.8, 0.62]:      # perfect targeting, a good model, sending to everyone (base rate)
    value = share_at_risk * saved_share * margin_back - voucher
    print(f"share of contacted customers truly at risk {share_at_risk:.2f}: value per voucher EUR {value:.2f}")
share of contacted customers truly at risk 1.00: value per voucher EUR -1.20
share of contacted customers truly at risk 0.80: value per voucher EUR -1.76
share of contacted customers truly at risk 0.62: value per voucher EUR -2.26

(التعليق في الكود معناه: "استهداف مثالي، ونموذج جيد، والإرسال للجميع (المعدل الأساسي)".)

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


6. شرح بصري

 BUSINESS QUESTION ─▶ TASK TYPE   number → regression │ category → classification │ groups → clustering │ count/cause/rule → NOT ML
                         │
                 PREDICTION MOMENT  "the day after the first order"
                         │
   FEATURES known before the moment ✔ channel, app, basket, late first delivery      ✘ app opens days 1-7, second order date (leakage)
                         │
   BASELINE first      regression: mean (or group mean)      classification: majority class (or one rule)
                         │
   VALUE CHECK   better prediction → better decision → worth more than the cost of the model?   no → rule / analysis / experiment

وصف الرسم: يُفرز سؤال العمل إلى نوع مهمة: الرقم يعني انحدارًا، والفئة تعني تصنيفًا، والمجموعات تعني تجميعًا، والعدّ أو السؤال السببي أو القاعدة الثابتة تعني أنه لا حاجة إلى تعلّم الآلة. ثم تُثبَّت لحظة التنبؤ، مثلًا اليوم التالي للطلب الأول. والخصائص المعروفة قبل تلك اللحظة مسموح بها، مثل القناة، واستخدام التطبيق، والسلة، وتأخر أول توصيلة؛ أما الخصائص التي تأتي بعدها، مثل مرات فتح التطبيق في الأيام السبعة التالية أو تاريخ الطلب الثاني، فهي تسرّب. ونموذج المقارنة يأتي أولًا: المتوسط أو متوسط المجموعة للانحدار، والفئة الأغلب أو قاعدة واحدة للتصنيف. وأخيرًا يسأل فحص القيمة هل يحسّن التنبؤ الأفضل قرارًا بما يكفي لدفع تكلفة النموذج؛ وإن لم يكن، تُستخدم قاعدة أو تحليل أو تجربة بدلًا منه. (نصوص الرسم: BUSINESS QUESTION = سؤال العمل؛ TASK TYPE = نوع المهمة؛ number → regression = رقم ← انحدار؛ category → classification = فئة ← تصنيف؛ groups → clustering = مجموعات ← تجميع؛ count/cause/rule → NOT ML = عدّ/سبب/قاعدة ← ليس تعلّم آلة؛ PREDICTION MOMENT = لحظة التنبؤ؛ the day after the first order = اليوم التالي للطلب الأول؛ FEATURES known before the moment = خصائص معروفة قبل اللحظة؛ channel, app, basket, late first delivery = القناة، والتطبيق، والسلة، وتأخر أول توصيلة؛ app opens days 1-7, second order date (leakage) = فتح التطبيق في الأيام 1–7، وتاريخ الطلب الثاني (تسرّب)؛ BASELINE first = نموذج المقارنة أولًا؛ mean (or group mean) = المتوسط (أو متوسط المجموعة)؛ majority class (or one rule) = الفئة الأغلب (أو قاعدة واحدة)؛ VALUE CHECK = فحص القيمة؛ better prediction → better decision → worth more than the cost of the model? = تنبؤ أفضل ← قرار أفضل ← يساوي أكثر من تكلفة النموذج؟؛ no → rule / analysis / experiment = لا ← قاعدة / تحليل / تجربة.)


7. تدريب موجَّه

افتح L75_starter.ipynb.

  1. لمشكلة عدم العودة خلال 60 يومًا، اكتب نوع المهمة، ولحظة التنبؤ، والهدف.
  2. شغّل فحص لحظة التنبؤ. وعلّم كل عمود بأنه مسموح به أو لا، واشرح العمودين غير المسموح بهما في جملة واحدة لكل منهما.
  3. احسب نموذجَي المقارنة للتصنيف (الفئة الأغلب، وقاعدة من اختيارك) ونموذجَي المقارنة للانحدار لساعات التوصيل (المتوسط، ومتوسط مجموعة من اختيارك).
  4. أعد حساب جدول القيمة لكل قسيمة باستجابة 0.35 بدلًا من 0.20. هل تتغير الخلاصة؟
  5. شغّل Restart Kernel and Run All Cells….

8. تدريب مستقل

الجزء 1 — خمس مشكلات. لكل مشكلة من مشكلات Cedar Lane، حدّد نوع المهمة (انحدار، أو تصنيف، أو تجميع، أو ليست تعلّم آلة)، والهدف (إن وُجد)، ولحظة التنبؤ، وخاصيتين مسموحًا بهما، وخاصية واحدة ستتسرب، ونموذج المقارنة:

  1. تقدير عدد الدقائق التي يستغرقها تجهيز طلب استلام، عند تقديم الطلب.
  2. تقرير هل سيُلغى الطلب، في لحظة تقديمه.
  3. إيجاد مجموعات من أعضاء برنامج الولاء لهم عادات تسوّق متشابهة.
  4. الإبلاغ عن عدد الطلبات التي تعاملت معها كل نقطة استلام الأسبوع الماضي.
  5. معرفة هل يزيد تصميم جديد لصفحة الدفع معدل التحويل.

الجزء 2 — تعلّم الآلة أم لا لطوابير الاستلام. مستخدمًا ميثاق طوابير الاستلام الذي كتبته في U17، اكتب فقرة واحدة: هل تعلّم الآلة هو الأداة المناسبة للقرار الذي سمّيته؟ اذكر نموذج المقارنة (مثلًا "متوسط الانتظار في تلك النقطة وتلك الساعة الشهر الماضي")، وما الذي يجب أن يتنبأ به النموذج بشكل أفضل، وكم يساوي ذلك التحسن.

اعمل في L75_starter.ipynb (الجزء 2). واعرض الجزء 1 في جدول.


9. اختبار الفهم (Knowledge Check) — هل هو تعلّم آلة؟

Q1. "How many hours will this delivery take?" (كم ساعة سيستغرق هذا التوصيل؟) من أي نوع هذه المهمة؟

  • A) تجميع
  • B) تصنيف
  • C) انحدار
  • D) ليست تعلّم آلة

Q2. "إيجاد مجموعات من العملاء لهم عادات متشابهة، دون هدف" هو:

  • A) تعلّم غير خاضع للإشراف (تجميع)
  • B) انحدار على درجة عادات لكل عميل
  • C) تصنيف إلى مخلص وغير مخلص
  • D) تجربة عشوائية على المجموعات

Q3. ما لحظة التنبؤ؟

  • A) عندما يُدرَّب النموذج على كل البيانات التاريخية في مستودع البيانات
  • B) عندما صُدّرت البيانات من نظام المبيعات من أجل التحليل
  • C) نهاية السنة المالية، حين تُعرض النتائج على مجلس الإدارة
  • D) عندما يُجرى التنبؤ في الاستخدام الفعلي، وهي التي تحدد الخصائص المسموح بها

Q4. يُجرى التنبؤ في اليوم التالي للطلب الأول. أي خاصية تتسرب؟

  • A) قناة الاستقطاب المسجّلة عند فتح الحساب
  • B) مرات فتح التطبيق خلال الأيام السبعة التالية للطلب الأول
  • C) هل وصلت أول توصيلة بعد الموعد الموعود
  • D) قيمة السلة الأولى، المأخوذة من الطلب الأول

Q5. ما نموذج المقارنة المعتاد لمهمة التصنيف؟

  • A) شبكة عصبية عميقة مدرّبة على كل الخصائص
  • B) التنبؤ دائمًا بالفئة الأكثر تكرارًا
  • C) أفضل نموذج من العام الماضي، بعد إعادة تدريبه على بيانات جديدة
  • D) غابة عشوائية (random forest) بالإعدادات الافتراضية

Q6. نموذج يحقق دقة 0.64؛ والتنبؤ بالفئة الأكثر تكرارًا يحقق 0.62. ماذا يترتب على ذلك؟

  • A) النموذج يعمل بوضوح، لأن أي مكسب على نموذج المقارنة، مهما صغر، يثبت القيمة
  • B) الدقة لا صلة لها بمهام التصنيف، لذلك المقارنة لا تخبرك بشيء على الإطلاق
  • C) النموذج يضيف القليل على نموذج المقارنة هنا؛ تحقّق هل يغيّر ترتيبه قرارًا ما
  • D) نموذج المقارنة لا بد أنه خاطئ، لأن النموذج يجب أن يتفوق عليه بأكثر من ذلك بكثير

Q7. أفضل طريقة للإجابة عن "Does free delivery increase orders?" (هل يزيد التوصيل المجاني الطلبات؟) هي:

  • A) تجربة عشوائية مع مجموعة ضابطة
  • B) نموذج انحدار على بيانات الطلبات التاريخية
  • C) تجميع العملاء حسب عدد مرات طلبهم
  • D) لوحة متابعة للطلبات قبل وبعد

Q8. في ظل الافتراضات المذكورة، تخسر القسيمة مالًا حتى عندما تُرسل فقط إلى العملاء المعرّضين للخطر فعلًا. ماذا يعني ذلك لنموذج الاستهداف؟

  • A) ابنِ نموذجًا أدق، حتى تُهدر قسائم أقل
  • B) لا يستطيع أي نموذج أن يجعل العرض مربحًا؛ غيّر العرض أو اختبره أولًا
  • C) أرسل القسيمة للجميع، حتى لا يفوتك أي عميل معرّض للخطر
  • D) اخفض عتبة النموذج، حتى يتأهل لها عملاء أكثر

10. الذكاء الاصطناعي في التطبيق (اختياري، وفي حدود)

الهدف: أن تطلب من مساعد ذكاء اصطناعي اقتراح خصائص لهدف تسرّب العملاء، ثم تفحص كل منها مقابل لحظة التنبؤ.

  1. اسأل:

"Suggest ten features to predict whether a new online-grocery customer will not order again within 60 days."

وبالعربية: "اقترح عشر خصائص للتنبؤ بما إذا كان عميل جديد لمتجر بقالة إلكتروني لن يطلب مرة أخرى خلال 60 يومًا."

  1. لكل اقتراح، اكتب متى سيكون معروفًا: قبل أو بعد اليوم التالي للطلب الأول. وعلّم ما يأتي "بعد" على أنه تسرّب.
  2. تحقق أي الخصائص المقترحة موجودة في new_customers.csv.

الحدود:

  • استخدام الذكاء الاصطناعي اختياري.
  • لا بيانات في الطلبات المكتوبة للذكاء الاصطناعي.
  • أنت من يقرّر الخصائص المسموح بها، حسب لحظة التنبؤ، لا حسب مدى قدرتها التنبؤية الظاهرة.

11. التحقق من مخرجات الذكاء الاصطناعي

  1. التوقيتات: لكل خاصية أبقيتها، سمِّ العمود وتأكد من أنه يُسجَّل قبل لحظة التنبؤ.
  2. اختبار التسرّب: لأي خاصية مقترحة موجودة في الجدول، اعمل جدولًا تقاطعيًا لها مع الهدف؛ والفصل شبه المثالي علامة تحذير.
  3. نموذج المقارنة: احسب درجته من البيانات بنفسك.
  4. دوّن أي اقتراحات الذكاء الاصطناعي كانت تسرّبًا.

12. منظور الأعمال

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


13. مهمة عمل — مذكرة "تعلّم آلة أم لا"

نشاط خيالي: Cedar Lane. يطلب مسؤول العمليات "an AI model to predict delivery times" (أي: "نموذج ذكاء اصطناعي للتنبؤ بأوقات التوصيل"). اكتب مذكرة (من 80 إلى 120 كلمة): نوع المهمة، ولحظة التنبؤ، والهدف، وخاصيتين مسموحًا بهما، ونموذج المقارنة ومتوسط خطئه المطلق (MAE) من البيانات، والقرار الذي سيحسّنه التنبؤ الأفضل.


14. تحدٍّ قصير — الخاصية المثالية

نشاط خيالي: Cedar Lane. يبلّغ زميل عن قاعدة لتسرّب العملاء "beats every baseline easily" (أي: "تتفوق على كل نماذج المقارنة بسهولة"):

rule = cust["app_opens_first_7d"] <= 1
print("accuracy of 'opens the app at most once in week 1 -> will not return':", round((rule.astype(int) == cust["no_return_60d"]).mean(), 3))
accuracy of 'opens the app at most once in week 1 -> will not return': 0.731

(النص المطبوع معناه: دقة القاعدة "يفتح التطبيق مرة واحدة على الأكثر في الأسبوع الأول ← لن يعود".)

  1. قبل أن تقرأ الرقم، قل ما المشكلة في هذه الخاصية لتنبؤ يُجرى في اليوم التالي للطلب الأول.
  2. هل يمكن أن تظل القاعدة مفيدة لقرار مختلف له لحظة تنبؤ لاحقة؟ أي قرار؟
  3. أعد كتابة ادعاء زميلك بحيث يصبح صادقًا.
  4. اكتب جملة واحدة يحتفظ بها فريقك كقاعدة عن الخصائص ولحظة التنبؤ.

سلّم عملك قبل أن تتلقى الملاحظات. لا يوجد حل منشور هنا.


15. المصادر

مطلوب (حوالي 30 دقيقة):

  • scikit-learn: Getting Started (توثيق scikit-learn 1.9.1)، عن المقدّرات، وfit وpredict، والمحوّلات، والتقييم. https://scikit-learn.org/stable/getting_started.html (فُتح في 25 أكتوبر 2026.)

موصى به:

  • scikit-learn: Metrics and scoring (1.9.1)، الذي يذكر أن المقدّرات الوهمية (dummy estimators) تعطي قيمة أساسية للمقاييس. https://scikit-learn.org/stable/modules/model_evaluation.html (فُتح في 25 أكتوبر 2026.)
  • DeepLearning.AI، منصة تعليم الذكاء الاصطناعي التي أسسها Andrew Ng. https://www.deeplearning.ai/ (فُتح في 25 أكتوبر 2026.)

16. شخصية تتابعها / قدوة

Andrew Ng (اختارته D.World للدروس L75 وL76 وL81 وL82).

  • حقيقة مُتحقَّق منها: مذكور في سجل القدوات في المرحلة 1 من D.World، R03، لتعليم الذكاء الاصطناعي وتعلّم الآلة؛ والصفحة الرئيسية لـ DeepLearning.AI تذكره مؤسسًا لها (فُتحت في 25 أكتوبر 2026).
  • لماذا توصي به D.World: يتابعه كثيرون لتعليمه تعلّم الآلة للمبتدئين، مع تركيز عملي على متى وكيف يُطبَّق.
  • ملاحظة صادقة: لا نذكر إلا سجل D.World وما تقوله صفحة DeepLearning.AI.
  • جرّب هذا: ابحث عن مورد مجاني من DeepLearning.AI عن صياغة مشكلات تعلّم الآلة. واكتب جملة واحدة عما يقول إنه يجب فعله قبل تدريب النموذج.

17. المصطلحات

المصطلح معناه في هذا الدرس
التعلّم الخاضع للإشراف (Supervised learning) التعلّم من أمثلة يكون الهدف (الإجابة) فيها معروفًا
التعلّم غير الخاضع للإشراف (Unsupervised learning) إيجاد بنية (مثل المجموعات) دون هدف
الانحدار (Regression) التنبؤ برقم
التصنيف (Classification) التنبؤ بفئة، وغالبًا مع احتمال
الهدف (Target) النتيجة التي يتنبأ بها النموذج الخاضع للإشراف
الخاصية (Feature) مُدخَل يُستخدم في إجراء التنبؤ
لحظة التنبؤ (Prediction moment) اللحظة في الاستخدام الفعلي التي يُجرى فيها التنبؤ؛ ولا يجوز استخدام إلا المعلومات المتاحة حينها
نموذج المقارنة الأساسي (Baseline model) أبسط تنبؤ أمين (المتوسط، أو الفئة الأغلب، أو قاعدة واحدة) يجب أن يتفوق عليه أي نموذج
التسرّب (Leakage) استخدام معلومات لن تكون متاحة في لحظة التنبؤ

للمراجعة: تجهيز الخصائص (L39–L41) · الوعي بالتسرّب (L42) · تنبؤات المقارنة الأساسية (L70).


18. تأمّل

  1. أي تنبؤ في عملك سيغيّر قرارًا، وأيها سيكون مثيرًا للاهتمام فقط؟
  2. ما لحظة التنبؤ لتوقّع تستخدمه بانتظام؟
  3. متى رأيت قاعدة بسيطة تتفوق على طريقة معقدة؟

19. الخطوة التالية

التالي: L76 — أول نموذج لك في scikit-learn (Your First scikit-learn Model). تثبّت scikit-learn، وتقسّم البيانات إلى مجموعات تدريب وتحقق واختبار، وتقارن بأمانة بين نموذج مقارنة رسمي وأول نموذج لك.


20. أدلة التقييم

الدليل ماذا يُظهر كيف يُقيَّم
جدول المهمة/الهدف/الخصائص/نموذج المقارنة لخمس مشكلات + فقرة تعلّم آلة أم لا (التدريب المستقل) أنواع مهام صحيحة منها ما ليس تعلّم آلة؛ ولحظات التنبؤ؛ والخصائص المسموح بها مقابل المتسربة؛ ونماذج المقارنة؛ والتفكير في القيمة دليل التقييم L75-IP
التدريب الموجَّه (فحص اللحظة، وأربعة نماذج مقارنة، وجدول القيمة) اكتشاف التسرّبات؛ وحساب نماذج المقارنة؛ والخلاصة في ظل افتراض جديد دليل التقييم L75-GP
اختبار الفهم (Q1–Q8) أنواع المهام؛ ولحظة التنبؤ؛ والتسرّب؛ ونماذج المقارنة؛ وتعلّم آلة أم لا 7 إجابات صحيحة أو أكثر من 8
مهمة العمل والتحدي القصير مذكرة تعلّم آلة أم لا مع MAE لنموذج المقارنة؛ والقاعدة "المثالية" المتسربة دليلا التقييم L75-WT وL75-MC

المراجع

  1. scikit-learn developers. Getting Started (1.9.1). https://scikit-learn.org/stable/getting_started.html (SK-START). يدعم: واجهة المقدّرات، وfit/predict.
  2. scikit-learn developers. Metrics and scoring (1.9.1). https://scikit-learn.org/stable/modules/model_evaluation.html (SK-EVAL). يدعم: المقدّرات الوهمية كنماذج مقارنة.
  3. DeepLearning.AI. Home page. https://www.deeplearning.ai/ (DLAI). يدعم: سجل القدوة (R03؛ والمؤسس مذكور في الصفحة).
  4. D.World Stage 4 Detailed Lesson Map v0.9 (صف L75). وثيقة داخلية.
L76 · Your First scikit-learn Model: fit, predict & Train/Validation/Test About 3 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

L77 · Linear Regression: Coefficients, Categorical Features & Limits About 3 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

L78 · Classification: Logistic Regression, Probabilities & Thresholds About 3 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

L79 · Non-Linear Models: Decision Trees & k-Nearest Neighbours About 3 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

L80 · Unsupervised Learning: k-Means Clustering & Segment Profiles About 2.5 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

U18 Exit Check — Baseline vs Model Membersللمشتركين

The exit brief is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

تكليف نهاية الوحدة ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

U19 · Model Evaluation & Responsible MLتقييم النماذج وتعلم الآلة المسؤول

Stage 4المرحلة 4

Free: the first lesson. The other lessons, the exit brief and the practice files are for Starter and Membership.

مجاني: الدرس الأول. باقي الدروس وتكليف نهاية الوحدة وملفات التمرين لأصحاب باقة البداية والاشتراك.

Download U19 practice files (.zip, 358 KB)حمّل ملفات تمرين U19 (zip، 358 KB)

Unzip into a short folder such as D:\DWorld on Windows. The zip has only learner files: no answers.

فك الضغط في مجلد قصير مثل D:\DWorld على ويندوز. الملف يحتوي ملفات المتعلم فقط بدون إجابات.

L81 · Regression Metrics: MAE, MSE, RMSE, R2 & the BaselineL81 · مقاييس الانحدار: MAE وMSE وRMSE وR2 ونموذج المقارنة الأساسي About 2.5 hoursحوالي ساعتين ونصف Freeمجاني

L81 — Regression Metrics: MAE, MSE, RMSE, R2 & the Baseline

Learner file. Answers and model solutions are in a separate instructor-only file. Version: U19 Production v1 · Content date: 25 October 2026. Time estimates are planning estimates until learners have tested them. The code in this lesson was run with Python 3.13.16, pandas 3.0.5, NumPy 2.5.3 and scikit-learn 1.9.1 (recorded in D.World's internal Code Test Report); Python 3.13 is the accepted course version. Not run with Python 3.14 or inside JupyterLab.

All businesses are fictional and all data is synthetic.


1. Lesson Identity

Field Value
Title Regression Metrics: MAE, MSE, RMSE, R2 & the Baseline
Stage Stage 4 — Real Projects & Machine Learning
Unit U19 — Model Evaluation & Responsible ML
Lesson ID L81
Skills Error definitions; MAE vs MSE/RMSE (sensitivity to large errors); R² and its baseline (the mean); negative R²; metrics in business units; asymmetric costs; error distributions and percentiles; uncertainty of a metric (bootstrap)
Difficulty Intermediate
Estimated time About 2.5 hours (planning estimate, unvalidated)
Assessment level Practice / Application
Prerequisites U18 (models, splits, baselines), L70 (MAE), L54 (bootstrap), L52 (percentiles).

Time breakdown (planning estimate): concept and worked example 55 min · guided practice 30 min · independent practice 35 min · knowledge check 10 min · AI 5 min (optional) · workplace task and mini challenge 15 min.

What you need: practice_files (L81_starter.ipynb; u19_data/deliveries_ml.csv — the same delivery data as U18 — and u19_data/van_load_predictions.csv).

The U19 data. u19_data/ holds deliveries_ml.csv (from U18), churn_customers.csv (existing customers and whether they stopped ordering in the next 60 days; L82–L85), fraud_orders.csv (orders and whether they were fraudulent; L82, L84) and van_load_predictions.csv (two models' predictions of van-loading minutes; this lesson).


2. Learning Objective

By the end of this lesson, you will be able to:

  • calculate MAE, MSE, RMSE and R² for regression models, by hand and with scikit-learn;
  • interpret each against a baseline, in business units, including what a negative R² means;
  • choose the metric that matches what errors cost the business, with an interval for its uncertainty.

D.World approved objective (verbatim): Calculate and interpret MAE, MSE, RMSE and R2 for regression models, compare them against a baseline, and choose the metric that matches the business cost of errors.


3. Why It Matters

In U18 you compared delivery-time models with one number, MAE. But "the model is off by 0.54 hours on average" hides questions that operations cares about: how often is it badly wrong? Are big misses rare or common? Is late worse than early? And how sure are we of that 0.54?

Different metrics answer different questions. MAE treats every minute of error the same. RMSE punishes large errors more. R² compares the model with the simplest baseline, the mean. None is "the right one" in general: the right one is the one that reflects what errors cost this business.

Key principle: pick the regression metric from the business cost of errors, report it in business units next to the baseline, look at the whole error distribution, and give the metric an interval.


4. Concept

import numpy as np
import pandas as pd
from sklearn.dummy import DummyRegressor
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score, root_mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder
from sklearn.tree import DecisionTreeRegressor

deliv = pd.read_csv("u19_data/deliveries_ml.csv")
NUM, CAT = ["distance_km", "items"], ["weekday", "zone", "slot"]
X, y = deliv[NUM + CAT], deliv["delivery_hours"]
X_temp, X_test, y_temp, y_test = train_test_split(X, y, test_size=0.20, random_state=42)        # the U18 split
X_train, X_val, y_train, y_val = train_test_split(X_temp, y_temp, test_size=0.25, random_state=42)
enc = OneHotEncoder(drop=["Wed", "South", "08-12"], sparse_output=False).fit(X_train[CAT])
plain = lambda df: np.hstack([df[NUM].to_numpy(), enc.transform(df[CAT])])
flag = lambda df: np.column_stack([plain(df), (df["distance_km"] > 14).astype(float)])
models = {"baseline (mean)": (DummyRegressor(), plain), "linear": (LinearRegression(), plain),
          "linear + over 14 km": (LinearRegression(), flag), "tree depth 6": (DecisionTreeRegressor(max_depth=6, random_state=0), plain)}
pred = {name: m.fit(prep(X_train), y_train).predict(prep(X_val)) for name, (m, prep) in models.items()}
print("validation rows:", len(y_val), "| models:", list(pred))
validation rows: 800 | models: ['baseline (mean)', 'linear', 'linear + over 14 km', 'tree depth 6']

Part A — Four metrics from one list of errors

For each row, the error is actual − predicted. Four summaries:

Metric Formula Units What it rewards
MAE mean of |error| hours small typical errors; every hour counts the same
MSE mean of error² hours² few large errors (squares make big errors huge)
RMSE √MSE hours like MSE, back in hours; always ≥ MAE
R² 1 − MSE(model) / MSE(predicting the mean) none improvement over the mean baseline; 1 = perfect, 0 = no better than the mean

Compute them by hand once, then with scikit-learn:

e = y_val.to_numpy() - pred["linear + over 14 km"]
mae_h, mse_h = np.mean(np.abs(e)), np.mean(e ** 2)
r2_h = 1 - mse_h / np.mean((y_val.to_numpy() - y_val.mean()) ** 2)
print(f"by hand : MAE {mae_h:.3f}  MSE {mse_h:.3f}  RMSE {np.sqrt(mse_h):.3f}  R2 {r2_h:.3f}")
p = pred["linear + over 14 km"]
print(f"sklearn : MAE {mean_absolute_error(y_val, p):.3f}  MSE {mean_squared_error(y_val, p):.3f}  "
      f"RMSE {root_mean_squared_error(y_val, p):.3f}  R2 {r2_score(y_val, p):.3f}")
by hand : MAE 0.537  MSE 0.465  RMSE 0.682  R2 0.762
sklearn : MAE 0.537  MSE 0.465  RMSE 0.682  R2 0.762

Now all four models side by side:

table = pd.DataFrame({name: {"MAE": mean_absolute_error(y_val, p), "RMSE": root_mean_squared_error(y_val, p),
                             "R2": r2_score(y_val, p)} for name, p in pred.items()}).T.round(3)
print(table.to_string())
                       MAE   RMSE     R2
baseline (mean)      1.032  1.400 -0.000
linear               0.599  0.758  0.707
linear + over 14 km  0.537  0.682  0.762
tree depth 6         0.603  0.761  0.705

Reading the table: the linear model with the "over 14 km" feature is best on all three. RMSE is larger than MAE for every model; the gap grows when some errors are large. R² says the best model removes about 76% of the squared error of the mean baseline.

Part B — R²'s baseline, and a negative R²

R² compares with predicting the mean of the data being scored. So the mean predictor gets R² = 0 on its own data, and slightly below 0 on new data (its mean comes from the training set):

print("R2 of predicting the validation mean on validation:", round(r2_score(y_val, np.full(len(y_val), y_val.mean())), 6))
print(f"R2 of the training mean on validation (the DummyRegressor): {r2_score(y_val, pred['baseline (mean)']):.6f}")
print("R2 of a fixed guess of 6 hours for everyone:", round(r2_score(y_val, np.full(len(y_val), 6.0)), 3))
R2 of predicting the validation mean on validation: 0.0
R2 of the training mean on validation (the DummyRegressor): -0.000008
R2 of a fixed guess of 6 hours for everyone: -2.928

A negative R² means the model is worse than just predicting the mean: here, a fixed guess of 6 hours. A "high" R² does not mean the model is useful either: R² says nothing about whether an average error of half an hour is good enough for the decision. Always read it with a metric in business units.

Part C — Look at the error distribution

Two models can have similar MAE and very different large errors. Percentiles of the absolute error show the tail:

rows = {}
for name in ["linear", "linear + over 14 km", "tree depth 6"]:
    ae = np.abs(y_val.to_numpy() - pred[name])
    rows[name] = {"median": np.median(ae), "P90": np.percentile(ae, 90), "P99": np.percentile(ae, 99), "max": ae.max(),
                  "share > 1.5 h": (ae > 1.5).mean()}
print(pd.DataFrame(rows).T.round(3).to_string())
                     median    P90    P99    max  share > 1.5 h
linear                0.501  1.285  2.080  2.674          0.048
linear + over 14 km   0.450  1.164  1.699  2.140          0.035
tree depth 6          0.508  1.247  1.889  2.751          0.055

The plain linear model has the largest P90 and P99 (it misses long deliveries by a lot, L77), while the tree has the single largest miss and the most misses over 1.5 hours. The extra feature gives the smallest value on every tail measure.

Part D — When errors cost different amounts

For delivery promises, a delivery that arrives later than predicted (actual > predicted) breaks a promise; one that arrives earlier costs little. Suppose operations says (assumption) that an hour of being late costs three times an hour of being early:

def asym_cost(actual, predicted, late_weight=3.0):
    err = actual - predicted                       # > 0: later than predicted
    return float(np.mean(np.where(err > 0, late_weight * err, -err)))


for name in ["linear", "linear + over 14 km", "tree depth 6"]:
    print(f"{name:<22} asymmetric cost per delivery {asym_cost(y_val.to_numpy(), pred[name]):.3f} | MAE {mean_absolute_error(y_val, pred[name]):.3f}")
print("same best model, adding 0.5 h buffer:", round(asym_cost(y_val.to_numpy(), pred["linear + over 14 km"] + 0.5), 3))
linear                 asymmetric cost per delivery 1.202 | MAE 0.599
linear + over 14 km    asymmetric cost per delivery 1.080 | MAE 0.537
tree depth 6           asymmetric cost per delivery 1.204 | MAE 0.603
same best model, adding 0.5 h buffer: 0.857

With asymmetric costs, the best promise is not the model's prediction itself: adding a buffer reduces the expected cost, because late hours are expensive. The metric followed the business cost, and it changed the decision.

Part E — How sure is the number? A bootstrap interval

The validation MAE comes from 800 deliveries; another 800 would give a slightly different value. A bootstrap (L54) resamples the validation rows with replacement many times:

rng = np.random.default_rng(81)
yv, p1, p2 = y_val.to_numpy(), pred["linear"], pred["linear + over 14 km"]
boot, diff = [], []
for _ in range(2000):
    idx = rng.integers(0, len(yv), len(yv))
    m1, m2 = np.mean(np.abs(yv[idx] - p1[idx])), np.mean(np.abs(yv[idx] - p2[idx]))
    boot.append(m2)
    diff.append(m1 - m2)
print("MAE of the best model: 95% interval", np.percentile(boot, [2.5, 97.5]).round(3))
print("MAE improvement over plain linear: 95% interval", np.percentile(diff, [2.5, 97.5]).round(3))
MAE of the best model: 95% interval [0.508 0.568]
MAE improvement over plain linear: 95% interval [0.043 0.082]

The best model's MAE is about 0.54 hours, give or take a few hundredths. The improvement over the plain linear model is clearly above zero: the extra feature helps, not just on this sample. (Resampling the same rows for both models, as here, compares them fairly.)


5. Worked Example

Cedar Lane (fictional), synthetic data. Operations asks: "Which delivery-time model should we use, and how should we judge it?"

Step 1 — What do errors cost? Being late breaks a promise to a customer; being early costs little. Large lateness generates complaints. So: penalise large errors (RMSE or P90) and late errors more than early ones (asymmetric cost).

Step 2 — Compare on validation, against the baseline (Part A table): the linear model with the "over 14 km" feature wins on MAE, RMSE and R².

Step 3 — Look at the tail (Part C): it has the smallest P99 and the fewest misses over 1.5 hours.

Step 4 — Decision rule with asymmetric cost (Part D): promise prediction + buffer; a 0.5-hour buffer cuts the asymmetric cost (try other buffers in the guided practice).

Step 5 — Uncertainty (Part E): MAE ≈ 0.54 h with a narrow bootstrap interval; the improvement over plain linear is clearly positive.

Recommendation: "Use the linear model with the long-distance feature to set delivery windows, with a buffer chosen from the late-vs-early cost. Judge it each month by the share of deliveries later than promised and by the P90 error, not only by the average."


6. Visual Explanation

 errors e = actual − predicted
   MAE  = mean |e|        (hours; all errors equal)          RMSE = √ mean e²  (hours; big errors weigh more; RMSE ≥ MAE)
   R²   = 1 − MSE(model) / MSE(mean)    1 perfect · 0 = mean baseline · < 0 worse than the mean
 DISTRIBUTION  median · P90 · P99 · max · share > 1.5 h      → the tail decides complaints
 ASYMMETRIC COST  late hour × 3, early hour × 1  → best promise = prediction + buffer
 UNCERTAINTY  bootstrap the validation rows → interval for MAE and for the difference between models

Alt text: Errors are actual minus predicted. MAE is the mean absolute error in hours and treats all errors equally; RMSE is the square root of the mean squared error, in hours, weighting big errors more and never smaller than MAE; R squared is one minus the model's mean squared error divided by that of predicting the mean, with 1 perfect, 0 equal to the mean baseline and below 0 worse than the mean. The error distribution is described by the median, 90th and 99th percentiles, maximum and share above 1.5 hours. An asymmetric cost weights a late hour three times an early hour, so the best promise is the prediction plus a buffer. Bootstrapping the validation rows gives intervals for MAE and for the difference between models.


7. Guided Practice

Open L81_starter.ipynb.

  1. Rebuild the four delivery models on the U18 split; compute MAE, MSE, RMSE and R² for one model by hand and confirm with scikit-learn.
  2. Build the metric table for all four models; explain in two sentences why RMSE > MAE for every model.
  3. Show R² = 0 for the mean of the data being scored, and a negative R² for a bad constant guess.
  4. Compute the error percentiles; plot a histogram of the best model's errors.
  5. Compute the asymmetric cost for buffers of 0, 0.25, 0.5, 0.75 and 1 hour; which buffer is best on validation?
  6. Bootstrap a 95% interval for the best model's MAE and for its improvement over plain linear.
  7. Run Restart Kernel and Run All Cells….

8. Independent Practice

Part 1 — Two van-loading models. van_load_predictions.csv contains the actual loading minutes of 1,500 van loads and the predictions of two candidate models, A and B.

  1. Compute MAE, RMSE and R² for both models, and the error percentiles (median, P90, P99, max).
  2. Bootstrap a 95% interval for the difference in MAE and for the difference in RMSE (B − A).
  3. Which model does MAE prefer? Which does RMSE prefer? Explain the disagreement from the error distribution.

Part 2 — Operations penalises large delays heavily. The warehouse lead says: "An occasional 25-minute surprise blocks the loading bay and delays a whole route; a few minutes either way do not matter." Recommend MAE or RMSE for choosing between A and B, and the model, in 80–120 words, using the error distribution as evidence.

Work in L81_starter.ipynb (Part 2).


9. Knowledge Check — Regression Metrics

Q1. Which metric treats every hour of error the same, whatever the size of the error?

  • A) RMSE, because it is in the same units as the target
  • B) MSE, because it averages all squared errors equally
  • C) MAE, because each hour of error counts the same
  • D) R², because it compares the model with the mean

Q2. Why is RMSE always at least as large as MAE?

  • A) Squaring gives large errors more weight, so the root of the mean square is never below MAE
  • B) RMSE uses more rows than MAE, because it also counts the rows of the validation set
  • C) RMSE includes the baseline's error, so it adds the mean predictor's mistakes as well
  • D) It is only a convention of scikit-learn; other libraries report an RMSE below the MAE

Q3. A model has R² = 0 on the validation set. What does that mean?

  • A) The model is perfect on the validation rows, because its errors cancel
  • B) The model has no errors left that any more complex model could still fix
  • C) The model's MAE is zero, so every prediction is exact
  • D) It does no better than predicting the mean of the validation target

Q4. What does a negative R² mean?

  • A) A coding error, because R² can never be negative
  • B) The model is worse than predicting the mean
  • C) The model predicts negative values for some rows
  • D) The model is overfitting the validation set

Q5. Two models have the same MAE, but model B has a much larger P99 error. When should you prefer model A?

  • A) Never: equal MAE means equal quality for the business
  • B) Only if R² is higher for model B than for model A
  • C) When large errors are especially costly for the business
  • D) Only when the test set agrees with the result on the validation set

Q6. Late deliveries cost three times as much as early ones. What follows for the promise you give customers?

  • A) Add a buffer to the prediction, set by minimising the asymmetric cost on validation
  • B) Use the raw prediction, because it minimises MAE and therefore the total cost too
  • C) Always round predictions down, so that deliveries look early
  • D) Switch to R², because it weighs the late deliveries more

Q7. What does a bootstrap interval for the validation MAE express?

  • A) The range of the delivery times in the validation data, from shortest to longest
  • B) How much the MAE would vary with a different sample of similar deliveries
  • C) The training MAE, with a margin added for new data
  • D) The share of the errors that are above the mean error

Q8. An AI assistant says "R² = 0.7 means 70% of predictions are correct". What is right?

  • A) It is correct: 70% of the predictions are within the error margin
  • B) R² = 0.7 means the MAE is 0.3 hours on the validation data
  • C) R² = 0.7: the model removes about 70% of the mean baseline's squared error
  • D) R² is the share of rows used for training, so 70% of the rows were training rows

10. AI in Practice (optional, bounded)

Goal: check an AI explanation of R² against a calculation.

  1. Ask: "Explain R² for a regression model to a business manager."
  2. Test every claim with your data: compute R² for the mean predictor (should be 0 on its own data) and for a bad constant (negative).
  3. Correct any claim such as "percentage of correct predictions" or "R² cannot be negative".

Boundaries: AI is optional; no data in prompts; keep only claims your notebook confirms.


11. AI Verification

  1. Mean predictor: R² of the mean of the scored data = 0 (to rounding).
  2. Negative R²: produce one and explain it.
  3. NumPy check: recompute MAE, RMSE and R² with NumPy for one model.
  4. Write down which AI statement you corrected.

12. Business Lens

The metric should reflect what errors cost the business, not what is conventional. A model chosen by MAE may produce the rare large miss that blocks a loading bay; a model chosen by R² may look excellent and still be off by an hour. Translating errors into costs (late vs early, small vs large) and reporting intervals turns "the model is 0.54" into a decision: which promise to give customers, and how much buffer it needs.


13. Workplace Task — The Metric Choice Note

Fictional business: Cedar Lane. Finance wants one number to track the basket-value model from L76 each month (its validation MAE was about €4.5 per order, against about €12.9 for the average-basket baseline; RMSE is a little higher than MAE). Write a note (80–120 words): which metric you recommend (MAE, RMSE or R²) and why, in euros, what it would mean for a day of 100 orders, and which second number you would watch alongside it.


14. Mini Challenge — The Impressive R²

Fictional business: Cedar Lane. A colleague reports "R² = 0.76, the model explains 76% of delivery time, so 76% of promises will be right."

best = pred["linear + over 14 km"]
within_30 = np.mean(np.abs(y_val.to_numpy() - best) <= 0.5)
print("R2:", round(r2_score(y_val, best), 3), "| share of deliveries predicted within 30 minutes:", round(within_30, 3))
R2: 0.762 | share of deliveries predicted within 30 minutes: 0.546
  1. Before reading the output, say what R² does and does not tell you about "promises being right".
  2. What does the second number tell operations that R² does not?
  3. Rewrite the colleague's sentence so that it is correct.
  4. Write one sentence your team can keep as a rule for reporting regression models.

Submit before feedback. No solution is provided here.


15. Resources

Required (about 30 min):

  • scikit-learn: Metrics and scoring (1.9.1), regression metrics section: mean_absolute_error, mean_squared_error, root_mean_squared_error, r2_score. https://scikit-learn.org/stable/modules/model_evaluation.html (Opened 25 Oct 2026.)

Recommended:

  • OpenIntro: Introduction to Modern Statistics (2nd edition, free online), chapters on bootstrapping and confidence intervals. https://www.openintro.org/book/ims/ (Opened 25 Oct 2026.)

16. Person to Follow / Role Model

Andrew Ng (mapped by D.World for L75, L76, L81, L82).

  • Verified fact: listed in the D.World Stage 1 role-model record R03 for AI / ML education; the DeepLearning.AI home page names him as its founder (opened 25 Oct 2026).
  • Why D.World recommends him: his teaching stresses choosing a single evaluation metric that reflects the goal before comparing models.
  • Honest note: we state only the D.World record and what the DeepLearning.AI page says.
  • Try this: find a DeepLearning.AI resource on choosing an evaluation metric. Summarise in one sentence how it suggests handling a second, "must-not-get-worse" metric.

17. Glossary

Term Meaning in this lesson
MAE Mean absolute error: the average size of errors, in the target's units
MSE Mean squared error: the average squared error; large errors dominate
RMSE Root mean squared error: √MSE, back in the target's units; ≥ MAE
R2 (R²) 1 − MSE(model)/MSE(mean): improvement over predicting the mean; can be negative
Error distribution The spread of errors, described with percentiles (median, P90, P99) and the maximum
Asymmetric cost A cost that is different for errors in each direction (late vs early)
Bootstrap interval A range for a metric from recomputing it on many resamples of the evaluation rows

Review: MAE (L70) · bootstrap (L54) · percentiles (L52).


18. Reflection

  1. In your work, are errors in one direction more costly than in the other?
  2. Which single number about a model would you put on a manager's dashboard, and which would you add next to it?
  3. When have you seen a high R² reported as proof of usefulness?

19. Next Step

Next: L82 — Classification Metrics: Confusion Matrix, Precision, Recall, F1 & Costs. The same question for yes/no models: which errors cost what, and which threshold minimises the cost?


20. Assessment Evidence

Evidence What it shows How it is judged
Van-loading metric comparison + recommendation (Independent Practice) Four metrics and percentiles; bootstrap intervals for differences; MAE/RMSE disagreement explained; metric chosen from the stated cost Rubric L81-IP
Guided notebook (hand metrics, table, R² baseline, percentiles, buffer, bootstrap) Correct metrics; negative R² explained; buffer chosen on validation Rubric L81-GP
Knowledge check (Q1–Q8) Metric definitions; R²; tails; asymmetric cost; bootstrap 7 or more of 8 correct
Workplace task and mini challenge Metric choice for finance; R² misread Rubrics L81-WT, L81-MC

References

  1. scikit-learn developers. Metrics and scoring (1.9.1). https://scikit-learn.org/stable/modules/model_evaluation.html (SK-EVAL). Supports: regression metric functions.
  2. OpenIntro. Introduction to Modern Statistics, 2nd ed. https://www.openintro.org/book/ims/ (OI-IMS). Supports: bootstrap and confidence intervals.
  3. DeepLearning.AI. Home page. https://www.deeplearning.ai/ (DLAI). Supports: role-model record (R03).
  4. D.World Stage 4 Detailed Lesson Map v0.9 (L81 row). Internal.

L81 — مقاييس الانحدار: MAE وMSE وRMSE وR2 ونموذج المقارنة الأساسي

ملف المتعلّم. الإجابات والحلول النموذجية في ملف منفصل خاص بالمدرّس فقط. الإصدار: U19 Production v1 · تاريخ المحتوى: 25 أكتوبر 2026. تقديرات الوقت تقديرات للتخطيط إلى أن يختبرها المتعلّمون. الكود في هذا الدرس شُغّل باستخدام Python 3.13.16 وpandas 3.0.5 وNumPy 2.5.3 وscikit-learn 1.9.1 (مسجّلة في تقرير اختبار الكود الداخلي في D.World)؛ وPython 3.13 هو الإصدار المعتمد في الدورة. ولم يُشغَّل باستخدام Python 3.14 ولا داخل JupyterLab.

كل الأنشطة التجارية خيالية، وكل البيانات مصطنعة.


1. بطاقة الدرس

البند القيمة
العنوان مقاييس الانحدار: MAE وMSE وRMSE وR2 ونموذج المقارنة الأساسي
المرحلة المرحلة 4 — مشاريع حقيقية وتعلّم الآلة
الوحدة U19 — تقييم النماذج وتعلّم الآلة المسؤول
رقم الدرس L81
المهارات تعريفات الخطأ؛ MAE مقابل MSE/RMSE (الحساسية للأخطاء الكبيرة)؛ R² ونموذج مقارنته (المتوسط)؛ R² السالب؛ المقاييس بوحدات العمل؛ التكاليف غير المتماثلة؛ توزيعات الأخطاء ومئيناتها؛ عدم اليقين في المقياس (bootstrap)
المستوى متوسط
الوقت المتوقع حوالي ساعتين ونصف (تقدير للتخطيط، غير مُتحقَّق منه)
مستوى التقييم تدريب / تطبيق
المتطلبات السابقة U18 (النماذج، والتقسيمات، ونماذج المقارنة)، وL70 (MAE)، وL54 (bootstrap)، وL52 (المئينات).

تفصيل الوقت (تقدير للتخطيط):

  • المفهوم والمثال المحلول: 55 دقيقة.
  • التدريب الموجَّه: 30 دقيقة.
  • التدريب المستقل: 35 دقيقة.
  • اختبار الفهم: 10 دقائق.
  • الذكاء الاصطناعي: 5 دقائق (اختياري).
  • مهمة العمل والتحدي القصير: 15 دقيقة.

ما تحتاج إليه: مجلد practice_files (L81_starter.ipynb؛ وu19_data/deliveries_ml.csv، وهي بيانات التوصيل نفسها من U18، وu19_data/van_load_predictions.csv).

بيانات U19. في u19_data/: deliveries_ml.csv (من U18)، وchurn_customers.csv (العملاء الحاليون وهل توقفوا عن الطلب في الستين يومًا التالية؛ L82–L85)، وfraud_orders.csv (الطلبات وهل كانت احتيالية؛ L82 وL84)، وvan_load_predictions.csv (تنبؤات نموذجين بدقائق تحميل الشاحنات؛ هذا الدرس).


2. هدف التعلّم

في نهاية هذا الدرس ستكون قادرًا على أن:

  • تحسب MAE وMSE وRMSE وR² لنماذج الانحدار، يدويًا وباستخدام scikit-learn؛
  • تفسّر كلًّا منها مقابل نموذج مقارنة، بوحدات العمل، بما في ذلك معنى R² السالب؛
  • تختار المقياس الذي يطابق ما تكلّفه الأخطاء للعمل، مع مدى يعبّر عن عدم اليقين فيه.

الهدف المعتمد من D.World (بنصّه): Calculate and interpret MAE, MSE, RMSE and R2 for regression models, compare them against a baseline, and choose the metric that matches the business cost of errors.


3. لماذا يهمّك هذا؟

في U18 قارنت نماذج وقت التوصيل برقم واحد هو MAE. لكن عبارة "النموذج يخطئ بمقدار 0.54 ساعة في المتوسط" تخفي أسئلة يهتم بها قسم العمليات: كم مرة يخطئ خطأً كبيرًا؟ هل الإخفاقات الكبيرة نادرة أم شائعة؟ هل التأخير أسوأ من التبكير؟ وما مدى ثقتنا بذلك الرقم 0.54؟

المقاييس المختلفة تجيب عن أسئلة مختلفة. فـ MAE يعامل كل دقيقة خطأ بالطريقة نفسها. وRMSE يعاقب الأخطاء الكبيرة أكثر. وR² يقارن النموذج بأبسط نموذج مقارنة، وهو المتوسط. ولا يوجد بينها "المقياس الصحيح" بشكل عام: الصحيح هو الذي يعكس ما تكلّفه الأخطاء لهذا العمل.

المبدأ الأساسي: اختر مقياس الانحدار من تكلفة الأخطاء على العمل، واعرضه بوحدات العمل إلى جانب نموذج المقارنة، وانظر إلى توزيع الأخطاء كله، وأعطِ المقياس مدى.


4. المفهوم

import numpy as np
import pandas as pd
from sklearn.dummy import DummyRegressor
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score, root_mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder
from sklearn.tree import DecisionTreeRegressor

deliv = pd.read_csv("u19_data/deliveries_ml.csv")
NUM, CAT = ["distance_km", "items"], ["weekday", "zone", "slot"]
X, y = deliv[NUM + CAT], deliv["delivery_hours"]
X_temp, X_test, y_temp, y_test = train_test_split(X, y, test_size=0.20, random_state=42)        # the U18 split
X_train, X_val, y_train, y_val = train_test_split(X_temp, y_temp, test_size=0.25, random_state=42)
enc = OneHotEncoder(drop=["Wed", "South", "08-12"], sparse_output=False).fit(X_train[CAT])
plain = lambda df: np.hstack([df[NUM].to_numpy(), enc.transform(df[CAT])])
flag = lambda df: np.column_stack([plain(df), (df["distance_km"] > 14).astype(float)])
models = {"baseline (mean)": (DummyRegressor(), plain), "linear": (LinearRegression(), plain),
          "linear + over 14 km": (LinearRegression(), flag), "tree depth 6": (DecisionTreeRegressor(max_depth=6, random_state=0), plain)}
pred = {name: m.fit(prep(X_train), y_train).predict(prep(X_val)) for name, (m, prep) in models.items()}
print("validation rows:", len(y_val), "| models:", list(pred))
validation rows: 800 | models: ['baseline (mean)', 'linear', 'linear + over 14 km', 'tree depth 6']

(التعليق في الكود معناه: "تقسيم U18". وأسماء النماذج: baseline (mean) = نموذج المقارنة (المتوسط)؛ linear = خطي؛ linear + over 14 km = خطي + أكثر من 14 كم؛ tree depth 6 = شجرة بعمق 6.)

الجزء A — أربعة مقاييس من قائمة واحدة من الأخطاء

لكل صف، الخطأ (error) هو القيمة الفعلية − القيمة المتنبأ بها. وهناك أربعة ملخصات:

المقياس المعادلة الوحدات ماذا يكافئ
MAE متوسط |الخطأ| ساعات الأخطاء المعتادة الصغيرة؛ وكل ساعة تُحسب بالقدر نفسه
MSE متوسط الخطأ² ساعات² قلة الأخطاء الكبيرة (التربيع يجعل الأخطاء الكبيرة ضخمة)
RMSE √MSE ساعات مثل MSE، لكن بالساعات؛ ودائمًا ≥ MAE
R² 1 − MSE(النموذج) / MSE(التنبؤ بالمتوسط) بلا وحدة التحسن على نموذج المتوسط؛ 1 = مثالي، و0 = ليس أفضل من المتوسط

احسبها يدويًا مرة، ثم باستخدام scikit-learn:

e = y_val.to_numpy() - pred["linear + over 14 km"]
mae_h, mse_h = np.mean(np.abs(e)), np.mean(e ** 2)
r2_h = 1 - mse_h / np.mean((y_val.to_numpy() - y_val.mean()) ** 2)
print(f"by hand : MAE {mae_h:.3f}  MSE {mse_h:.3f}  RMSE {np.sqrt(mse_h):.3f}  R2 {r2_h:.3f}")
p = pred["linear + over 14 km"]
print(f"sklearn : MAE {mean_absolute_error(y_val, p):.3f}  MSE {mean_squared_error(y_val, p):.3f}  "
      f"RMSE {root_mean_squared_error(y_val, p):.3f}  R2 {r2_score(y_val, p):.3f}")
by hand : MAE 0.537  MSE 0.465  RMSE 0.682  R2 0.762
sklearn : MAE 0.537  MSE 0.465  RMSE 0.682  R2 0.762

والآن النماذج الأربعة جنبًا إلى جنب:

table = pd.DataFrame({name: {"MAE": mean_absolute_error(y_val, p), "RMSE": root_mean_squared_error(y_val, p),
                             "R2": r2_score(y_val, p)} for name, p in pred.items()}).T.round(3)
print(table.to_string())
                       MAE   RMSE     R2
baseline (mean)      1.032  1.400 -0.000
linear               0.599  0.758  0.707
linear + over 14 km  0.537  0.682  0.762
tree depth 6         0.603  0.761  0.705

قراءة الجدول: النموذج الخطي مع خاصية "أكثر من 14 كم" هو الأفضل في المقاييس الثلاثة. وRMSE أكبر من MAE لكل نموذج؛ والفجوة بينهما تكبر عندما تكون بعض الأخطاء كبيرة. ويقول R² إن أفضل نموذج يزيل حوالي 76% من مربعات أخطاء نموذج المتوسط.

الجزء B — نموذج المقارنة في R²، وR² السالب

R² يقارن مع التنبؤ بمتوسط البيانات التي يجري تقييمها. لذلك يحصل التنبؤ بالمتوسط على R² = 0 على بياناته نفسها، وعلى قيمة أقل قليلًا من 0 على بيانات جديدة (لأن متوسطه مأخوذ من مجموعة التدريب):

print("R2 of predicting the validation mean on validation:", round(r2_score(y_val, np.full(len(y_val), y_val.mean())), 6))
print(f"R2 of the training mean on validation (the DummyRegressor): {r2_score(y_val, pred['baseline (mean)']):.6f}")
print("R2 of a fixed guess of 6 hours for everyone:", round(r2_score(y_val, np.full(len(y_val), 6.0)), 3))
R2 of predicting the validation mean on validation: 0.0
R2 of the training mean on validation (the DummyRegressor): -0.000008
R2 of a fixed guess of 6 hours for everyone: -2.928

(الأسطر المطبوعة معناها: R2 للتنبؤ بمتوسط مجموعة التحقق عليها نفسها؛ وR2 لمتوسط التدريب على مجموعة التحقق (DummyRegressor)؛ وR2 لتخمين ثابت قدره 6 ساعات للجميع.)

R² السالب يعني أن النموذج أسوأ من مجرد التنبؤ بالمتوسط: هنا، تخمين ثابت قدره 6 ساعات. ولا يعني R² "المرتفع" أن النموذج مفيد أيضًا: فـ R² لا يقول شيئًا عن هل خطأ متوسطه نصف ساعة جيد بما يكفي للقرار. لذلك اقرأه دائمًا مع مقياس بوحدات العمل.

الجزء C — انظر إلى توزيع الأخطاء

قد يكون لنموذجين MAE متقارب وأخطاء كبيرة مختلفة جدًا. ومئينات الخطأ المطلق تُظهر الذيل:

rows = {}
for name in ["linear", "linear + over 14 km", "tree depth 6"]:
    ae = np.abs(y_val.to_numpy() - pred[name])
    rows[name] = {"median": np.median(ae), "P90": np.percentile(ae, 90), "P99": np.percentile(ae, 99), "max": ae.max(),
                  "share > 1.5 h": (ae > 1.5).mean()}
print(pd.DataFrame(rows).T.round(3).to_string())
                     median    P90    P99    max  share > 1.5 h
linear                0.501  1.285  2.080  2.674          0.048
linear + over 14 km   0.450  1.164  1.699  2.140          0.035
tree depth 6          0.508  1.247  1.889  2.751          0.055

(الأعمدة: median = الوسيط؛ P90 وP99 = المئين 90 و99؛ max = الأكبر؛ share > 1.5 h = نسبة الأخطاء التي تزيد على 1.5 ساعة.)

النموذج الخطي البسيط له أكبر P90 وP99 (فهو يخطئ في التوصيلات الطويلة بفارق كبير، L77)، بينما للشجرة أكبر خطأ منفرد وأكثر الأخطاء التي تتجاوز 1.5 ساعة. أما الخاصية الإضافية فتعطي أصغر قيمة في كل مقاييس الذيل.

الجزء D — عندما تختلف تكلفة الأخطاء

في وعود التوصيل، التوصيلة التي تصل متأخرة عن المتنبأ به (الفعلي > المتنبأ به) تنقض وعدًا؛ أما التي تصل مبكرًا فتكلّف القليل. افترض أن قسم العمليات يقول (افتراض) إن ساعة التأخير تكلّف ثلاثة أضعاف ساعة التبكير:

def asym_cost(actual, predicted, late_weight=3.0):
    err = actual - predicted                       # > 0: later than predicted
    return float(np.mean(np.where(err > 0, late_weight * err, -err)))


for name in ["linear", "linear + over 14 km", "tree depth 6"]:
    print(f"{name:<22} asymmetric cost per delivery {asym_cost(y_val.to_numpy(), pred[name]):.3f} | MAE {mean_absolute_error(y_val, pred[name]):.3f}")
print("same best model, adding 0.5 h buffer:", round(asym_cost(y_val.to_numpy(), pred["linear + over 14 km"] + 0.5), 3))
linear                 asymmetric cost per delivery 1.202 | MAE 0.599
linear + over 14 km    asymmetric cost per delivery 1.080 | MAE 0.537
tree depth 6           asymmetric cost per delivery 1.204 | MAE 0.603
same best model, adding 0.5 h buffer: 0.857

(التعليق في الكود معناه: "أكبر من 0: أبطأ من المتنبأ به". والسطر الأخير معناه: أفضل نموذج نفسه بعد إضافة هامش احتياطي قدره 0.5 ساعة.)

مع التكاليف غير المتماثلة (asymmetric costs)، لا يكون أفضل وعد هو تنبؤ النموذج نفسه: فإضافة هامش احتياطي تقلل التكلفة المتوقعة، لأن ساعات التأخير مكلفة. لقد اتبع المقياس تكلفة العمل، فغيّر القرار.

الجزء E — ما مدى ثقتنا بالرقم؟ مدى bootstrap

MAE في مجموعة التحقق يأتي من 800 توصيلة؛ و800 أخرى ستعطي قيمة مختلفة قليلًا. وطريقة bootstrap (L54) تعيد سحب صفوف التحقق مع الإرجاع مرات كثيرة:

rng = np.random.default_rng(81)
yv, p1, p2 = y_val.to_numpy(), pred["linear"], pred["linear + over 14 km"]
boot, diff = [], []
for _ in range(2000):
    idx = rng.integers(0, len(yv), len(yv))
    m1, m2 = np.mean(np.abs(yv[idx] - p1[idx])), np.mean(np.abs(yv[idx] - p2[idx]))
    boot.append(m2)
    diff.append(m1 - m2)
print("MAE of the best model: 95% interval", np.percentile(boot, [2.5, 97.5]).round(3))
print("MAE improvement over plain linear: 95% interval", np.percentile(diff, [2.5, 97.5]).round(3))
MAE of the best model: 95% interval [0.508 0.568]
MAE improvement over plain linear: 95% interval [0.043 0.082]

MAE لأفضل نموذج حوالي 0.54 ساعة، بزيادة أو نقصان بضعة أجزاء من المئة. والتحسن على النموذج الخطي البسيط أعلى من الصفر بوضوح: فالخاصية الإضافية تساعد، لا في هذه العينة فقط. (إعادة سحب الصفوف نفسها للنموذجين، كما هنا، تقارن بينهما بعدل.)


5. مثال محلول

Cedar Lane (خيالية)، بيانات مصطنعة. يسأل قسم العمليات: "Which delivery-time model should we use, and how should we judge it?" (أي: "أي نموذج لوقت التوصيل نستخدم، وكيف نحكم عليه؟")

الخطوة 1 — كم تكلّف الأخطاء؟ التأخير ينقض وعدًا للعميل؛ والتبكير يكلّف القليل. والتأخير الكبير يولّد شكاوى. إذن: عاقب الأخطاء الكبيرة (RMSE أو P90) وعاقب أخطاء التأخير أكثر من أخطاء التبكير (تكلفة غير متماثلة).

الخطوة 2 — قارن على مجموعة التحقق، مقابل نموذج المقارنة (جدول الجزء A): النموذج الخطي مع خاصية "أكثر من 14 كم" يفوز في MAE وRMSE وR².

الخطوة 3 — انظر إلى الذيل (الجزء C): له أصغر P99 وأقل عدد من الأخطاء التي تتجاوز 1.5 ساعة.

الخطوة 4 — قاعدة القرار مع التكلفة غير المتماثلة (الجزء D): عِد بـ التنبؤ + هامش احتياطي؛ فهامش قدره 0.5 ساعة يخفض التكلفة غير المتماثلة (جرّب هوامش أخرى في التدريب الموجَّه).

الخطوة 5 — عدم اليقين (الجزء E): MAE ≈ 0.54 ساعة مع مدى bootstrap ضيّق؛ والتحسن على النموذج الخطي البسيط موجب بوضوح.

التوصية: "Use the linear model with the long-distance feature to set delivery windows, with a buffer chosen from the late-vs-early cost. Judge it each month by the share of deliveries later than promised and by the P90 error, not only by the average." (أي: "استخدم النموذج الخطي مع خاصية المسافة الطويلة لتحديد فترات التوصيل، مع هامش احتياطي يُختار من تكلفة التأخير مقابل التبكير. واحكم عليه كل شهر بنسبة التوصيلات التي تأخرت عن الموعد الموعود وبخطأ P90، لا بالمتوسط وحده.")


6. شرح بصري

 errors e = actual − predicted
   MAE  = mean |e|        (hours; all errors equal)          RMSE = √ mean e²  (hours; big errors weigh more; RMSE ≥ MAE)
   R²   = 1 − MSE(model) / MSE(mean)    1 perfect · 0 = mean baseline · < 0 worse than the mean
 DISTRIBUTION  median · P90 · P99 · max · share > 1.5 h      → the tail decides complaints
 ASYMMETRIC COST  late hour × 3, early hour × 1  → best promise = prediction + buffer
 UNCERTAINTY  bootstrap the validation rows → interval for MAE and for the difference between models

وصف الرسم: الأخطاء هي القيمة الفعلية ناقص المتنبأ بها. MAE هو متوسط الخطأ المطلق بالساعات ويعامل كل الأخطاء بالتساوي؛ وRMSE هو الجذر التربيعي لمتوسط مربعات الأخطاء، بالساعات، ويعطي الأخطاء الكبيرة وزنًا أكبر ولا يكون أبدًا أصغر من MAE؛ وR² هو واحد ناقص متوسط مربعات أخطاء النموذج مقسومًا على نظيره عند التنبؤ بالمتوسط، و1 يعني مثاليًا، و0 يساوي نموذج المتوسط، وما دون 0 أسوأ من المتوسط. ويوصف توزيع الأخطاء بالوسيط، والمئين 90 والمئين 99، والقيمة الكبرى، ونسبة الأخطاء التي تتجاوز 1.5 ساعة. والتكلفة غير المتماثلة تعطي ساعة التأخير ثلاثة أضعاف وزن ساعة التبكير، فيكون أفضل وعد هو التنبؤ مع هامش احتياطي. وإعادة سحب صفوف التحقق بطريقة bootstrap تعطي مدى لـ MAE وللفرق بين النماذج. (نصوص الرسم: errors e = actual − predicted = الأخطاء e = الفعلي − المتنبأ به؛ hours; all errors equal = ساعات؛ كل الأخطاء متساوية؛ big errors weigh more = الأخطاء الكبيرة تزن أكثر؛ 1 perfect · 0 = mean baseline · < 0 worse than the mean = 1 مثالي · 0 = نموذج المتوسط · أقل من 0 أسوأ من المتوسط؛ DISTRIBUTION = التوزيع؛ the tail decides complaints = الذيل يحدد الشكاوى؛ ASYMMETRIC COST = التكلفة غير المتماثلة؛ late hour × 3, early hour × 1 = ساعة التأخير × 3، وساعة التبكير × 1؛ best promise = prediction + buffer = أفضل وعد = التنبؤ + هامش احتياطي؛ UNCERTAINTY = عدم اليقين؛ bootstrap the validation rows → interval for MAE and for the difference between models = أعد سحب صفوف التحقق ← مدى لـ MAE وللفرق بين النماذج.)


7. تدريب موجَّه

افتح L81_starter.ipynb.

  1. أعد بناء نماذج التوصيل الأربعة على تقسيم U18؛ واحسب MAE وMSE وRMSE وR² لنموذج واحد يدويًا، وتأكد منها باستخدام scikit-learn.
  2. ابنِ جدول المقاييس للنماذج الأربعة؛ واشرح في جملتين لماذا RMSE > MAE لكل نموذج.
  3. بيّن أن R² = 0 لمتوسط البيانات التي يجري تقييمها، وأن R² سالب لتخمين ثابت سيئ.
  4. احسب مئينات الأخطاء؛ وارسم مدرّجًا تكراريًا لأخطاء أفضل نموذج.
  5. احسب التكلفة غير المتماثلة لهوامش احتياطية قدرها 0 و0.25 و0.5 و0.75 و1 ساعة؛ أي هامش هو الأفضل على مجموعة التحقق؟
  6. استخدم bootstrap لحساب مدى 95% لـ MAE أفضل نموذج ولتحسنه على النموذج الخطي البسيط.
  7. شغّل Restart Kernel and Run All Cells….

8. تدريب مستقل

الجزء 1 — نموذجان لتحميل الشاحنات. يحتوي van_load_predictions.csv على دقائق التحميل الفعلية لـ 1,500 حمولة شاحنة، وتنبؤات نموذجين مرشحين هما A وB.

  1. احسب MAE وRMSE وR² للنموذجين، ومئينات الأخطاء (الوسيط، وP90، وP99، والأكبر).
  2. استخدم bootstrap لحساب مدى 95% للفرق في MAE وللفرق في RMSE (B − A).
  3. أي نموذج يفضّله MAE؟ وأيهما يفضّله RMSE؟ اشرح الاختلاف من توزيع الأخطاء.

الجزء 2 — قسم العمليات يعاقب التأخيرات الكبيرة بشدة. يقول مسؤول المستودع: "An occasional 25-minute surprise blocks the loading bay and delays a whole route; a few minutes either way do not matter." (أي: "مفاجأة عرضية مدتها 25 دقيقة تسد رصيف التحميل وتؤخر مسارًا كاملًا؛ أما بضع دقائق زيادة أو نقصانًا فلا تهم.") أوصِ بـ MAE أو RMSE للاختيار بين A وB، وبالنموذج، في 80 إلى 120 كلمة، مستخدمًا توزيع الأخطاء دليلًا.

اعمل في L81_starter.ipynb (الجزء 2).


9. اختبار الفهم (Knowledge Check) — مقاييس الانحدار

Q1. أي مقياس يعامل كل ساعة خطأ بالطريقة نفسها، مهما كان حجم الخطأ؟

  • A) RMSE، لأنه بوحدات الهدف نفسها
  • B) MSE، لأنه يأخذ متوسط كل مربعات الأخطاء بالتساوي
  • C) MAE، لأن كل ساعة خطأ تُحسب بالقدر نفسه
  • D) R²، لأنه يقارن النموذج بالمتوسط

Q2. لماذا يكون RMSE دائمًا مساويًا لـ MAE على الأقل؟

  • A) التربيع يعطي الأخطاء الكبيرة وزنًا أكبر، فلا يقل جذر متوسط المربعات أبدًا عن MAE
  • B) RMSE يستخدم صفوفًا أكثر من MAE، لأنه يحسب صفوف مجموعة التحقق أيضًا
  • C) RMSE يتضمن خطأ نموذج المقارنة، فيضيف أخطاء التنبؤ بالمتوسط أيضًا
  • D) إنه مجرد عُرف في scikit-learn؛ ومكتبات أخرى تعرض RMSE أقل من MAE

Q3. نموذج له R² = 0 على مجموعة التحقق. ماذا يعني ذلك؟

  • A) النموذج مثالي على صفوف التحقق، لأن أخطاءه تلغي بعضها
  • B) لم يبقَ في النموذج أي أخطاء يمكن أن يصلحها نموذج أعقد
  • C) MAE للنموذج صفر، فكل تنبؤ دقيق تمامًا
  • D) أداؤه ليس أفضل من التنبؤ بمتوسط هدف مجموعة التحقق

Q4. ماذا يعني R² السالب؟

  • A) خطأ في الكود، لأن R² لا يمكن أن يكون سالبًا أبدًا
  • B) النموذج أسوأ من التنبؤ بالمتوسط
  • C) النموذج يتنبأ بقيم سالبة لبعض الصفوف
  • D) النموذج يفرط في التكيّف مع مجموعة التحقق

Q5. لنموذجين MAE نفسه، لكن خطأ P99 للنموذج B أكبر بكثير. متى يجب أن تفضّل النموذج A؟

  • A) أبدًا: تساوي MAE يعني تساوي الجودة للعمل
  • B) فقط إذا كان R² للنموذج B أعلى منه للنموذج A
  • C) عندما تكون الأخطاء الكبيرة مكلفة بشكل خاص للعمل
  • D) فقط عندما تتفق مجموعة الاختبار مع النتيجة على مجموعة التحقق

Q6. التوصيلات المتأخرة تكلّف ثلاثة أضعاف المبكرة. ماذا يترتب على ذلك للوعد الذي تعطيه للعملاء؟

  • A) أضف هامشًا احتياطيًا إلى التنبؤ، يُحدَّد بتقليل التكلفة غير المتماثلة على مجموعة التحقق
  • B) استخدم التنبؤ الخام، لأنه يقلل MAE وبالتالي التكلفة الكلية أيضًا
  • C) قرّب التنبؤات دائمًا إلى الأسفل، حتى تبدو التوصيلات مبكرة
  • D) انتقل إلى R²، لأنه يعطي التوصيلات المتأخرة وزنًا أكبر

Q7. ماذا يعبّر مدى bootstrap لـ MAE في مجموعة التحقق؟

  • A) مدى أوقات التوصيل في بيانات التحقق، من الأقصر إلى الأطول
  • B) مقدار تغيّر MAE مع عينة مختلفة من توصيلات مشابهة
  • C) MAE في التدريب، مع هامش مضاف للبيانات الجديدة
  • D) نسبة الأخطاء التي تزيد على متوسط الخطأ

Q8. يقول مساعد ذكاء اصطناعي: "R² = 0.7 means 70% of predictions are correct" (أي: "R² = 0.7 يعني أن 70% من التنبؤات صحيحة"). ما الصحيح؟

  • A) هذا صحيح: 70% من التنبؤات داخل هامش الخطأ
  • B) R² = 0.7 يعني أن MAE يساوي 0.3 ساعة على بيانات التحقق
  • C) R² = 0.7: النموذج يزيل حوالي 70% من مربعات أخطاء نموذج المتوسط
  • D) R² هو نسبة الصفوف المستخدمة في التدريب، إذن 70% من الصفوف كانت صفوف تدريب

10. الذكاء الاصطناعي في التطبيق (اختياري، وفي حدود)

الهدف: أن تفحص شرحًا من الذكاء الاصطناعي لـ R² مقابل حساب فعلي.

  1. اسأل:

"Explain R² for a regression model to a business manager."

وبالعربية: "اشرح R² لنموذج انحدار لمدير في مجال الأعمال."

  1. اختبر كل ادعاء ببياناتك: احسب R² للتنبؤ بالمتوسط (يجب أن يكون 0 على بياناته نفسها) ولتخمين ثابت سيئ (سالب).
  2. صحّح أي ادعاء مثل "نسبة التنبؤات الصحيحة" أو "R² لا يمكن أن يكون سالبًا".

الحدود:

  • استخدام الذكاء الاصطناعي اختياري.
  • لا بيانات في الطلبات المكتوبة للذكاء الاصطناعي.
  • لا تُبقِ إلا الادعاءات التي يؤكدها دفترك.

11. التحقق من مخرجات الذكاء الاصطناعي

  1. التنبؤ بالمتوسط: R² لمتوسط البيانات التي يجري تقييمها = 0 (مع التقريب).
  2. R² السالب: أنتج قيمة سالبة واشرحها.
  3. فحص NumPy: أعد حساب MAE وRMSE وR² باستخدام NumPy لنموذج واحد.
  4. دوّن أي عبارة من الذكاء الاصطناعي صحّحتها.

12. منظور الأعمال

يجب أن يعكس المقياس ما تكلّفه الأخطاء للعمل، لا ما هو متعارف عليه. فالنموذج المختار بـ MAE قد ينتج ذلك الخطأ الكبير النادر الذي يسد رصيف التحميل؛ والنموذج المختار بـ R² قد يبدو ممتازًا ومع ذلك يخطئ بساعة. وترجمة الأخطاء إلى تكاليف (تأخير مقابل تبكير، صغير مقابل كبير) وعرض المدى يحوّلان عبارة "النموذج 0.54" إلى قرار: أي وعد نعطيه للعملاء، وكم هامشًا احتياطيًا يحتاج.


13. مهمة عمل — مذكرة اختيار المقياس

نشاط خيالي: Cedar Lane. يريد قسم المالية رقمًا واحدًا لمتابعة نموذج قيمة السلة من L76 كل شهر (كان MAE في التحقق حوالي 4.5 يورو لكل طلب، مقابل حوالي 12.9 يورو لنموذج المقارنة بمتوسط السلة؛ وRMSE أعلى قليلًا من MAE). اكتب مذكرة (من 80 إلى 120 كلمة): أي مقياس توصي به (MAE أو RMSE أو R²) ولماذا، باليورو، وماذا يعني ليوم فيه 100 طلب، وأي رقم ثانٍ ستراقبه معه.


14. تحدٍّ قصير — R² المبهر

نشاط خيالي: Cedar Lane. يبلّغ زميل: "R² = 0.76, the model explains 76% of delivery time, so 76% of promises will be right." (أي: "R² = 0.76، النموذج يفسّر 76% من وقت التوصيل، إذن 76% من الوعود ستكون صحيحة.")

best = pred["linear + over 14 km"]
within_30 = np.mean(np.abs(y_val.to_numpy() - best) <= 0.5)
print("R2:", round(r2_score(y_val, best), 3), "| share of deliveries predicted within 30 minutes:", round(within_30, 3))
R2: 0.762 | share of deliveries predicted within 30 minutes: 0.546

(الرقم الثاني معناه: نسبة التوصيلات التي تُنبِّئ بها بفارق 30 دقيقة أو أقل.)

  1. قبل أن تقرأ المخرجات، قل ما الذي يخبرك به R² وما الذي لا يخبرك به عن "صحة الوعود".
  2. ماذا يخبر الرقم الثاني قسم العمليات ولا يخبره به R²؟
  3. أعد كتابة جملة زميلك بحيث تصبح صحيحة.
  4. اكتب جملة واحدة يحتفظ بها فريقك كقاعدة لعرض نماذج الانحدار.

سلّم عملك قبل أن تتلقى الملاحظات. لا يوجد حل منشور هنا.


15. المصادر

مطلوب (حوالي 30 دقيقة):

  • scikit-learn: Metrics and scoring (1.9.1)، قسم مقاييس الانحدار: mean_absolute_error وmean_squared_error وroot_mean_squared_error وr2_score. https://scikit-learn.org/stable/modules/model_evaluation.html (فُتح في 25 أكتوبر 2026.)

موصى به:

  • OpenIntro: Introduction to Modern Statistics (الطبعة الثانية، مجانية على الإنترنت)، الفصول الخاصة بـ bootstrap وفترات الثقة. https://www.openintro.org/book/ims/ (فُتح في 25 أكتوبر 2026.)

16. شخصية تتابعها / قدوة

Andrew Ng (اختارته D.World للدروس L75 وL76 وL81 وL82).

  • حقيقة مُتحقَّق منها: مذكور في سجل القدوات في المرحلة 1 من D.World، R03، لتعليم الذكاء الاصطناعي وتعلّم الآلة؛ والصفحة الرئيسية لـ DeepLearning.AI تذكره مؤسسًا لها (فُتحت في 25 أكتوبر 2026).
  • لماذا توصي به D.World: تعليمه يؤكد اختيار مقياس تقييم واحد يعكس الهدف قبل مقارنة النماذج.
  • ملاحظة صادقة: لا نذكر إلا سجل D.World وما تقوله صفحة DeepLearning.AI.
  • جرّب هذا: ابحث عن مورد من DeepLearning.AI عن اختيار مقياس التقييم. ولخّص في جملة واحدة كيف يقترح التعامل مع مقياس ثانٍ "يجب ألّا يسوء".

17. المصطلحات

المصطلح معناه في هذا الدرس
MAE متوسط الخطأ المطلق (Mean absolute error): متوسط حجم الأخطاء، بوحدات الهدف
MSE متوسط مربعات الخطأ (Mean squared error): متوسط الخطأ المربّع؛ وتطغى فيه الأخطاء الكبيرة
RMSE جذر متوسط مربعات الخطأ (Root mean squared error): √MSE، بوحدات الهدف؛ و≥ MAE
R2 (R²) 1 − MSE(النموذج)/MSE(المتوسط): التحسن على التنبؤ بالمتوسط؛ ويمكن أن يكون سالبًا
توزيع الأخطاء (Error distribution) انتشار الأخطاء، ويوصف بالمئينات (الوسيط، وP90، وP99) والقيمة الكبرى
التكلفة غير المتماثلة (Asymmetric cost) تكلفة تختلف بحسب اتجاه الخطأ (تأخير مقابل تبكير)
مدى bootstrap (Bootstrap interval) مدى لمقياس ما ينتج عن إعادة حسابه على عينات كثيرة مسحوبة من صفوف التقييم

للمراجعة: MAE (L70) · bootstrap (L54) · المئينات (L52).


18. تأمّل

  1. في عملك، هل الأخطاء في اتجاه أكثر تكلفة منها في الاتجاه الآخر؟
  2. أي رقم واحد عن نموذج ستضعه على لوحة متابعة مدير، وأي رقم ستضيفه بجانبه؟
  3. متى رأيت R² مرتفعًا يُعرض كدليل على الفائدة؟

19. الخطوة التالية

التالي: L82 — مقاييس التصنيف: مصفوفة الالتباس، والدقة، والاستدعاء، وF1، والتكاليف (Classification Metrics: Confusion Matrix, Precision, Recall, F1 & Costs). السؤال نفسه لنماذج نعم/لا: أي الأخطاء تكلّف كم، وأي عتبة تقلل التكلفة؟


20. أدلة التقييم

الدليل ماذا يُظهر كيف يُقيَّم
مقارنة مقاييس تحميل الشاحنات + التوصية (التدريب المستقل) أربعة مقاييس ومئينات؛ ومدى bootstrap للفروق؛ وشرح اختلاف MAE وRMSE؛ واختيار المقياس من التكلفة المذكورة دليل التقييم L81-IP
الدفتر الموجَّه (المقاييس اليدوية، والجدول، ونموذج المقارنة في R²، والمئينات، والهامش الاحتياطي، وbootstrap) مقاييس صحيحة؛ وشرح R² السالب؛ واختيار الهامش على مجموعة التحقق دليل التقييم L81-GP
اختبار الفهم (Q1–Q8) تعريفات المقاييس؛ وR²؛ والذيول؛ والتكلفة غير المتماثلة؛ وbootstrap 7 إجابات صحيحة أو أكثر من 8
مهمة العمل والتحدي القصير اختيار المقياس لقسم المالية؛ وسوء قراءة R² دليلا التقييم L81-WT وL81-MC

المراجع

  1. scikit-learn developers. Metrics and scoring (1.9.1). https://scikit-learn.org/stable/modules/model_evaluation.html (SK-EVAL). يدعم: دوال مقاييس الانحدار.
  2. OpenIntro. Introduction to Modern Statistics, 2nd ed. https://www.openintro.org/book/ims/ (OI-IMS). يدعم: bootstrap وفترات الثقة.
  3. DeepLearning.AI. Home page. https://www.deeplearning.ai/ (DLAI). يدعم: سجل القدوة (R03).
  4. D.World Stage 4 Detailed Lesson Map v0.9 (صف L81). وثيقة داخلية.
L82 · Classification Metrics: Confusion Matrix, Precision, Recall, F1 & Costs About 3 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

L83 · Validation, Cross-Validation & Overfitting About 3 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

L84 · Leakage & Error Analysis About 3 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

L85 · Responsible ML: Fairness Basics, Documentation & Monitoring About 2.5 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

U19 Exit = Project 7 — Predictive ML Membersللمشتركين

The exit brief is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

تكليف نهاية الوحدة ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

U20 · Practical ML Workflowسير العمل العملي في تعلم الآلة

Stage 4المرحلة 4

Free: the first lesson. The other lessons, the exit brief and the practice files are for Starter and Membership.

مجاني: الدرس الأول. باقي الدروس وتكليف نهاية الوحدة وملفات التمرين لأصحاب باقة البداية والاشتراك.

Download U20 practice files (.zip, 237 KB)حمّل ملفات تمرين U20 (zip، 237 KB)

Unzip into a short folder such as D:\DWorld on Windows. The zip has only learner files: no answers.

فك الضغط في مجلد قصير مثل D:\DWorld على ويندوز. الملف يحتوي ملفات المتعلم فقط بدون إجابات.

L86 · Preprocessing Pipelines: ColumnTransformer & PipelineL86 · خطوط معالجة البيانات المسبقة: ColumnTransformer وPipeline About 3 hoursحوالي 3 ساعات Freeمجاني

L86 — Preprocessing Pipelines: ColumnTransformer & Pipeline

Learner file. Answers and model solutions are in a separate instructor-only file. Version: U20 Production v1 · Content date: 25 October 2026. Time estimates are planning estimates until learners have tested them. The code in this lesson was run with Python 3.13.16, pandas 3.0.5, NumPy 2.5.3 and scikit-learn 1.9.1 (recorded in D.World's internal Code Test Report); Python 3.13 is the accepted course version. Not run with Python 3.14 or inside JupyterLab.

All businesses are fictional and all data is synthetic.


1. Lesson Identity

Field Value
Title Preprocessing Pipelines: ColumnTransformer & Pipeline
Stage Stage 4 — Real Projects & Machine Learning
Unit U20 — Practical ML Workflow
Lesson ID L86
Skills Why pipelines (one object, no leakage, same steps at prediction time); SimpleImputer, OneHotEncoder (handle_unknown), StandardScaler; ColumnTransformer for numeric vs categorical columns; Pipeline steps; cross_validate on a pipeline; inspecting a fitted pipeline (get_feature_names_out); unseen categories at prediction time
Difficulty Intermediate
Estimated time About 3 hours (planning estimate, unvalidated)
Assessment level Practice / Application
Prerequisites U18–U19 (estimators, CV, leakage), L35 (missing values), L40 (encoding), L84 (leakage).

Time breakdown (planning estimate): concept and worked example 65 min · guided practice 40 min · independent practice 40 min · knowledge check 10 min · AI 5 min (optional) · workplace task and mini challenge 20 min.

What you need: practice_files (L86_starter.ipynb; u20_data/churn20.csv, u20_data/returns_orders.csv, u20_data/returns_new_orders.csv).

The U20 data. churn20.csv is a new version of the churn table with missing values (region, acquisition channel, basket) and three categorical columns; returns_orders.csv records whether an order was returned; returns_new_orders.csv contains next week's orders, without the outcome; colleague_experiment_log.csv is used in L88.


2. Learning Objective

By the end of this lesson, you will be able to:

  • build a scikit-learn Pipeline with a ColumnTransformer that imputes, encodes and scales mixed data;
  • cross-validate the whole pipeline and show that it prevents preprocessing leakage;
  • use the fitted pipeline on new rows, including missing values and categories it has never seen.

D.World approved objective (verbatim): Build a scikit-learn Pipeline with a ColumnTransformer that imputes, encodes and scales mixed data, and show that it prevents preprocessing leakage during cross-validation.


3. Why It Matters

Until now, preprocessing lived in separate notebook cells: fill missing values here, encode there, scale somewhere else, then fit. That works once. It breaks when the model must run again next month, on new rows, by someone else: a step is forgotten, applied in the wrong order, fitted on the wrong rows, or a new category crashes the encoder.

A Pipeline packs every step and the model into one object. You call fit once and predict once; inside cross-validation every step is refitted on the training folds only. The scikit-learn guide lists the three benefits: convenience, joint parameter selection, and safety: pipelines "help avoid leaking statistics from your test data into the trained model in cross-validation".

Key principle: put every learned preprocessing step and the model into one Pipeline, with a ColumnTransformer that treats each column type correctly. Cross-validate the whole pipeline, and use the same object to predict on new data.


4. Concept

import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, cross_validate, train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler

churn = pd.read_csv("u20_data/churn20.csv")
NUM = ["tenure_months", "app_user", "orders_90d", "orders_180d", "days_since_last", "avg_basket", "complaints_90d",
       "late_deliveries_90d", "discount_share"]
CAT = ["region", "acq_channel", "payment_method"]
print(churn.shape, "| churn rate", round(churn["churned_60d"].mean(), 3))
print("missing values:", churn.isna().sum()[lambda s: s > 0].to_dict())
X, y = churn[NUM + CAT], churn["churned_60d"]
X_dev, X_test, y_dev, y_test = train_test_split(X, y, test_size=0.20, random_state=42, stratify=y)
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
(6000, 14) | churn rate 0.22
missing values: {'region': 196, 'acq_channel': 112, 'avg_basket': 355}

Part A — The building blocks

Step Class What it learns in fit What transform does
Fill missing numbers SimpleImputer(strategy="median") the median of each column fills gaps with it
Fill missing categories SimpleImputer(strategy="most_frequent") the most common value fills gaps with it
One-hot encode OneHotEncoder(handle_unknown="ignore") the list of categories 0/1 columns; an unseen category becomes all zeros
Scale StandardScaler() mean and standard deviation (x − mean) / std

Each step learns something from the rows it is fitted on. That is exactly why it must only ever be fitted on training rows.

Part B — ColumnTransformer + Pipeline

A ColumnTransformer sends different columns to different preprocessing, then joins the results. A Pipeline chains named steps; all but the last must be transformers, the last is the model:

numeric = Pipeline([("impute", SimpleImputer(strategy="median")), ("scale", StandardScaler())])
categorical = Pipeline([("impute", SimpleImputer(strategy="most_frequent")),
                        ("onehot", OneHotEncoder(handle_unknown="ignore"))])
preprocess = ColumnTransformer([("num", numeric, NUM), ("cat", categorical, CAT)])
model = Pipeline([("prep", preprocess), ("clf", LogisticRegression(max_iter=1000))])
print(model)
Pipeline(steps=[('prep',
                 ColumnTransformer(transformers=[('num',
                                                  Pipeline(steps=[('impute',
                                                                   SimpleImputer(strategy='median')),
                                                                  ('scale',
                                                                   StandardScaler())]),
                                                  ['tenure_months', 'app_user',
                                                   'orders_90d', 'orders_180d',
                                                   'days_since_last',
                                                   'avg_basket',
                                                   'complaints_90d',
                                                   'late_deliveries_90d',
                                                   'discount_share']),
                                                 ('cat',
                                                  Pipeline(steps=[('impute',
                                                                   SimpleImputer(strategy='most_frequent')),
                                                                  ('onehot',
                                                                   OneHotEncoder(handle_unknown='ignore'))]),
                                                  ['region', 'acq_channel',
                                                   'payment_method'])])),
                ('clf', LogisticRegression(max_iter=1000))])

Parameters of any step are reached with step__parameter names, which L87 uses for tuning:

model.set_params(clf__C=0.5, prep__num__impute__strategy="mean")
print(model.get_params()["clf__C"], model.get_params()["prep__num__impute__strategy"])
model.set_params(clf__C=1.0, prep__num__impute__strategy="median")       # back to the defaults used below
0.5 mean

Part C — Cross-validate the pipeline vs a manual workflow

The manual way (as in many notebooks): impute, scale and encode all development rows first, then cross-validate only the model. Every preprocessing statistic has seen the validation folds:

manual = X_dev.copy()
manual[NUM] = manual[NUM].fillna(manual[NUM].median())                                  # median of ALL rows
manual[NUM] = (manual[NUM] - manual[NUM].mean()) / manual[NUM].std(ddof=0)              # scaled with ALL rows
manual = pd.get_dummies(manual.fillna({c: manual[c].mode()[0] for c in CAT}), columns=CAT, dtype=float)
leaky = cross_validate(LogisticRegression(max_iter=1000), manual, y_dev, cv=cv, scoring="roc_auc")["test_score"]
honest = cross_validate(model, X_dev, y_dev, cv=cv, scoring="roc_auc")["test_score"]
print("manual (preprocessed on all rows):", leaky.round(4), "| mean", round(leaky.mean(), 4))
print("pipeline (refitted in each fold): ", honest.round(4), "| mean", round(honest.mean(), 4))
manual (preprocessed on all rows): [0.7881 0.7705 0.8085 0.8015 0.8285] | mean 0.7994
pipeline (refitted in each fold):  [0.788  0.7705 0.8085 0.8015 0.8285] | mean 0.7994

The two means are almost identical here: medians, means and category lists barely change between training folds of 3,840 rows. That is typical for simple preprocessing on large data, and it is not a reason to keep the manual way. With small data, target-based encodings, feature selection or oversampling, the same mistake inflates scores a lot (the scikit-learn pitfalls page shows feature selection on all rows turning a random model's 0.5 accuracy into 0.76). The pipeline makes the honest procedure automatic, whatever the steps.

Part D — Inspect the fitted pipeline

model.fit(X_dev, y_dev)
names = model.named_steps["prep"].get_feature_names_out()
print(len(names), "columns after preprocessing")
print(names[:4].tolist(), "...", names[-4:].tolist())
print("medians learned for imputation (first 3):", model.named_steps["prep"].named_transformers_["num"].named_steps["impute"].statistics_[:3])
21 columns after preprocessing
['num__tenure_months', 'num__app_user', 'num__orders_90d', 'num__orders_180d'] ... ['cat__acq_channel_social', 'cat__payment_method_card', 'cat__payment_method_cash_on_delivery', 'cat__payment_method_wallet']
medians learned for imputation (first 3): [9. 0. 3.]

Part E — Predicting on new rows: missing values and unseen categories

Next month a new region, "Harbour", appears, and one customer has no basket value recorded:

new = pd.DataFrame([{"tenure_months": 2, "app_user": 0, "orders_90d": 2, "orders_180d": 2, "days_since_last": 40, "avg_basket": np.nan,
                     "complaints_90d": 1, "late_deliveries_90d": 0, "discount_share": 0.4,
                     "region": "Harbour", "acq_channel": "social", "payment_method": "card"}])
print("churn probability for the new customer:", round(float(model.predict_proba(new)[0, 1]), 3))
strict = Pipeline([("prep", ColumnTransformer([("num", numeric, NUM),
                                              ("cat", Pipeline([("impute", SimpleImputer(strategy="most_frequent")),
                                                                ("onehot", OneHotEncoder(handle_unknown="error"))]), CAT)])),
                   ("clf", LogisticRegression(max_iter=1000))]).fit(X_dev, y_dev)
try:
    strict.predict_proba(new)
except ValueError as e:
    print("with handle_unknown='error':", str(e).splitlines()[0][:90])
churn probability for the new customer: 0.468
with handle_unknown='error': Found unknown categories ['Harbour'] in column 0 during transform

With handle_unknown="ignore" the unseen region becomes all zeros (treated like "none of the known regions") and the missing basket is filled with the training median: the pipeline still answers. With "error", it refuses. Which is right is a business choice: a silent default is convenient, a loud error forces someone to look. Either way, monitor how often unseen categories appear (L85).


5. Worked Example

Cedar Lane (fictional), synthetic data. The retention team's churn model must now run every month on fresh data, which has missing values and occasionally new categories.

Step 1 — Columns: nine numeric (median imputation, scaling), three categorical (most-frequent imputation, one-hot with handle_unknown="ignore").

Step 2 — One object: Pipeline([("prep", ColumnTransformer(...)), ("clf", LogisticRegression())]) (Part B).

Step 3 — Honest CV: five stratified folds on the development data; every step refitted inside each fold (Part C): mean AUC about 0.80.

Step 4 — Inspection: 21 columns after preprocessing; imputation medians stored inside the object (Part D).

Step 5 — New data: an unseen region and a missing basket are handled (Part E); a monitoring KPI is added: share of rows with unseen categories per month.

Result for the team: "The model, its preprocessing and its settings are one file-ready object. Fitting and predicting are one line each, cross-validation is honest by construction, and new data with gaps or new regions will not crash it."


6. Visual Explanation

                         ┌─ num: [SimpleImputer(median) → StandardScaler]  ← 9 numeric columns
 raw table ─▶ ColumnTransformer
                         └─ cat: [SimpleImputer(most_frequent) → OneHotEncoder(handle_unknown="ignore")] ← 3 categorical
                                      │ joined: 21 columns
                                      ▼
                          LogisticRegression   = Pipeline("prep" → "clf")    params: clf__C, prep__num__impute__strategy
 cross_validate(Pipeline) → every step refitted on the training folds only (no statistics from validation rows)
 predict(new rows) → same medians, same categories, same scaling; unseen category → zeros (or an error, if you choose)

Alt text: A raw table enters a ColumnTransformer. Nine numeric columns go through a median imputer and a standard scaler; three categorical columns go through a most-frequent imputer and a one-hot encoder that ignores unknown categories. The results are joined into 21 columns and passed to logistic regression; together these form a Pipeline with steps named prep and clf, whose parameters are reached with names like clf__C. Cross-validating the pipeline refits every step on the training folds only. Predicting on new rows reuses the same medians, categories and scaling, and an unseen category becomes zeros or raises an error by choice.


7. Guided Practice

Open L86_starter.ipynb.

  1. Load churn20.csv; list the missing values and the column types.
  2. Build the numeric and categorical sub-pipelines, the ColumnTransformer and the full Pipeline; print it.
  3. Cross-validate the pipeline; reproduce the manual workflow and compare the scores. Write two sentences on why the difference is small here and why the pipeline is still required.
  4. Fit on the development data; print the number of output columns and the learned medians.
  5. Predict for a new customer with an unseen region and a missing value; repeat with handle_unknown="error" and record the message.
  6. Run Restart Kernel and Run All Cells….

8. Independent Practice

Part 1 — Returns model. returns_orders.csv records whether an order was returned. It has missing values (basket value, customer tenure), a categorical category with a rare value, and payment.

  1. Build a Pipeline with a ColumnTransformer suited to these columns; justify each imputation choice in one line.
  2. Split off a stratified test set; cross-validate the pipeline (ROC AUC) on the development data.
  3. Fit on the development data and predict return probabilities for returns_new_orders.csv, which contains a category the model has never seen. Confirm that no prediction fails, and count the rows with the unseen category.
  4. Print the transformed column names and check their number.

Part 2 — Package a colleague's notebook. A colleague's notebook does this in five cells:

cell 1: df["basket_value"] = df["basket_value"].fillna(df["basket_value"].mean())
cell 2: df["customer_tenure_months"] = df["customer_tenure_months"].fillna(0)
cell 3: df = pd.get_dummies(df, columns=["category", "payment"])
cell 4: df[num_cols] = StandardScaler().fit_transform(df[num_cols])
cell 5: X_train, X_test, ... = train_test_split(df, ...); model.fit(X_train, y_train)

Rewrite it as one Pipeline and explain, in 80–120 words, three problems the rewrite removes (think about which rows each step learns from, what happens with next week's orders, and the meaning of filling tenure with 0).

Work in L86_starter.ipynb (section "Independent practice").


9. Knowledge Check — Pipelines

Q1. What is the main safety benefit of a Pipeline in cross-validation?

  • A) It makes the model more accurate on the training data, because the steps are fitted together
  • B) Each preprocessing step is refitted on the training folds only, never on the validation fold
  • C) It removes the need for a separate test set, since every single fold is already validated once
  • D) It chooses the best model and the best preprocessing steps automatically for each fold

Q2. What does a ColumnTransformer do?

  • A) Applies different preprocessing to different columns and joins the results
  • B) Removes every column that contains missing values before the model is fitted
  • C) Converts all columns to text so one encoder can treat them alike
  • D) Splits the rows into cross-validation folds of equal size

Q3. A new category appears at prediction time. What does OneHotEncoder(handle_unknown="ignore") do?

  • A) Raises an error and stops the prediction run
  • B) Drops that row from the prediction output
  • C) Adds a new column during prediction
  • D) Encodes it as all zeros for that feature

Q4. How do you set the regularisation C of a pipeline step named "clf"?

  • A) model.C = 0.5
  • B) model.set_params(C=0.5)
  • C) model.set_params(clf__C=0.5)
  • D) It cannot be set once built

Q5. Preprocessing all rows before CV gave almost the same score as the pipeline here. What follows?

  • A) The manual way is fine in general, so pipelines are optional for imputation and scaling
  • B) Pipelines are only needed for small datasets, where each row has more influence
  • C) Leakage never matters with imputation, because medians barely change between folds
  • D) Here the effect was small; elsewhere it can be large, so keep the pipeline

Q6. Where are the medians used for imputation stored after fit?

  • A) Inside the fitted imputer (statistics_), which is inside the pipeline
  • B) In the CSV file, as an extra row written by fit
  • C) They are recomputed from the new rows each time predict is called on them
  • D) In the model's coefficients, next to the intercept

Q7. Why is fillna(0) for missing customer tenure risky?

  • A) It slows the model down, because zero values are slower to compute inside a pipeline
  • B) It invents a real-looking value (a brand-new customer), which can bias the model
  • C) Zero is not accepted as a value by scikit-learn models, so fitting would fail
  • D) It removes the column from the model when it is fitted

Q8. What should happen to the same Pipeline object at prediction time?

  • A) Refit it on the new rows first, so that the medians and categories match the new data
  • B) Rebuild the preprocessing by hand with the same steps and settings
  • C) Call predict_proba on the raw new rows; the fitted steps run in the same order
  • D) Only the model step is used; the preprocessing was needed only for training

10. AI in Practice (optional, bounded)

Goal: ask an AI assistant to write a ColumnTransformer for your columns, then check it.

  1. Give it the column names and types only (no data): "Write a scikit-learn ColumnTransformer and Pipeline for these columns, with imputation, one-hot encoding and scaling, and a logistic regression."
  2. Check: are the column lists correct and complete? Is handle_unknown set? Is anything fitted outside the pipeline (for example fit_transform on all data before CV)?
  3. Run it with cross_validate and compare with your own pipeline.

Boundaries: AI is optional; share names and types, not rows; every line you keep must run and be checked.


11. AI Verification

  1. Columns: print get_feature_names_out() and count the columns.
  2. Unseen category: predict on a row with a new category; it must not fail (if that is your choice).
  3. No outside fitting: search the code for fit_transform or fillna on the full data before CV.
  4. Write down what you changed in the AI's code.

12. Business Lens

Pipelines reduce errors when models move from a notebook to repeated use. The same object fits, cross-validates, predicts and can be saved (L88). That removes a whole class of "it worked in the notebook" failures: forgotten steps, steps fitted on the wrong rows, and crashes on new categories. It also makes the model reviewable: one printed object shows every step.


13. Workplace Task — The Handover Note

Fictional business: Cedar Lane. A colleague takes over the monthly churn run. Write a handover note (80–120 words): what the pipeline contains, what happens with missing values and unseen categories, which single object to use for predictions, and what to monitor.


14. Mini Challenge — The Silent Default

Fictional business: Cedar Lane. Next month 10% of customers come from a new acquisition channel, "partner".

batch = X_test.copy()
batch.iloc[: len(batch) // 10, batch.columns.get_loc("acq_channel")] = "partner"
p_new = model.predict_proba(batch)[:, 1]
p_old = model.predict_proba(X_test)[:, 1]
print("rows with the new channel:", len(batch) // 10, "| mean predicted churn, those rows: before", round(p_old[: len(batch) // 10].mean(), 3),
      "after", round(p_new[: len(batch) // 10].mean(), 3))
Output: open it after you have answered question 1
rows with the new channel: 120 | mean predicted churn, those rows: before 0.221 after 0.244

(This uses the test rows only to show behaviour, not to choose anything.)

  1. Before you open the output, predict what happens to these customers' scores when their channel is unknown to the model.
  2. Is the change in scores a problem? For which decisions?
  3. Propose a rule: when should an unseen category raise an error instead of being ignored?
  4. Write one sentence your team can keep as a rule about unseen categories.

Submit before feedback. No solution is provided here.


15. Resources

Required (about 30 min):

  • scikit-learn: Pipelines and composite estimators (1.9.1): convenience, joint parameter selection and safety; make_pipeline; step__parameter names; ColumnTransformer, make_column_transformer, remainder; get_feature_names_out. https://scikit-learn.org/stable/modules/compose.html (Opened 25 Oct 2026.)

Recommended:

  • scikit-learn: Preprocessing data (1.9.1): OneHotEncoder options including handle_unknown; StandardScaler. https://scikit-learn.org/stable/modules/preprocessing.html (Opened 25 Oct 2026.)
  • scikit-learn: Common pitfalls and recommended practices (1.9.1): the feature-selection leakage example and "the scikit-learn pipeline is a great way to prevent data leakage". https://scikit-learn.org/stable/common_pitfalls.html (Opened 25 Oct 2026.)

16. Person to Follow / Role Model

scikit-learn developers (organisational example; mapped by D.World for L84, L86–L89).

  • Verified fact: the scikit-learn user guide (1.9.1) documents common pitfalls, defines data leakage, and recommends pipelines to prevent it (pages opened 25 Oct 2026).
  • Why D.World recommends them: the composite-estimator guide is a model of clear, example-driven documentation for production habits.
  • Honest note: an organisational example; we quote only the documentation.
  • Try this: find the make_column_selector example on the compose page. Write one sentence on when selecting columns by type is safer than listing names, and when it is riskier.

17. Glossary

Term Meaning in this lesson
Pipeline One scikit-learn object chaining preprocessing steps and a final model, fitted and used as a unit
ColumnTransformer Applies different transformers to different columns and joins the outputs
Imputer A transformer that fills missing values with a learned value (median, most frequent…)
Transformer An object with fit and transform that learns from training rows and changes data
handle_unknown OneHotEncoder option for categories not seen in fit ("error", "ignore", …)
get_feature_names_out Returns the names of the columns a fitted transformer produces
step__parameter The naming rule for reaching a parameter of a step inside a pipeline

Review: missing values (L35) · encoding (L40) · leakage (L84).


18. Reflection

  1. Which notebook of yours would break first if run by someone else next month?
  2. In your data, which categories might appear later that the model has never seen?
  3. When would you rather have an error than a silent default?

19. Next Step

Next: L87 — Model Selection & Hyperparameter Tuning. With the whole workflow in one pipeline, you can search for the best settings of every step at once, honestly.


20. Assessment Evidence

Evidence What it shows How it is judged
Returns pipeline + CV + new-orders predictions; colleague rewrite (Independent Practice) Correct column routing and imputation choices; honest CV; unseen category handled; three problems explained Rubric L86-IP
Guided notebook (pipeline, manual vs pipeline CV, inspection, unseen category) Working pipeline; comparison explained; inspection Rubric L86-GP
Knowledge check (Q1–Q8) Safety; ColumnTransformer; handle_unknown; parameter names; inspection; prediction 7 or more of 8 correct
Workplace task and mini challenge Handover note; silent default Rubrics L86-WT, L86-MC

References

  1. scikit-learn developers. Pipelines and composite estimators (1.9.1). https://scikit-learn.org/stable/modules/compose.html (SK-COMP). Supports: pipeline benefits (quotation), ColumnTransformer, naming.
  2. scikit-learn developers. Preprocessing data (1.9.1). https://scikit-learn.org/stable/modules/preprocessing.html (SK-PRE).
  3. scikit-learn developers. Common pitfalls and recommended practices (1.9.1). https://scikit-learn.org/stable/common_pitfalls.html (SK-PIT). Supports: leakage example; role model.
  4. D.World Stage 4 Detailed Lesson Map v0.9 (L86 row). Internal.

L86 — خطوط معالجة البيانات المسبقة: ColumnTransformer وPipeline

ملف المتعلّم. الإجابات والحلول النموذجية في ملف منفصل خاص بالمدرّس فقط. الإصدار: U20 Production v1 · تاريخ المحتوى: 25 أكتوبر 2026. تقديرات الوقت تقديرات للتخطيط إلى أن يختبرها المتعلّمون. الكود في هذا الدرس شُغّل باستخدام Python 3.13.16 وpandas 3.0.5 وNumPy 2.5.3 وscikit-learn 1.9.1 (مسجّلة في تقرير اختبار الكود الداخلي في D.World)؛ وPython 3.13 هو الإصدار المعتمد في الدورة. ولم يُشغَّل باستخدام Python 3.14 ولا داخل JupyterLab.

كل الأنشطة التجارية خيالية، وكل البيانات مصطنعة.


1. بطاقة الدرس

البند القيمة
العنوان خطوط معالجة البيانات المسبقة: ColumnTransformer وPipeline
المرحلة المرحلة 4 — مشاريع حقيقية وتعلّم الآلة
الوحدة U20 — سير العمل العملي في تعلّم الآلة
رقم الدرس L86
المهارات لماذا خطوط المعالجة (كائن واحد، بلا تسرّب، والخطوات نفسها وقت التنبؤ)؛ SimpleImputer وOneHotEncoder (handle_unknown) وStandardScaler؛ ColumnTransformer للأعمدة الرقمية مقابل الفئوية؛ خطوات Pipeline؛ cross_validate على خط معالجة؛ فحص خط معالجة مدرَّب (get_feature_names_out)؛ الفئات غير المرئية وقت التنبؤ
المستوى متوسط
الوقت المتوقع حوالي 3 ساعات (تقدير للتخطيط، غير مُتحقَّق منه)
مستوى التقييم تدريب / تطبيق
المتطلبات السابقة U18–U19 (المقدّرات، والتحقق المتقاطع، والتسرّب)، وL35 (القيم المفقودة)، وL40 (الترميز)، وL84 (التسرّب).

تفصيل الوقت (تقدير للتخطيط):

  • المفهوم والمثال المحلول: 65 دقيقة.
  • التدريب الموجَّه: 40 دقيقة.
  • التدريب المستقل: 40 دقيقة.
  • اختبار الفهم: 10 دقائق.
  • الذكاء الاصطناعي: 5 دقائق (اختياري).
  • مهمة العمل والتحدي القصير: 20 دقيقة.

ما تحتاج إليه: مجلد practice_files (L86_starter.ipynb؛ وu20_data/churn20.csv وu20_data/returns_orders.csv وu20_data/returns_new_orders.csv).

بيانات U20. churn20.csv نسخة جديدة من جدول تسرّب العملاء فيها قيم مفقودة (المنطقة، وقناة الاستقطاب، والسلة) وثلاثة أعمدة فئوية؛ وreturns_orders.csv يسجّل هل أُرجع الطلب؛ وreturns_new_orders.csv فيه طلبات الأسبوع القادم، دون النتيجة؛ وcolleague_experiment_log.csv يُستخدم في L88.


2. هدف التعلّم

في نهاية هذا الدرس ستكون قادرًا على أن:

  • تبني خط معالجة Pipeline في scikit-learn مع ColumnTransformer يملأ القيم المفقودة ويرمّز ويوحّد مقياس البيانات المختلطة؛
  • تجري التحقق المتقاطع على خط المعالجة كله، وتبيّن أنه يمنع التسرّب في المعالجة المسبقة؛
  • تستخدم خط المعالجة المدرَّب على صفوف جديدة، بما فيها قيم مفقودة وفئات لم يرها من قبل.

الهدف المعتمد من D.World (بنصّه): Build a scikit-learn Pipeline with a ColumnTransformer that imputes, encodes and scales mixed data, and show that it prevents preprocessing leakage during cross-validation.


3. لماذا يهمّك هذا؟

حتى الآن، كانت المعالجة المسبقة (preprocessing) موزّعة على خلايا منفصلة في الدفتر: املأ القيم المفقودة هنا، ورمّز هناك، ووحّد المقياس في مكان آخر، ثم درّب. هذا ينجح مرة واحدة. لكنه ينهار عندما يجب أن يعمل النموذج مرة أخرى الشهر القادم، على صفوف جديدة، على يد شخص آخر: تُنسى خطوة، أو تُطبّق بترتيب خاطئ، أو تُدرَّب على الصفوف الخطأ، أو تتسبب فئة جديدة في تعطّل المرمّز.

خط المعالجة Pipeline يجمع كل الخطوات والنموذج في كائن واحد. تستدعي fit مرة وpredict مرة؛ وداخل التحقق المتقاطع تُعاد ملاءمة كل خطوة على طيّات التدريب فقط. ويذكر دليل scikit-learn ثلاث فوائد: السهولة، واختيار المعاملات معًا، والأمان: فخطوط المعالجة "help avoid leaking statistics from your test data into the trained model in cross-validation" (أي: "تساعد على تجنب تسرّب الإحصاءات من بيانات الاختبار إلى النموذج المدرَّب أثناء التحقق المتقاطع").

المبدأ الأساسي: ضع كل خطوة معالجة مسبقة تتعلم من البيانات، ومعها النموذج، في Pipeline واحد، مع ColumnTransformer يعامل كل نوع من الأعمدة بالشكل الصحيح. وأجرِ التحقق المتقاطع على خط المعالجة كله، واستخدم الكائن نفسه للتنبؤ على البيانات الجديدة.


4. المفهوم

import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import StratifiedKFold, cross_validate, train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler

churn = pd.read_csv("u20_data/churn20.csv")
NUM = ["tenure_months", "app_user", "orders_90d", "orders_180d", "days_since_last", "avg_basket", "complaints_90d",
       "late_deliveries_90d", "discount_share"]
CAT = ["region", "acq_channel", "payment_method"]
print(churn.shape, "| churn rate", round(churn["churned_60d"].mean(), 3))
print("missing values:", churn.isna().sum()[lambda s: s > 0].to_dict())
X, y = churn[NUM + CAT], churn["churned_60d"]
X_dev, X_test, y_dev, y_test = train_test_split(X, y, test_size=0.20, random_state=42, stratify=y)
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
(6000, 14) | churn rate 0.22
missing values: {'region': 196, 'acq_channel': 112, 'avg_basket': 355}

الجزء A — اللبنات الأساسية

الخطوة الصنف (Class) ماذا تتعلم في fit ماذا يفعل transform
ملء الأرقام المفقودة SimpleImputer(strategy="median") وسيط كل عمود يملأ الفجوات به
ملء الفئات المفقودة SimpleImputer(strategy="most_frequent") القيمة الأكثر شيوعًا يملأ الفجوات بها
الترميز الأحادي (One-hot) OneHotEncoder(handle_unknown="ignore") قائمة الفئات أعمدة 0/1؛ والفئة غير المرئية تصبح أصفارًا كلها
توحيد المقياس StandardScaler() المتوسط والانحراف المعياري (x − المتوسط) / الانحراف المعياري

كل خطوة تتعلم شيئًا من الصفوف التي تُدرَّب عليها. ولهذا بالضبط يجب ألّا تُدرَّب أبدًا إلا على صفوف التدريب.

الجزء B — ColumnTransformer + Pipeline

ColumnTransformer يرسل أعمدة مختلفة إلى معالجات مسبقة مختلفة، ثم يجمع النتائج. وPipeline يربط خطوات مسمّاة في سلسلة؛ وكلها ما عدا الأخيرة يجب أن تكون محوّلات (transformers)، والأخيرة هي النموذج:

numeric = Pipeline([("impute", SimpleImputer(strategy="median")), ("scale", StandardScaler())])
categorical = Pipeline([("impute", SimpleImputer(strategy="most_frequent")),
                        ("onehot", OneHotEncoder(handle_unknown="ignore"))])
preprocess = ColumnTransformer([("num", numeric, NUM), ("cat", categorical, CAT)])
model = Pipeline([("prep", preprocess), ("clf", LogisticRegression(max_iter=1000))])
print(model)
Pipeline(steps=[('prep',
                 ColumnTransformer(transformers=[('num',
                                                  Pipeline(steps=[('impute',
                                                                   SimpleImputer(strategy='median')),
                                                                  ('scale',
                                                                   StandardScaler())]),
                                                  ['tenure_months', 'app_user',
                                                   'orders_90d', 'orders_180d',
                                                   'days_since_last',
                                                   'avg_basket',
                                                   'complaints_90d',
                                                   'late_deliveries_90d',
                                                   'discount_share']),
                                                 ('cat',
                                                  Pipeline(steps=[('impute',
                                                                   SimpleImputer(strategy='most_frequent')),
                                                                  ('onehot',
                                                                   OneHotEncoder(handle_unknown='ignore'))]),
                                                  ['region', 'acq_channel',
                                                   'payment_method'])])),
                ('clf', LogisticRegression(max_iter=1000))])

يُوصل إلى معاملات أي خطوة بأسماء على صيغة step__parameter، وسيستخدمها L87 في الضبط:

model.set_params(clf__C=0.5, prep__num__impute__strategy="mean")
print(model.get_params()["clf__C"], model.get_params()["prep__num__impute__strategy"])
model.set_params(clf__C=1.0, prep__num__impute__strategy="median")       # back to the defaults used below
0.5 mean

(التعليق في الكود معناه: "العودة إلى القيم الافتراضية المستخدمة أدناه".)

الجزء C — التحقق المتقاطع على خط المعالجة مقابل سير عمل يدوي

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

manual = X_dev.copy()
manual[NUM] = manual[NUM].fillna(manual[NUM].median())                                  # median of ALL rows
manual[NUM] = (manual[NUM] - manual[NUM].mean()) / manual[NUM].std(ddof=0)              # scaled with ALL rows
manual = pd.get_dummies(manual.fillna({c: manual[c].mode()[0] for c in CAT}), columns=CAT, dtype=float)
leaky = cross_validate(LogisticRegression(max_iter=1000), manual, y_dev, cv=cv, scoring="roc_auc")["test_score"]
honest = cross_validate(model, X_dev, y_dev, cv=cv, scoring="roc_auc")["test_score"]
print("manual (preprocessed on all rows):", leaky.round(4), "| mean", round(leaky.mean(), 4))
print("pipeline (refitted in each fold): ", honest.round(4), "| mean", round(honest.mean(), 4))
manual (preprocessed on all rows): [0.7881 0.7705 0.8085 0.8015 0.8285] | mean 0.7994
pipeline (refitted in each fold):  [0.788  0.7705 0.8085 0.8015 0.8285] | mean 0.7994

(التعليقان في الكود معناهما: "وسيط كل الصفوف"، و"توحيد المقياس بكل الصفوف". والسطران المطبوعان: يدوي (معالجة مسبقة على كل الصفوف)، وخط معالجة (يُعاد تدريبه في كل طيّة).)

المتوسطان متطابقان تقريبًا هنا: فالوسيطات والمتوسطات وقوائم الفئات بالكاد تتغير بين طيّات تدريب فيها 3,840 صفًا. وهذا معتاد مع المعالجة المسبقة البسيطة على بيانات كبيرة، وليس سببًا للإبقاء على الطريقة اليدوية. فمع البيانات الصغيرة، أو الترميز المعتمد على الهدف، أو اختيار الخصائص، أو زيادة العينات (oversampling)، يضخّم الخطأ نفسه الدرجات كثيرًا (صفحة الأخطاء الشائعة في scikit-learn تعرض كيف يحوّل اختيار الخصائص على كل الصفوف دقة 0.5 لنموذج عشوائي إلى 0.76). وخط المعالجة يجعل الإجراء الأمين تلقائيًا، أيًّا كانت الخطوات.

الجزء D — افحص خط المعالجة المدرَّب

model.fit(X_dev, y_dev)
names = model.named_steps["prep"].get_feature_names_out()
print(len(names), "columns after preprocessing")
print(names[:4].tolist(), "...", names[-4:].tolist())
print("medians learned for imputation (first 3):", model.named_steps["prep"].named_transformers_["num"].named_steps["impute"].statistics_[:3])
21 columns after preprocessing
['num__tenure_months', 'num__app_user', 'num__orders_90d', 'num__orders_180d'] ... ['cat__acq_channel_social', 'cat__payment_method_card', 'cat__payment_method_cash_on_delivery', 'cat__payment_method_wallet']
medians learned for imputation (first 3): [9. 0. 3.]

(المطبوع: 21 عمودًا بعد المعالجة المسبقة؛ والوسيطات التي تعلّمها ملء القيم (أول 3).)

الجزء E — التنبؤ على صفوف جديدة: قيم مفقودة وفئات غير مرئية

في الشهر القادم تظهر منطقة جديدة اسمها "Harbour"، وعميل لم تُسجَّل له قيمة سلة:

new = pd.DataFrame([{"tenure_months": 2, "app_user": 0, "orders_90d": 2, "orders_180d": 2, "days_since_last": 40, "avg_basket": np.nan,
                     "complaints_90d": 1, "late_deliveries_90d": 0, "discount_share": 0.4,
                     "region": "Harbour", "acq_channel": "social", "payment_method": "card"}])
print("churn probability for the new customer:", round(float(model.predict_proba(new)[0, 1]), 3))
strict = Pipeline([("prep", ColumnTransformer([("num", numeric, NUM),
                                              ("cat", Pipeline([("impute", SimpleImputer(strategy="most_frequent")),
                                                                ("onehot", OneHotEncoder(handle_unknown="error"))]), CAT)])),
                   ("clf", LogisticRegression(max_iter=1000))]).fit(X_dev, y_dev)
try:
    strict.predict_proba(new)
except ValueError as e:
    print("with handle_unknown='error':", str(e).splitlines()[0][:90])
churn probability for the new customer: 0.468
with handle_unknown='error': Found unknown categories ['Harbour'] in column 0 during transform

(السطر الأول: احتمال تسرّب العميل الجديد. والثاني رسالة الخطأ: "وُجدت فئات غير معروفة ['Harbour'] في العمود 0 أثناء التحويل".)

مع handle_unknown="ignore" تصبح المنطقة غير المرئية أصفارًا كلها (تُعامل كأنها "ليست أيًّا من المناطق المعروفة")، وتُملأ السلة المفقودة بوسيط التدريب: فيظل خط المعالجة يجيب. ومع "error" يرفض. وأيهما الصحيح قرار عمل: فالقيمة الافتراضية الصامتة مريحة، والخطأ الصريح يجبر أحدًا على النظر. وفي الحالتين، راقب عدد مرات ظهور الفئات غير المرئية (L85).


5. مثال محلول

Cedar Lane (خيالية)، بيانات مصطنعة. يجب الآن أن يعمل نموذج تسرّب العملاء لفريق الاحتفاظ كل شهر على بيانات جديدة، فيها قيم مفقودة وأحيانًا فئات جديدة.

الخطوة 1 — الأعمدة: تسعة رقمية (ملء بالوسيط، وتوحيد للمقياس)، وثلاثة فئوية (ملء بالأكثر تكرارًا، وترميز أحادي مع handle_unknown="ignore").

الخطوة 2 — كائن واحد: Pipeline([("prep", ColumnTransformer(...)), ("clf", LogisticRegression())]) (الجزء B).

الخطوة 3 — تحقق متقاطع أمين: خمس طيّات طبقية على بيانات التطوير؛ وتُعاد ملاءمة كل خطوة داخل كل طيّة (الجزء C): متوسط AUC حوالي 0.80.

الخطوة 4 — الفحص: 21 عمودًا بعد المعالجة المسبقة؛ ووسيطات الملء محفوظة داخل الكائن (الجزء D).

الخطوة 5 — البيانات الجديدة: تُعالَج منطقة غير مرئية وسلة مفقودة (الجزء E)؛ ويُضاف مؤشر للمراقبة: نسبة الصفوف التي فيها فئات غير مرئية كل شهر.

النتيجة للفريق: "The model, its preprocessing and its settings are one file-ready object. Fitting and predicting are one line each, cross-validation is honest by construction, and new data with gaps or new regions will not crash it." (أي: "النموذج ومعالجته المسبقة وإعداداته كائن واحد جاهز للحفظ في ملف. والتدريب والتنبؤ سطر واحد لكل منهما، والتحقق المتقاطع أمين بطبيعة البناء، والبيانات الجديدة التي فيها فجوات أو مناطق جديدة لن تعطّله.")


6. شرح بصري

                         ┌─ num: [SimpleImputer(median) → StandardScaler]  ← 9 numeric columns
 raw table ─▶ ColumnTransformer
                         └─ cat: [SimpleImputer(most_frequent) → OneHotEncoder(handle_unknown="ignore")] ← 3 categorical
                                      │ joined: 21 columns
                                      ▼
                          LogisticRegression   = Pipeline("prep" → "clf")    params: clf__C, prep__num__impute__strategy
 cross_validate(Pipeline) → every step refitted on the training folds only (no statistics from validation rows)
 predict(new rows) → same medians, same categories, same scaling; unseen category → zeros (or an error, if you choose)

وصف الرسم: جدول خام يدخل ColumnTransformer. تمر تسعة أعمدة رقمية بأداة ملء بالوسيط ثم بموحّد للمقياس؛ وتمر ثلاثة أعمدة فئوية بأداة ملء بالأكثر تكرارًا ثم بمرمّز أحادي يتجاهل الفئات غير المعروفة. وتُجمع النتائج في 21 عمودًا وتُمرَّر إلى الانحدار اللوجستي؛ ومعًا تكوّن Pipeline بخطوتين اسمهما prep وclf، ويُوصل إلى معاملاتهما بأسماء مثل clf__C. والتحقق المتقاطع على خط المعالجة يعيد ملاءمة كل خطوة على طيّات التدريب فقط. والتنبؤ على صفوف جديدة يعيد استخدام الوسيطات والفئات وتوحيد المقياس نفسها، والفئة غير المرئية تصبح أصفارًا أو تثير خطأً حسب اختيارك. (نصوص الرسم: raw table = جدول خام؛ 9 numeric columns = 9 أعمدة رقمية؛ 3 categorical = 3 فئوية؛ joined: 21 columns = مجمّعة: 21 عمودًا؛ params = المعاملات؛ every step refitted on the training folds only (no statistics from validation rows) = كل خطوة تُعاد ملاءمتها على طيّات التدريب فقط (لا إحصاءات من صفوف التحقق)؛ predict(new rows) = التنبؤ (صفوف جديدة)؛ same medians, same categories, same scaling = الوسيطات نفسها، والفئات نفسها، وتوحيد المقياس نفسه؛ unseen category → zeros (or an error, if you choose) = فئة غير مرئية ← أصفار (أو خطأ، إذا اخترت ذلك).)


7. تدريب موجَّه

افتح L86_starter.ipynb.

  1. حمّل churn20.csv؛ واسرد القيم المفقودة وأنواع الأعمدة.
  2. ابنِ خطَّي المعالجة الفرعيين للأعمدة الرقمية والفئوية، وColumnTransformer، وPipeline الكامل؛ واطبعه.
  3. أجرِ التحقق المتقاطع على خط المعالجة؛ وأعد إنتاج سير العمل اليدوي وقارن الدرجات. واكتب جملتين عن سبب صغر الفرق هنا، وسبب بقاء خط المعالجة ضروريًا.
  4. درّب على بيانات التطوير؛ واطبع عدد أعمدة المخرجات والوسيطات التي تعلّمها.
  5. تنبّأ لعميل جديد بمنطقة غير مرئية وقيمة مفقودة؛ ثم كرّر مع handle_unknown="error" وسجّل الرسالة.
  6. شغّل Restart Kernel and Run All Cells….

8. تدريب مستقل

الجزء 1 — نموذج المرتجعات. يسجّل returns_orders.csv هل أُرجع الطلب. وفيه قيم مفقودة (قيمة السلة، ومدة تعامل العميل)، وعمود فئوي category فيه قيمة نادرة، وعمود payment.

  1. ابنِ Pipeline مع ColumnTransformer يناسب هذه الأعمدة؛ وبرّر كل اختيار لطريقة الملء في سطر واحد.
  2. افصل مجموعة اختبار طبقية؛ وأجرِ التحقق المتقاطع على خط المعالجة (ROC AUC) على بيانات التطوير.
  3. درّب على بيانات التطوير وتنبّأ باحتمالات الإرجاع لـ returns_new_orders.csv، الذي يحتوي فئة لم يرها النموذج قط. وتأكد من أن أي تنبؤ لا يفشل، واحسب عدد الصفوف التي فيها الفئة غير المرئية.
  4. اطبع أسماء الأعمدة بعد التحويل وتحقق من عددها.

الجزء 2 — حزّم دفتر زميل. دفتر زميل يفعل هذا في خمس خلايا:

cell 1: df["basket_value"] = df["basket_value"].fillna(df["basket_value"].mean())
cell 2: df["customer_tenure_months"] = df["customer_tenure_months"].fillna(0)
cell 3: df = pd.get_dummies(df, columns=["category", "payment"])
cell 4: df[num_cols] = StandardScaler().fit_transform(df[num_cols])
cell 5: X_train, X_test, ... = train_test_split(df, ...); model.fit(X_train, y_train)

أعد كتابته في صورة Pipeline واحد، واشرح في 80 إلى 120 كلمة ثلاث مشكلات تزيلها إعادة الكتابة (فكّر في الصفوف التي تتعلم منها كل خطوة، وما يحدث مع طلبات الأسبوع القادم، ومعنى ملء مدة التعامل بـ 0).

اعمل في L86_starter.ipynb (قسم "Independent practice").


9. اختبار الفهم (Knowledge Check) — خطوط المعالجة

Q1. ما فائدة الأمان الرئيسية لـ Pipeline في التحقق المتقاطع؟

  • A) يجعل النموذج أدق على بيانات التدريب، لأن الخطوات تُدرَّب معًا
  • B) كل خطوة معالجة مسبقة تُعاد ملاءمتها على طيّات التدريب فقط، ولا تُلاءم أبدًا على طيّة التحقق
  • C) يلغي الحاجة إلى مجموعة اختبار منفصلة، لأن كل طيّة تُستخدم للتحقق مرة بالفعل
  • D) يختار أفضل نموذج وأفضل خطوات معالجة تلقائيًا لكل طيّة

Q2. ماذا يفعل ColumnTransformer؟

  • A) يطبّق معالجة مسبقة مختلفة على أعمدة مختلفة ويجمع النتائج
  • B) يحذف كل عمود فيه قيم مفقودة قبل تدريب النموذج
  • C) يحوّل كل الأعمدة إلى نص حتى يعاملها مرمّز واحد بالطريقة نفسها
  • D) يقسّم الصفوف إلى طيّات تحقق متقاطع متساوية الحجم

Q3. تظهر فئة جديدة وقت التنبؤ. ماذا يفعل OneHotEncoder(handle_unknown="ignore")؟

  • A) يثير خطأً ويوقف عملية التنبؤ
  • B) يحذف ذلك الصف من مخرجات التنبؤ
  • C) يضيف عمودًا جديدًا أثناء التنبؤ
  • D) يرمّزها أصفارًا كلها لتلك الخاصية

Q4. كيف تضبط معامل التنظيم C لخطوة في خط المعالجة اسمها "clf"؟

  • A) model.C = 0.5
  • B) model.set_params(C=0.5)
  • C) model.set_params(clf__C=0.5)
  • D) لا يمكن ضبطه بعد البناء

Q5. المعالجة المسبقة لكل الصفوف قبل التحقق المتقاطع أعطت هنا تقريبًا الدرجة نفسها التي أعطاها خط المعالجة. ماذا يترتب على ذلك؟

  • A) الطريقة اليدوية مقبولة بشكل عام، لذلك خطوط المعالجة اختيارية للملء وتوحيد المقياس
  • B) خطوط المعالجة مطلوبة فقط لمجموعات البيانات الصغيرة، حيث يكون لكل صف تأثير أكبر
  • C) التسرّب لا يهم أبدًا مع الملء، لأن الوسيطات بالكاد تتغير بين الطيّات
  • D) هنا كان الأثر صغيرًا؛ وفي مواضع أخرى قد يكون كبيرًا، فاحتفظ بخط المعالجة

Q6. أين تُحفظ الوسيطات المستخدمة في الملء بعد fit؟

  • A) داخل أداة الملء المدرَّبة (statistics_)، الموجودة داخل خط المعالجة
  • B) في ملف CSV، كصف إضافي يكتبه fit
  • C) يُعاد حسابها من الصفوف الجديدة في كل مرة يُستدعى فيها predict عليها
  • D) في معاملات النموذج، بجانب الحد الثابت

Q7. لماذا يكون fillna(0) لمدة تعامل العميل المفقودة أمرًا محفوفًا بالمخاطر؟

  • A) يبطئ النموذج، لأن القيم الصفرية أبطأ في الحساب داخل خط المعالجة
  • B) يخترع قيمة تبدو حقيقية (عميل جديد تمامًا)، وهذا قد يحرف النموذج
  • C) نماذج scikit-learn لا تقبل الصفر كقيمة، فيفشل التدريب
  • D) يحذف العمود من النموذج عند تدريبه

Q8. ماذا يجب أن يحدث لكائن Pipeline نفسه وقت التنبؤ؟

  • A) أعد تدريبه على الصفوف الجديدة أولًا، حتى تطابق الوسيطات والفئات البيانات الجديدة
  • B) أعد بناء المعالجة المسبقة يدويًا بالخطوات والإعدادات نفسها
  • C) استدعِ predict_proba على الصفوف الجديدة الخام؛ فتعمل الخطوات المدرَّبة بالترتيب نفسه
  • D) تُستخدم خطوة النموذج فقط؛ فالمعالجة المسبقة كانت مطلوبة للتدريب فقط

10. الذكاء الاصطناعي في التطبيق (اختياري، وفي حدود)

الهدف: أن تطلب من مساعد ذكاء اصطناعي كتابة ColumnTransformer لأعمدتك، ثم تفحصه.

  1. أعطه أسماء الأعمدة وأنواعها فقط (بلا بيانات):

"Write a scikit-learn ColumnTransformer and Pipeline for these columns, with imputation, one-hot encoding and scaling, and a logistic regression."

وبالعربية: "اكتب ColumnTransformer وPipeline في scikit-learn لهذه الأعمدة، مع ملء القيم المفقودة، والترميز الأحادي، وتوحيد المقياس، وانحدار لوجستي."

  1. افحص: هل قوائم الأعمدة صحيحة وكاملة؟ هل ضُبط handle_unknown؟ هل يُدرَّب أي شيء خارج خط المعالجة (مثل fit_transform على كل البيانات قبل التحقق المتقاطع)؟
  2. شغّله مع cross_validate وقارنه بخط المعالجة الخاص بك.

الحدود:

  • استخدام الذكاء الاصطناعي اختياري.
  • شارك الأسماء والأنواع، لا الصفوف.
  • كل سطر تحتفظ به يجب أن يعمل وأن يُفحص.

11. التحقق من مخرجات الذكاء الاصطناعي

  1. الأعمدة: اطبع get_feature_names_out() واحسب عدد الأعمدة.
  2. الفئة غير المرئية: تنبّأ على صف فيه فئة جديدة؛ ويجب ألّا يفشل (إن كان هذا اختيارك).
  3. لا تدريب في الخارج: ابحث في الكود عن fit_transform أو fillna على البيانات الكاملة قبل التحقق المتقاطع.
  4. دوّن ما غيّرته في كود الذكاء الاصطناعي.

12. منظور الأعمال

خطوط المعالجة تقلل الأخطاء عندما تنتقل النماذج من الدفتر إلى الاستخدام المتكرر. فالكائن نفسه يُدرَّب، ويُجرى عليه التحقق المتقاطع، ويتنبأ، ويمكن حفظه (L88). وهذا يزيل فئة كاملة من أعطال "كان يعمل في الدفتر": خطوات منسية، وخطوات دُرّبت على الصفوف الخطأ، وتعطّل بسبب فئات جديدة. ويجعل النموذج قابلًا للمراجعة أيضًا: فكائن واحد مطبوع يُظهر كل الخطوات.


13. مهمة عمل — مذكرة التسليم

نشاط خيالي: Cedar Lane. يتسلّم زميل عملية التشغيل الشهرية لنموذج تسرّب العملاء. اكتب مذكرة تسليم (من 80 إلى 120 كلمة): ماذا يحتوي خط المعالجة، وماذا يحدث مع القيم المفقودة والفئات غير المرئية، وأي كائن واحد يُستخدم للتنبؤات، وماذا يجب أن يُراقب.


14. تحدٍّ قصير — القيمة الافتراضية الصامتة

نشاط خيالي: Cedar Lane. في الشهر القادم يأتي 10% من العملاء من قناة استقطاب جديدة اسمها "partner" (شريك).

batch = X_test.copy()
batch.iloc[: len(batch) // 10, batch.columns.get_loc("acq_channel")] = "partner"
p_new = model.predict_proba(batch)[:, 1]
p_old = model.predict_proba(X_test)[:, 1]
print("rows with the new channel:", len(batch) // 10, "| mean predicted churn, those rows: before", round(p_old[: len(batch) // 10].mean(), 3),
      "after", round(p_new[: len(batch) // 10].mean(), 3))
المخرجات: افتحها بعد أن تجيب عن السؤال 1
rows with the new channel: 120 | mean predicted churn, those rows: before 0.221 after 0.244

(المطبوع: عدد الصفوف بالقناة الجديدة؛ ومتوسط التسرّب المتنبأ به لتلك الصفوف قبل وبعد.)

(هذا يستخدم صفوف الاختبار فقط لإظهار السلوك، لا لاختيار أي شيء.)

  1. قبل أن تفتح المخرجات، توقّع ماذا يحدث لدرجات هؤلاء العملاء عندما تكون قناتهم غير معروفة للنموذج.
  2. هل التغير في الدرجات مشكلة؟ ولأي قرارات؟
  3. اقترح قاعدة: متى يجب أن تثير الفئة غير المرئية خطأً بدلًا من تجاهلها؟
  4. اكتب جملة واحدة يحتفظ بها فريقك كقاعدة عن الفئات غير المرئية.

سلّم عملك قبل أن تتلقى الملاحظات. لا يوجد حل منشور هنا.


15. المصادر

مطلوب (حوالي 30 دقيقة):

  • scikit-learn: Pipelines and composite estimators (1.9.1): السهولة، واختيار المعاملات معًا، والأمان؛ وmake_pipeline؛ وأسماء step__parameter؛ وColumnTransformer وmake_column_transformer وremainder؛ وget_feature_names_out. https://scikit-learn.org/stable/modules/compose.html (فُتح في 25 أكتوبر 2026.)

موصى به:

  • scikit-learn: Preprocessing data (1.9.1): خيارات OneHotEncoder ومنها handle_unknown؛ وStandardScaler. https://scikit-learn.org/stable/modules/preprocessing.html (فُتح في 25 أكتوبر 2026.)
  • scikit-learn: Common pitfalls and recommended practices (1.9.1): مثال التسرّب في اختيار الخصائص، وعبارة "the scikit-learn pipeline is a great way to prevent data leakage" (أي: "خط المعالجة في scikit-learn طريقة رائعة لمنع تسرّب البيانات"). https://scikit-learn.org/stable/common_pitfalls.html (فُتح في 25 أكتوبر 2026.)

16. شخصية تتابعها / قدوة

مطوّرو scikit-learn (نموذج مؤسسي؛ اختارته D.World للدروس L84 وL86–L89).

  • حقيقة مُتحقَّق منها: دليل مستخدم scikit-learn (1.9.1) يوثّق الأخطاء الشائعة، ويعرّف تسرّب البيانات، ويوصي بخطوط المعالجة لمنعه (فُتحت الصفحات في 25 أكتوبر 2026).
  • لماذا توصي بهم D.World: دليل المقدّرات المركّبة نموذج للتوثيق الواضح القائم على الأمثلة لعادات العمل في بيئة الإنتاج.
  • ملاحظة صادقة: نموذج مؤسسي؛ ولا نقتبس إلا من التوثيق.
  • جرّب هذا: ابحث عن مثال make_column_selector في صفحة compose. واكتب جملة واحدة عن متى يكون اختيار الأعمدة حسب النوع أكثر أمانًا من سرد الأسماء، ومتى يكون أكثر خطورة.

17. المصطلحات

المصطلح معناه في هذا الدرس
خط المعالجة (Pipeline) كائن واحد في scikit-learn يربط خطوات معالجة مسبقة ونموذجًا نهائيًا في سلسلة، ويُدرَّب ويُستخدم كوحدة واحدة
ColumnTransformer يطبّق محوّلات مختلفة على أعمدة مختلفة ويجمع المخرجات
أداة الملء (Imputer) محوّل يملأ القيم المفقودة بقيمة متعلَّمة (الوسيط، أو الأكثر تكرارًا…)
المحوّل (Transformer) كائن له fit وtransform، يتعلم من صفوف التدريب ويغيّر البيانات
handle_unknown خيار في OneHotEncoder للفئات التي لم تظهر في fit ("error"، و"ignore"، …)
get_feature_names_out يعيد أسماء الأعمدة التي ينتجها محوّل مدرَّب
step__parameter قاعدة التسمية للوصول إلى معامل خطوة داخل خط المعالجة

للمراجعة: القيم المفقودة (L35) · الترميز (L40) · التسرّب (L84).


18. تأمّل

  1. أي دفتر من دفاترك سيتعطل أولًا إذا شغّله شخص آخر الشهر القادم؟
  2. في بياناتك، أي الفئات قد تظهر لاحقًا ولم يرها النموذج قط؟
  3. متى تفضّل أن يظهر خطأ على وجود قيمة افتراضية صامتة؟

19. الخطوة التالية

التالي: L87 — اختيار النموذج وضبط المعاملات الفائقة (Model Selection & Hyperparameter Tuning). بعد أن أصبح سير العمل كله في خط معالجة واحد، تستطيع البحث عن أفضل إعدادات لكل الخطوات معًا، بأمانة.


20. أدلة التقييم

الدليل ماذا يُظهر كيف يُقيَّم
خط معالجة المرتجعات + التحقق المتقاطع + تنبؤات الطلبات الجديدة؛ وإعادة كتابة دفتر الزميل (التدريب المستقل) توجيه صحيح للأعمدة واختيارات صحيحة للملء؛ وتحقق متقاطع أمين؛ ومعالجة الفئة غير المرئية؛ وشرح المشكلات الثلاث دليل التقييم L86-IP
الدفتر الموجَّه (خط المعالجة، والتحقق المتقاطع اليدوي مقابل خط المعالجة، والفحص، والفئة غير المرئية) خط معالجة يعمل؛ وشرح المقارنة؛ والفحص دليل التقييم L86-GP
اختبار الفهم (Q1–Q8) الأمان؛ وColumnTransformer؛ وhandle_unknown؛ وأسماء المعاملات؛ والفحص؛ والتنبؤ 7 إجابات صحيحة أو أكثر من 8
مهمة العمل والتحدي القصير مذكرة التسليم؛ والقيمة الافتراضية الصامتة دليلا التقييم L86-WT وL86-MC

المراجع

  1. scikit-learn developers. Pipelines and composite estimators (1.9.1). https://scikit-learn.org/stable/modules/compose.html (SK-COMP). يدعم: فوائد خطوط المعالجة (الاقتباس)، وColumnTransformer، والتسمية.
  2. scikit-learn developers. Preprocessing data (1.9.1). https://scikit-learn.org/stable/modules/preprocessing.html (SK-PRE).
  3. scikit-learn developers. Common pitfalls and recommended practices (1.9.1). https://scikit-learn.org/stable/common_pitfalls.html (SK-PIT). يدعم: مثال التسرّب؛ ونموذج القدوة.
  4. D.World Stage 4 Detailed Lesson Map v0.9 (صف L86). وثيقة داخلية.
L87 · Model Selection & Hyperparameter Tuning About 3 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

L88 · Reproducibility & Experiment Tracking About 2.5 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

L89 · Interpreting Models: Permutation Importance & Communicating Behaviour About 2.5 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

U20 Exit Check — Reproducible Pipeline & Experiment Log Membersللمشتركين

The exit brief is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

تكليف نهاية الوحدة ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

U21 · Real-World Business Projectsمشاريع أعمال حقيقية

Stage 4المرحلة 4

Free: the first lesson. The other lessons, the exit brief and the practice files are for Starter and Membership.

مجاني: الدرس الأول. باقي الدروس وتكليف نهاية الوحدة وملفات التمرين لأصحاب باقة البداية والاشتراك.

Download U21 practice files (.zip, 1.4 MB)حمّل ملفات تمرين U21 (zip، 1.4 MB)

Unzip into a short folder such as D:\DWorld on Windows. The zip has only learner files: no answers.

فك الضغط في مجلد قصير مثل D:\DWorld على ويندوز. الملف يحتوي ملفات المتعلم فقط بدون إجابات.

L90 · The End-to-End Project Playbook: From Charter to Measured ImpactL90 · دليل المشروع من البداية إلى النهاية: من الميثاق إلى أثر مُقاس About 2.5 hoursحوالي ساعتين ونصف Freeمجاني

L90 — The End-to-End Project Playbook: From Charter to Measured Impact

Learner file. Answers and model solutions are in a separate instructor-only file. Version: U21 Production v1 · Content date: 26 October 2026. Time estimates are planning estimates until learners have tested them. The code in this lesson was run with Python 3.13.16, pandas 3.0.5, NumPy 2.5.3, SciPy 1.18.1 and scikit-learn 1.9.1 (recorded in D.World's internal Code Test Report); Python 3.13 is the accepted course version. Not run with Python 3.14 or inside JupyterLab.

All businesses are fictional and all data is synthetic.


1. Lesson Identity

Field Value
Title The End-to-End Project Playbook: From Charter to Measured Impact
Stage Stage 4 — Real Projects & Machine Learning
Unit U21 — Real-World Business Projects
Lesson ID L90
Skills Project lifecycle (charter, data, analysis/model, evaluation, recommendation, measurement, monitoring); deciding whether a model is needed; impact-measurement options and their strength; expected business impact with ranges; documentation set (charter, notebook, memo, model card, AI-use trail); review checkpoints
Difficulty Intermediate
Estimated time About 2.5 hours (planning estimate, unvalidated)
Assessment level Application
Prerequisites U17 (charters), L67 (unit economics), L69 (A/B power), U18–U20 (models, evaluation, workflow).

Time breakdown (planning estimate): concept and worked example 55 min · guided practice 30 min · independent practice 35 min · knowledge check 10 min · AI 5 min (optional) · workplace task and mini challenge 15 min.

What you need: practice_files (L90_starter.ipynb; u21_data/churn20.csv, u21_data/churn_scoring_oct.csv, u21_data/retention_pilot_spring.csv).


2. Learning Objective

By the end of this lesson, you will be able to:

  • plan an end-to-end business project from charter to recommendation, with review checkpoints;
  • design how its impact will be measured (randomized holdout, test or before/after with caveats), with a sample size from a power simulation;
  • keep an AI-use trail that records what AI was used for and what you verified.

D.World approved objective (verbatim): Plan an end-to-end business project from charter to recommendation, including an impact-measurement design (test, holdout or before/after with caveats) and an AI-use trail.


3. Why It Matters

Stage 4 taught the parts: a charter (U17), models and baselines (U18), honest evaluation and costs (U19), a reproducible workflow (U20). A real project needs all of them in order, and it does not end when the model is trained. It ends when a decision has been taken and its effect has been measured.

Many projects stop at "the model has an AUC of 0.80" or "accuracy 0.91". Those numbers say how well the model ranks or classifies; they do not say whether the business is better off. The retention team wants to know: "If we send the offer to the customers you pick, how much margin do we keep, and how will we know?" That needs an expected impact with a range, and a measurement design decided before the launch.

Key principle: plan the whole cycle before you start (charter → data → model only if needed → evaluation with costs → recommendation with an expected impact range → measurement with a holdout → monitoring), and write down how AI was used and checked at every step.


4. Concept

import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler

churn = pd.read_csv("u21_data/churn20.csv")
scoring = pd.read_csv("u21_data/churn_scoring_oct.csv")
pilot = pd.read_csv("u21_data/retention_pilot_spring.csv")
print("history:", churn.shape, "| October customers to score:", scoring.shape, "| pilot:", pilot.shape)
print("60-day churn rate in the history:", round(churn["churned_60d"].mean(), 3))
history: (6000, 14) | October customers to score: (3000, 14) | pilot: (4000, 4)
60-day churn rate in the history: 0.22

Part A — The project lifecycle

Step Question it answers Output Checkpoint (who reviews)
1 Charter What decision, for whom, by when; success metric; constraints (U17) Charter Decision owner signs off
2 Data Is the data fit for the decision? Timing, coverage, leaks (U09, L84) Data checks Analyst + data owner
3 Analysis / model Is a model needed? Baselines first (U18) Notebook / pipeline (U20) Peer review
4 Evaluation How good, for whom, at what cost? (U19) Metrics with spread; cost table Peer review
5 Recommendation What should we do, and what is it worth? Decision memo with an expected impact range Decision owner
6 Measurement How will we know it worked? Impact-measurement design (holdout or test) Decision owner + analyst
7 Monitoring When do we stop or retrain? (L85) KPIs with triggers and owners Named owner

The documentation set travels with the project: charter, reproducible notebook, decision memo, model card (L85) and an AI-use trail. The AWS Cloud Adoption Framework puts the first rule plainly: "Begin by defining business problems that can be solved with AI/ML, and have a clear idea of the business value to be gained."

Part B — Is a model needed?

The same framework warns: "Some business problems don't need ML and simple business rules can do a much better job." Compare a simple rule with the model before building anything bigger. Rule: contact customers with no order in the last 90 days. Model: the U20 churn pipeline. Both are judged on the same held-out customers, for the same number of contacts:

NUM = ["tenure_months", "app_user", "orders_90d", "orders_180d", "days_since_last", "avg_basket", "complaints_90d",
       "late_deliveries_90d", "discount_share"]
CAT = ["region", "acq_channel", "payment_method"]


def churn_pipeline():
    num = Pipeline([("impute", SimpleImputer(strategy="median")), ("scale", StandardScaler())])
    cat = Pipeline([("impute", SimpleImputer(strategy="most_frequent")), ("onehot", OneHotEncoder(handle_unknown="ignore"))])
    return Pipeline([("prep", ColumnTransformer([("num", num, NUM), ("cat", cat, CAT)])),
                     ("clf", LogisticRegression(C=0.1, max_iter=1000))])


X_dev, X_test, y_dev, y_test = train_test_split(churn[NUM + CAT], churn["churned_60d"], test_size=0.20, random_state=42,
                                                stratify=churn["churned_60d"])
model = churn_pipeline().fit(X_dev, y_dev)
p_test = model.predict_proba(X_test)[:, 1]
rule = (X_test["orders_90d"] == 0).to_numpy()
k = int(rule.sum())
top_k = np.argsort(-p_test)[:k]
print(f"rule flags {k} of {len(X_test)} customers | churn rate among them: {y_test.to_numpy()[rule].mean():.3f}")
print(f"model's top {k}: churn rate {y_test.to_numpy()[top_k].mean():.3f} | model AUC {roc_auc_score(y_test, p_test):.3f}")
print(f"churners caught: rule {y_test.to_numpy()[rule].sum()} | model {y_test.to_numpy()[top_k].sum()} of {y_test.sum()}")
rule flags 188 of 1200 customers | churn rate among them: 0.590
model's top 188: churn rate 0.606 | model AUC 0.803
churners caught: rule 111 | model 114 of 263

For this number of contacts, the simple rule is almost as good as the model: 111 against 114 churners caught, churn rates 0.590 against 0.606. That is a real finding, not a failure. The model is still useful here for two reasons: it gives a ranking, so the team can contact any number of customers (the rule only says yes or no for 188 of them), and its probabilities can be combined with each customer's value (L91). If neither mattered, the rule would be the better choice: cheaper to run and easier to explain.

Part C — From model results to expected business impact

A model's AUC is not money. Expected impact turns predictions into an estimate of what the decision changes, with a range. You need three inputs: how many customers you contact, how many of them would have churned (predicted risk), and how much the offer reduces churn. The last number must come from evidence: here, the spring pilot, a randomized test in which high-risk customers were split at random into voucher and control:

rates = pilot.groupby("group")["churned_60d"].agg(["count", "mean"])
print(rates.round(3).to_string())
rel = 1 - rates.loc["voucher", "mean"] / rates.loc["control", "mean"]
rng = np.random.default_rng(90)
c = pilot.loc[pilot["group"] == "control", "churned_60d"].to_numpy()
v = pilot.loc[pilot["group"] == "voucher", "churned_60d"].to_numpy()
boot = [1 - rng.choice(v, len(v)).mean() / rng.choice(c, len(c)).mean() for _ in range(2000)]
lo, hi = np.percentile(boot, [5, 95])
print(f"relative churn reduction: {rel:.3f} | 90% bootstrap interval {lo:.3f} to {hi:.3f}")
         count   mean
group                
control   2036  0.441
voucher   1964  0.354
relative churn reduction: 0.197 | 90% bootstrap interval 0.143 to 0.248

Among the high-risk customers in the pilot, the voucher cut churn from 0.441 to 0.354: a relative reduction of about 20%, with a 90% interval of about 14% to 25%. This interval, not a guess, is what the impact estimate should carry. One caution: the pilot only included high-risk customers; the effect may be different for others.

Apply it to October: score the customers, contact the 400 highest-risk ones (the team's monthly capacity), and estimate the churners prevented and the margin kept, at the low, central and high ends of the pilot interval:

full_model = churn_pipeline().fit(churn[NUM + CAT], churn["churned_60d"])          # final model: all labelled history
scoring["p_churn"] = full_model.predict_proba(scoring[NUM + CAT])[:, 1]
target = scoring.nlargest(400, "p_churn")
COST_PER_CONTACT = 4.0                                                              # EUR: voucher redemptions + handling, average
for label, r in [("low", lo), ("central", rel), ("high", hi)]:
    prevented = (target["p_churn"] * r).sum()
    kept = (target["p_churn"] * r * target["margin_next_12m"]).sum()
    print(f"{label:>7}: churners prevented ≈ {prevented:5.1f} | margin kept ≈ EUR {kept:7.0f} | cost EUR {400 * COST_PER_CONTACT:.0f} "
          f"| net ≈ EUR {kept - 400 * COST_PER_CONTACT:7.0f}")
    low: churners prevented ≈  33.4 | margin kept ≈ EUR     561 | cost EUR 1600 | net ≈ EUR   -1039
central: churners prevented ≈  45.9 | margin kept ≈ EUR     770 | cost EUR 1600 | net ≈ EUR    -830
   high: churners prevented ≈  57.8 | margin kept ≈ EUR     970 | cost EUR 1600 | net ≈ EUR    -630

The estimate is a surprise: contacting the 400 highest-risk customers is expected to lose money, about €630 to €1,040 a month, because many of the highest-risk customers bring little margin (they have almost stopped ordering). The model is right about who will churn; the plan is wrong about who to contact. L91 builds a targeting rule that combines risk, the offer's effect and customer value. Finding this before the launch is exactly what an expected-impact step is for.

Part D — How will we know? Impact-measurement options

Design How Strength Main risk
Randomized holdout Among the customers the rule selects, a random share (for example 20%) gets no offer; compare churn Strong: the only difference between the groups is the offer Needs enough customers; some value is given up in the holdout
A/B test (L69) Two versions to random groups Strong Same as above; one change at a time
Before/after Compare churn before and after the launch Weak: seasons, prices and competitors change too Must state the caveats; use only when nothing else is possible
Matched comparison Compare with similar customers who were not contacted Medium Hidden differences between the groups

A holdout group is a random part of the eligible customers who are deliberately not treated, so that their outcome shows what would have happened without the action. The publisher's description of Kohavi, Tang and Xu's book on controlled experiments puts the problem plainly: "Getting numbers is easy; getting numbers you can trust is hard."

The seven steps stay the same, but what fills them does not: each case needs its own unit, metric and design. A churn offer can hold out customers (L91). A staffing forecast cannot "hold out" a counter from having staff, so it is measured by running the new forecast beside the old one (L92). A recommendation box is tested by showing it to a random half of customers and measuring margin per customer, not clicks (L93). Copying one case's design into another is a common way to measure the wrong thing.

Part E — How big must the holdout be? A power simulation (L69)

Each month 400 customers are selected. With a 20% holdout, 80 get no offer. Is that enough to see a 20% relative reduction? The answer depends on how often the selected customers churn without the offer, so use the mean predicted risk of the group you will actually contact (here, the 400 from Part C), not the churn rate of all customers. Simulate it, as in L69:

from scipy import stats


def power_holdout(n_selected, p_control, holdout_share=0.20, rel_reduction=0.20, sims=2000, seed=90):
    rng = np.random.default_rng(seed)
    n_h = int(n_selected * holdout_share)
    n_t = n_selected - n_h
    hits = 0
    for _ in range(sims):
        ch = rng.binomial(n_h, p_control)
        ct = rng.binomial(n_t, p_control * (1 - rel_reduction))
        table = [[ct, n_t - ct], [ch, n_h - ch]]
        hits += stats.fisher_exact(table, alternative="less").pvalue < 0.05
    return hits / sims


p_sel = target["p_churn"].mean()                                                     # churn rate expected without the offer
print(f"mean predicted risk of the 400 selected: {p_sel:.3f}")
for months in [1, 2, 3, 4]:
    print(f"{months} month(s), {400 * months:>4} selected customers: power {power_holdout(400 * months, p_sel):.2f}")
mean predicted risk of the 400 selected: 0.583
1 month(s),  400 selected customers: power 0.52
2 month(s),  800 selected customers: power 0.82
3 month(s), 1200 selected customers: power 0.93
4 month(s), 1600 selected customers: power 0.98

The 400 highest-risk customers churn at about 0.58 without the offer. With one month (400 customers, 80 in the holdout), a real 20% reduction would be detected only about half the time (0.52); two months give about 0.82. The plan should therefore pool at least two months of randomized holdouts before judging the offer, and say so in the charter. Deciding after one month could easily produce "no significant effect" even if the offer works.

The size depends on who is selected. Fewer churners in the selected group means fewer events to compare, so lower power for the same number of customers. Part C showed that this selection loses money; when L91 changes who is contacted, the selected group's churn rate changes, and the power simulation must be run again for the new group.

Part F — The AI-use trail

Keep a short table for every AI use in a project. It answers the reviewer's question "what did the AI do, and how do you know it was right?":

Date Tool Used for What I checked What I changed or rejected
12 Oct AI assistant Draft of the charter's risk list Compared each risk with the case facts Removed two risks that did not apply; added capacity
14 Oct AI assistant Code for the power simulation Reran with a known case (no effect → about 5% "power") Fixed the one-sided test direction

The AI-use trail is part of the deliverable, not an extra: a result whose AI help cannot be traced cannot be reviewed.


5. Worked Example

Cedar Lane (fictional), synthetic data. The retention lead asks: "Plan the churn-offer project so that in three months I can tell the board what it was worth."

Step 1 — Charter (U17): decision: which 400 customers get the monthly retention voucher; owner: retention lead; success metric: margin kept minus offer cost, measured against a randomized holdout; constraint: 400 contacts a month, €4 per contact.

Step 2 — Data and model (Parts B–C): for the same number of contacts the simple 90-day rule is almost as good as the model (111 against 114 churners); the model is kept because the plan needs a ranking that can be combined with customer value, built with the U20 workflow.

Step 3 — Expected impact (Part C): with the pilot's 14% to 25% reduction, contacting the 400 highest-risk customers would lose about €630 to €1,040 a month. The plan is changed before launch: target by expected value (L91), and estimate again.

Step 4 — Measurement (Parts D–E): a randomized 20% holdout every month; one month is not enough evidence; pool at least two months (power about 0.82 for the 400 highest-risk customers) before deciding, and rerun the simulation if the selection changes.

Step 5 — Monitoring: churn rate in the offer and holdout groups each month (owner: retention lead), share of customers contacted twice, model AUC on last month's holdout and non-contacted customers, whose outcomes the offer did not change (owner: analyst), with a review if the AUC falls below 0.75.

Step 6 — AI-use trail: every AI-assisted draft or code block listed with what was checked.


6. Visual Explanation

 1 CHARTER ─▶ 2 DATA ─▶ 3 MODEL? (rule vs model, baselines) ─▶ 4 EVALUATION (spread, costs) ─▶ 5 RECOMMENDATION
                                                                                         expected impact = contacts × risk
                                                                                         × measured reduction × margin − cost
                                                                                         (low / central / high from the pilot)
 6 MEASUREMENT: randomized HOLDOUT (strong) · A/B test (strong) · matched comparison (medium) · before/after (weak, caveats)
               size from a POWER SIMULATION (L69) → pool months until power ≈ 0.8
 7 MONITORING: KPIs · triggers · owners              ALWAYS: AI-use trail (tool · use · check · change)

Alt text: A chain of seven steps: charter, data, a decision whether a model is needed by comparing a rule with a model and baselines, evaluation with spread and costs, and a recommendation whose expected impact equals contacts times risk times the measured reduction times margin minus cost, given as low, central and high values from the pilot. Measurement designs are listed by strength: randomized holdout and A/B test strong, matched comparison medium, before/after weak with caveats; the holdout size comes from a power simulation, pooling months until power is about 0.8. Monitoring has KPIs, triggers and owners. An AI-use trail recording tool, use, check and change runs through every step.


7. Guided Practice

Open L90_starter.ipynb.

  1. Write the six-line charter for the churn-offer case (decision, owner, success metric, constraint, data, deadline).
  2. Compare the 90-day rule with the model on the held-out customers (Part B). Decide in one sentence whether the model is needed.
  3. Estimate the relative churn reduction from the pilot with a bootstrap interval (Part C).
  4. Score the October customers and compute the expected impact range for 400 contacts.
  5. Run the power simulation for 1 to 4 months, using the mean predicted risk of the selected customers, and choose the measurement period.
  6. Start an AI-use trail for this notebook (even if you used no AI: write "none").
  7. Run Restart Kernel and Run All Cells….

8. Independent Practice

Part 1 — A plan for a new case. Cedar Lane's pickup counters have no-shows: customers who do not collect their order. Facts (synthetic): about 3,000 pickups a week; no-show rate about 6%; each no-show costs about €3 (handling and restocking); an SMS reminder costs €0.05; the counter team believes reminders could cut no-shows by a quarter.

Write a project plan (300–400 words) with the seven lifecycle steps: charter; data you would need; whether a model is needed (or a rule: remind everyone); expected impact with a low/central/high range and the assumptions; an impact-measurement design (unit, randomization, holdout share, primary metric, one guardrail) with a sample size from a power simulation (adapt power_holdout); monitoring; and the AI-use trail.

Part 2 — Critique a colleague's plan. A colleague's plan ends like this:

5. Train a random forest on last year's data.
6. Model accuracy 0.91 on the test set.
7. Deploy the model to the CRM. Project complete.

Write a critique (100–150 words): what is missing or misleading in these three steps? Then rewrite steps 5–7 so that the plan ends with a decision, an expected impact range and a measurement design.

Work in L90_starter.ipynb (section "Independent practice").


9. Knowledge Check — Project Playbook

Q1. When does an end-to-end project end?

  • A) When the model reaches its target accuracy on the held-out test set
  • B) When the decision is taken and its effect has been measured
  • C) When the notebook and the model card have been shared with the team
  • D) When the deadline in the charter is reached, whatever the state of the work

Q2. A simple rule catches almost as many churners as the model for the same number of contacts. What is the sound next step?

  • A) Prefer the model, because a model uses more signals than a rule and will improve as data grows
  • B) Drop both and wait for a larger sample before deciding anything
  • C) Consider the rule: simpler to run and explain, unless the model adds value worth its cost
  • D) Deploy both and let the CRM choose one at random for each customer

Q3. Where should the "reduction in churn from the offer" in an expected-impact estimate come from?

  • A) From a randomized pilot or test, with its interval
  • B) From the model's AUC on the test set, scaled to the share of churners
  • C) From the retention team's best guess, stated as one exact number
  • D) From the share of customers the model flags as high risk this month

Q4. Why is a before/after comparison a weak way to measure impact?

  • A) It needs a power simulation first, and those are hard to run correctly for churn data
  • B) It always overestimates the effect, by a fixed amount that depends on the season
  • C) It can only be computed when a model has scored every customer
  • D) Seasons, prices and competitors change too, so the difference is not only the action's effect

Q5. What is a holdout group?

  • A) The customers the model could not score because of missing data
  • B) A random share of eligible customers who are deliberately not treated
  • C) The test set kept aside during model training, used once at the very end
  • D) The customers who were offered the voucher but then chose not to redeem it

Q6. A power simulation gives 0.35 for one month of data. What does this mean?

  • A) A real effect of the planned size would be found only about one time in three
  • B) The offer changes the behaviour of about 35% of the customers who receive it
  • C) The holdout should hold 35% of the selected customers to reach enough power
  • D) The test would wrongly declare an effect 35% of the time when there is none

Q7. Why give expected impact as a range (low, central, high)?

  • A) Because managers find three numbers easier to accept than one single precise number
  • B) To make the estimate look more careful and more scientific than a single number would
  • C) Because the inputs are uncertain, and the decision should hold across that range
  • D) Because the model's AUC is reported with three decimals

Q8. What belongs in an AI-use trail?

  • A) Only the final answer the AI gave, pasted in full so that nothing is lost
  • B) The tool, what it was used for, what you checked and what you changed or rejected
  • C) A statement that no AI was used, added whether or not it was used
  • D) The AI's confidence score for each answer, so reviewers see which parts it trusted

10. AI in Practice (optional, bounded)

Goal: ask an AI assistant to critique your project plan, and keep only critiques you can tie to the case facts.

  1. Paste your plan (no customer data) and ask: "Critique this analytics project plan: what is missing to show business impact?"
  2. For each critique, write the case fact it relies on. Drop critiques that are generic or do not apply.
  3. Record the exchange in your AI-use trail.

Boundaries: AI is optional; no data in prompts; you decide which critiques are valid.


11. AI Verification

  1. Metrics: every success metric in the plan has a measurement method and a baseline (what it would be without the action).
  2. Holdout size: confirm the planned size with your own power simulation (L69), not with a number the AI gave.
  3. Facts: every number in the plan traces to the case or to your notebook.
  4. Trail: the AI-use trail lists the check you did for each AI use.

12. Business Lens

Projects create value only when their impact is measured and acted on. A model that ranks well but is never compared with a holdout gives the business a cost and a belief, not a result. A plan with an expected impact range and a holdout turns the project into a decision the board can check: "we expected €X to €Y; we measured €Z".


13. Workplace Task — The One-Paragraph Plan

Fictional business: Cedar Lane. Write the paragraph (80–120 words) the retention lead will read at the planning meeting: the decision, the expected impact range for one month (from your notebook), how the holdout will measure it, how long the measurement will take and why, and the one risk that could change the plan.


14. Mini Challenge — "It Worked!"

Fictional business: Cedar Lane. After a new loyalty scheme launched on 1 April, a colleague writes: "Churn fell from 24% (Jan–Mar) to 21% (Apr–Jun). The scheme works!" You find last year's figures for the same months.

before_after = pd.DataFrame({"Jan-Mar": [0.25, 0.24], "Apr-Jun": [0.22, 0.21]}, index=["last year (no scheme)", "this year (scheme from April)"])
before_after["change"] = before_after["Apr-Jun"] - before_after["Jan-Mar"]
print(before_after.to_string())
Output: open it after you have answered question 1
                               Jan-Mar  Apr-Jun  change
last year (no scheme)             0.25     0.22   -0.03
this year (scheme from April)     0.24     0.21   -0.03
  1. Before you open the output, write what last year's figures would need to look like for the colleague to be right.
  2. What does the comparison with last year suggest about the scheme's effect?
  3. Which design would have measured the effect properly, and what would it have needed at launch?
  4. Write one sentence your team can keep as a rule about before/after claims.

Submit before feedback. No solution is provided here.


15. Resources

Required (about 25 min):

  • AWS Cloud Adoption Framework, Business Perspective: Data science (AWS whitepaper): start from the business problem and its value; check whether ML is needed; quantifiable performance metrics; proof of concept, then validating return on investment in the real world. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/data-science.html (Opened 26 Oct 2026.)

Recommended:

  • AWS Cloud Adoption Framework, Business Perspective: Business insights: identify the decisions that need insights and measure their impact (the page notes that it is kept for historical reference). https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/business-insights.html (Opened 26 Oct 2026.)
  • Ron Kohavi, Diane Tang and Ya Xu: Trustworthy Online Controlled Experiments: A Practical Guide to A/B Testing (Cambridge University Press, 2020): the reference on controlled experiments and holdouts. https://www.cambridge.org/core/books/trustworthy-online-controlled-experiments/D97B26382EB0EB2DC2019A7A7B518F59 (Opened 26 Oct 2026.)

16. Person to Follow / Role Model

Cassie Kozyrkov.

  • Verified fact: on her home page she describes herself as a "Decision Intelligence Pioneer" and "Google's First Chief Decision Scientist" (page opened 26 Oct 2026).
  • Why D.World recommends her: she frames data work around decisions: what action you will take, and what would change your mind, which is exactly what an end-to-end plan must state.
  • Honest note: follow her for how to frame decisions; check technical claims against documentation, as with any author.
  • Try this: on her home page, find her one-line definition of decision intelligence. Rewrite your guided-practice charter's first line so it names the action, not the analysis.

17. Glossary

Term Meaning in this lesson
Project lifecycle The ordered steps of a project: charter, data, analysis or model, evaluation, recommendation, measurement, monitoring
Impact measurement The design that shows what an action changed (holdout, A/B test, matched comparison, before/after)
Holdout group A random part of the eligible customers who are deliberately not treated, to show the outcome without the action
Expected impact The estimated business effect of a decision (for example margin kept minus cost), with a range from uncertain inputs
AI-use trail A table of every AI use in a project: tool, purpose, what was checked, what was changed
Power simulation Repeating a planned test many times on simulated data to see how often a real effect would be detected (L69)

Review: charters (U17) · A/B power (L69) · unit economics (L67).


18. Reflection

  1. Which of your earlier projects ended at a model metric? What was the missing last step?
  2. When would you accept a before/after comparison, and what would you write next to it?
  3. Who in a real team should sign off the measurement design, and why before the launch?

19. Next Step

Next: L91 — Case Clinic: Churn & Risk Scoring with a Cost-Based Targeting Rule. The model's scores become a targeting rule that puts the monthly capacity where it saves the most margin.


20. Assessment Evidence

Evidence What it shows How it is judged
No-show project plan with impact-measurement design + AI-use trail; critique and rewrite (Independent Practice) Seven steps; rule vs model; expected impact range; randomized design with power; monitoring; trail Rubric L90-IP
Guided notebook (charter, rule vs model, pilot interval, impact range, power) Evidence-based reduction; range; measurement period from power Rubric L90-GP
Knowledge check (Q1–Q8) Project end; rule vs model; evidence for effects; before/after; holdout; power; ranges; AI trail 7 or more of 8 correct
Workplace task and mini challenge One-paragraph plan; before/after claim Rubrics L90-WT, L90-MC

References

  1. Amazon Web Services. AWS Cloud Adoption Framework: Business Perspective — Data science. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/data-science.html (AWS-DS). Supports: problem and value first; ML may not be needed (quotations).
  2. Amazon Web Services. AWS Cloud Adoption Framework: Business Perspective — Business insights. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/business-insights.html (AWS-BI).
  3. Kohavi, R., Tang, D. & Xu, Y. Trustworthy Online Controlled Experiments: A Practical Guide to A/B Testing. Cambridge University Press, 2020. https://www.cambridge.org/core/books/trustworthy-online-controlled-experiments/D97B26382EB0EB2DC2019A7A7B518F59 (KOHAVI). Supports: quotation from the book description.
  4. Kozyrkov, C. Home page. https://www.kozyr.com/ (KOZYR). Supports: role-model self-description.
  5. D.World Stage 4 Detailed Lesson Map v0.9 (L90 row). Internal.

L90 — دليل المشروع من البداية إلى النهاية: من الميثاق إلى أثر مُقاس

ملف المتعلّم. الإجابات والحلول النموذجية في ملف منفصل خاص بالمدرّس فقط. الإصدار: U21 Production v1 · تاريخ المحتوى: 26 أكتوبر 2026. تقديرات الوقت تقديرات للتخطيط إلى أن يختبرها المتعلّمون. الكود في هذا الدرس شُغّل باستخدام Python 3.13.16 وpandas 3.0.5 وNumPy 2.5.3 وSciPy 1.18.1 وscikit-learn 1.9.1 (مسجّلة في تقرير اختبار الكود الداخلي في D.World)؛ وPython 3.13 هو الإصدار المعتمد في الدورة. ولم يُشغَّل باستخدام Python 3.14 ولا داخل JupyterLab.

كل الأنشطة التجارية خيالية، وكل البيانات مصطنعة.


1. بطاقة الدرس

البند القيمة
العنوان دليل المشروع من البداية إلى النهاية: من الميثاق إلى أثر مُقاس
المرحلة المرحلة 4 — مشاريع حقيقية وتعلّم الآلة
الوحدة U21 — مشاريع أعمال من الواقع
رقم الدرس L90
المهارات دورة حياة المشروع (الميثاق، والبيانات، والتحليل/النموذج، والتقييم، والتوصية، والقياس، والمراقبة)؛ تقرير هل النموذج مطلوب؛ خيارات قياس الأثر ومدى قوتها؛ الأثر المتوقع على العمل مع مدى؛ مجموعة التوثيق (الميثاق، والدفتر، والمذكرة، وبطاقة النموذج، وسجل استخدام الذكاء الاصطناعي)؛ نقاط المراجعة
المستوى متوسط
الوقت المتوقع حوالي ساعتين ونصف (تقدير للتخطيط، غير مُتحقَّق منه)
مستوى التقييم تطبيق
المتطلبات السابقة U17 (المواثيق)، وL67 (اقتصاديات الوحدة)، وL69 (قوة اختبار A/B)، وU18–U20 (النماذج، والتقييم، وسير العمل).

تفصيل الوقت (تقدير للتخطيط):

  • المفهوم والمثال المحلول: 55 دقيقة.
  • التدريب الموجَّه: 30 دقيقة.
  • التدريب المستقل: 35 دقيقة.
  • اختبار الفهم: 10 دقائق.
  • الذكاء الاصطناعي: 5 دقائق (اختياري).
  • مهمة العمل والتحدي القصير: 15 دقيقة.

ما تحتاج إليه: مجلد practice_files (L90_starter.ipynb؛ وu21_data/churn20.csv وu21_data/churn_scoring_oct.csv وu21_data/retention_pilot_spring.csv).


2. هدف التعلّم

في نهاية هذا الدرس ستكون قادرًا على أن:

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

الهدف المعتمد من D.World (بنصّه): Plan an end-to-end business project from charter to recommendation, including an impact-measurement design (test, holdout or before/after with caveats) and an AI-use trail.


3. لماذا يهمّك هذا؟

علّمتك المرحلة 4 الأجزاء: ميثاق (U17)، ونماذج ونماذج مقارنة (U18)، وتقييم أمين وتكاليف (U19)، وسير عمل قابل لإعادة التشغيل (U20). والمشروع الحقيقي يحتاج إليها كلها بالترتيب، ولا ينتهي عند تدريب النموذج. بل ينتهي عندما يُتخذ قرار ويُقاس أثره.

مشاريع كثيرة تتوقف عند "للنموذج AUC قدره 0.80" أو "الدقة 0.91". هذه الأرقام تقول مدى جودة ترتيب النموذج أو تصنيفه؛ ولا تقول هل أصبح العمل في وضع أفضل. ويريد فريق الاحتفاظ بالعملاء أن يعرف: "If we send the offer to the customers you pick, how much margin do we keep, and how will we know?" (أي: "إذا أرسلنا العرض إلى العملاء الذين تختارهم، كم هامشًا نحتفظ به، وكيف سنعرف؟"). وهذا يحتاج إلى أثر متوقع مع مدى، وإلى تصميم للقياس يُقرَّر قبل الإطلاق.

المبدأ الأساسي: خطط الدورة كاملة قبل أن تبدأ (الميثاق ← البيانات ← نموذج فقط إذا لزم ← تقييم مع التكاليف ← توصية مع مدى للأثر المتوقع ← قياس بمجموعة استبعاد ← مراقبة)، واكتب كيف استُخدم الذكاء الاصطناعي وكيف فُحص في كل خطوة.


4. المفهوم

import numpy as np
import pandas as pd
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler

churn = pd.read_csv("u21_data/churn20.csv")
scoring = pd.read_csv("u21_data/churn_scoring_oct.csv")
pilot = pd.read_csv("u21_data/retention_pilot_spring.csv")
print("history:", churn.shape, "| October customers to score:", scoring.shape, "| pilot:", pilot.shape)
print("60-day churn rate in the history:", round(churn["churned_60d"].mean(), 3))
history: (6000, 14) | October customers to score: (3000, 14) | pilot: (4000, 4)
60-day churn rate in the history: 0.22

الجزء A — دورة حياة المشروع

الخطوة السؤال الذي تجيب عنه المُخرَج نقطة المراجعة (من يراجع)
1 الميثاق أي قرار، ولمن، وبحلول متى؛ ومقياس النجاح؛ والقيود (U17) الميثاق صاحب القرار يعتمده
2 البيانات هل البيانات صالحة للقرار؟ التوقيت، والتغطية، والتسرّبات (U09، L84) فحوص البيانات المحلّل + صاحب البيانات
3 التحليل / النموذج هل النموذج مطلوب؟ نماذج المقارنة أولًا (U18) الدفتر / خط المعالجة (U20) مراجعة الزملاء
4 التقييم ما مدى الجودة، ولمن، وبأي تكلفة؟ (U19) مقاييس مع تباينها؛ وجدول التكاليف مراجعة الزملاء
5 التوصية ماذا يجب أن نفعل، وكم يساوي ذلك؟ مذكرة قرار مع مدى للأثر المتوقع صاحب القرار
6 القياس كيف سنعرف أنه نجح؟ تصميم لقياس الأثر (مجموعة استبعاد أو اختبار) صاحب القرار + المحلّل
7 المراقبة متى نتوقف أو نعيد التدريب؟ (L85) مؤشرات أداء مع محفّزات وأصحاب مسؤولية مسؤول مسمّى

مجموعة التوثيق ترافق المشروع: الميثاق، والدفتر القابل لإعادة التشغيل، ومذكرة القرار، وبطاقة النموذج (L85)، وسجل استخدام الذكاء الاصطناعي (AI-use trail). ويضع إطار AWS لاعتماد السحابة القاعدة الأولى بوضوح: "Begin by defining business problems that can be solved with AI/ML, and have a clear idea of the business value to be gained." (أي: "ابدأ بتحديد مشكلات أعمال يمكن حلها بالذكاء الاصطناعي/تعلّم الآلة، وكوّن فكرة واضحة عن القيمة التي سيكسبها العمل.")

الجزء B — هل النموذج مطلوب؟

ويحذّر الإطار نفسه: "Some business problems don't need ML and simple business rules can do a much better job." (أي: "بعض مشكلات الأعمال لا تحتاج إلى تعلّم الآلة، وقواعد العمل البسيطة قد تؤدي المهمة أفضل بكثير.") قارن قاعدة بسيطة بالنموذج قبل أن تبني أي شيء أكبر. القاعدة: تواصل مع العملاء الذين لم يطلبوا شيئًا في آخر 90 يومًا. والنموذج: خط معالجة تسرّب العملاء من U20. ويُحكم على الاثنين على العملاء المحجوزين أنفسهم، وبعدد مرات التواصل نفسه:

NUM = ["tenure_months", "app_user", "orders_90d", "orders_180d", "days_since_last", "avg_basket", "complaints_90d",
       "late_deliveries_90d", "discount_share"]
CAT = ["region", "acq_channel", "payment_method"]


def churn_pipeline():
    num = Pipeline([("impute", SimpleImputer(strategy="median")), ("scale", StandardScaler())])
    cat = Pipeline([("impute", SimpleImputer(strategy="most_frequent")), ("onehot", OneHotEncoder(handle_unknown="ignore"))])
    return Pipeline([("prep", ColumnTransformer([("num", num, NUM), ("cat", cat, CAT)])),
                     ("clf", LogisticRegression(C=0.1, max_iter=1000))])


X_dev, X_test, y_dev, y_test = train_test_split(churn[NUM + CAT], churn["churned_60d"], test_size=0.20, random_state=42,
                                                stratify=churn["churned_60d"])
model = churn_pipeline().fit(X_dev, y_dev)
p_test = model.predict_proba(X_test)[:, 1]
rule = (X_test["orders_90d"] == 0).to_numpy()
k = int(rule.sum())
top_k = np.argsort(-p_test)[:k]
print(f"rule flags {k} of {len(X_test)} customers | churn rate among them: {y_test.to_numpy()[rule].mean():.3f}")
print(f"model's top {k}: churn rate {y_test.to_numpy()[top_k].mean():.3f} | model AUC {roc_auc_score(y_test, p_test):.3f}")
print(f"churners caught: rule {y_test.to_numpy()[rule].sum()} | model {y_test.to_numpy()[top_k].sum()} of {y_test.sum()}")
rule flags 188 of 1200 customers | churn rate among them: 0.590
model's top 188: churn rate 0.606 | model AUC 0.803
churners caught: rule 111 | model 114 of 263

(المطبوع: القاعدة تعلّم 188 من 1200 عميل، ومعدل التسرّب بينهم 0.590؛ وأعلى 188 في ترتيب النموذج معدل تسرّبهم 0.606؛ والعملاء المتسرّبون الذين اكتُشفوا: 111 بالقاعدة و114 بالنموذج من أصل 263.)

لهذا العدد من مرات التواصل، القاعدة البسيطة جيدة تقريبًا مثل النموذج: 111 مقابل 114 عميلًا متسرّبًا اكتُشفوا، ومعدلا تسرّب 0.590 مقابل 0.606. وهذه نتيجة حقيقية، لا فشل. ويظل النموذج مفيدًا هنا لسببين: فهو يعطي ترتيبًا، فيستطيع الفريق التواصل مع أي عدد من العملاء (أما القاعدة فتقول نعم أو لا لـ 188 منهم فقط)، ويمكن الجمع بين احتمالاته وقيمة كل عميل (L91). ولو لم يكن أي منهما مهمًا، لكانت القاعدة الاختيار الأفضل: أرخص في التشغيل وأسهل في الشرح.

الجزء C — من نتائج النموذج إلى الأثر المتوقع على العمل

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

rates = pilot.groupby("group")["churned_60d"].agg(["count", "mean"])
print(rates.round(3).to_string())
rel = 1 - rates.loc["voucher", "mean"] / rates.loc["control", "mean"]
rng = np.random.default_rng(90)
c = pilot.loc[pilot["group"] == "control", "churned_60d"].to_numpy()
v = pilot.loc[pilot["group"] == "voucher", "churned_60d"].to_numpy()
boot = [1 - rng.choice(v, len(v)).mean() / rng.choice(c, len(c)).mean() for _ in range(2000)]
lo, hi = np.percentile(boot, [5, 95])
print(f"relative churn reduction: {rel:.3f} | 90% bootstrap interval {lo:.3f} to {hi:.3f}")
         count   mean
group
control   2036  0.441
voucher   1964  0.354
relative churn reduction: 0.197 | 90% bootstrap interval 0.143 to 0.248

بين العملاء عالي الخطر في التجربة، خفّضت القسيمة التسرّب من 0.441 إلى 0.354: خفض نسبي قدره حوالي 20%، مع مدى 90% من حوالي 14% إلى 25%. وهذا المدى، لا التخمين، هو ما يجب أن يحمله تقدير الأثر. وتنبيه واحد: التجربة شملت العملاء عالي الخطر فقط؛ وقد يختلف الأثر مع غيرهم.

طبّقه على أكتوبر: احسب درجات العملاء، وتواصل مع أعلى 400 منهم خطرًا (الطاقة الشهرية للفريق)، وقدّر عدد حالات التسرّب التي ستُمنع والهامش الذي سيُحتفظ به، عند الطرف الأدنى والأوسط والأعلى من مدى التجربة:

full_model = churn_pipeline().fit(churn[NUM + CAT], churn["churned_60d"])          # final model: all labelled history
scoring["p_churn"] = full_model.predict_proba(scoring[NUM + CAT])[:, 1]
target = scoring.nlargest(400, "p_churn")
COST_PER_CONTACT = 4.0                                                              # EUR: voucher redemptions + handling, average
for label, r in [("low", lo), ("central", rel), ("high", hi)]:
    prevented = (target["p_churn"] * r).sum()
    kept = (target["p_churn"] * r * target["margin_next_12m"]).sum()
    print(f"{label:>7}: churners prevented ≈ {prevented:5.1f} | margin kept ≈ EUR {kept:7.0f} | cost EUR {400 * COST_PER_CONTACT:.0f} "
          f"| net ≈ EUR {kept - 400 * COST_PER_CONTACT:7.0f}")
    low: churners prevented ≈  33.4 | margin kept ≈ EUR     561 | cost EUR 1600 | net ≈ EUR   -1039
central: churners prevented ≈  45.9 | margin kept ≈ EUR     770 | cost EUR 1600 | net ≈ EUR    -830
   high: churners prevented ≈  57.8 | margin kept ≈ EUR     970 | cost EUR 1600 | net ≈ EUR    -630

(التعليقان في الكود معناهما: "النموذج النهائي: كل التاريخ الموسوم"، و"باليورو: استخدام القسائم + المعالجة، في المتوسط". والأعمدة المطبوعة: حالات التسرّب الممنوعة، والهامش المحتفَظ به، والتكلفة، والصافي، عند الطرف الأدنى والأوسط والأعلى.)

التقدير مفاجئ: التواصل مع أعلى 400 عميل خطرًا يُتوقع أن يخسر مالًا، حوالي 630 إلى 1,040 يورو شهريًا، لأن كثيرًا من العملاء الأعلى خطرًا يجلبون هامشًا قليلًا (فقد توقفوا تقريبًا عن الطلب). النموذج محق في تحديد من سيتسرّب؛ لكن الخطة مخطئة في تحديد من نتواصل معه. وسيبني L91 قاعدة استهداف تجمع بين الخطر، وأثر العرض، وقيمة العميل. واكتشاف ذلك قبل الإطلاق هو بالضبط الغرض من خطوة الأثر المتوقع.

الجزء D — كيف سنعرف؟ خيارات قياس الأثر

التصميم الطريقة القوة الخطر الرئيسي
مجموعة استبعاد عشوائية (Randomized holdout) من بين العملاء الذين تختارهم القاعدة، نسبة عشوائية (مثلًا 20%) لا تحصل على عرض؛ ثم يُقارن التسرّب قوي: الفرق الوحيد بين المجموعتين هو العرض يحتاج إلى عدد كافٍ من العملاء؛ وتُترك بعض القيمة في مجموعة الاستبعاد
اختبار A/B (L69) نسختان لمجموعتين عشوائيتين قوي مثل ما سبق؛ وتغيير واحد في كل مرة
قبل/بعد (Before/after) مقارنة التسرّب قبل الإطلاق وبعده ضعيف: المواسم والأسعار والمنافسون يتغيرون أيضًا يجب ذكر التحفظات؛ ولا يُستخدم إلا حين لا يكون غيره ممكنًا
مقارنة مطابقة (Matched comparison) المقارنة مع عملاء مشابهين لم يُتواصل معهم متوسط فروق خفية بين المجموعتين

مجموعة الاستبعاد (holdout group) جزء عشوائي من العملاء المؤهلين لا يُطبَّق عليهم الإجراء عمدًا، حتى تُظهر نتيجتهم ما كان سيحدث دون الإجراء. ويصوغ وصف الناشر لكتاب Kohavi وTang وXu عن التجارب المضبوطة المشكلة بوضوح: "Getting numbers is easy; getting numbers you can trust is hard." (أي: "الحصول على أرقام سهل؛ أما الحصول على أرقام تستطيع الوثوق بها فصعب.")

الخطوات السبع تبقى كما هي، لكن ما يملؤها يتغير: فكل حالة تحتاج إلى وحدتها ومقياسها وتصميمها الخاص. عرض الاحتفاظ بالعملاء يمكن أن يستبعد عملاء (L91). أما توقع أعداد الموظفين فلا يمكنه "استبعاد" نقطة استلام من وجود موظفين، لذلك يُقاس بتشغيل التوقع الجديد بجانب القديم (L92). ومربع التوصيات يُختبر بعرضه على نصف عشوائي من العملاء وقياس الهامش لكل عميل، لا النقرات (L93). ونسخ تصميم حالة إلى حالة أخرى طريقة شائعة لقياس الشيء الخطأ.

الجزء E — كم يجب أن يكون حجم مجموعة الاستبعاد؟ محاكاة القوة الإحصائية (L69)

كل شهر يُختار 400 عميل. ومع مجموعة استبعاد قدرها 20%، لا يحصل 80 منهم على عرض. هل يكفي ذلك لرؤية خفض نسبي قدره 20%؟ الإجابة تعتمد على عدد مرات تسرّب العملاء المختارين دون العرض، لذلك استخدم متوسط الخطر المتنبأ به للمجموعة التي ستتواصل معها فعلًا (هنا، الـ 400 من الجزء C)، لا معدل تسرّب كل العملاء. حاكِ ذلك، كما في L69:

from scipy import stats


def power_holdout(n_selected, p_control, holdout_share=0.20, rel_reduction=0.20, sims=2000, seed=90):
    rng = np.random.default_rng(seed)
    n_h = int(n_selected * holdout_share)
    n_t = n_selected - n_h
    hits = 0
    for _ in range(sims):
        ch = rng.binomial(n_h, p_control)
        ct = rng.binomial(n_t, p_control * (1 - rel_reduction))
        table = [[ct, n_t - ct], [ch, n_h - ch]]
        hits += stats.fisher_exact(table, alternative="less").pvalue < 0.05
    return hits / sims


p_sel = target["p_churn"].mean()                                                     # churn rate expected without the offer
print(f"mean predicted risk of the 400 selected: {p_sel:.3f}")
for months in [1, 2, 3, 4]:
    print(f"{months} month(s), {400 * months:>4} selected customers: power {power_holdout(400 * months, p_sel):.2f}")
mean predicted risk of the 400 selected: 0.583
1 month(s),  400 selected customers: power 0.52
2 month(s),  800 selected customers: power 0.82
3 month(s), 1200 selected customers: power 0.93
4 month(s), 1600 selected customers: power 0.98

(التعليق في الكود معناه: "معدل التسرّب المتوقع دون العرض". والمطبوع: متوسط الخطر المتنبأ به للـ 400 المختارين، ثم القوة الإحصائية لعدد الأشهر وعدد العملاء المختارين.)

أعلى 400 عميل خطرًا يتسرّبون بمعدل حوالي 0.58 دون العرض. ومع شهر واحد (400 عميل، منهم 80 في مجموعة الاستبعاد)، لن يُكتشف خفض حقيقي قدره 20% إلا في حوالي نصف المرات (0.52)؛ ويعطي شهران حوالي 0.82. لذلك يجب أن تجمع الخطة شهرين على الأقل من مجموعات الاستبعاد العشوائية قبل الحكم على العرض، وأن تذكر ذلك في الميثاق. فالقرار بعد شهر واحد قد يُنتج بسهولة "لا أثر ذا دلالة" حتى لو كان العرض ناجحًا.

الحجم يعتمد على من يُختار. قلة المتسرّبين في المجموعة المختارة تعني أحداثًا أقل للمقارنة، وبالتالي قوة أقل للعدد نفسه من العملاء. وقد أظهر الجزء C أن هذا الاختيار يخسر مالًا؛ وعندما يغيّر L91 من يُتواصل معهم، يتغير معدل تسرّب المجموعة المختارة، ويجب إعادة تشغيل محاكاة القوة للمجموعة الجديدة.

الجزء F — سجل استخدام الذكاء الاصطناعي

احتفظ بجدول قصير لكل استخدام للذكاء الاصطناعي في المشروع. وهو يجيب عن سؤال المراجع: "ماذا فعل الذكاء الاصطناعي، وكيف تعرف أنه كان صحيحًا؟":

التاريخ الأداة استُخدم في ما الذي فحصته ما الذي غيّرته أو رفضته
12 أكتوبر مساعد ذكاء اصطناعي مسودة قائمة المخاطر في الميثاق قارنت كل خطر بوقائع الحالة حذفت خطرين لا ينطبقان؛ وأضفت الطاقة الاستيعابية
14 أكتوبر مساعد ذكاء اصطناعي كود محاكاة القوة الإحصائية أعدت التشغيل على حالة معروفة (لا أثر ← "قوة" حوالي 5%) صحّحت اتجاه الاختبار أحادي الطرف

سجل استخدام الذكاء الاصطناعي جزء من المُخرَج، لا إضافة: فالنتيجة التي لا يمكن تتبّع مساعدة الذكاء الاصطناعي فيها لا يمكن مراجعتها.


5. مثال محلول

Cedar Lane (خيالية)، بيانات مصطنعة. يطلب مسؤول الاحتفاظ بالعملاء: "Plan the churn-offer project so that in three months I can tell the board what it was worth." (أي: "خطّط مشروع عرض الاحتفاظ بالعملاء بحيث أستطيع بعد ثلاثة أشهر أن أخبر مجلس الإدارة بقيمته.")

الخطوة 1 — الميثاق (U17): القرار: أي 400 عميل يحصلون على قسيمة الاحتفاظ الشهرية؛ وصاحبه: مسؤول الاحتفاظ بالعملاء؛ ومقياس النجاح: الهامش المحتفَظ به ناقص تكلفة العرض، مقاسًا مقابل مجموعة استبعاد عشوائية؛ والقيد: 400 تواصل شهريًا، بتكلفة 4 يورو لكل تواصل.

الخطوة 2 — البيانات والنموذج (الجزءان B–C): لعدد مرات التواصل نفسه، قاعدة الـ 90 يومًا البسيطة جيدة تقريبًا مثل النموذج (111 مقابل 114 متسرّبًا)؛ ويُحتفظ بالنموذج لأن الخطة تحتاج إلى ترتيب يمكن الجمع بينه وبين قيمة العميل، ويُبنى بسير عمل U20.

الخطوة 3 — الأثر المتوقع (الجزء C): مع خفض التجربة من 14% إلى 25%، التواصل مع أعلى 400 عميل خطرًا سيخسر حوالي 630 إلى 1,040 يورو شهريًا. فتُغيَّر الخطة قبل الإطلاق: الاستهداف حسب القيمة المتوقعة (L91)، ثم التقدير من جديد.

الخطوة 4 — القياس (الجزءان D–E): مجموعة استبعاد عشوائية بنسبة 20% كل شهر؛ وشهر واحد ليس دليلًا كافيًا؛ فاجمع شهرين على الأقل (قوة حوالي 0.82 لأعلى 400 عميل خطرًا) قبل القرار، وأعد تشغيل المحاكاة إذا تغير الاختيار.

الخطوة 5 — المراقبة: معدل التسرّب في مجموعتي العرض والاستبعاد كل شهر (المسؤول: مسؤول الاحتفاظ بالعملاء)، ونسبة العملاء الذين تُوصل معهم مرتين، وAUC النموذج على مجموعة استبعاد الشهر الماضي وعلى العملاء الذين لم يُتواصل معهم، وهم الذين لم يغيّر العرض نتائجهم (المسؤول: المحلّل)، مع مراجعة إذا انخفض AUC عن 0.75.

الخطوة 6 — سجل استخدام الذكاء الاصطناعي: كل مسودة أو كتلة كود ساعد فيها الذكاء الاصطناعي مدرجة مع ما فُحص.


6. شرح بصري

 1 CHARTER ─▶ 2 DATA ─▶ 3 MODEL? (rule vs model, baselines) ─▶ 4 EVALUATION (spread, costs) ─▶ 5 RECOMMENDATION
                                                                                         expected impact = contacts × risk
                                                                                         × measured reduction × margin − cost
                                                                                         (low / central / high from the pilot)
 6 MEASUREMENT: randomized HOLDOUT (strong) · A/B test (strong) · matched comparison (medium) · before/after (weak, caveats)
               size from a POWER SIMULATION (L69) → pool months until power ≈ 0.8
 7 MONITORING: KPIs · triggers · owners              ALWAYS: AI-use trail (tool · use · check · change)

وصف الرسم: سلسلة من سبع خطوات: الميثاق، والبيانات، وقرار هل النموذج مطلوب بمقارنة قاعدة بنموذج وبنماذج مقارنة، والتقييم مع التباين والتكاليف، وتوصية يساوي أثرها المتوقع عدد مرات التواصل × الخطر × الخفض المقاس × الهامش ناقص التكلفة، ويُعطى بقيم دنيا ووسطى وعليا من التجربة. وتُسرد تصاميم القياس حسب قوتها: مجموعة الاستبعاد العشوائية واختبار A/B قويان، والمقارنة المطابقة متوسطة، وقبل/بعد ضعيف مع تحفظات؛ ويأتي حجم مجموعة الاستبعاد من محاكاة للقوة، مع جمع الأشهر حتى تصل القوة إلى حوالي 0.8. والمراقبة فيها مؤشرات أداء ومحفّزات وأصحاب مسؤولية. ويمتد سجل لاستخدام الذكاء الاصطناعي يدوّن الأداة والاستخدام والفحص والتغيير عبر كل خطوة. (نصوص الرسم: CHARTER = الميثاق؛ DATA = البيانات؛ MODEL? (rule vs model, baselines) = نموذج؟ (قاعدة مقابل نموذج، ونماذج مقارنة)؛ EVALUATION (spread, costs) = التقييم (التباين، والتكاليف)؛ RECOMMENDATION = التوصية؛ expected impact = contacts × risk × measured reduction × margin − cost = الأثر المتوقع = التواصل × الخطر × الخفض المقاس × الهامش − التكلفة؛ low / central / high from the pilot = أدنى / أوسط / أعلى من التجربة؛ MEASUREMENT = القياس؛ randomized HOLDOUT (strong) = مجموعة استبعاد عشوائية (قوي)؛ matched comparison (medium) = مقارنة مطابقة (متوسط)؛ before/after (weak, caveats) = قبل/بعد (ضعيف، مع تحفظات)؛ size from a POWER SIMULATION = الحجم من محاكاة القوة؛ pool months until power ≈ 0.8 = اجمع الأشهر حتى تصل القوة إلى ≈ 0.8؛ MONITORING: KPIs · triggers · owners = المراقبة: مؤشرات الأداء · المحفّزات · أصحاب المسؤولية؛ ALWAYS: AI-use trail (tool · use · check · change) = دائمًا: سجل استخدام الذكاء الاصطناعي (الأداة · الاستخدام · الفحص · التغيير).)


7. تدريب موجَّه

افتح L90_starter.ipynb.

  1. اكتب ميثاقًا من ستة أسطر لحالة عرض الاحتفاظ بالعملاء (القرار، وصاحبه، ومقياس النجاح، والقيد، والبيانات، والموعد النهائي).
  2. قارن قاعدة الـ 90 يومًا بالنموذج على العملاء المحجوزين (الجزء B). وقرّر في جملة واحدة هل النموذج مطلوب.
  3. قدّر الخفض النسبي في التسرّب من التجربة مع مدى bootstrap (الجزء C).
  4. احسب درجات عملاء أكتوبر واحسب مدى الأثر المتوقع لـ 400 تواصل.
  5. شغّل محاكاة القوة من شهر إلى 4 أشهر، مستخدمًا متوسط الخطر المتنبأ به للعملاء المختارين، واختر فترة القياس.
  6. ابدأ سجلًا لاستخدام الذكاء الاصطناعي لهذا الدفتر (حتى لو لم تستخدمه: اكتب "لا شيء").
  7. شغّل Restart Kernel and Run All Cells….

8. تدريب مستقل

الجزء 1 — خطة لحالة جديدة. في نقاط الاستلام في Cedar Lane مشكلة عدم الحضور (no-shows): عملاء لا يستلمون طلباتهم. الوقائع (مصطنعة): حوالي 3,000 عملية استلام أسبوعيًا؛ ومعدل عدم الحضور حوالي 6%؛ وكل حالة عدم حضور تكلّف حوالي 3 يورو (المعالجة وإعادة التخزين)؛ ورسالة تذكير SMS تكلّف 0.05 يورو؛ وفريق نقاط الاستلام يعتقد أن التذكيرات قد تخفض عدم الحضور بمقدار الربع.

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

الجزء 2 — انتقد خطة زميل. تنتهي خطة زميل هكذا:

5. Train a random forest on last year's data.
6. Model accuracy 0.91 on the test set.
7. Deploy the model to the CRM. Project complete.

(ترجمة الخطوات: 5. درّب غابة عشوائية على بيانات العام الماضي. 6. دقة النموذج 0.91 على مجموعة الاختبار. 7. انشر النموذج في نظام إدارة علاقات العملاء CRM. اكتمل المشروع.)

اكتب نقدًا (من 100 إلى 150 كلمة): ما الناقص أو المضلّل في هذه الخطوات الثلاث؟ ثم أعد كتابة الخطوات 5–7 بحيث تنتهي الخطة بقرار، ومدى للأثر المتوقع، وتصميم للقياس.

اعمل في L90_starter.ipynb (قسم "Independent practice").


9. اختبار الفهم (Knowledge Check) — دليل المشروع

Q1. متى ينتهي المشروع من البداية إلى النهاية؟

  • A) عندما يصل النموذج إلى الدقة المستهدفة على مجموعة الاختبار المحجوزة
  • B) عندما يُتخذ القرار ويُقاس أثره
  • C) عندما يُشارك الدفتر وبطاقة النموذج مع الفريق
  • D) عندما يحين الموعد النهائي في الميثاق، أيًّا كانت حالة العمل

Q2. قاعدة بسيطة تكتشف عددًا من المتسرّبين يقارب ما يكتشفه النموذج لعدد مرات التواصل نفسه. ما الخطوة التالية السليمة؟

  • A) فضّل النموذج، لأنه يستخدم إشارات أكثر من القاعدة وسيتحسن مع نمو البيانات
  • B) تخلَّ عن الاثنين وانتظر عينة أكبر قبل تقرير أي شيء
  • C) فكّر في القاعدة: أبسط في التشغيل والشرح، ما لم يضف النموذج قيمة تستحق تكلفته
  • D) انشر الاثنين واترك نظام CRM يختار أحدهما عشوائيًا لكل عميل

Q3. من أين يجب أن يأتي "الخفض في التسرّب بسبب العرض" في تقدير الأثر المتوقع؟

  • A) من تجربة أو اختبار عشوائي، مع مداه
  • B) من AUC النموذج على مجموعة الاختبار، معدّلًا بحسب نسبة المتسرّبين
  • C) من أفضل تخمين لفريق الاحتفاظ بالعملاء، مذكورًا كرقم واحد دقيق
  • D) من نسبة العملاء الذين يصنّفهم النموذج عالي الخطر هذا الشهر

Q4. لماذا تُعد مقارنة قبل/بعد طريقة ضعيفة لقياس الأثر؟

  • A) تحتاج إلى محاكاة للقوة أولًا، ومن الصعب تشغيلها بشكل صحيح لبيانات التسرّب
  • B) تبالغ دائمًا في تقدير الأثر، بمقدار ثابت يعتمد على الموسم
  • C) لا يمكن حسابها إلا عندما يكون النموذج قد حسب درجة كل عميل
  • D) المواسم والأسعار والمنافسون يتغيرون أيضًا، فلا يكون الفرق أثر الإجراء وحده

Q5. ما مجموعة الاستبعاد؟

  • A) العملاء الذين لم يستطع النموذج حساب درجاتهم بسبب بيانات مفقودة
  • B) نسبة عشوائية من العملاء المؤهلين لا يُطبَّق عليهم الإجراء عمدًا
  • C) مجموعة الاختبار المحجوزة أثناء تدريب النموذج، وتُستخدم مرة واحدة في النهاية
  • D) العملاء الذين عُرضت عليهم القسيمة ثم اختاروا ألّا يستخدموها

Q6. محاكاة القوة تعطي 0.35 لشهر واحد من البيانات. ماذا يعني ذلك؟

  • A) الأثر الحقيقي بالحجم المخطط له لن يُكتشف إلا في حوالي مرة من كل ثلاث
  • B) العرض يغيّر سلوك حوالي 35% من العملاء الذين يتلقونه
  • C) يجب أن تضم مجموعة الاستبعاد 35% من العملاء المختارين للوصول إلى قوة كافية
  • D) سيعلن الاختبار خطأً وجود أثر في 35% من المرات حين لا يوجد أثر

Q7. لماذا يُعطى الأثر المتوقع في صورة مدى (أدنى، وأوسط، وأعلى)؟

  • A) لأن المديرين يجدون ثلاثة أرقام أسهل في القبول من رقم واحد دقيق
  • B) ليبدو التقدير أكثر حذرًا وعلمية مما يبدو عليه رقم واحد
  • C) لأن المدخلات غير مؤكدة، ويجب أن يصمد القرار عبر ذلك المدى
  • D) لأن AUC النموذج يُعرض بثلاثة أرقام عشرية

Q8. ماذا يجب أن يتضمن سجل استخدام الذكاء الاصطناعي؟

  • A) الإجابة النهائية التي أعطاها الذكاء الاصطناعي فقط، ملصقة كاملة حتى لا يضيع شيء
  • B) الأداة، وفيم استُخدمت، وما الذي فحصته، وما الذي غيّرته أو رفضته
  • C) عبارة تقول إنه لم يُستخدم ذكاء اصطناعي، تُضاف سواء استُخدم أم لا
  • D) درجة ثقة الذكاء الاصطناعي في كل إجابة، حتى يرى المراجعون الأجزاء التي وثق بها

10. الذكاء الاصطناعي في التطبيق (اختياري، وفي حدود)

الهدف: أن تطلب من مساعد ذكاء اصطناعي نقد خطة مشروعك، ولا تُبقي إلا الانتقادات التي تستطيع ربطها بوقائع الحالة.

  1. الصق خطتك (بلا بيانات عملاء) واسأل:

"Critique this analytics project plan: what is missing to show business impact?"

وبالعربية: "انتقد خطة مشروع التحليلات هذه: ما الناقص لإظهار الأثر على العمل؟"

  1. لكل انتقاد، اكتب واقعة الحالة التي يعتمد عليها. واحذف الانتقادات العامة أو التي لا تنطبق.
  2. سجّل المحادثة في سجل استخدام الذكاء الاصطناعي.

الحدود:

  • استخدام الذكاء الاصطناعي اختياري.
  • لا بيانات في الطلبات المكتوبة للذكاء الاصطناعي.
  • أنت من يقرّر أي الانتقادات صحيحة.

11. التحقق من مخرجات الذكاء الاصطناعي

  1. المقاييس: لكل مقياس نجاح في الخطة طريقة قياس ونقطة مرجعية (ما سيكون عليه دون الإجراء).
  2. حجم مجموعة الاستبعاد: تأكد من الحجم المخطط بمحاكاة القوة الخاصة بك (L69)، لا برقم أعطاه الذكاء الاصطناعي.
  3. الوقائع: كل رقم في الخطة يرجع إلى الحالة أو إلى دفترك.
  4. السجل: سجل استخدام الذكاء الاصطناعي يذكر الفحص الذي أجريته لكل استخدام.

12. منظور الأعمال

المشاريع لا تصنع قيمة إلا عندما يُقاس أثرها ويُتصرف بناءً عليه. النموذج الذي يرتّب جيدًا لكنه لا يُقارن أبدًا بمجموعة استبعاد يعطي العمل تكلفة واعتقادًا، لا نتيجة. والخطة التي فيها مدى للأثر المتوقع ومجموعة استبعاد تحوّل المشروع إلى قرار يستطيع مجلس الإدارة التحقق منه: "توقعنا من X إلى Y يورو؛ وقسنا Z يورو".


13. مهمة عمل — الخطة في فقرة واحدة

نشاط خيالي: Cedar Lane. اكتب الفقرة (من 80 إلى 120 كلمة) التي سيقرؤها مسؤول الاحتفاظ بالعملاء في اجتماع التخطيط: القرار، ومدى الأثر المتوقع لشهر واحد (من دفترك)، وكيف ستقيسه مجموعة الاستبعاد، وكم سيستغرق القياس ولماذا، والخطر الواحد الذي قد يغيّر الخطة.


14. تحدٍّ قصير — "لقد نجح!"

نشاط خيالي: Cedar Lane. بعد إطلاق برنامج ولاء جديد في 1 أبريل، يكتب زميل: "Churn fell from 24% (Jan–Mar) to 21% (Apr–Jun). The scheme works!" (أي: "انخفض التسرّب من 24% (يناير–مارس) إلى 21% (أبريل–يونيو). البرنامج ناجح!") وتجد أنت أرقام العام الماضي للأشهر نفسها.

before_after = pd.DataFrame({"Jan-Mar": [0.25, 0.24], "Apr-Jun": [0.22, 0.21]}, index=["last year (no scheme)", "this year (scheme from April)"])
before_after["change"] = before_after["Apr-Jun"] - before_after["Jan-Mar"]
print(before_after.to_string())
المخرجات: افتحها بعد أن تجيب عن السؤال 1
                               Jan-Mar  Apr-Jun  change
last year (no scheme)             0.25     0.22   -0.03
this year (scheme from April)     0.24     0.21   -0.03

(الصفّان: العام الماضي (بلا برنامج)، وهذا العام (البرنامج من أبريل)؛ والعمود change = التغير.)

  1. قبل أن تفتح المخرجات، اكتب كيف يجب أن تبدو أرقام العام الماضي حتى يكون زميلك محقًا.
  2. ماذا تقترح المقارنة مع العام الماضي عن أثر البرنامج؟
  3. أي تصميم كان سيقيس الأثر بشكل صحيح، وماذا كان سيحتاج عند الإطلاق؟
  4. اكتب جملة واحدة يحتفظ بها فريقك كقاعدة عن ادعاءات قبل/بعد.

سلّم عملك قبل أن تتلقى الملاحظات. لا يوجد حل منشور هنا.


15. المصادر

مطلوب (حوالي 25 دقيقة):

  • AWS Cloud Adoption Framework, Business Perspective: Data science (ورقة بيضاء من AWS): ابدأ من مشكلة العمل وقيمتها؛ وتحقق هل تعلّم الآلة مطلوب؛ ومقاييس أداء قابلة للقياس الكمي؛ وإثبات المفهوم، ثم التحقق من العائد على الاستثمار في الواقع. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/data-science.html (فُتح في 26 أكتوبر 2026.)

موصى به:

  • AWS Cloud Adoption Framework, Business Perspective: Business insights: حدّد القرارات التي تحتاج إلى رؤى وقِس أثرها (تذكر الصفحة أنها محفوظة كمرجع تاريخي). https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/business-insights.html (فُتح في 26 أكتوبر 2026.)
  • Ron Kohavi وDiane Tang وYa Xu: Trustworthy Online Controlled Experiments: A Practical Guide to A/B Testing (Cambridge University Press، 2020): المرجع في التجارب المضبوطة ومجموعات الاستبعاد. https://www.cambridge.org/core/books/trustworthy-online-controlled-experiments/D97B26382EB0EB2DC2019A7A7B518F59 (فُتح في 26 أكتوبر 2026.)

16. شخصية تتابعها / قدوة

Cassie Kozyrkov.

  • حقيقة مُتحقَّق منها: تصف نفسها في صفحتها الرئيسية بأنها "Decision Intelligence Pioneer" (رائدة في ذكاء القرار) و"Google's First Chief Decision Scientist" (أول كبيرة علماء القرار في Google) (فُتحت الصفحة في 26 أكتوبر 2026).
  • لماذا توصي بها D.World: تصوغ عمل البيانات حول القرارات: أي إجراء ستتخذه، وما الذي سيغيّر رأيك، وهذا بالضبط ما يجب أن تذكره خطة المشروع من البداية إلى النهاية.
  • ملاحظة صادقة: تابعها لتعرف كيف تصوغ القرارات؛ وتحقق من الادعاءات التقنية مقابل التوثيق، كما مع أي مؤلف.
  • جرّب هذا: في صفحتها الرئيسية، ابحث عن تعريفها لذكاء القرار في سطر واحد. وأعد كتابة السطر الأول من ميثاق التدريب الموجَّه بحيث يسمّي الإجراء، لا التحليل.

17. المصطلحات

المصطلح معناه في هذا الدرس
دورة حياة المشروع (Project lifecycle) خطوات المشروع المرتّبة: الميثاق، والبيانات، والتحليل أو النموذج، والتقييم، والتوصية، والقياس، والمراقبة
قياس الأثر (Impact measurement) التصميم الذي يُظهر ما غيّره الإجراء (مجموعة استبعاد، أو اختبار A/B، أو مقارنة مطابقة، أو قبل/بعد)
مجموعة الاستبعاد (Holdout group) جزء عشوائي من العملاء المؤهلين لا يُطبَّق عليهم الإجراء عمدًا، لإظهار النتيجة دون الإجراء
الأثر المتوقع (Expected impact) الأثر المقدَّر للقرار على العمل (مثل الهامش المحتفَظ به ناقص التكلفة)، مع مدى ناتج عن مدخلات غير مؤكدة
سجل استخدام الذكاء الاصطناعي (AI-use trail) جدول بكل استخدام للذكاء الاصطناعي في المشروع: الأداة، والغرض، وما فُحص، وما تغيّر
محاكاة القوة الإحصائية (Power simulation) تكرار اختبار مخطط له مرات كثيرة على بيانات محاكاة لمعرفة عدد مرات اكتشاف أثر حقيقي (L69)

للمراجعة: المواثيق (U17) · قوة اختبار A/B (L69) · اقتصاديات الوحدة (L67).


18. تأمّل

  1. أي من مشاريعك السابقة انتهى عند مقياس للنموذج؟ وما الخطوة الأخيرة التي كانت ناقصة؟
  2. متى ستقبل مقارنة قبل/بعد، وماذا ستكتب بجانبها؟
  3. من في فريق حقيقي يجب أن يعتمد تصميم القياس، ولماذا قبل الإطلاق؟

19. الخطوة التالية

التالي: L91 — عيادة حالة: تسرّب العملاء وتقييم الخطر بقاعدة استهداف قائمة على التكلفة (Case Clinic: Churn & Risk Scoring with a Cost-Based Targeting Rule). تصبح درجات النموذج قاعدة استهداف تضع الطاقة الشهرية حيث تنقذ أكبر قدر من الهامش.


20. أدلة التقييم

الدليل ماذا يُظهر كيف يُقيَّم
خطة مشروع عدم الحضور مع تصميم لقياس الأثر + سجل استخدام الذكاء الاصطناعي؛ والنقد وإعادة الكتابة (التدريب المستقل) الخطوات السبع؛ والقاعدة مقابل النموذج؛ ومدى الأثر المتوقع؛ وتصميم عشوائي مع القوة؛ والمراقبة؛ والسجل دليل التقييم L90-IP
الدفتر الموجَّه (الميثاق، والقاعدة مقابل النموذج، ومدى التجربة، ومدى الأثر، والقوة) خفض قائم على الأدلة؛ ومدى؛ وفترة قياس محددة من القوة دليل التقييم L90-GP
اختبار الفهم (Q1–Q8) نهاية المشروع؛ والقاعدة مقابل النموذج؛ وأدلة الأثر؛ وقبل/بعد؛ ومجموعة الاستبعاد؛ والقوة؛ والمدى؛ وسجل الذكاء الاصطناعي 7 إجابات صحيحة أو أكثر من 8
مهمة العمل والتحدي القصير الخطة في فقرة واحدة؛ وادعاء قبل/بعد دليلا التقييم L90-WT وL90-MC

المراجع

  1. Amazon Web Services. AWS Cloud Adoption Framework: Business Perspective — Data science. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/data-science.html (AWS-DS). يدعم: المشكلة والقيمة أولًا؛ وقد لا يكون تعلّم الآلة مطلوبًا (اقتباسات).
  2. Amazon Web Services. AWS Cloud Adoption Framework: Business Perspective — Business insights. https://docs.aws.amazon.com/whitepapers/latest/aws-caf-business-perspective/business-insights.html (AWS-BI).
  3. Kohavi, R., Tang, D. & Xu, Y. Trustworthy Online Controlled Experiments: A Practical Guide to A/B Testing. Cambridge University Press, 2020. https://www.cambridge.org/core/books/trustworthy-online-controlled-experiments/D97B26382EB0EB2DC2019A7A7B518F59 (KOHAVI). يدعم: الاقتباس من وصف الكتاب.
  4. Kozyrkov, C. Home page. https://www.kozyr.com/ (KOZYR). يدعم: وصف القدوة لنفسها.
  5. D.World Stage 4 Detailed Lesson Map v0.9 (صف L90). وثيقة داخلية.
L91 · Case Clinic: Churn & Risk Scoring with a Cost-Based Targeting Rule About 3 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

L92 · Case Clinic: Demand Forecasting with Features vs Baselines About 3 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

L93 · Case Clinic: Product Recommendations & Measuring Their Value About 3 hours Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

U21 Exit = Project 8 — End-to-End Business Project + Stage 4 Integrated Check Membersللمشتركين

The exit brief is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

تكليف نهاية الوحدة ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

Stage 4 Integrated Check Membersللمشتركين

This lesson is part of Starter and Membership. Starter gives you 7 days of full access for EGP 269. Membership is EGP 999 for 30 days.

هذا الدرس ضمن باقة البداية والاشتراك. باقة البداية تمنحك 7 أيام وصول كامل مقابل 269 جنيهًا، والاشتراك 999 جنيهًا لمدة 30 يومًا.

Keep goingاستمر

Finish each unit's exit check before you move on. Your certificate lists the checks you passed.

أنهِ تقييم نهاية كل وحدة قبل أن تنتقل. شهادتك تعرض التقييمات التي اجتزتها.