المحددات والمعكوسات والمنقولات
احسب محددات المصفوفات باستخدام np.linalg.det، ومعكوساتها باستخدام np.linalg.inv، ومنقولاتها باستخدام .T
المحددات والمعكوسات والمنقولات درس مجاني في Pandas & NumPy Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Pandas & NumPy Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Pandas & NumPy Academy 4 دروس في المجموع.
منقول المصفوفة
يقلب منقول المصفوفة اتجاهها حول قطرها: فتصبح الصفوف أعمدة، والأعمدة صفوفًا. إذا كان شكل A هو (m, n)، فإن شكل A.T هو (n, m). تظهر المنقولات في كل مكان في الجبر الخطي: عند حساب مصفوفات التغاير، وتنفيذ الانتشار العكسي للتدرجات، والتحويل بين اصطلاحي متجه الصف ومتجه العمود. يصل NumPy إلى المنقول باستخدام السمة .T — ولا تُنشأ نسخة، بل هو مجرد منظور ذي خطوات وصول معاد ترتيبها.
import numpy as np
A = np.array([[1, 2, 3],
[4, 5, 6]])
print('A shape:', A.shape) # (2, 3)
print('A.T shape:', A.T.shape) # (3, 2)
print(A.T)المنقول عمليًا
من الأنماط الشائعة حساب A.T @ A، الذي ينتج مصفوفة مربعة متناظرة تظهر في انحدار المربعات الصغرى وتحليل المكونات الرئيسية والمعادلات العادية. إذا كان شكل A هو (n, p)، فإن شكل A.T @ A هو (p, p). وتكون النتيجة متناظرة دائمًا لأن (A.T @ A)[i,j] == (A.T @ A)[j,i]. وتستفيد العديد من أدوات الحل العددية من هذه الخاصية لزيادة الكفاءة.
import numpy as np
A = np.array([[1.0, 2.0],
[3.0, 4.0],
[5.0, 6.0]]) # shape (3, 2)
ATA = A.T @ A # shape (2, 2), symmetric
print('A.T @ A:')
print(ATA)
print('Is symmetric:', np.allclose(ATA, ATA.T))المحدد: ماذا يعني؟
محدد المصفوفة المربعة قيمة عددية تحمل معلومات هندسية؛ إذ يقيس العامل الذي تغيّر به المصفوفة مساحات الأشكال (في بُعدين) أو حجومها (في أبعاد أعلى). يعني المحدد الصفري أن المصفوفة مفردة — فهي تضغط الفضاء إلى فضاء جزئي ذي بُعد أقل، ولا معكوس لها. ويضمن المحدد غير الصفري أن المصفوفة قابلة للعكس. يحسب NumPy المحدد باستخدام np.linalg.det().
import numpy as np
# Non-singular matrix
A = np.array([[3.0, 1.0],
[2.0, 4.0]])
print('det(A):', np.linalg.det(A)) # 3*4 - 1*2 = 10
# Singular matrix (row 2 = 2 * row 1)
B = np.array([[1.0, 2.0],
[2.0, 4.0]])
print('det(B):', np.linalg.det(B)) # ~0حساب المعكوس باستخدام np.linalg.inv()
يحقق معكوس المصفوفة A، ويرمز إليه بالرمز A⁻¹، العلاقة A @ A⁻¹ = I، حيث I هي مصفوفة الوحدة. لا توجد المعكوسات إلا للمصفوفات المربعة غير المفردة. يحسب np.linalg.inv(A) المعكوس عدديًا. عمليًا، ينبغي أن تتجنبوا حساب المعكوسات صراحةً في معظم الحالات، لأن ذلك غير مستقر عدديًا؛ وبدلًا من ذلك، فضّلوا استخدام np.linalg.solve() لحل أنظمة المعادلات. ومع ذلك، يظل الفهم المفاهيمي للمعكوسات أساسيًا.
import numpy as np
A = np.array([[3.0, 1.0],
[2.0, 4.0]])
A_inv = np.linalg.inv(A)
print('Inverse:')
print(A_inv)
# Verify: A @ A_inv should be identity
I = A @ A_inv
print('A @ A_inv (should be I):')
print(np.round(I, 10))عدم الاستقرار العددي للعكس المباشر
يؤدي حساب معكوس المصفوفة ثم إجراء الضرب إلى إدخال أخطاء الفاصلة العائمة وتراكمها. فعلى سبيل المثال، يكون حل A_inv @ b أقل دقة من استدعاء np.linalg.solve(A, b) مباشرةً. وتكون المصفوفة جيدة التكييف (أي إن محددها بعيد عن الصفر) أقل تأثرًا بهذه الأخطاء. ويقيس عدد الشرط (np.linalg.cond(A)) مدى قرب المصفوفة من أن تكون مفردة؛ وتشير أعداد الشرط الكبيرة إلى مشكلات عددية.
import numpy as np
A = np.array([[1.0, 2.0],
[1.0001, 2.0]])
print('Condition number:', np.linalg.cond(A))
# Very high condition number -> near-singular, unstable inversion
b = np.array([3.0, 3.0001])
# Prefer solve over inv @ b
print('Solution via solve:', np.linalg.solve(A, b))المصفوفات المتعامدة ومنقولاتها
هناك فئة خاصة من المصفوفات تُسمى المصفوفات المتعامدة، وتحقق A.T @ A = I. وهذا يعني أن المنقول هو المعكوس نفسه، مما يجعل عكس المصفوفات المتعامدة قليل التكلفة للغاية. وتكون مصفوفات الدوران والعامل Q في تحليل QR متعامدة. وتشكل أعمدة المصفوفة المتعامدة أساسًا متعامدًا موحّدًا — إذ يكون طول كل عمود مساويًا للوحدة، ويكون عموديًا على كل عمود آخر.
import numpy as np
# 90-degree rotation matrix is orthogonal
theta = np.pi / 2
R = np.array([[np.cos(theta), -np.sin(theta)],
[np.sin(theta), np.cos(theta)]])
print('R.T @ R (should be identity):')
print(np.round(R.T @ R, 10))
print('Is orthogonal:', np.allclose(R.T @ R, np.eye(2)))المعكوس الزائف للمصفوفات غير المربعة
لا يوجد المعكوس العادي إلا للمصفوفات المربعة، لكن المعكوس الزائف لمور-بنروز يعمّم مفهوم العكس ليشمل أي مصفوفة. يحسب np.linalg.pinv(A) هذا المعكوس باستخدام SVD. وهو أساس حل المربعات الصغرى للأنظمة زائدة التحديد (أي التي تحتوي على معادلات أكثر من المجهولات)، وهو بالضبط ما يحله الانحدار الخطي. إذا كانت A مربعة وقابلة للعكس، فإن pinv(A) تساوي inv(A).
import numpy as np
# Over-determined system: 3 equations, 2 unknowns
A = np.array([[1.0, 1.0],
[1.0, 2.0],
[1.0, 3.0]])
b = np.array([2.0, 3.0, 5.0])
# Least-squares solution using pseudo-inverse
x = np.linalg.pinv(A) @ b
print('Best-fit solution:', x)
# Or use lstsq directly
x2, _, _, _ = np.linalg.lstsq(A, b, rcond=None)
print('lstsq solution:', x2)إشارة المحدد وتحجيم الحجم
تشير إشارة المحدد إلى ما إذا كان التحويل يحافظ على الاتجاه أم يعكسه. يعني المحدد الموجب أن الاتجاه محفوظ (كما في الدوران)، بينما يعني المحدد السالب أن الاتجاه قد انعكس (كما في الانعكاس). وتعطي القيمة المطلقة عامل تحجيم الحجم. بالنسبة إلى مصفوفة 2×2 [[a,b],[c,d]]، يكون det = a*d - b*c. ويتعامل NumPy بكفاءة مع الأحجام التعسفية للمصفوفات المربعة.
import numpy as np
# Identity: det = 1 (no scaling, no flip)
I = np.eye(3)
print('det(I):', np.linalg.det(I)) # 1.0
# Scaling by 2 in all directions: det = 8 = 2^3
S = 2 * np.eye(3)
print('det(2I):', np.linalg.det(S)) # 8.0
# Reflection: det = -1
F = np.array([[-1.0, 0.0],
[ 0.0, 1.0]])
print('det(reflection):', np.linalg.det(F))استخدام np.linalg.slogdet() لتحقيق الاستقرار
بالنسبة إلى المصفوفات الكبيرة، قد يتجاوز المحدد الحد الأقصى أو يهبط إلى الصفر بسبب التدفق السفلي، حتى عندما تكون المصفوفة غير مفردة. يعيد np.linalg.slogdet(A) القيمة (sign, log_abs_det) — أي الإشارة واللوغاريتم الطبيعي للقيمة المطلقة للمحدد — مما يتجنب تجاوز السعة العددي. ويُستخدم هذا على نطاق واسع في النماذج الاحتمالية (مثل دوال الإمكان الغاوسية)، حيث تُجرى الحسابات في الفضاء اللوغاريتمي للحفاظ على الأعداد ضمن نطاق يمكن التعامل معه.
import numpy as np
A = np.random.rand(100, 100)
# Direct det might underflow for large matrices
sign, logdet = np.linalg.slogdet(A)
print('Sign:', sign)
print('Log|det|:', logdet)
print('Actual det (may be ~0 due to float):', np.linalg.det(A))
print('Reconstructed |det|:', np.exp(logdet))عمليًا: حل مصفوفة 2x2 يدويًا مقارنةً بـ NumPy
بالنسبة إلى مصفوفة 2×2 [[a, b], [c, d]]، يكون المعكوس (1/det) * [[d, -b], [-c, a]]، حيث det = ad - bc. يساعدكم الإلمام بهذه الصيغة في التحقق سريعًا من نتيجة NumPy. أما بالنسبة إلى أي مصفوفة أكبر، فحساب المعكوس تحليليًا غير عملي — ولهذا تحديدًا نستخدم np.linalg.inv(). احرصوا دائمًا على التحقق من النتائج العددية باستخدام np.allclose(A @ A_inv, np.eye(n)).
import numpy as np
a, b, c, d = 3.0, 1.0, 2.0, 4.0
A = np.array([[a, b], [c, d]])
det = a*d - b*c
# Manual inverse
A_inv_manual = (1/det) * np.array([[d, -b], [-c, a]])
print('Manual inv:')
print(A_inv_manual)
# NumPy inverse
print('np.linalg.inv:')
print(np.linalg.inv(A))
print('Match:', np.allclose(A_inv_manual, np.linalg.inv(A)))دمج المنقول والمعكوس في مسارات المعالجة
يجمع نمط شائع في الجبر الخطي بين المنقول والمعكوس: إذ يعطي حساب (A.T @ A)⁻¹ @ A.T مصفوفة الإسقاط المستخدمة في المربعات الصغرى العادية. وفي NumPy، يمكن كتابة ذلك على صورة np.linalg.inv(A.T @ A) @ A.T، لكن np.linalg.lstsq يظل أفضل عدديًا. يساعدكم فهم النمط الأساسي على معرفة ما يفعله أداة الحل وتصحيح المشكلات عندما تكون المصفوفات شبه مفردة.
import numpy as np
# Design matrix for simple linear regression (with bias)
X = np.column_stack([np.ones(5), np.array([1., 2., 3., 4., 5.])])
y = np.array([2.1, 3.9, 6.2, 8.1, 9.8])
# OLS via normal equations: beta = (X.T @ X)^-1 @ X.T @ y
beta = np.linalg.inv(X.T @ X) @ X.T @ y
print('Coefficients (intercept, slope):', np.round(beta, 3))
# Verify with lstsq
beta2, _, _, _ = np.linalg.lstsq(X, y, rcond=None)
print('lstsq result:', np.round(beta2, 3))تحقّق سريع
اختبر مدى فهمك لمفاهيم تحليل البيانات الواردة في هذا الدرس.
مراجعة الدرس
في هذا الدرس تعلّمت أن A.T هو المنقول الذي يبدّل الصفوف والأعمدة، وأن np.linalg.inv() يحسب معكوس المصفوفة، لكن يُفضّل نادرًا استخدامه مباشرةً (وفضّلوا solve أو lstsq)، وأن np.linalg.det() يعيد المحدد الذي يساوي صفرًا للمصفوفات المفردة. بعد ذلك سنستكشف حل الأنظمة الخطية مباشرةً باستخدام np.linalg.solve.
الأسئلة الشائعة
هل درس «المحددات والمعكوسات والمنقولات» مجاني؟
نعم — نص درس «المحددات والمعكوسات والمنقولات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Pandas & NumPy Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Pandas & NumPy Academy 4 دروس في المجموع.
ماذا ستتعلم في «المحددات والمعكوسات والمنقولات»؟
احسب محددات المصفوفات باستخدام np.linalg.det، ومعكوساتها باستخدام np.linalg.inv، ومنقولاتها باستخدام .T تتمرن على Pandas & NumPy Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Pandas & NumPy Academy؟
لا تُشترط خبرة سابقة. Pandas & NumPy Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «المحددات والمعكوسات والمنقولات»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Pandas & NumPy Academy هذا؟
نعم. كل درس في Pandas & NumPy Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- ضرب المصفوفات باستخدام np.matmul و@
- المحددات والمعكوسات والمنقولات
- حل الأنظمة الخطية
- نظرة عامة على القيم الذاتية وSVD