من أهم الخطوات وأولها عند البدء بتحليل البيانات أو التنقيب عنها هو إجراء عمليات تحليل استكشافية على البيانات لفهم طبيعتها وللحصول على فكرة أولية عما تحتويه هذه البيانات وما هو الهدف المراد تحقيقه من التحليل أو التنقيب. لذلك، نقدم لكم في نمذجيات هذا الدرس العملي الذي يحتوي شرحاً مختصراً عن كيفية استيراد البيانات واستكشافها باستخدام لغة البايثون ومكتباتها المتخصصة في هذا المجال وعبر استخدام الأداة الرائعة جوبيتر.
من المهم قبل البدء بأي عملية استكشاف بيانات أن نتعرف على مصدر هذه البيانات، حتى نفهم السياق الذي وُجدت فيه، وبذلك نستطيع التعرف على الأهداف المراد تحقيقها من الاستكشاف. البيانات المستخدمة في هذا الدرس جُمعت من نظام كالبورد 360 وهو نظام خاص بإدارة التعليم الكترونياً، وهي عبارة عن بيانات مجموعة من الطلاب هدفها توقع أداء الطلاب وفقاً لمجموعة من الخصائص عددها 16.
خصائص البيانات
قبل البدء في شرح البيانات التي سنعمل عليها، من المهم توضيح بعض المفاهيم:
- خصائص البيانات: هي مجموع الأعمدة أو السمات التي تُشكل سجل البيانات، وفي حالتنا هذه فإن جميع السجلات الموجودة تتشارك نفس مُسميات الخصائص والسمات.
- أنواع البيانات: لكل خاصية في البيانات نوع معين لا يتغير، وتكون الخاصية أحد أربع أنواع:
- إسمية (Nominal).
- ترتيبية (Ordinal).
- مجال (Range).
- نسبة (Ratio).
- بعض المصادر تُشير إلى الأنواع الإسمية والترتيبية معاً بالخصائص الفئوية (Categorical) أو النوعية (Qualitative) ويُشار الى خصائص المجال والنسبة الى الخصائص الكمية (Quantitive) أو الرقمية (Numeric).
- إطار البيانات (Dataframe): هو مصطلح برمجي خاص بمكتبة Pandas في لغة البايثون، وهو المُتغير الذي يحتفظ بالبيانات عند استيرادها من ملفات خارجية مثل csv او xls ويُمَّكْنُنَا من التعامل مع البيانات ومعالجتها.
خصائص بيانات الطلاب المُستخدمة في هذا الدرس:
الخاصية |
الوصف |
طبيعة الخاصية |
مجال القيم |
Gender |
جنس الطالب |
ترتيبية |
Male , Female |
Nationality |
الجنسية |
اسمية |
Kuwait, Lebanon, Egypt, SaudiArabia, USA, Jordan, Venezuela, Iran, Tunis, Morocco, Syria, Palestine, Iraq, Lybia |
Place of birth |
مكان الميلاد |
اسمية |
Kuwait, Lebanon, Egypt, SaudiArabia, USA, Jordan, Venezuela, Iran, Tunis, Morocco, Syria, Palestine, Iraq, Lybia |
Educational Stages |
مستوى الطالب |
ترتيبية |
lowerlevel, MiddleSchool, HighSchool |
Grade Levels |
الصف |
ترتيبية |
G-01, G-02, G-03, G-04, G-05, G-06, G-07, G-08, G-09, G-10, G-11, G-12 |
Section ID |
الشعبة |
ترتيبية |
A, B, C |
Topic |
المادة |
اسمية |
English, Spanish, French, Arabic, IT, Math, Chemistry, Biology, Science, History, Quran, Geology |
Semester |
الفصل الدراسي |
ترتيبية |
First, Second |
Relation |
ولي الأمر |
اسمية |
mom, father |
Raised hand |
عدد مرات رفع اليد في الصف |
رقمية – مجال |
0-100 |
Visited resources |
عدد زيارات الطالب لمحتوى المادة |
رقمية – مجال |
0-100 |
Viewing announcements |
عدد مرات تصفح الطالب للاعلانات |
رقمية – مجال |
0-100 |
Discussion groups |
عدد مرات مشاركة الطالب في مجموعات النقاش |
رقمية – مجال |
0-100 |
Parent Answering Survey |
هل شارك ولي الامر في الاستبانة |
ترتيبية |
Yes, No |
Parent School Satisfaction |
رضى ولي الامر عن المدرسة |
ترتيبية |
Yes, No |
Student Absence Days |
عدد ايام غياب الطالب |
ترتيبية |
above-7, under-7 |
Grade/Mark |
درجة الطالب |
ترتيبية |
L (low level)
M (middle level)
H (high level)
|
تستطيع الحصول على نُسخة من البيانات بصيغة csv من خلال الرابط التالي:
https://www.kaggle.com/aljarah/xAPI-Edu-Data
الجانب العملي باستخدام جوبيتر
أولاً: استيراد المكتبات والبيانات
في البداية نقوم باستيراد المكتبات اللازمة للعمل:
لإجراء عملية استيراد البيانات من ملف csv نستخدم الدالة read_csv الخاصة بمكتبة Pandas. نتيجة استدعاء الدالة عبارة عن إطار البيانات والذي سنسميه اختصاراً بـ df (مُعامل encoding يُستخدم لتحديد الترميز عند قراءة البيانات):
In [2]:
إذا كانت البيانات محفوظة لديك بشكل مُختلف عن صيغة csv فلا تقلق، فمكتبة Pandas تُقدم تشكيلة واسعة من دوال استيراد وقراءة البيانات التي تكون بصيغة json، excel، html أو حتى أن تكون البيانات في قاعدة بيانات.
ثانيا: التعرف على البيانات
الخطوة الأولى للحصول على صورة مبدئية عن البيانات هي استخدام الدالة describe والتي تقوم بتنفيذ عمليات إحصائية سريعة على خصائص البيانات المحفوظة في إطار البيانات:
In [3]:
Out [3]:
|
raisedhands |
VisITedResources |
AnnouncementsView |
Discussion |
count |
480.000000 |
480.000000 |
480.000000 |
480.000000 |
mean |
46.775000 |
54.797917 |
37.918750 |
43.283333 |
std |
30.779223 |
33.080007 |
26.611244 |
27.637735 |
min |
0.000000 |
0.000000 |
0.000000 |
1.000000 |
25% |
15.750000 |
20.000000 |
14.000000 |
20.000000 |
50% |
50.000000 |
65.000000 |
33.000000 |
39.000000 |
75% |
75.000000 |
84.000000 |
58.000000 |
70.000000 |
max |
100.000000 |
99.000000 |
98.000000 |
99.000000 |
In [4]:
Out [4]:
gender |
NationalITy |
PlaceofBirth |
StageID |
GradeID |
SectionID |
Topic |
Semester |
Relation |
raisedhands |
VisITedResources |
AnnouncementsView |
Discussion |
ParentAnsweringSurvey |
ParentschoolSatisfaction |
StudentAbsenceDays |
Class |
count |
480 |
480 |
480 |
480 |
480 |
480 |
480 |
480 |
480 |
480.000000 |
480.000000 |
480.000000 |
480.000000 |
480 |
480 |
480 |
480 |
unique |
2 |
14 |
14 |
3 |
10 |
3 |
12 |
2 |
2 |
NaN |
NaN |
NaN |
NaN |
2 |
2 |
2 |
3 |
top |
M |
KW |
KuwaIT |
MiddleSchool |
G-02 |
A |
IT |
F |
Father |
NaN |
NaN |
NaN |
NaN |
Yes |
Good |
Under-7 |
M |
freq |
305 |
179 |
180 |
248 |
147 |
283 |
95 |
245 |
283 |
NaN |
NaN |
NaN |
NaN |
270 |
292 |
289 |
211 |
mean |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
46.775000 |
54.797917 |
37.918750 |
43.283333 |
NaN |
NaN |
NaN |
NaN |
std |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
30.779223 |
33.080007 |
26.611244 |
27.637735 |
NaN |
NaN |
NaN |
NaN |
min |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
0.000000 |
0.000000 |
0.000000 |
1.000000 |
NaN |
NaN |
NaN |
NaN |
25% |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
15.750000 |
20.000000 |
14.000000 |
20.000000 |
NaN |
NaN |
NaN |
NaN |
50% |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
50.000000 |
65.000000 |
33.000000 |
39.000000 |
NaN |
NaN |
NaN |
NaN |
75% |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
75.000000 |
84.000000 |
58.000000 |
70.000000 |
NaN |
NaN |
NaN |
NaN |
max |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
NaN |
100.000000 |
99.000000 |
98.000000 |
99.000000 |
NaN |
NaN |
NaN |
NaN |
بالإضافة لدالة describe السابقة، يمكننا استخدام الدالة info والتي تقوم بعرض معلومات مختصرة عن إطار البيانات:
In [5]:
Out [5]:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 480 entries, 0 to 479
Data columns (total 17 columns):
gender 480 non-null object
NationalITy 480 non-null object
PlaceofBirth 480 non-null object
StageID 480 non-null object
GradeID 480 non-null object
SectionID 480 non-null object
Topic 480 non-null object
Semester 480 non-null object
Relation 480 non-null object
raisedhands 480 non-null int64
VisITedResources 480 non-null int64
AnnouncementsView 480 non-null int64
Discussion 480 non-null int64
ParentAnsweringSurvey 480 non-null object
ParentschoolSatisfaction 480 non-null object
StudentAbsenceDays 480 non-null object
Class 480 non-null object
dtypes: int64(4), object(13)
memory usage: 63.8+ KB
النتيجة السابقة لدالة info تحتوي معلومات عن هيكلية البيانات لدينا، من حيث عدد السجلات، عدد الأعمدة، نوع كل عمود وعدد القيم فيه بالإضافة لحجم الذاكرة المستهلكة لصالح إطار البيانات.
لمعرفة أبعاد إطار البيانات الذي نتعامل معه بطريقة مباشرة، نستخدم الخاصية shape:
In [6]:
أثناء عملنا سنحتاج غالباً للاطلاع على عينة من البيانات. من الممكن الحصول على عينة عشوائية باستخدام الدالة sample مع تحديد عدد القيم التي تريدها. بالاضافة لذلك، نستطيع الحصول على أول/اخر سجلات في إطار البيانات باستخدام الدوال head و tail على الترتيب.
In [7]:
Out [7]:
|
gender |
NationalITy |
PlaceofBirth |
StageID |
GradeID |
SectionID |
Topic |
Semester |
Relation |
raisedhands |
VisITedResources |
AnnouncementsView |
Discussion |
ParentAnsweringSurvey |
ParentschoolSatisfaction |
StudentAbsenceDays |
Class |
322 |
M |
Jordan |
Jordan |
lowerlevel |
G-02 |
A |
French |
F |
Father |
10 |
15 |
10 |
21 |
No |
Bad |
Above-7 |
L |
116 |
F |
KW |
KuwaIT |
lowerlevel |
G-02 |
C |
IT |
F |
Mum |
77 |
80 |
12 |
19 |
Yes |
Good |
Above-7 |
M |
299 |
M |
Jordan |
Jordan |
lowerlevel |
G-04 |
A |
Science |
S |
Father |
32 |
14 |
32 |
29 |
No |
Good |
Above-7 |
M |
Out [8]:
|
gender |
NationalITy |
PlaceofBirth |
StageID |
GradeID |
SectionID |
Topic |
Semester |
Relation |
raisedhands |
VisITedResources |
AnnouncementsView |
Discussion |
ParentAnsweringSurvey |
ParentschoolSatisfaction |
StudentAbsenceDays |
Class |
0 |
M |
KW |
KuwaIT |
lowerlevel |
G-04 |
A |
IT |
F |
Father |
15 |
16 |
2 |
20 |
Yes |
Good |
Under-7 |
M |
1 |
M |
KW |
KuwaIT |
lowerlevel |
G-04 |
A |
IT |
F |
Father |
20 |
20 |
3 |
25 |
Yes |
Good |
Under-7 |
M |
2 |
M |
KW |
KuwaIT |
lowerlevel |
G-04 |
A |
IT |
F |
Father |
10 |
7 |
0 |
30 |
No |
Bad |
Above-7 |
L |
3 |
M |
KW |
KuwaIT |
lowerlevel |
G-04 |
A |
IT |
F |
Father |
30 |
25 |
5 |
35 |
No |
Bad |
Above-7 |
L |
4 |
M |
KW |
KuwaIT |
lowerlevel |
G-04 |
A |
IT |
F |
Father |
40 |
50 |
12 |
50 |
No |
Bad |
Above-7 |
M |
Out [9]:
|
gender |
NationalITy |
PlaceofBirth |
StageID |
GradeID |
SectionID |
Topic |
Semester |
Relation |
raisedhands |
VisITedResources |
AnnouncementsView |
Discussion |
ParentAnsweringSurvey |
ParentschoolSatisfaction |
StudentAbsenceDays |
Class |
475 |
F |
Jordan |
Jordan |
MiddleSchool |
G-08 |
A |
Chemistry |
S |
Father |
5 |
4 |
5 |
8 |
No |
Bad |
Above-7 |
L |
476 |
F |
Jordan |
Jordan |
MiddleSchool |
G-08 |
A |
Geology |
F |
Father |
50 |
77 |
14 |
28 |
No |
Bad |
Under-7 |
M |
477 |
F |
Jordan |
Jordan |
MiddleSchool |
G-08 |
A |
Geology |
S |
Father |
55 |
74 |
25 |
29 |
No |
Bad |
Under-7 |
M |
478 |
F |
Jordan |
Jordan |
MiddleSchool |
G-08 |
A |
History |
F |
Father |
30 |
17 |
14 |
57 |
No |
Bad |
Above-7 |
L |
479 |
F |
Jordan |
Jordan |
MiddleSchool |
G-08 |
A |
History |
S |
Father |
35 |
14 |
23 |
62 |
No |
Bad |
Above-7 |
L |
للتأكد من أن إطار البيانات لدينا لا يحتوي على قيم فارغة نستخدم الدالة isnull الخاصة بإطار البيانات بالطريقة التالية:
In [10]:
النتيجة السابقة تعني أنه لا يوجد أي قيمة فارغة لأي خاصية في البيانات، وفي حال وجود قيمة فارغة ستكون النتيجة True.
للقيام ببعض العمليات الإحصائية مباشرة على خاصية من الخواص، فمن الممكن استخدام دوال مكتبة Numpy مثل mean، max، min، std وغيرها كما في المثال التالي:
Out [11]:
46.775
100
0
30.74714417632964
ثالثا: الإستعلام عن البيانات
من المهم جداً أثناء التعامل مع البيانات اجراء بعض عمليات الاستعلام وفق شروط ومحددات نريدها. فمثلاً، لو أردنا الاستعلام عن عدد الطلاب الذكور والاناث في البيانات نقوم باستخدام دالة value_counts والتي تقوم بتجميع قيم عمود مُعين وتحدد عدد التكرارات حسب كل مجموعة:
In [12]:
Out [12]:
M 305
F 175
Name: gender, dtype: int64
للاستعلام عن سجلات في إطار البيانات وفق شروط معينة، فإن مكتبة Pandas تُقدم الدالة query الخاصة بإطار البيانات، وهي دالة تسهل عليك إجراء عمليات إستعلام وفق محددات وشروط. فمثلاً، لو أردنا الإستعلام عن الطالبات من دولة الكويت الذين كان عدد مرات رفع اليد في الفصل أكثر من 50 وبحيث نعرض خاصية الجنس وعدد مرات رفع اليد فقط، نستخدم الدالة query بالطريقة التالية:
In [13]:
Out [13]:
|
gender |
raisedhands |
9 |
F |
70 |
18 |
F |
69 |
20 |
F |
60 |
68 |
F |
70 |
94 |
F |
80 |
95 |
F |
100 |
101 |
F |
70 |
110 |
F |
70 |
116 |
F |
77 |
122 |
F |
66 |
123 |
F |
70 |
في بعض الأحيان قد نحتاج لاستخدام متغيرات على مستوى الشيفرة البرمجية داخل جملة الشرط لدالة query. في هذه الحالة نستطيع الوصول للمتغيرات باستخدام الرمز الخاص @ ثم اسم المتغير داخل جملة الشرط كالتالي:
df.query("gender == 'F' and Topic == 'IT' and raisedhands > @x " )[["gender","raisedhands"]]
رابعاً: الإظهار المرئي
من أسرع الطرق التي تساعدنا في فهم البيانات والحصول على قراءات وملاحظات سريعة عنها هو استخدام تقنيات الإظهار المرئي للبيانات، وتتعدد الأشكال والرسومات البيانية والإحصائية التي يمكن إجراؤها. سنذكر تحت هذا العنوان بعضاً منها.
من المواضيع المهمة أثناء تحليل البيانات والتنقيب عنها هو معرفة درجة ارتباط خصائص البيانات ببعضها، وبإمكاننا استخدام دالة corr الخاصة بإطار البيانات للحصول على جدول يوضح درجة ارتباط الخصائص الرقمية ببعضها:
In [14]:
Out [14]:
|
raisedhands |
VisITedResources |
AnnouncementsView |
Discussion |
raisedhands |
1.000000 |
0.691572 |
0.643918 |
0.339386 |
VisITedResources |
0.691572 |
1.000000 |
0.594500 |
0.243292 |
AnnouncementsView |
0.643918 |
0.594500 |
1.000000 |
0.417290 |
Discussion |
0.339386 |
0.243292 |
0.417290 |
1.000000 |
تتراوح درجة الارتباط من 0 الى 1 حيث كلما اقتربت الدرجة من القيمة 1 كلما زادت الارتباطية بين الخاصيتين وهذا يسمح لنا بالإستغناء عن أحدهما، وهذا الأمر يُفيد في موضوع إنقاص الأبعاد (Dimensionality Reduction)، وكلما اقتربت الدرجة الى القيمة 0 كلما نقصت الترابطية بين الخاصيتين واصبحا مستقلين عن بعضهما البعض بحيث لا نستطيع الاستغناء عن أحدهما.
لإظهار الجدول السابق بطريقة مرئية نقوم بما يلي:
In [15]:
في الشكل السابق، كلما اقترب اللون الى الأسود كلما زادت الترابطية وكلما اقترب اللون الى الأبيض كلما قلت درجت الترابطية.
في كثير من التجارب نحتاج للحصول على شكل رسومي يوضح عدد تكرار السجلات لخاصية معينة (اسمية أو ترتيبية) حسب مجال القيم التي تحتويها. تُقدم مكتبة Seaborn الدالة countplot التي تقوم بذلك، فمثلاً، لو اردنا التعرف على أعداد الطلاب حسب الجنسيات، نقوم بالتالي:
In [16]:
في المثال السابق، قمنا باستدعاء الدالة countplot ومررنا لها في البداية العمود الذي نريد إجراء عملية العد بناءا على قيمته وهو في حالتنا NationalITy ومن ثم نحدد إطار البيانات الذي نعمل عليه، وفي النهاية تختار مجموعة الألوان الخاصة بالشكل. الدالة set_xticklabels نستخدمها لإجراء عملية تدوير (70 درجة) لأسماء الجنسيات حتى لا تتداخل فيما بينها ويظهر الشكل بطريقة مُرتبة.
من خلال الشكل البياني السابق، وبالنظر السريع له، نحصل على معلومة مفادها أن أغلب الطلاب هم من دولة الكويت والأردن. المثال التالي يوضح كيفية إجراء نفس الأمر على خاصية درجة الطالب:
In [17]:
ونلاحظ من الشكل أن أغلب الطلاب حصلوا على درجة متوسطة M في المواد بشكل عام، وعدد الطلاب الذين حصلوا على علامة عالية H هم أكثر بقليل من الطلاب الذين حصلوا على درجة متدنية L.
لعرض أعداد الطلاب حسب المواد مع تفصيل الأعداد حسب الدرجة نُمرر للدالة countplot المُعامل hue ونحدد اسم خاصية الدرجة كما يلي:
In [18]:
قد تكون الأعمدة البيانية في بعض الأحيان غير تفصيلية، لذلك، نستطيع استخدام ما يُسمى بأشكال السرب (Swarm Shapes) بحيث يتم رسم كل نقطة تُمثل سجل في البيانات على الشكل:
In [19]:
من الشكل السابق يتضح لنا أن أغلب الطلاب الذين رفعوا أيديهم في الصف أكثر من 60 مرة حصلوا درجة عالية H، بينما أغلب الطلاب الذين حصلوا على درجة متدنية L لم تزد مرات رفع اليد في الصف عن 20 مرة، بينما الطلاب الذين حصلوا على درجة متوسطة توزعت مرات رفع اليد لديهم على مجال الخاصية.
تُقدم مكتبة Seaborn دالة أخرى تُسمى joinplot لرسم شكل بياني يوضح علاقة متغيرين مع بعضهم البعض:
In [20]:
نلاحظ من الشكل وجود علاقة بين عدد مرات زيارة محتوى المواد وعدد مرات رفع اليد في الصف، حيث كلما زاد أحدهما زاد الأخر والعكس صحيح.
طرق الإظهار المرئي والأشكال التي يُمكن استخدامها كثيرة ومتنوعة، وهدفنا هو إعطاء لمحة سريعة عن أهم الأشكال المستخدمة وعرض الطريقة الأساسية لإستخدامها. يمكنكم تنزيل الكود وتجربته من
هنا.
خاتمة
قدمنا في هذا الدرس مجموعة من الطرق العملية لاستيراد البيانات وإجراء بعض العمليات الإستكشافية عليها مثل العمليات الاحصائية، الاستعلام عن البيانات والإظهار المرئي، وتمكنا من خلال الدرس تطبيق هذه العمليات على بيانات لمجموعة من الطلاب وعرضنا لكم بعض القراءات والملاحظات التي حصلنا عليها باستخدام الطرق الاستكشافية.
التقنيات، العمليات والمكتبات المُستخدمة في هذا الدرس تم ذكرها على سبيل المثال وليس الحصر، حيث يوجد العديد من الطرق والمكتبات والتقنيات الأخرى التي لا مجال لذكرها هنا.
سيكون من الجيد مشاركتنا تجاربكم في إجراء عمليات إستكشاف البيانات عبر التعليقات في هذا الدرس.
مرتبط
درس مميز ورائع. بارك الله في علمك أخ إبراهيم، وأشكرك على مساهمتك في نشر العلم.
العفو د.فارس
الدروس العملية في هكذا مواضيع مهمة جدا، ونحتاج لتقوية المحتوى العربي في هذا المجال لما له من فائدة على المستوى الأكاديمي والبحثي وكذلك المستوى التطبيقي في الشركات والمؤسسات.
تحياتي العطرة.
معلومات رائعة كعادة مواضيع نمذجيات
كمبتدئ في مجال البيانات لدي تساؤل, هل يعجز مايكروسوفت اكسيل عن تقديم مثل هذه المخرجات؟
شكرا لك رامي
برنامج الإكسيل يقدم العديد من الخيارات التي تتيح لك إجراء عمليات استكشافية على البيانات وإجراء بعض العمليات الأخرى ولكن كل ذلك يندرج تحت المُهمة الرئيسية للإكسيل كأداة مكتبية عامة تقدم حلولا في جدولة البيانات وليس كأداة أو برنامج متخصص في علم البيانات.
تحياتي
شكرا يا اخي علي هذا الدرس المهم وجزاك الله كل خير
وشكرا
عفوا وأهلا بكم
درس ممتاز وشيق
كم نحتاج لمثل هذه الدروس
وفقك الله ..
شكرا مهندس ابراهيم
وزادك الله علماً
بارك الله في علمكم ونفع بكم …..
مشكور أخي الغالي مقال جدا رائع
لو تكرمت عندي سؤال ….
ماهي الأساسيات والمهارت التي يجب ان اركز عليها كباحث في هذا المجال ؟