Machine Learning: الانحدار اللوجستي

آخر تحديث: 2026-08-26

الانحدار اللوجستي ليس حقًا "انحدارًا" — إنه مصنف قوي يُخرج الاحتمالات، وليس الأرقام الخام.

1. ما ستتعلمه


2. قصة حقيقية من عمليات SaaS

(1) نقطة الألم: اكتشاف التخلي متأخرًا جدًا، ومكلف استعادتهم

تدير Alice منصة SaaS تضم 50 ألف مستخدم نشط بمعدل تخلي شهري 8% — أي 4 آلاف مستخدم يُفقدون كل شهر. مع قيمة كل مستخدم حوالي 2 ألف دولار سنويًا، الخسارة الشهرية تقريبًا 670 ألف دولار. المشكلة: بحلول وقت إلغاء المستخدم للاشتراك، يكون الأوان قد فات — معدل نجاح الاستعادة أقل من 5%.

(2) حل الانحدار اللوجستي

يمكن للانحدار اللوجستي التنبؤ باحتمالية التخلي بمجرد أن يُظهر سلوك المستخدم علامات تحذير، مما يوفر إنذارًا مبكرًا يتراوح بين 2-4 أسابيع ويرفع معدل نجاح الاستعادة إلى 30%.

PYTHON
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report

model = LogisticRegression(class_weight="balanced")
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred, target_names=["Retained", "Churned"]))

(3) النتيجة: كل عميل مُستحق قيمته 2 ألف دولار

باستخدام الانحدار اللوجستي، تحدد Alice المستخدمين عالي مخاطر التخلي مسبقًا وتوفر 1.2 ألف مستخدم شهريًا، مما يضيف ما يقرب من 2.4 مليون دولار في الإيرادات السنوية. استعادة العميل تكلف حوالي 50 دولارًا — أقل بكثير من تكلفة 500 دولار لاكتساب عميل جديد.


3. من الخطي إلى اللوجستي

(1) دالة السيني

يستخدم الانحدار اللوجستي دالة السيني لضغط المخرجات الخطية في النطاق [0,1] كاحتمالية: $\sigma(z) = \frac{1}{1+e^{-z}}$

100%
graph LR
    INPUT[ميزات الإدخال x] --> LINEAR[تركيبة خطية<br/>z = w·x + b]
    LINEAR --> SIGMOID[دالة السيني<br/>σ = 1/(1+e^(-z))]
    SIGMOID --> PROB[P(y=1) = σ]
    PROB --> DECISION{P ≥ 0.5?}
    DECISION -->|نعم| CLASS1[الفئة 1<br/>مثلًا: متخلي]
    DECISION -->|لا| CLASS0[الفئة 0<br/>مثلًا: محتفظ]

▶ مثال: تصور دالة السيني

PYTHON
import numpy as np
import matplotlib.pyplot as plt

z = np.linspace(-8, 8, 100)
sigmoid = 1 / (1 + np.exp(-z))

fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(z, sigmoid, linewidth=2, color="#2196F3")
ax.axhline(0.5, color="red", linestyle="--", alpha=0.5, label="Decision boundary")
ax.axvline(0, color="gray", linestyle="--", alpha=0.3)
ax.set_xlabel("z (linear combination)")
ax.set_ylabel("σ(z) = P(y=1)")
ax.set_title("Sigmoid Function")
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig("sigmoid.png", dpi=150)

Output:

TEXT 📖 للعرض فقط
# Executed successfully

(2) خسارة الانتروبيا المتقاطعة

دالة الخسارة للانحدار اللوجستي هي الانتروبيا المتقاطعة (Log Loss):

$L = -\frac{1}{n}\sum[y\log(\hat{y}) + (1-y)\log(1-\hat{y})]$

التسمية الحقيقية الاحتمالية المتنبأ بها الخسارة البديهة
y=1 ŷ=0.99 0.01 عقوبة شبه معدومة
y=1 ŷ=0.5 0.69 عقوبة معتدلة
y=1 ŷ=0.01 4.60 عقوبة ضخمة
y=0 ŷ=0.01 0.01 عقوبة شبه معدومة
y=0 ŷ=0.99 4.60 عقوبة ضخمة

4. الانحدار اللوجستي مع Scikit-learn

▶ مثال: تصنيف ثنائي — التنبؤ بنية شراء المستخدم

PYTHON
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import numpy as np

rng = np.random.default_rng(42)
n = 1000
X = rng.standard_normal((n, 4))  # [وقت_التصفح, عدد_الصفحات, قيمة_السلة, عدد_الزيارات]
y = (X[:, 0] * 0.5 + X[:, 1] * 1.2 + X[:, 2] * 2.0 + rng.normal(0, 0.5, n) > 1.5).astype(int)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)

pipe = Pipeline([
    ("scaler", StandardScaler()),
    ("model", LogisticRegression(random_state=42)),
])
pipe.fit(X_train, y_train)
y_pred = pipe.predict(X_test)
y_prob = pipe.predict_proba(X_test)[:, 1]  # احتمالية الفئة 1

print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
print(f"\nConfusion Matrix:\n{confusion_matrix(y_test, y_pred)}")
print(f"\nClassification Report:\n{classification_report(y_test, y_pred)}")
print(f"\nSample probabilities: {y_prob[:5].round(3)}")

Output:

TEXT 📖 للعرض فقط
# Executed successfully

▶ مثال: تنبؤ Alice بتخلي مستخدمي SaaS

PYTHON
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score, precision_recall_fscore_support
import pandas as pd
import numpy as np

rng = np.random.default_rng(42)
n = 5000
df = pd.DataFrame({
    "tenure_months": rng.integers(1, 60, n),
    "monthly_usage_hours": rng.exponential(20, n),
    "support_tickets": rng.poisson(2, n),
    "payment_delay_days": rng.integers(0, 30, n),
    "plan_tier": rng.choice([1, 2, 3], n, p=[0.5, 0.35, 0.15]),
})

# منطق التخلي: مدة قصيرة + استخدام قليل + تذاكر كثيرة + تأخيرات
churn_score = (
    -0.05 * df["tenure_months"]
    - 0.1 * df["monthly_usage_hours"]
    + 0.5 * df["support_tickets"]
    + 0.1 * df["payment_delay_days"]
    + rng.normal(0, 1, n)
)
df["churned"] = (churn_score > 2).astype(int)
print(f"Churn rate: {df['churned'].mean():.1%}")

# التدريب بـ class_weight="balanced" للبيانات غير المتوازنة
X = df.drop(columns=["churned"])
y = df["churned"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)

model = LogisticRegression(class_weight="balanced", max_iter=500, random_state=42)
model.fit(X_train, y_train)

y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1]
auc = roc_auc_score(y_test, y_prob)
precision, recall, f1, _ = precision_recall_fscore_support(y_test, y_pred, average="binary")

print(f"AUC-ROC: {auc:.4f}")
print(f"Precision: {precision:.4f}, Recall: {recall:.4f}, F1: {f1:.4f}")

Output:

TEXT 📖 للعرض فقط
# Executed successfully

5. امتدادات متعددة الفئات

(1) One-vs-Rest مقابل Softmax

▶ مثال: متعدد الفئات — التصنيف التلقائي لفئات المنتجات

PYTHON
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score

X, y = load_iris(return_X_y=True)

# One-vs-Rest (افتراضي)
ovr_model = LogisticRegression(multi_class="ovr", max_iter=200)
ovr_scores = cross_val_score(ovr_model, X, y, cv=5, scoring="accuracy")

# Softmax (Multinomial)
softmax_model = LogisticRegression(multi_class="multinomial", max_iter=200)
softmax_scores = cross_val_score(softmax_model, X, y, cv=5, scoring="accuracy")

print(f"One-vs-Rest:  {ovr_scores.mean():.4f} +/- {ovr_scores.std():.4f}")
print(f"Softmax:      {softmax_scores.mean():.4f} +/- {softmax_scores.std():.4f}")

Output:

TEXT 📖 للعرض فقط
# Executed successfully
البُعد One-vs-Rest Softmax (Multinomial)
المبدأ K من المصنفات الثنائية مصنف واحد متعدد الفئات
معايرة الاحتمالات لا ضمان بأن مجموعها 1 مجموعها 1 بدقة
الكفاءة الحسابية قابل للتوازي يتطلب تحسينًا مشتركًا
الأفضل لـ فئات كثيرة فئات قليلة، تحتاج احتمالات

6. مقاييس التصنيف والخيارات التجارية

(1) مصفوفة الارتباك والمقاييس المشتقة

▶ مثال: منحنى ROC ومنحنى PR

PYTHON
from sklearn.metrics import roc_curve, auc, precision_recall_curve
import matplotlib.pyplot as plt
import numpy as np

# افترض y_test و y_prob من المثال السابق
rng = np.random.default_rng(42)
y_test = rng.choice([0, 1], 500, p=[0.85, 0.15])
y_prob = np.clip(y_test * 0.8 + rng.normal(0, 0.3, 500), 0, 1)

fig, axes = plt.subplots(1, 2, figsize=(14, 5))

# منحنى ROC
fpr, tpr, _ = roc_curve(y_test, y_prob)
roc_auc = auc(fpr, tpr)
axes[0].plot(fpr, tpr, color="#2196F3", lw=2, label=f"AUC = {roc_auc:.3f}")
axes[0].plot([0, 1], [0, 1], "r--", alpha=0.5)
axes[0].set_xlabel("False Positive Rate")
axes[0].set_ylabel("True Positive Rate")
axes[0].set_title("ROC Curve")
axes[0].legend()

# منحنى PR
precision_vals, recall_vals, _ = precision_recall_curve(y_test, y_prob)
axes[1].plot(recall_vals, precision_vals, color="#4CAF50", lw=2)
axes[1].set_xlabel("Recall")
axes[1].set_ylabel("Precision")
axes[1].set_title("Precision-Recall Curve")

plt.tight_layout()
plt.savefig("roc_pr_curves.png", dpi=150)

Output:

TEXT 📖 للعرض فقط
# Executed successfully

(2) اختيار المقاييس لسيناريو عملك

السيناريو المقياس ذو الأولوية السبب استراتيجية العتبة
تنبؤ تخلي المستخدمين Recall تفويت عميل متخلٍ مكلف خفض العتبة (0.3)
تصفية البريد المزعج Precision تصنيف بريد شرعي بشكل خاطئ غير مقبول رفع العتبة (0.7)
توصية المنتج F1 التوازن بين الدقة والتغطية الافتراضي (0.5)
كشف الاحتيال Recall تفويت الاحتيال مكلف للغاية خفض العتبة (0.2)
📌 نقطة رئيسية: في تنبؤ التخلي، يهم الاستدعاء أكثر من الدقة — تفويت عميل متخلٍ واحد يكلف 2 ألف دولار، بينما إنذار كاذب على عميل محتفظ يهدر 50 دولارًا فقط في تكاليف الاستعادة. ضبط عتبة القرار يمكن أن يحسن القيمة التجارية.


❓ أسئلة شائعة

س لماذا يُسمى الانحدار اللوجستي "انحدارًا"؟
ج لأسباب تاريخية — إنه يصمم بطريقة انحدار (تركيبة خطية)، لكن المخرج يمر عبر السيني ليصبح احتمالية فئة. إنه في الأساس خوارزمية تصنيف؛ الاسم مضلل.
س ماذا يعني class_weight=balanced؟
ج يزن تلقائيًا كل فئة بمقلوب تكرارها، مما يعطي فئة الأقلية وزنًا أعلى. مع معدل تخلي 8%، يكون وزن فئة المتخلين = 1/0.08 = 12.5، ووزن فئة المحتفظين = 1/0.92 = 1.09.
س هل يجب أن تكون عتبة القرار 0.5؟
ج لا على الإطلاق. 0.5 هو الافتراضي فقط، لكن السيناريوهات التجارية غالبًا تستدعي الضبط. لتنبؤ التخلي يمكنك خفضها إلى 0.3 (تعزيز الاستدعاء)؛ للبريد المزعج يمكنك رفعها إلى 0.7 (تعزيز الدقة). دع التكاليف التجارية تقود العتبة.
س أيهما أفضل، ROC-AUC أم PR-AUC؟
ج انظر إلى ROC-AUC عندما تكون الفئات متوازنة، و PR-AUC عندما تكون غير متوازنة بشدة. لتنبؤ التخلي (8% مقابل 92%)، يوصى بـ PR-AUC.
س هل يمكن للانحدار اللوجستي التعامل مع العلاقات غير الخطية؟
ج ليس افتراضيًا. ولكن يمكنك إضافة ميزات متعددة الحدود (PolynomialFeatures) ليتعلم حدود قرار غير خطية — essentially doing linear classification in a higher-dimensional space.
س ما فائدة تنظيم L1 في الانحدار اللوجستي؟
ج نفس الانحدار الخطي — ينتج L1 حلولًا متفرقة ويؤدي اختيار الميزات التلقائي. استخدم LogisticRegression(penalty="l1", solver="saga") لتمكين L1.

📖 ملخص

📝 تمارين

  1. أساسي (الصعوبة ⭐): استخدم الانحدار اللوجستي للتصنيف متعدد الفئات على مجموعة بيانات Iris، واطبع الدقة و classification_report. تلميح: LogisticRegression(max_iter=200) + classification_report.
  2. متوسط (الصعوبة ⭐⭐): محاكاة مجموعة بيانات غير متوازنة (95:5) وقارن الاستدعاء للانحدار اللوجستي الافتراضي مقابل class_weight="balanced". تلميح: استخدم make_classification(weights=[0.95, 0.05]).
  3. تحدي (الصعوبة ⭐⭐⭐): نفّذ خط أنابيب تنبؤ التخلي الكامل لـ Alice — ولّد بيانات مستخدمي SaaS المحاكاة، ودرب نموذج الانحدار اللوجستي، وارسم منحنيات ROC/PR، واحسب Recall/Precision/F1 عند عتبات مختلفة، واعثر على العتبة المثلى تجاريًا. تلميح: roc_curve + precision_recall_curve + تكرار على العتبات.

← الدرس السابق: الانحدار الخطي | الدرس التالي: أشجار القرار والغابات العشوائية →

Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%