Loading
Loading
على الرغم من اسمها، Logistic Regression هي خوارزمية تصنيف لا انحدار. إنها أساس كل نماذج الـ Classification الحديثة.
تخيّل أنك تحاول التنبؤ بما إذا كان بريد إلكتروني مزعجاً:
σ(z) = 1 / (1 + e^(-z))
هذه الدالة تحوّل أي رقم إلى قيمة بين 0 و 1:
القرار:
إذا σ(z) ≥ 0.5 → الفئة 1 (مزعج)
إذا σ(z) < 0.5 → الفئة 0 (حقيقي)
عندما يكون لديك أكثر من فئتين، هناك طريقتان:
One-vs-Rest (OvR):
Softmax (Multi-class):
Confusion Matrix:
التنبؤ
0 1
الفعلي 0 TN(✓) FP(✗)
1 FN(✗) TP(✓)
Accuracy: (TP + TN) / الكل — لا تعمل مع البيانات غير المتوازنة
Precision: TP / (TP + FP) — من التنبؤات بـ 1، كم كانت صحيحة؟
Recall: TP / (TP + FN) — من الفعليين 1، كم اكتشفنا؟
F1 Score: 2 × (Precision × Recall) / (Precision + Recall) — التوازن بينهما
| التطبيق | الأهم | السبب | |---------|-------|-------| | كشف السرطان | Recall عالي | لا نريد تفويت حالة مريضة | | فلترة Spam | Precision عالي | لا نريد حذف بريد مهم | | كشف الاحتيال | كلاهما | الخسارتان مكلفتان |
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import (accuracy_score, precision_score,
recall_score, f1_score,
confusion_matrix, classification_report)
print("=" * 55)
print("Logistic Regression: كشف البريد المزعج")
print("=" * 55)
# ─────────────────────────────────────────
# بيانات مصطنعة للبريد الإلكتروني
# ─────────────────────────────────────────
np.random.seed(42)
n = 1000
# ميزات تميّز البريد المزعج
has_free_word = np.random.binomial(1, 0.6, n) # كلمة "مجاني"
num_links = np.random.poisson(3, n) # عدد الروابط
caps_ratio = np.random.beta(2, 5, n) # نسبة الأحرف الكبيرة
sender_known = np.random.binomial(1, 0.7, n) # المرسل معروف؟
email_length = np.random.normal(300, 150, n) # طول الرسالة
# spam = دالة للميزات
spam_score = (1.5 * has_free_word + 0.3 * num_links
+ 2.0 * caps_ratio - 2.5 * sender_known
+ np.random.normal(0, 0.5, n))
is_spam = (spam_score > 0.2).astype(int)
print(f"نسبة البريد المزعج: {is_spam.mean():.1%}")
df = pd.DataFrame({
"has_free_word": has_free_word,
"num_links": num_links,
"caps_ratio": caps_ratio,
"sender_known": sender_known,
"email_length": email_length,
"is_spam": is_spam
})
# ─────────────────────────────────────────
# تحضير وتدريب
# ─────────────────────────────────────────
features = ["has_free_word", "num_links", "caps_ratio",
"sender_known", "email_length"]
X = df[features]
y = df["is_spam"]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, stratify=y, random_state=42
)
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)
model = LogisticRegression(random_state=42)
model.fit(X_train_s, y_train)
# ─────────────────────────────────────────
# التقييم الكامل
# ─────────────────────────────────────────
y_pred = model.predict(X_test_s)
y_prob = model.predict_proba(X_test_s)[:, 1] # احتمال كونه spam
print("\n" + "=" * 55)
print("نتائج التقييم:")
print(f" Accuracy = {accuracy_score(y_test, y_pred):.3f}")
print(f" Precision = {precision_score(y_test, y_pred):.3f}")
print(f" Recall = {recall_score(y_test, y_pred):.3f}")
print(f" F1 Score = {f1_score(y_test, y_pred):.3f}")
print("\nConfusion Matrix:")
cm = confusion_matrix(y_test, y_pred)
print(f" TN={cm[0,0]} FP={cm[0,1]}")
print(f" FN={cm[1,0]} TP={cm[1,1]}")
print("\nتقرير مفصل:")
print(classification_report(y_test, y_pred,
target_names=["حقيقي", "مزعج"]))
# ─────────────────────────────────────────
# أهمية الميزات
# ─────────────────────────────────────────
coef_df = pd.DataFrame({
"feature": features,
"coefficient": model.coef_[0]
}).sort_values("coefficient", ascending=False)
print("أهمية الميزات:")
for _, row in coef_df.iterrows():
bar = "█" * int(abs(row["coefficient"]) * 5)
sign = "+" if row["coefficient"] > 0 else "-"
print(f" {row['feature']:15s}: {sign}{abs(row['coefficient']):.2f} {bar}")