تطبيق SciPy وstatsmodels في بايثون عملياً: الكود والأوامر التي تهم حقاً

بايثون SciPy statsmodels: الأساسيات في مقال واحد — كود حقيقي، مخططات وخطوات ملموسة، مقتطفات من دورة مكونة من 37 درسًا.

تطبيق SciPy وstatsmodels في بايثون عملياً: الكود والأوامر التي تهم حقاً

لا توجد نظرية مطولة هنا: نفتح الطرفية ونمارس. إليك أساسيات Python SciPy statsmodels، مستخرجة مباشرة من دورة كاملة تضم 37 درسًا — مع كود حقيقي يمكنك نسخه ولصقه الآن.

tl;dr
  • مقدمة وتثبيت
  • تذكير NumPy لـ SciPy
  • اكتشاف SciPy
  • الإحصاء الوصفي باستخدام scipy.stats
  • الاختبارات الإحصائية باستخدام SciPy
~$ cat ./parcours.md # Python SciPy statsmodels — 10 فصول
01
مقدمة وتثبيت
→ عرض الدورة→ تثبيت Python والمكتبات+ 1 دروس أخرى
02
تذكير NumPy لـ SciPy
→ مصفوفات NumPy، اللبنة الأساسية→ ما يمكن فعله بمصفوفة NumPy+ 1 دروس أخرى
03
اكتشاف SciPy
→ ما هو SciPy وما فائدته؟→ تنظيم وحدات scipy.stats+ 1 دروس أخرى
04
إحصاءات وصفية باستخدام scipy.stats
→ المتوسط، الوسيط والمنوال→ التباين، الانحراف المعياري والتشتت+ 1 دروس أخرى
05
اختبارات إحصائية باستخدام SciPy
→ مقدمة إلى الاختبارات الإحصائية وقيمة p→ اختبار t للطالب — مقارنة متوسطين+ 2 دروس أخرى
06
مقدمة إلى Statsmodels
→ ما هو Statsmodels وكيف يختلف عن SciPy؟→ تحميل البيانات واستكشاف المجموعات المدمجة+ 1 دروس أخرى
07
الانحدار الخطي باستخدام Statsmodels
→ نظرية الانحدار الخطي موضحة ببساطة→ الانحدار الخطي البسيط باستخدام Statsmodels+ 2 دروس أخرى
08
الانحدار اللوجستي باستخدام Statsmodels
→ نظرية الانحدار اللوجستي→ الانحدار اللوجستي عمليًا باستخدام Statsmodels+ 1 دروس أخرى
🏁
المشروع النهائي (+ 2 فصول في الطريق)
→ تعود بمشروع ملموس وقابل للعرض

التنبؤ بالمستقبل باستخدام ARIMA

NOTEما ستتعلمه — ARIMA هو نموذج يتعلم من اتجاهات الماضي للتنبؤ بالمستقبل. سنرى كيف يعمل، وكيفية إعداده، وكيفية استخدامه لإنشاء تنبؤ.

ما سنراه في هذا الدرس

ما هو ARIMA ببساطة؟

ARIMA هو خوارزمية تنبؤ. ينظر إلى القيم السابقة ويحاول استنتاج ما سيحدث في المستقبل.

TIPتشبيه — تخيل عالم أرصاد جوية. للتنبؤ بدرجة حرارة الغد، ينظر إلى درجات الحرارة في الأيام القليلة الماضية. إذا كانت درجات الحرارة في الأيام الثلاثة الماضية 18، 20، 22 درجة (اتجاه صاعد)، فمن المحتمل أن يتنبأ بـ 24 غدًا. ARIMA يفعل الشيء نفسه، لكنه يستخدم رياضيات دقيقة.

الاسم الكامل هو Auto-Regressive Integrated Moving Average. اسم معقد، لكن المفهوم بسيط: يعتمد النموذج على القيم السابقة وأخطاء التنبؤ السابقة لتقدير القيمة التالية.

المعاملات الثلاثة لـ ARIMA: p، d، q

نكتب ARIMA(p, d, q). كل حرف له دور محدد.

المعاملالمعنىمثال بسيط
p عدد القيم السابقة المستخدمة للتنبؤ p=2: ننظر إلى الشهرين الأخيرين
d عدد مرات تحويل السلسلة لتثبيتها d=1: في معظم الحالات يكفي d=1
q عدد أخطاء الماضي المستخدمة لتصحيح التنبؤ q=1: نأخذ بعين الاعتبار آخر خطأ
TIPنصيحة للمبتدئين — ابدأ دائمًا بـ ARIMA(1, 1, 1). هذا الإعداد الأساسي يعمل جيدًا في معظم الحالات. يمكنك تجربة قيم أخرى لاحقًا إذا لزم الأمر.
NOTEما فائدة d؟ — معظم السلاسل الحقيقية لها اتجاه (المبيعات تزداد كل سنة، على سبيل المثال). يحتاج ARIMA إلى أن تكون السلسلة «مستقرة» (بدون اتجاه) ليعمل. يقوم المعامل d بتحويل السلسلة لجعلها مستقرة. d=1 يعني حساب الفرق بين القيم المتتالية.

بناء نموذج ARIMA خطوة بخطوة

نعود إلى سلسلة المبيعات الشهرية على مدى 4 سنوات. سنستخدم أول 38 شهرًا لتدريب النموذج، والـ 10 أشهر الأخيرة للتحقق من جودة التنبؤات.

output
import pandas as pd
import numpy as np
from statsmodels.tsa.arima.model import ARIMA

# --- إعادة إنشاء سلسلة المبيعات الشهرية ---
np.random.seed(42)
dates = pd.date_range(start="2020-01", periods=48, freq="ME")
tendance = np.arange(48) * 1.0
mois = dates.month
saisonnalite = 10 * np.sin(2 * np.pi * (mois - 3) / 12)
bruit = np.random.normal(0, 3, 48)
ventes = 100 + tendance + saisonnalite + bruit
serie = pd.Series(ventes, index=dates, name="Ventes")

# --- التقسيم: 38 شهرًا للتعلم، 10 أشهر للاختبار ---
train = serie.iloc[:38]   # بيانات التدريب
test  = serie.iloc[38:]   # بيانات الاختبار (المستقبل المعروف)

print(f"Entrainement : {len(train)} mois")
print(f"Test         : {len(test)} mois")
output
# --- إنشاء وضبط النموذج ---
# order=(p, d, q) = (1, 1, 1) : الإعداد الأساسي
modele = ARIMA(train, order=(1, 1, 1))
resultat = modele.fit()

# عرض ملخص مختصر
print(f"AIC du modele : {resultat.aic:.2f}")
print("Modele ajuste avec succes !")
TIPAIC = Akaike Information Criterion. هو درجة تقيس جودة النموذج. كلما انخفضت، كان أفضل. نستخدمه لمقارنة عدة نماذج ARIMA.

إنشاء تنبؤ

الآن بعد تدريب النموذج، نطلب منه التنبؤ بالـ 10 أشهر القادمة.

output
# إنشاء تنبؤ لـ 10 أشهر
prevision = resultat.forecast(steps=10)

# مقارنة التنبؤ بالقيم الحقيقية
comparaison = pd.DataFrame({
    "Reel"    : test.values.round(1),
    "Prevision": prevision.values.round(1),
    "Erreur"  : (test.values - prevision.values).round(1)
}, index=test.index)

print(comparaison)
NOTEكيف تقرأ هذا الجدول؟
  • Reel : المبيعات الحقيقية لهذه الأشهر (التي أخفيناها عن النموذج أثناء التدريب)
  • Prevision : ما تنبأ به نموذج ARIMA
  • Erreur : الفرق. خطأ قريب من 0 جيد. خطأ كبير يعني أن التنبؤ كان سيئًا.

قياس جودة التنبؤ

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

output
mae = np.abs(test.values - prevision.values).mean()
print(f"Erreur moyenne absolue (MAE) : {mae:.1f} unites")
print(f"Moyenne des ventes reelles   : {test.mean():.1f} unites")
print(f"Erreur relative              : {mae / test.mean() * 100:.1f}%")
TIPالتفسير — يخطئ النموذج في المتوسط بـ 9.1 وحدة، على مبيعات متوسطة تبلغ 141. وهذا يمثل خطأ بنسبة 6.4%. بالنسبة لنموذج ARIMA(1,1,1) الأساسي، هذا مقبول. يمكن تحسينه باختبار قيم أخرى لـ p و q.

التنبؤ بالمستقبل بعد البيانات المتاحة

في الحياة الواقعية، لا تملك بيانات اختبار للمقارنة. تريد فقط التنبؤ بالأشهر القادمة.

أول سكريبت SciPy

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

الأهداف التعليمية

TIPعند نهاية هذه الوحدة — ستكون قد نفذت أول سكريبت SciPy، وستفهم بنية سكريبت التحليل، وستكون مرتاحًا للانتقال إلى الفصول التالية.

بنية سكريبت تحليل نموذجي

كل سكريبت تحليل بيانات في Python يتبع نمطًا مشابهًا. تعلم هذا النمط الآن سيساعدك في جميع الفصول اللاحقة.

المخطط العام

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

أنت أستاذ. لديك درجات 20 طالبًا من 100. تريد فهم:

الخطوة 1: الاستيرادات

أول شيء تفعله في أي سكريبت هو استيراد المكتبات. إليك السبب في استخدام أسماء مستعارة:

output
import numpy as np                   # np أقصر في الكتابة من numpy
from scipy import stats              # نستورد فقط وحدة stats من SciPy
import matplotlib.pyplot as plt      # plt هو الاسم المستعار القياسي لرسم الرسوم البيانية
NOTEلماذا from scipy import stats وليس import scipy؟ — SciPy مقسم إلى وحدات فرعية. استيراد stats فقط أكثر كفاءة لأننا نحمل فقط ما نحتاجه. نكتب بعد ذلك stats.mean() بدلاً من scipy.stats.mean().

الخطوة 2: إنشاء البيانات

output
notes = np.array([
    72, 85, 91, 63, 78, 55, 88, 94, 70, 82,
    66, 79, 87, 61, 90, 75, 83, 68, 77, 95
])

print("Nombre d'etudiants :", len(notes))
print("Notes              :", notes)
TIPnp.array() — هذه الدالة تنشئ مصفوفة NumPy من قائمة Python. مصفوفة NumPy تشبه قائمة Python، لكنها أقوى بكثير للحسابات الرياضية. SciPy يعمل دائمًا مع مصفوفات NumPy.

الخطوة 3: حساب الإحصاءات باستخدام scipy.stats

output
moyenne = np.mean(notes)
mediane = np.median(notes)
ecart_type = np.std(notes)
minimum = np.min(notes)
maximum = np.max(notes)

print(f"Moyenne    : {moyenne:.2f}")
print(f"Mediane    : {mediane:.2f}")
print(f"Ecart-type : {ecart_type:.2f}")
print(f"Minimum    : {minimum}")
print(f"Maximum    : {maximum}")

الخطوة 4: استخدام scipy.stats للذهاب أبعد

NumPy يحسب الإحصاءات الأساسية. SciPy يذهب أبعد بإضافة مقاييس مثل الالتواء (skewness) والتفلطح (kurtosis)، اللذين يشيران إلى شكل التوزيع.

output
asymetrie = stats.skew(notes)
aplatissement = stats.kurtosis(notes)
description = stats.describe(notes)

print(f"Asymetrie (skewness)   : {asymetrie:.4f}")
print(f"Aplatissement (kurt)   : {aplatissement:.4f}")
print()
print("Description complete par scipy.stats.describe() :")
print(description)

الخطوة 5: تفسير النتائج

الإحصاءالقيمةما يعنيه
المتوسط77.95في المتوسط، حصل الطلاب على ما يقارب 78/100
الوسيط78.50نصف الطلاب حصلوا على أقل من 78.5 والنصف الآخر أكثر
الانحراف المعياري11.32تختلف الدرجات بحوالي 11 نقاط حول المتوسط
الالتواء (-0.25)طفيفالتوزيع شبه متماثل (تركيز طفيف نحو الدرجات العالية)
التفلطح (-0.88)سالبتوزيع أكثر تسطحًا قليلاً من التوزيع الطبيعي (platykurtique)
NOTEالمتوسط مقابل الوسيط — المتوسط (77.95) والوسيط (78.50) قريبان جدًا هنا. هذا يشير إلى عدم وجود قيم متطرفة «تسحب» المتوسط للأعلى أو للأسفل. عندما يختلف المتوسط والوسيط كثيرًا، غالبًا ما يشير ذلك إلى قيم شاذة (outliers).

الخطوة 6: التصور (إضافي)

output
plt.figure(figsize=(8, 4))
plt.hist(notes, bins=8, color='steelblue', edgecolor='white', alpha=0.8)
plt.axvline(moyenne, color='red', linestyle='--', label=f'Moyenne ({moyenne:.1f})')
plt.axvline(mediane, color='orange', linestyle='-', label=f'Mediane ({mediane:.1f})')
plt.xlabel("Note sur 100")
plt.ylabel("Nombre d'etudiants")
plt.title("Distribution des notes de la classe")
plt.legend()
plt.tight_layout()
plt.show()
TIPplt.axvline() — هذه الدالة ترسم خطًا عموديًا على الرسم البياني. مفيدة لوضع علامة على المتوسط أو الوسيط في المدرج التكراري.

ما يمكن فعله بمصفوفة NumPy

NOTEما ستتعلمه — كيف تقرأ قيمة محددة في مصفوفة، وكيف تحتفظ بقيم معينة فقط، وكيف تجري حسابات على المصفوفة بأكملها دفعة واحدة.

ما سنراه في هذا الدرس

قراءة قيمة محددة في مصفوفة

تخيل أن مصفوفتك صف من الخانات المرقمة. الخانة الأولى مرقمة 0، وليس 1. هذه اتفاقية في Python. الخانة الثانية هي 1، والثالثة 2، وهكذا.

TIPتشبيه — مثل طوابق مبنى في أوروبا: الطابق الأرضي هو الطابق 0. الطابق الأول هو 1. في Python، نعد بنفس الطريقة.

يمكننا أيضًا العد من النهاية باستخدام أرقام سالبة. -1 يعطي العنصر الأخير، -2 قبل الأخير، إلخ.

output
import numpy as np

# مصفوفة من 7 درجات حرارة أسبوعية
temperatures = np.array([18.5, 22.1, 19.8, 25.3, 21.0, 17.2, 23.4])
#                          [0]   [1]   [2]   [3]   [4]   [5]   [6]

print( temperatures[0] )   # 18.5  -> الاثنين (القيمة الأولى)
print( temperatures[2] )   # 19.8  -> الأربعاء (القيمة الثالثة)
print( temperatures[-1] )  # 23.4  -> الأحد (القيمة الأخيرة)
print( temperatures[-2] )  # 17.2  -> السبت (قبل الأخيرة)

اختيار عدة قيم متتالية

إذا أردت أخذ جزء من المصفوفة، استخدم الترميز بداية:نهاية. انتبه: قيمة النهاية مستبعدة. إذا كتبت [1:4]، تحصل على الخانات 1، 2 و3، لكن ليس الخانة 4.

TIPتشبيه — مثل تقطيع رغيف خبز. إذا قلت «أعطني من القطعة 1 إلى القطعة 4»، يعطيك الخباز القطع 1، 2، 3. تبقى القطعة 4 في المتجر.
output
temperatures = np.array([18.5, 22.1, 19.8, 25.3, 21.0, 17.2, 23.4])

# الأيام الثلاثة الأولى (الاثنين، الثلاثاء، الأربعاء)
print( temperatures[:3] )     # بداية محذوفة = من البداية

# من الثلاثاء إلى الجمعة (الفهرس 1 إلى 4، 4 مستبعد)
print( temperatures[1:4] )

# اليومان الأخيران
print( temperatures[-2:] )    # نهاية محذوفة = حتى النهاية

# يوم كل يومين (الاثنين، الأربعاء، الجمعة، الأحد)
print( temperatures[::2] )

الاحتفاظ فقط بالقيم التي تحقق شرطًا

هذا من أقوى ميزات NumPy. يمكنك القول «أعطني فقط درجات الحرارة الأعلى من 21 درجة» ويقوم NumPy بالاختيار تلقائيًا.

إليك كيف يعمل في خطوتين:

output
temperatures = np.array([18.5, 22.1, 19.8, 25.3, 21.0, 17.2, 23.4])

# الخطوة 1: أي يوم تكون فيه درجة الحرارة أعلى من 21؟
masque = temperatures > 21
print("Masque :", masque)
# True حيث أكبر من 21، False خلاف ذلك

# الخطوة 2: الاحتفاظ فقط بهذه القيم
print("Jours > 21 degres :", temperatures[masque])

# يمكن أيضًا القيام بالخطوتين في سطر واحد:
print("Jours < 20 degres :", temperatures[temperatures < 20])
NOTEكيف تقرأ القناع؟ — القناع له نفس حجم المصفوفة. لكل قيمة في المصفوفة، يقول True (نعم، هذه القيمة تحقق الشرط) أو False (لا). NumPy يحتفظ بعد ذلك فقط بالمواضع المميزة بـ True.

إجراء حسابات رياضية على المصفوفة بأكملها

يقدم NumPy دوال رياضية تُطبق على كل عنصر في نفس الوقت. لا حاجة لحلقة. تكتب سطرًا واحدًا ويقوم NumPy بالحساب على جميع القيم.

output
data = np.array([4.0, 9.0, 16.0, 25.0])

# np.sqrt = الجذر التربيعي لكل قيمة
print("Racine carree :", np.sqrt(data))

# np.log = اللوغاريتم الطبيعي لكل قيمة
print("Logarithme    :", np.round(np.log(data), 2))

# np.abs = القيمة المطلقة (يزيل الإشارة السالبة)
nombres = np.array([-3, 5, -7, 2])
print("Valeur absolue:", np.abs(nombres))

حساب الإحصاءات على المصفوفة بأكملها

هذه الدوال تلخص المصفوفة في رقم واحد:

output
ventes = np.array([1200, 850, 1500, 970, 1100, 1350, 780])

print("Total de la semaine :", np.sum(ventes))
print("Moyenne journaliere :", np.mean(ventes).round(1))
print("Journee la plus haute :", np.max(ventes))
print("Journee la plus basse :", np.min(ventes))

# cumsum : المجموع التراكمي يومًا بيوم
print("Cumul jour par jour  :", np.cumsum(ventes))
TIPما فائدة cumsum؟ — cumsum تعني «المجموع التراكمي». كل قيمة معروضة هي الإجمالي منذ البداية. هنا: الاثنين = 1200، الاثنين+الثلاثاء = 2050، إلخ. مفيد لمتابعة إيرادات تتراكم.

تطبيق حساب على جميع القيم في نفس الوقت

في Python العادية، إذا أردت إضافة 10% إلى كل سعر في قائمة، تكتب حلقة. مع NumPy، لا تحتاج إلى ذلك. تكتب العملية مرة واحدة وتُطبق على جميع القيم. يُسمى هذا broadcasting.

TIPتشبيه — تخيل سنة من ارتفاع الأسعار. كل الأسعار في قائمتك تزداد بنسبة 20%. مع NumPy، تضرب المصفوفة كاملة بـ 1.20 في سطر واحد. بدون NumPy، كان يجب كتابة حلقة تمر على كل سعر على حدة.
va-plus-loin

يغطي هذا المقال المقتطفات الأكثر فائدة — الدورة الكاملة Python SciPy statsmodels (11 فصول، 37 درسًا، تمارين مصححة ومشروع نهائي) تأخذك إلى النهاية.

./acceder-au-cours-complet cours gratuit : Maîtriser Claude Code

الأسئلة الشائعة

كم من الوقت لتعلم Python SciPy statsmodels؟
مع تقدم منظم (11 فصول، 37 درسًا قصيرًا وعمليًا)، يمكن الوصول إلى مستوى تشغيلي في بضعة أسابيع بمعدل 30 إلى 60 دقيقة يوميًا. المهم هو ممارسة كل مفهوم فورًا.
هل هناك متطلبات سابقة؟
تكفي أساسيات في الحوسبة. إذا كنت تعرف استخدام الطرفية وقراءة كود بسيط، فأنت جاهز.
من أين نبدأ عمليًا؟
أعد إنتاج أوامر هذا المقال، ثم تابع الدورة الكاملة Python SciPy statsmodels: تربط الـ 37 درسًا بالترتيب، مع تمارين ومشروع نهائي.

📬 هل تريد تلقي هذا النوع من الأدلة كل أسبوع؟ اشترك مجانًا — كود حقيقي، بدون كلام فارغ.