مادة الذكاء الاصطناعي | الانحدار اللوجستي

دليل تفاعلي: الانحدار اللوجستي

تعلم كيف يتنبأ النموذج بالحلول الثنائية، وكيف يقرر بين نعم ولا عبر دالة السجmoid.

إعداد: أ. أبو بكر Prof Aboubakr
0 و 1
النتيجة
0.5
العتبة
yes
قرار
Python
أداة التنفيذ

كيف نفكر بهكذا؟

📊

أدخل البيانات

مثل العمر، الدخل، أو درجة الاختبار.

🧠

احسب الاحتمال

النموذج يحول البيانات إلى رقم بين 0 و 1.

قارن مع 0.5

إذا كان أكبر، فقرار نعم، وإلا لا.

🎯

خذ القرار

مثال: شراء أم لا، نجاح أم فشل.

كود بسيط بايثون

import numpy as np

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

for x in [-3, 0, 2, 5]:
    print(x, round(sigmoid(x), 3))

هذا الكود يحسب قيمة sigmoid لأي رقم.

عندما x صغير، الرقم يكون قريباً من 0.

وعندما x كبير، الرقم يصبح قريباً من 1.

الحكمة: النموذج يعطينا احتمالاً، ثم نقرر.

حكاية صغيرة لتسهيل الفهم

☀️

المرحلة 1

نجمع بعض المعلومات: عمر الطالب، عدد ساعات المذاكرة.

🌧️

المرحلة 2

النموذج يحول هذه المعلومات إلى احتمال النجاح.

🏆

المرحلة 3

إذا كان الاحتمال كبيراً، نقول: نعم، الطالب سيحصل على النجاح.

الانحدار اللوجستي للطلاب الصغار

الانحدار اللوجستي يساعد الكمبيوتر على اتخاذ قرار بين نعم ولا.

مثال: هل هذا المريض مريض؟ هل هذه الرسالة مزعجة؟ هل هذا الطالب ناجح؟

بدل من القول: "القيمة 7"، يخبرنا النموذج: "احتمال النجاح = 0.82"، ثم يقرر بناءً على العتبة 0.5.

قانون بسيط: إذا كان الاحتمال أكبر من 0.5، فنقول نعم/1. إذا كان أصغر، فنقول لا/0.
Python مثال سريع scikit-learn
from sklearn.linear_model import LogisticRegression

X = [[1], [2], [3], [4], [5]]
y = [0, 0, 1, 1, 1]

model = LogisticRegression()
model.fit(X, y)
print(model.predict([[3.5]]))

رسم المنحنى السحري

معلومة سريعة

الدالة اللوجستية تأخذ أي رقم وتحوّله إلى قيمة بين 0 و 1.

σ(z) = 1 / (1 + e^(-z))

عندما z كبير وموجب، فالقيمة قريبة من 1.

عندما z صغير أو سالب، فالقيمة قريبة من 0.

لعبة: هل هذه النقطة نعم أم لا؟

لوحة التحدي مستوى 1

النقاط

0

العتبة

0.5

قانون القرار

إذا كان الاحتمال أعلى من 0.5 فهذا نعم، وإلا فهو لا.

الترتيب الصحيح: clean → model → train → confusion matrix → export

عرض سريع من البيانات: df.head()

male age education currentSmoker cigsPerDay BPMeds prevalentStroke prevalentHyp diabetes totChol sysBP diaBP BMI heartRate glucose TenYearCHD
1 39 4.0 0 0.0 0.0 0 0 0 195.0 106.0 70.0 26.97 80.0 77.0 0
0 46 2.0 0 0.0 0.0 0 0 0 250.0 121.0 81.0 28.73 95.0 76.0 0
1 48 1.0 1 20.0 0.0 0 0 0 245.0 127.5 80.0 25.34 75.0 70.0 0

معنى كل عمود بالعربية

male: ذكر = 1 / أنثى = 0
age: العمر بالسنوات
education: مستوى التعليم
currentSmoker: هل يدخن حاليًا؟
cigsPerDay: عدد السجائر يوميًا
BPMeds: هل يتناول أدوية ضغط الدم؟
prevalentStroke: هل كان هناك سكتة سابقة؟
prevalentHyp: هل يعاني من ارتفاع ضغط الدم؟
diabetes: هل يعاني من السكري؟
totChol: مستوى الكولسترول الكلي
sysBP: ضغط الدم الانقباضي
diaBP: ضغط الدم الأنبساطي
BMI: مؤشر كتلة الجسم
heartRate: معدل ضربات القلب
glucose: مستوى السكر في الدم
TenYearCHD: هل سيصاب بمرض القلب خلال 10 سنوات؟ 1=نعم / 0=لا

شرح confusion matrix بالعربية

TP = True Positive

النموذج قال نعم، والواقع فعلاً نعم. مثال: شخص مصاب بالفعل، والنموذج توقع أنه مصاب.

TN = True Negative

النموذج قال لا، والواقع فعلاً لا. مثال: شخص سليم، والنموذج توقع أنه سليم.

FP = False Positive

النموذج قال نعم، لكن الواقع لا. هذا يعني خطأ في التنبؤ بالإصابة.

FN = False Negative

النموذج قال لا، لكن الواقع نعم. هذا يعني خطأ مهم جدًا لأنه أغفل المريض.

ملحوظة مهمة:

في مشاكل الطب، FN غالباً أكثر خطورة من FP لأن المرضى قد يتم تجاهلهم. لذلك نحتاج إلى مقارنة دقيقة بين الأنواع.

أول خطوة هي تنظيف البيانات: نزيل القيم المفقودة، ونضع البيانات في الشكل الصحيح قبل التدريب.

ثم نختار المتغيرات، ونبني نموذج Logistic Regression.

بعدها نقسم البيانات إلى تدريب واختبار، ونُدرّب النموذج، ثم نرسم confusion matrix لمعرفة دقة التوقعات.

في النهاية نحفظ النموذج في ملف للتخزين والاستخدام لاحقاً.

  • clean = تنظيف البيانات
  • model = بناء النموذج
  • train = تدريب النموذج
  • confusion matrix = تقييم التوقعات
  • export = حفظ النموذج
import pandas as pd
import pickle
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
import matplotlib.pyplot as plt

# 1. load
# 2. clean
# 3. model
# 4. train
# 5. confusion matrix
# 6. export

الكود الكامل:

import pandas as pd
import pickle
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
import matplotlib.pyplot as plt

# 1. قراءة البيانات

df = pd.read_csv("framingham.csv")

# 2. تنظيف البيانات
X = df.drop(columns=['TenYearCHD'])
y = df['TenYearCHD']

numeric_cols = X.select_dtypes(include=['number']).columns
categorical_cols = X.select_dtypes(exclude=['number']).columns

numeric_transformer = Pipeline([
    ('imputer', SimpleImputer(strategy='median'))
])

categorical_transformer = Pipeline([
    ('imputer', SimpleImputer(strategy='most_frequent')),
    ('encoder', OneHotEncoder(handle_unknown='ignore'))
])

preprocessor = ColumnTransformer([
    ('num', numeric_transformer, numeric_cols),
    ('cat', categorical_transformer, categorical_cols)
])

# 3. بناء النموذج
model = Pipeline([
    ('preprocessor', preprocessor),
    ('classifier', LogisticRegression(max_iter=1000))
])

# 4. تقسيم البيانات
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# 5. تدريب النموذج
model.fit(X_train, y_train)

# 6. توقعات الاختبار
pred = model.predict(X_test)

# 7. confusion matrix
cm = confusion_matrix(y_test, pred)
print(cm)

ConfusionMatrixDisplay.from_predictions(y_test, pred)
plt.title('Confusion Matrix - Logistic Regression')
plt.show()

# 8. export
with open('logistic_model.pkl', 'wb') as f:
    pickle.dump(model, f)

print('Model exported successfully!')

خطوات التنفيذ بشكل منفصل

1) تنظيف البيانات: ملء القيم المفقودة

df['education'] = df['education'].fillna(df['education'].mode()[0])
df['BPMeds'] = df['BPMeds'].fillna(df['BPMeds'].mode()[0])
df.isnull().sum()
df['cigsPerDay'] = df['cigsPerDay'].fillna(df['cigsPerDay'].mean())
df['totChol'] = df['totChol'].fillna(df['totChol'].mean())
df['BMI'] = df['BMI'].fillna(df['BMI'].mean())
df['heartRate'] = df['heartRate'].fillna(df['heartRate'].mean())
df['glucose'] = df['glucose'].fillna(df['glucose'].mean())
df.isnull().sum()

رسم مبسط: قبل وبعد التنظيف

قبل بعد صفر

2) بناء النموذج والتدريب

X = df.drop(columns=['TenYearCHD'])
y = df['TenYearCHD']

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)
model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)
pred = model.predict(X_test)

رسم مبسط: train و test

Train Test 80% 20%

3) confusion matrix: تقييم النموذج

from sklearn.metrics import confusion_matrix

cm = confusion_matrix(y_test, pred)
print(cm)
from sklearn.metrics import ConfusionMatrixDisplay
import matplotlib.pyplot as plt

ConfusionMatrixDisplay.from_predictions(y_test, pred)
plt.show()

مثال بصري

TN FP FN TP

4) حفظ النموذج (Export)

import pickle

with open('logistic_model.pkl', 'wb') as f:
    pickle.dump(model, f)

print('Model exported successfully!')

تمثيل بسيط: حفظ النموذج

Model pickle .pkl

اختبار سريع

ملخص

1. ماذا يفعل؟

يحسب احتمال كل شيء.

2. ماذا يخرج؟

رقم بين 0 و 1.

3. كيف يقرر؟

بمقارنة الاحتمال مع 0.5.