الارتباط بين متغيرين: cor()
يسأل الارتباط: حين يرتفع أحد المتغيرين، هل يميل الآخر إلى الارتفاع أيضًا (ارتباط موجب)، أم إلى الانخفاض (سالب)، أم يفعل ما يحلو له (قريب من الصفر)؟ وفي R يكون ذلك استدعاءً واحدًا:
والجواب نحو −0.87: فالسيارات الأثقل تحقق اقتصاد وقود أسوأ، والعلاقة قوية. وهذا الرقم الواحد هو معامل ارتباط بيرسون، ويُكتب عالميًا بالرمز r.
قراءة r
يقع المعامل دائمًا بين −1 و+1. وتعطي الإشارة الاتجاه، ويعطي المقدار القوة:
| |r| | القراءة النمطية | | --- | --- | | 0.0 – 0.2 | مهمل | | 0.2 – 0.4 | ضعيف | | 0.4 – 0.6 | متوسط | | 0.6 – 0.8 | قوي | | 0.8 – 1.0 | قوي جدًا |
وعامل هذه النطاقات مفاتيح للنقاش لا قانونًا، فقيمة r تساوي 0.6 مخيبة في الفيزياء بينما هي إنجاز مهني في علم النفس. وثمة خاصيتان تستحقان الترسيخ: r بلا وحدات (فارتباط الوزن بالأطنان مع اقتصاد الوقود يعطي r نفسها التي يعطيها الوزن بالكيلوغرامات، لأن r تُحسب على قيم مُعيَّرة)، كما أن r لا تقيس إلا الارتباط الخطي، فقد يكون r ≈ 0 لعلاقة على شكل حرف U مثالي.
والجملة التي يجب قولها: الارتباط ليس سببية. فمبيعات المثلجات وحالات الغرق ترتبط ارتباطًا قويًا عبر أشهر السنة، لا لأن المثلجات تُغرق الناس بل لأن الصيف يدفع الاثنين. فالارتباط يخبرك بأن متغيرين يتحركان معًا، وهو صامت عن السبب. فربما يدفع x المتغير y، وربما العكس، وربما يدفع شيء ثالث (الفصل هنا) كليهما. والحسم بين هذه الاحتمالات يحتاج إلى تجارب أو استدلال سببي دقيق، لا إلى قيمة r أكبر.
سبيرمان وكندال: حين يكون بيرسون الأداة الخطأ
يعمل بيرسون على القيم الخام، ما يجعله حساسًا للقيم الشاذة وأعمى عن العلاقات المنحنية. ويبدّل الوسيط method إلى بدائل قائمة على الرتب:
يستبدل سبيرمان كل قيمة برتبتها ثم يحسب بيرسون على الرتب. ولأن y تتزايد دائمًا مع تزايد x، تتحاذى كل الرتب ويُبلغ سبيرمان عن القيمة 1 بالضبط، إذ يتوقف حجم القيمة الشاذة عن الأهمية ويبقى موضعها فقط. والجأ إلى سبيرمان حين تكون البيانات ترتيبية (كمقاييس الاستبيانات) أو شديدة الالتواء، أو حين تكون العلاقة رتيبة لكنها غير مستقيمة. أما كندال فيجيب عن سؤال مشابه انطلاقًا من الأزواج المتوافقة والمتنافرة، وهو أمتن في العينات الصغيرة لكنه أبطأ، ويبقى سبيرمان الخيار الافتراضي الشائع.
مصفوفة الارتباط
لمسح العلاقات عبر متغيرات كثيرة دفعة واحدة، مرّر عدة أعمدة عددية إلى cor():
كل متغير مقابل كل متغير آخر، مع آحاد على القطر (فكل شيء يرتبط بنفسه ارتباطًا تامًا) وصورة مرآة عبره. والتقريب إلى منزلتين عشريتين أهم مما يبدو، فالمصفوفة غير المقرَّبة جدار من الأرقام، والغاية من المصفوفة أن تُمسح بالنظر. وهنا يُظهر المسح أن mpg يرتبط سلبًا بالثلاثة جميعًا (فالسيارات الأثقل والأقوى وذات المحركات الأكبر تحرق وقودًا أكثر)، بينما ترتبط wt وhp وdisp إيجابًا وبقوة فيما بينها، وهي عنقود من متغيرات "السيارة الكبيرة" سيهم حين تصل إلى الانحدار الخطي وصداع الازدواج الخطي المتعدد فيه.
القيم المفقودة: الوسيط use
مع البيانات المفقودة، تكون القيمة الافتراضية في cor() هي إرجاع NA بدل التخمين:
- تحذف
use = "complete.obs"كل صف يحتوي على أيNA، ثم تحسب المصفوفة كلها من الناجين. متسقة لكنها مبذّرة، فقيمةwtمفقودة تزيل ذلك الصف أيضًا من زوجmpg–hp. - تحسب
use = "pairwise.complete.obs"كل خلية من كل الصفوف التي يتوفر فيها ذلك الزوج. وهي تحتفظ ببيانات أكثر، لكن خلايا مختلفة تستند إلى مجموعات جزئية مختلفة، ما قد ينتج نادرًا جدًا مصفوفة غير متسقة داخليًا.
ولبضع قيم NA شاردة أي منهما يفي بالغرض، فقط صرّح بأيهما استخدمت.
هل هو معنوي؟ cor.test()
تعطي cor() رقمًا دون أي إحساس بما إذا كان قد يكون ضوضاء. وتجري cor.test() اختبار الفرضية:
ولنمرّ على المخرجات كتلة كتلة:
- t = −9.56 وdf = 30: إحصاء الاختبار. وفرضية العدم هي أن الارتباط الحقيقي صفر، وتُحوَّل قيمة r المرصودة إلى إحصاء t بدرجات حرية n − 2 (أي 32 سيارة − 2).
- قيمة p = 1.29e-10: لو كان الارتباط الحقيقي صفرًا، لكان احتمال رؤية r بهذا البعد عن الصفر في عينة من 32 نحو 0.0000000001. وهذا دليل ساحق على أن الارتباط حقيقي، لكن تذكّر أن قيمة p تتحدث عن اختلاف r عن الصفر، لا عن كون العلاقة كبيرة أو سببية.
- فترة ثقة 95 بالمئة: من −0.93 إلى −0.74: المدى المعقول للارتباط الحقيقي. وهي غالبًا أنفع من قيمة p: فحتى الطرف المتفائل من هذه الفترة ارتباط سالب قوي.
- تقديرات العينة: cor = −0.87: الرقم نفسه الذي أعطتك إياه
cor().
وتستحق العينات الصغيرة احترامًا إضافيًا هنا: فمع n = 10 تظهر ارتباطات بمقدار ±0.5 بمحض الحظ بمعدل مقلق، وستخبرك فترة الثقة الواسعة بذلك. أبلِغ عن الفترة لا عن قيمة p وحدها.
رؤيته: ارسم دائمًا
يضغط معامل الارتباط علاقة كاملة في رقم واحد، وقد يخفي هذا الضغط انحناءً أو تجمعات أو نقطة واحدة تقوم بكل العمل. فقبل أن تثق بأي r انظر إلى مخطط الانتشار:
plot(mtcars$wt, mtcars$mpg) # one pair
pairs(mtcars[, c("mpg", "wt", "hp", "disp")]) # every pair in the matrix
ترسم pairs() شبكة من مخططات الانتشار تطابق مصفوفة ارتباطك، وهي أسرع طريقة للتأكد من أن الأرقام تعني ما تظنه. وللحصول على رسوميات مصفوفية مصقولة بأسلوب الخرائط الحرارية، تكون حزمة corrplot هي الأداة المعيارية (install.packages("corrplot") ثم corrplot(cor(m))).
الخلاصة
- تعطي
cor(x, y)معامل بيرسون r: الإشارة اتجاه، والمقدار قوة، ويقع دائمًا في المجال [−1, 1] وبلا وحدات. - يقيس الارتباط التحرك المشترك الخطي ولا يقول شيئًا عن السببية، فالمتغير الثالث الكامن احتمال دائم.
- استخدم
method = "spearman"للرتب: البيانات الترتيبية والقيم الشاذة والعلاقات الرتيبة المنحنية. - تعطي
cor(df)على الأعمدة العددية المصفوفة، فقرّبها بـround(, 2)، وانتبه إلى الوسيطuse =عند وجود بيانات مفقودة. - تضيف
cor.test(x, y)قيمة p وفترة ثقة، فأبلِغ عن الفترة. - انظر دائمًا إلى مخطط الانتشار قبل تصديق الرقم.
في المستند التالي: حين يتحول السؤال من "هل يتحركان معًا؟" إلى "هل يختلف متوسط هذه المجموعة عن تلك؟"، أي اختبار t.
الأسئلة الشائعة
كيف تحسب الارتباط في R؟
تُرجع cor(x, y) معامل ارتباط بيرسون بين متجهين عدديين. ومرّر بدلًا من ذلك إطار بيانات من أعمدة عددية، أي cor(df)، لتحصل على مصفوفة الارتباط الكاملة. وللحصول على قيمة p وفترة ثقة استخدم cor.test(x, y).
كيف تحصل على قيمة p للارتباط في R؟
لا تعطيها cor() وحدها، فاستخدم cor.test(x, y). وتشمل مخرجاتها إحصاء t ودرجات الحرية وقيمة p لفرضية العدم القائلة بأن الارتباط الحقيقي صفر، وفترة ثقة 95%، والمعامل المقدَّر.
ما الفرق بين ارتباط بيرسون وارتباط سبيرمان؟
يقيس بيرسون (الافتراضي) الارتباط الخطي على القيم الخام. أما سبيرمان فيرتّب القيم أولًا، فيقيس ما إذا كانت العلاقة متزايدة أو متناقصة باطراد (رتيبة)، وهو أقل حساسية بكثير للقيم الشاذة. استخدم cor(x, y, method = "spearman") للبيانات الترتيبية أو الملتوية أو للعلاقات المنحنية لكن الرتيبة.
كيف تتعامل مع قيم NA في cor()؟
افتراضيًا تُرجع cor() القيمة NA إذا كانت أي قيمة مفقودة. مرّر use = "complete.obs" لحذف الصفوف التي تحوي أي قيمة مفقودة أولًا، أو use = "pairwise.complete.obs" في مصفوفة لاستخدام كل الصفوف التي يتوفر فيها كلا المتغيرين لكل زوج على حدة.