{"id":"l-ml-1-3","courseId":"ml-crash-course","lang":"ar","kind":"lesson","summary":"استخدم أي نموذج في scikit-learn عبر الاستدعاءات الثلاثة نفسها (fit وpredict وscore)، واقرأ ما تعلّمه النموذج بعد التدريب، واكتشف الحفظ بمقارنة نتيجتي التدريب والاختبار.","html":"<p>يأتي scikit-learn بعشرات النماذج، من الخطوط المستقيمة إلى غابات الأشجار، وتستخدمها جميعًا بالطريقة نفسها. تعلّم ثلاثة استدعاءات وستستطيع تجربة أيّ منها على بيانات الانقطاع في بضعة أسطر. هذا الاتساق هو السبب الرئيسي في كون scikit-learn المكتبة الافتراضية لتعلّم الآلة الكلاسيكي.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">ثلاثة استدعاءات</h2>\n<p>النموذج في scikit-learn هو <strong>estimator (مقدِّر)</strong>: كائن Python تنشئه بإعداداته، وتدرّبه بـ <code dir=\"ltr\">fit</code>، وتستخدمه بـ <code dir=\"ltr\">predict</code> و<code dir=\"ltr\">score</code>.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"0\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">from</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> sklearn.model_selection </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> train_test_split</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">from</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> sklearn.tree </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> DecisionTreeClassifier</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">churn </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.read_csv(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"churn.csv\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">features </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"tenure_days\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"orders\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"total_spent\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"avg_order_value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">            \"days_since_last_order\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"used_coupon\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"support_tickets\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"mobile_share\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">X, y </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> churn[features], churn[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"churned\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">X_train, X_test, y_train, y_test </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> train_test_split(</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    X, y, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">test_size</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0.25</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">random_state</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">42</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">stratify</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">y)</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">model </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> DecisionTreeClassifier(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">max_depth</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">random_state</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">42</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)  </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># 1. create</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">model.fit(X_train, y_train)                                    </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># 2. learn</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(model.predict(X_test)[:</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">10</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])                              </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># 3. use</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"train accuracy:\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">round</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(model.score(X_train, y_train), </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"test accuracy: \"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">round</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(model.score(X_test, y_test), </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">))</span></span></code></pre><div class=\"run-output\" data-run-output=\"0\" hidden></div></div>\n<p>ما يفعله كل استدعاء:</p>\n<ul>\n<li><strong>الـ constructor</strong> يأخذ <strong>الـ hyperparameters</strong>: خيارات تحدّدها قبل التدريب. <code dir=\"ltr\">max_depth=3</code> تعني أن الشجرة لا تطرح أكثر من ثلاثة أسئلة متتالية. و<code dir=\"ltr\">random_state=42</code> تجعل كسر التعادلات قابلًا للتكرار.</li>\n<li><strong><code dir=\"ltr\">fit(X_train, y_train)</code></strong> تنظر في الأمثلة وتتعلّم <strong>معاملات (parameters)</strong> النموذج. في الشجرة، هذه المعاملات هي الأسئلة والعتبات (“هل <code dir=\"ltr\">days_since_last_order</code> أكبر من 236.5؟”). وتُعيد النموذج نفسه، لذا يعمل أيضًا <code dir=\"ltr\">model = DecisionTreeClassifier().fit(X, y)</code>.</li>\n<li><strong><code dir=\"ltr\">predict(X)</code></strong> تُعيد تنبؤًا واحدًا لكل صف: وهنا مصفوفة من الأصفار والآحاد.</li>\n<li><strong><code dir=\"ltr\">score(X, y)</code></strong> تتنبأ ثم تقارن بالإجابات الحقيقية. في المصنِّفات تُعيد الـ <strong>accuracy (الدقة)</strong>، أي نسبة التنبؤات الصحيحة. وفي نماذج الانحدار تُعيد R²، الذي ستتعرّف عليه في القسم 2.</li>\n</ul>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 680 190\" role=\"img\" aria-labelledby=\"l-ml-1-3-t1\"><defs><marker id=\"arrow-l-ml-1-3-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-ml-1-3-t1\">يُنشأ الـ estimator بالـ hyperparameters، ثم يُدرَّب على بيانات التدريب ليتعلّم معاملات تُخزَّن في سمات تنتهي بشرطة سفلية، ثم يُستخدم للتنبؤ على بيانات جديدة أو لحساب النتيجة مقابل إجابات معروفة.</title>\n  <rect class=\"d-box\" x=\"20\" y=\"60\" width=\"150\" height=\"64\" rx=\"12\"/>\n  <text class=\"d-code\" x=\"95\" y=\"88\" text-anchor=\"middle\">Model(max_depth=3)</text>\n  <text class=\"d-label-muted\" x=\"95\" y=\"110\" text-anchor=\"middle\">hyperparameters</text>\n  <path class=\"d-arrow\" d=\"M170 92 L250 92\" marker-end=\"url(#arrow-l-ml-1-3-1)\"/>\n  <text class=\"d-code\" x=\"210\" y=\"80\" text-anchor=\"middle\">fit</text>\n  <rect class=\"d-box-primary\" x=\"255\" y=\"60\" width=\"170\" height=\"64\" rx=\"12\"/>\n  <text class=\"d-label\" x=\"340\" y=\"88\" text-anchor=\"middle\">نموذج مدرَّب</text>\n  <text class=\"d-code\" x=\"340\" y=\"110\" text-anchor=\"middle\">classes_, tree_ …</text>\n  <path class=\"d-arrow\" d=\"M425 80 L505 40\" marker-end=\"url(#arrow-l-ml-1-3-1)\"/>\n  <path class=\"d-arrow\" d=\"M425 104 L505 146\" marker-end=\"url(#arrow-l-ml-1-3-1)\"/>\n  <rect class=\"d-box-accent\" x=\"510\" y=\"16\" width=\"150\" height=\"48\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"585\" y=\"45\" text-anchor=\"middle\">predict(X)</text>\n  <rect class=\"d-box-success\" x=\"510\" y=\"122\" width=\"150\" height=\"48\" rx=\"10\"/>\n  <text class=\"d-code\" x=\"585\" y=\"151\" text-anchor=\"middle\">score(X, y)</text>\n</svg><figcaption>دورة حياة الـ estimator</figcaption></figure>\n<h2 id=\"sec-2\" tabindex=\"-1\">ما الذي يعرفه النموذج بعد التدريب</h2>\n<p>كل ما يتعلّمه النموذج أثناء <code dir=\"ltr\">fit</code> يُخزَّن في سمات (attributes) تنتهي أسماؤها بشرطة سفلية. وهي غير موجودة قبل <code dir=\"ltr\">fit</code>؛ فطلب إحداها يرفع <code dir=\"ltr\">AttributeError</code>، واستدعاء <code dir=\"ltr\">predict</code> على نموذج غير مدرَّب يرفع <code dir=\"ltr\">NotFittedError</code>.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"1\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">from</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> sklearn.model_selection </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> train_test_split</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">from</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> sklearn.tree </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> DecisionTreeClassifier</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">churn </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.read_csv(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"churn.csv\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">features </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"tenure_days\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"orders\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"total_spent\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"avg_order_value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">            \"days_since_last_order\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"used_coupon\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"support_tickets\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"mobile_share\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">X_train, X_test, y_train, y_test </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> train_test_split(</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    churn[features], churn[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"churned\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], </span><span style=\"color:#953800;--shiki-dark:#FFA657\">test_size</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0.25</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">random_state</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">42</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">    stratify</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">churn[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"churned\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">model </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> DecisionTreeClassifier(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">max_depth</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">random_state</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">42</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">).fit(X_train, y_train)</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(model.classes_)            </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># the labels it saw: [0 1]</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(model.n_features_in_)      </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># 8</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(model.feature_names_in_[:</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">new_customer </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.DataFrame([{</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"tenure_days\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">400</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"orders\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">2</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"total_spent\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">180.0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"avg_order_value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">90.0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"days_since_last_order\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">150</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"used_coupon\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"support_tickets\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"mobile_share\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0.5</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}])</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(model.predict(new_customer))        </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># [1]: likely to churn</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(model.predict_proba(new_customer))  </span><span style=\"color:#6E7781;--shiki-dark:#8B949E\"># [[0.36 0.64]]</span></span></code></pre><div class=\"run-output\" data-run-output=\"1\" hidden></div></div>\n<p>تعطيك <code dir=\"ltr\">predict_proba</code> الاحتمال الذي يقدّره النموذج لكل فئة، بترتيب <code dir=\"ltr\">classes_</code>. هذا العميل يحصل على 64% للانقطاع. ستعتمد على الاحتمالات كثيرًا في القسم 3، لأنها تتيح لك أن تختار مقدار الحذر الذي تريده.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">نتيجة التدريب تكذب</h2>\n<p>أزل الآن حدّ العمق وراقب ما يحدث. الشجرة غير المحدودة تواصل طرح الأسئلة حتى يجلس كل عميل من عملاء التدريب في ورقة لا تحوي إلا فئته.</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-run=\"python\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"python\" data-index=\"2\" aria-label=\"شغّل هذا المثال\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pandas </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">as</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">from</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> sklearn.model_selection </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> train_test_split</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">from</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> sklearn.tree </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> DecisionTreeClassifier</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">from</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> sklearn.neighbors </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> KNeighborsClassifier</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">churn </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> pd.read_csv(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"churn.csv\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">features </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"tenure_days\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"orders\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"total_spent\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"avg_order_value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">            \"days_since_last_order\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"used_coupon\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"support_tickets\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"mobile_share\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">X_train, X_test, y_train, y_test </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> train_test_split(</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    churn[features], churn[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"churned\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], </span><span style=\"color:#953800;--shiki-dark:#FFA657\">test_size</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0.25</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">random_state</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">42</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#953800;--shiki-dark:#FFA657\">    stratify</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">churn[</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"churned\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">for</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> model </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">in</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [DecisionTreeClassifier(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">max_depth</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">random_state</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">42</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">),</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">              DecisionTreeClassifier(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">random_state</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">42</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">),</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">              KNeighborsClassifier(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">n_neighbors</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">5</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)]:</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    model.fit(X_train, y_train)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">    print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">f</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">{</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">model</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">!r:55}</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> train </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">{</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">model.score(X_train, y_train)</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:.2f}</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">  test </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">{</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">model.score(X_test, y_test)</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:.2f}</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span></code></pre><div class=\"run-output\" data-run-output=\"2\" hidden></div></div>\n<p>الشجرة غير المحدودة مثالية على العملاء الـ 298 الذين درستهم، وأسوأ من الشجرة الضحلة على المئة الذين لم ترَهم. لقد حفظت خصوصيات العملاء الأفراد. هذه الفجوة بين أداء التدريب وأداء الاختبار هي <strong>الـ overfitting (الإفراط في التوافق)</strong>، وستقضي جزءًا كبيرًا من القسم 2 في تعلّم كيفية التحكم فيها.</p>\n<p>لاحظ أيضًا النموذج الثالث. خوارزمية أقرب k جيران (k-nearest neighbours) لا تشبه الشجرة في شيء (فهي تتنبأ بالنظر إلى أكثر خمسة عملاء تدريب تشابهًا)، ومع ذلك الكود متطابق. تبديل النموذج يكلّفك سطرًا واحدًا.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">العقد نفسه، والافتراضات مختلفة</h2>\n<p>الواجهة المشتركة تُخفي أفكارًا مختلفة جدًا عن العالم. فالشجرة تفترض أن الانقطاع يمكن وصفه بعدد قليل من أسئلة نعم/لا ذات حدود فاصلة حادة. وأقرب k جيران تفترض أن العملاء المتشابهين يتصرّفون بالطريقة نفسها، حيث “التشابه” يعني القرب حين يُعامَل كل عمود كمسافة. لا أحد الافتراضين صحيح بإطلاق؛ كلٌّ منهما مفيد في مواقف وخاطئ في أخرى. ولهذا تجرّب عدة نماذج على التقسيم نفسه بدل أن تتجادل حول أيّها يجب أن يفوز.</p>\n<p>نماذج الانحدار تلتزم العقد نفسه. <code dir=\"ltr\">DecisionTreeRegressor</code> و<code dir=\"ltr\">LinearRegression</code> تأخذان <code dir=\"ltr\">y</code> رقميًا، وتُعيد <code dir=\"ltr\">predict</code> أرقامًا بدل الفئات، وتُعيد <code dir=\"ltr\">score</code> قيمة R² بدل الـ accuracy. كل ما تتعلّمه عن estimator واحد ينتقل إلى البقية.</p>\n<p>تفصيلتان توفّران عليك الارتباك لاحقًا. استدعاء <code dir=\"ltr\">fit</code> مرة ثانية يمحو ما تعلّمه النموذج من قبل ويبدأ من الصفر؛ ولا يضيف إلى معرفته القديمة. والإعدادات التي مرّرتها إلى الـ constructor تبقى مقروءة كسمات عادية (<code dir=\"ltr\">model.max_depth</code>)، فيمكنك دائمًا التحقق مما طُلب من نموذج مدرَّب أن يفعله.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">خطأ شائع</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>تمرير جدول بشكل مختلف إلى predict</span></p>\n<p>تحتاج <code dir=\"ltr\">predict</code> إلى الأعمدة نفسها وبالترتيب نفسه كما في <code dir=\"ltr\">fit</code>. مرّر DataFrame أعمدته مبعثرة وسيرفع scikit-learn الخطأ <code dir=\"ltr\">ValueError: The feature names should match those that were passed during fit</code>. ومرّر مصفوفة NumPy مجرّدة ولن يستطيع التحقق من الأسماء إطلاقًا: سيعطي تحذيرًا ويستخدم الأعمدة بحسب مواقعها، ما يعطي إجابات خاطئة بصمت إذا اختلف ترتيبك. ابنِ مدخلات التنبؤ من قائمة <code dir=\"ltr\">features</code> نفسها التي درّبت بها.</p>\n</aside>\n<p>لديك الآن نموذج بدقة 73% على بيانات الاختبار. هل هذا جيد؟ لا يمكنك الحكم بعد، لأنك لم تسأل كم سيحقق نموذج بلا أي ذكاء على الإطلاق. هذا هو موضوع الدرس القادم.</p>\n","toc":[{"id":"sec-1","text":"ثلاثة استدعاءات","level":2},{"id":"sec-2","text":"ما الذي يعرفه النموذج بعد التدريب","level":2},{"id":"sec-3","text":"نتيجة التدريب تكذب","level":2},{"id":"sec-4","text":"العقد نفسه، والافتراضات مختلفة","level":2}],"takeaways":["كل estimator في scikit-learn يُنشأ بإعداداته، ويتعلّم في <code dir=\"ltr\">fit(X, y)</code>، ويُستخدم عبر <code dir=\"ltr\">predict(X)</code> و<code dir=\"ltr\">score(X, y)</code>.","الـ hyperparameters مثل <code dir=\"ltr\">max_depth</code> تحدّدها أنت قبل التدريب؛ أما المعاملات (parameters) مثل عتبات التقسيم فتُتعلَّم أثناء <code dir=\"ltr\">fit</code>.","سمات (attributes) النموذج المدرَّب تنتهي بشرطة سفلية (<code dir=\"ltr\">classes_</code> و<code dir=\"ltr\">feature_names_in_</code>) ولا توجد إلا بعد <code dir=\"ltr\">fit</code>.","تُعيد <code dir=\"ltr\">score</code> قيمة الـ accuracy للمصنِّفات وقيمة R² لنماذج الانحدار.","الفجوة الكبيرة بين نتيجتي التدريب والاختبار تعني أن النموذج حفظ صفوف تدريبه."],"further":[{"title":"Getting started: fitting and predicting","url":"https://scikit-learn.org/stable/getting_started.html"},{"title":"DecisionTreeClassifier","url":"https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html"},{"title":"Glossary: estimator, fit, predict","url":"https://scikit-learn.org/stable/glossary.html"}],"quiz":[{"q":"<p>ماذا يطبع هذا الكود؟</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"python\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Python</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">from</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> sklearn.tree </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">import</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> DecisionTreeClassifier</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">model </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> DecisionTreeClassifier(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">max_depth</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">3</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)</span></span>\n<span class=\"line\"><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">print</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(model.classes_)</span></span></code></pre></div>\n","options":[{"text":"<code dir=\"ltr\">[0 1]</code>، أي فئتا الانقطاع.","why":"<code dir=\"ltr\">classes_</code> تُتعلَّم من <code dir=\"ltr\">y</code> أثناء <code dir=\"ltr\">fit</code>. وهذا النموذج لم يرَ أي بيانات بعد."},{"text":"<code dir=\"ltr\">None</code>، لأنه لم تُحدَّد أي فئات بعد.","why":"لا ينشئ scikit-learn السمات التي يتعلّمها التدريب بقيمة <code dir=\"ltr\">None</code>. فهي غير موجودة أصلًا حتى يُنفَّذ <code dir=\"ltr\">fit</code>."},{"text":"خطأ <code dir=\"ltr\">AttributeError</code>، لأن <code dir=\"ltr\">classes_</code> لا توجد إلا بعد <code dir=\"ltr\">fit</code>.","why":"صحيح. الشرطة السفلية في آخر الاسم تدلّ على سمة ينشئها <code dir=\"ltr\">fit</code>."}],"answer":2},{"q":"<p>شجرة تحقق 1.00 على بيانات التدريب و0.72 على بيانات الاختبار. وشجرة بعمق 3 تحقق 0.78 و0.73. أيّهما النموذج الأفضل لـ Cartwheel؟</p>","options":[{"text":"الشجرة غير المحدودة، لأن 1.00 تُظهر أنها التقطت كل نمط.","why":"النتيجة المثالية في التدريب على بيانات مليئة بالضجيج مثل بيانات الانقطاع تعني أنها حفظت العملاء فردًا فردًا. ونتيجتها في الاختبار أقل."},{"text":"الشجرة بعمق 3، لأنها تؤدي على الأقل بالمستوى نفسه مع عملاء لم ترَهم، وهي أبسط بكثير.","why":"صحيح. احكم على البيانات المحجوزة؛ وحين تتعادل النتائج، فضّل النموذج ذا الأجزاء المتحركة الأقل."},{"text":"هما متساويتان، لأن نتيجتي الاختبار لا تختلفان إلا بـ 0.01.","why":"نتيجتا الاختبار متقاربتان، لكن الشجرة بعمق 3 أسهل في الشرح وأقل عرضة للتذبذب مع بيانات جديدة. وهذا يحسم التعادل."}],"answer":1},{"q":"<p>أيّ هذه القيم hyperparameter وليست معاملًا متعلَّمًا؟</p>","options":[{"text":"<code dir=\"ltr\">max_depth=3</code> الممرَّرة إلى <code dir=\"ltr\">DecisionTreeClassifier</code>","why":"صحيح. أنت تختارها قبل التدريب، وهي تحدّ من مدى تعقيد الشجرة المتعلَّمة."},{"text":"العتبة <code dir=\"ltr\">days_since_last_order &lt;= 236.5</code> في جذر شجرة مدرَّبة","why":"هذه العتبة يجدها <code dir=\"ltr\">fit</code> من البيانات. فهي معامل متعلَّم."},{"text":"<code dir=\"ltr\">coef_</code> في نموذج <code dir=\"ltr\">LinearRegression</code> مدرَّب","why":"المعاملات تُتعلَّم من البيانات، ولهذا تحمل الشرطة السفلية في آخر اسمها."}],"answer":0},{"q":"<p>درّبت نموذجًا على DataFrame أعمدته بترتيب معيّن، ثم استدعيت <code dir=\"ltr\">predict</code> على DataFrame فيه الأعمدة نفسها بترتيب مختلف. ماذا يحدث؟</p>","options":[{"text":"يعيد scikit-learn ترتيب الأعمدة نيابةً عنك ويتنبأ بشكل صحيح.","why":"يتحقق scikit-learn من الأسماء لكنه لا يعيد الترتيب. بل يرفض بدل أن يخمّن."},{"text":"يرفع <code dir=\"ltr\">ValueError</code> يقول إن أسماء الـ features يجب أن تكون بالترتيب نفسه كما في fit.","why":"صحيح. هذا الفحص يحميك من إدخال <code dir=\"ltr\">orders</code> بصمت في الخانة التي تعلّمها النموذج على أنها <code dir=\"ltr\">tenure_days</code>."},{"text":"يتنبأ بصمت مستخدمًا الأعمدة بحسب مواقعها.","why":"هذا ما يحدث مع مصفوفة NumPy التي لا أسماء لها. أما مع DataFrame فيلتقط فحص الأسماء عدم التطابق."}],"answer":1}],"exercise":{"kind":"python","files":["churn.csv"],"starter":"import pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.tree import DecisionTreeClassifier\n\nchurn = pd.read_csv(\"churn.csv\")\nfeatures = [\"tenure_days\", \"orders\", \"total_spent\", \"avg_order_value\",\n            \"days_since_last_order\", \"used_coupon\", \"support_tickets\", \"mobile_share\"]\nX_train, X_test, y_train, y_test = train_test_split(\n    churn[features], churn[\"churned\"], test_size=0.25, random_state=42,\n    stratify=churn[\"churned\"])\n\nnew_customer = pd.DataFrame([{\n    \"tenure_days\": 120, \"orders\": 6, \"total_spent\": 940.0, \"avg_order_value\": 156.7,\n    \"days_since_last_order\": 12, \"used_coupon\": 1, \"support_tickets\": 0,\n    \"mobile_share\": 0.8}])\n\n# 1. A tree limited to depth 3, and a tree with no depth limit (both random_state=42)\nshallow = DecisionTreeClassifier(max_depth=3, random_state=42)\ndeep = DecisionTreeClassifier(random_state=42)\n\n# 2. Fit both on the training data, then fill in the scores\nshallow_test = None\ndeep_train = None\ndeep_test = None\n\n# 3. The shallow tree's prediction (0 or 1) for new_customer\nnew_pred = None\n","solution":"import pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.tree import DecisionTreeClassifier\n\nchurn = pd.read_csv(\"churn.csv\")\nfeatures = [\"tenure_days\", \"orders\", \"total_spent\", \"avg_order_value\",\n            \"days_since_last_order\", \"used_coupon\", \"support_tickets\", \"mobile_share\"]\nX_train, X_test, y_train, y_test = train_test_split(\n    churn[features], churn[\"churned\"], test_size=0.25, random_state=42,\n    stratify=churn[\"churned\"])\n\nnew_customer = pd.DataFrame([{\n    \"tenure_days\": 120, \"orders\": 6, \"total_spent\": 940.0, \"avg_order_value\": 156.7,\n    \"days_since_last_order\": 12, \"used_coupon\": 1, \"support_tickets\": 0,\n    \"mobile_share\": 0.8}])\n\nshallow = DecisionTreeClassifier(max_depth=3, random_state=42).fit(X_train, y_train)\ndeep = DecisionTreeClassifier(random_state=42).fit(X_train, y_train)\n\nshallow_test = shallow.score(X_test, y_test)\ndeep_train = deep.score(X_train, y_train)\ndeep_test = deep.score(X_test, y_test)\n\nnew_pred = int(shallow.predict(new_customer)[0])\n\nprint(f\"shallow test {shallow_test:.2f} | deep train {deep_train:.2f}, test {deep_test:.2f}\")\n","checks":[{"id":"fitted","test":"hasattr(shallow, 'classes_') and hasattr(deep, 'classes_') and shallow.max_depth == 3 and deep.max_depth is None"},{"id":"shallow-test","test":"shallow_test is not None and abs(float(shallow_test) - 0.73) < 0.005"},{"id":"deep-scores","test":"deep_train is not None and float(deep_train) == 1.0 and abs(float(deep_test) - 0.72) < 0.005"},{"id":"prediction","test":"new_pred is not None and int(__import__('numpy').ravel(new_pred)[0]) == 0"}],"title":"درّب شجرتين وقارن بينهما","prompt":"<p>درّب شجرتي قرار على بيانات تدريب الانقطاع وشاهد الحفظ بالأرقام.</p>\n<ol>\n<li>درّب <code dir=\"ltr\">shallow</code> (<code dir=\"ltr\">max_depth=3</code>) و<code dir=\"ltr\">deep</code> (بلا حدّ للعمق)، وكلتاهما بـ <code dir=\"ltr\">random_state=42</code>.</li>\n<li>اجعل <code dir=\"ltr\">shallow_test</code> دقة الشجرة الضحلة على بيانات الاختبار، و<code dir=\"ltr\">deep_train</code> / <code dir=\"ltr\">deep_test</code> دقة الشجرة العميقة على بيانات التدريب والاختبار.</li>\n<li>اجعل <code dir=\"ltr\">new_pred</code> تنبؤ الشجرة الضحلة (0 أو 1) للعميل <code dir=\"ltr\">new_customer</code>.</li>\n</ol>\n","hints":["تُعيد <code dir=\"ltr\">fit</code> النموذج نفسه، لذا يعمل <code dir=\"ltr\">DecisionTreeClassifier(...).fit(X_train, y_train)</code> في سطر واحد.","تُعيد <code dir=\"ltr\">model.score(X, y)</code> قيمة الـ accuracy في المصنِّفات.","تُعيد <code dir=\"ltr\">predict</code> مصفوفة فيها قيمة لكل صف؛ خذ العنصر <code dir=\"ltr\">[0]</code> للعميل الجديد الوحيد."],"explanation":"<p>تحقق الشجرة العميقة 1.00 على العملاء الذين تدرّبت عليهم و0.72 على الجدد؛ بينما تحقق الشجرة بعمق 3 قيمة 0.73 على الجدد بجزء يسير من القواعد. نتيجة التدريب لنموذج مرن لا تخبرك بشيء يُذكر. العميل الجديد طلب قبل 12 يومًا ولديه ستة طلبات، فتتنبأ الشجرة الضحلة بـ 0 (سيبقى).</p>\n","checkLabels":{"fitted":"الشجرتان مدرَّبتان بإعدادات العمق الصحيحة","shallow-test":"shallow_test هي دقة الشجرة الضحلة على بيانات الاختبار","deep-scores":"deep_train وdeep_test هما نتيجتا الشجرة العميقة","prediction":"new_pred هو تنبؤ الشجرة الضحلة للعميل new_customer"}},"words":604,"readMinutes":4}