- تعد K-Nearest Neighbor واحدة من أبسط خوارزميات التعلم الآلي بناءً على تقنية التعلم الخاضع للإشراف.
- تفترض خوارزمية K-NN التشابه بين الحالة/البيانات الجديدة والحالات المتاحة وتضع الحالة الجديدة في الفئة الأكثر تشابهًا مع الفئات المتاحة.
- تقوم خوارزمية K-NN بتخزين جميع البيانات المتاحة وتصنيف نقطة بيانات جديدة بناءً على التشابه. وهذا يعني أنه عند ظهور بيانات جديدة، يمكن تصنيفها بسهولة إلى فئة مجموعة جيدة باستخدام خوارزمية K-NN.
- يمكن استخدام خوارزمية K-NN للانحدار وكذلك للتصنيف ولكن في الغالب يتم استخدامها لمشكلات التصنيف.
- K-NN هو خوارزمية غير حدودية مما يعني أنه لا يقدم أي افتراض بشأن البيانات الأساسية.
- ويسمى أيضا أ خوارزمية المتعلم الكسول لأنه لا يتعلم من مجموعة التدريب على الفور، بل يقوم بتخزين مجموعة البيانات وفي وقت التصنيف، يقوم بتنفيذ إجراء على مجموعة البيانات.
- تقوم خوارزمية KNN في مرحلة التدريب فقط بتخزين مجموعة البيانات وعندما تحصل على بيانات جديدة، تقوم بتصنيف تلك البيانات إلى فئة تشبه إلى حد كبير البيانات الجديدة.
لماذا نحتاج إلى خوارزمية K-NN؟
لنفترض أن هناك فئتين، أي الفئة أ والفئة ب، ولدينا نقطة بيانات جديدة ×1، لذا فإن نقطة البيانات هذه ستقع في أي من هذه الفئات. لحل هذا النوع من المشاكل، نحتاج إلى خوارزمية K-NN. بمساعدة K-NN، يمكننا بسهولة تحديد فئة أو فئة مجموعة بيانات معينة. النظر في الرسم البياني أدناه:
كيف يعمل K-NN؟
يمكن شرح عمل K-NN على أساس الخوارزمية التالية:
لنفترض أن لدينا نقطة بيانات جديدة ونحتاج إلى وضعها في الفئة المطلوبة. النظر في الصورة أدناه:
ربط قاعدة بيانات جافا
- أولاً، سنختار عدد الجيران، فنختار k=5.
- التالي سوف نقوم بحساب المسافة الإقليدية بين نقاط البيانات المسافة الإقليدية هي المسافة بين نقطتين، والتي سبق أن درسناها في الهندسة. ويمكن حسابها على النحو التالي:
- من خلال حساب المسافة الإقليدية، حصلنا على أقرب الجيران، حيث أقرب ثلاثة جيران في الفئة (أ) واثنين من أقرب الجيران في الفئة (ب). خذ بعين الاعتبار الصورة أدناه:
- كما نرى أن أقرب ثلاثة جيران هم من الفئة أ، وبالتالي يجب أن تنتمي نقطة البيانات الجديدة هذه إلى الفئة أ.
كيفية تحديد قيمة K في خوارزمية K-NN؟
فيما يلي بعض النقاط التي يجب تذكرها أثناء تحديد قيمة K في خوارزمية K-NN:
- لا توجد طريقة معينة لتحديد أفضل قيمة لـ 'K'، لذا نحتاج إلى تجربة بعض القيم للعثور على أفضل النتائج منها. القيمة الأكثر تفضيلاً لـ K هي 5.
- يمكن أن تكون القيمة المنخفضة جدًا لـ K، مثل K=1 أو K=2، مزعجة وتؤدي إلى تأثيرات القيم المتطرفة في النموذج.
- تعتبر القيم الكبيرة لـ K جيدة، ولكنها قد تجد بعض الصعوبات.
مزايا خوارزمية KNN:
- إنه سهل التنفيذ.
- إنه قوي لبيانات التدريب الصاخبة
- يمكن أن يكون أكثر فعالية إذا كانت بيانات التدريب كبيرة.
عيوب خوارزمية KNN:
- يحتاج دائمًا إلى تحديد قيمة K التي قد تكون معقدة بعض الوقت.
- تكلفة الحساب مرتفعة بسبب حساب المسافة بين نقاط البيانات لجميع عينات التدريب.
تنفيذ بايثون لخوارزمية KNN
للقيام بتنفيذ Python لخوارزمية K-NN، سنستخدم نفس المشكلة ومجموعة البيانات التي استخدمناها في الانحدار اللوجستي. ولكن هنا سنقوم بتحسين أداء النموذج. وفيما يلي وصف المشكلة:
مشكلة لخوارزمية K-NN: هناك شركة تصنيع سيارات قامت بتصنيع سيارة رباعية الدفع جديدة. تريد الشركة تقديم الإعلانات للمستخدمين المهتمين بشراء سيارة الدفع الرباعي هذه. بالنسبة لهذه المشكلة، لدينا مجموعة بيانات تحتوي على معلومات مستخدمين متعددين من خلال الشبكة الاجتماعية. تحتوي مجموعة البيانات على الكثير من المعلومات ولكن الراتب المقدر و عمر سننظر في المتغير المستقل و متغير تم شراؤه هو للمتغير التابع. فيما يلي مجموعة البيانات:
خطوات تنفيذ خوارزمية K-NN:
- خطوة المعالجة المسبقة للبيانات
- ملاءمة خوارزمية K-NN لمجموعة التدريب
- التنبؤ بنتيجة الاختبار
- دقة اختبار النتيجة (إنشاء مصفوفة الارتباك)
- تصور نتيجة مجموعة الاختبار.
خطوة المعالجة المسبقة للبيانات:
ستظل خطوة المعالجة المسبقة للبيانات كما هي تمامًا مثل الانحدار اللوجستي. أدناه هو رمز لذلك:
# importing libraries import numpy as nm import matplotlib.pyplot as mtp import pandas as pd #importing datasets data_set= pd.read_csv('user_data.csv') #Extracting Independent and dependent Variable x= data_set.iloc[:, [2,3]].values y= data_set.iloc[:, 4].values # Splitting the dataset into training and test set. from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test= train_test_split(x, y, test_size= 0.25, random_state=0) #feature Scaling from sklearn.preprocessing import StandardScaler st_x= StandardScaler() x_train= st_x.fit_transform(x_train) x_test= st_x.transform(x_test)
من خلال تنفيذ التعليمات البرمجية أعلاه، يتم استيراد مجموعة البيانات الخاصة بنا إلى برنامجنا ومعالجتها مسبقًا بشكل جيد. بعد توسيع نطاق الميزات، ستبدو مجموعة بيانات الاختبار الخاصة بنا كما يلي:
من الصورة الناتجة أعلاه، يمكننا أن نرى أنه تم تغيير حجم بياناتنا بنجاح.
الآن سوف نقوم بملاءمة مصنف K-NN مع بيانات التدريب. للقيام بذلك سوف نقوم باستيراد تصنيف الجيران فئة من سكتعلم الجيران مكتبة. بعد استيراد الفصل، سنقوم بإنشاء ملف مصنف كائن من الطبقة. المعلمة من هذه الفئة ستكون
#Fitting K-NN classifier to the training set from sklearn.neighbors import KNeighborsClassifier classifier= KNeighborsClassifier(n_neighbors=5, metric='minkowski', p=2 ) classifier.fit(x_train, y_train)
الإخراج: بتنفيذ الكود أعلاه، سوف نحصل على الإخراج على النحو التالي:
Out[10]: KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=None, n_neighbors=5, p=2, weights='uniform')
#Predicting the test set result y_pred= classifier.predict(x_test)
انتاج:
سيكون إخراج الكود أعلاه:
سنقوم الآن بإنشاء مصفوفة الارتباك لنموذج K-NN الخاص بنا لمعرفة دقة المصنف. أدناه هو رمز لذلك:
#Creating the Confusion matrix from sklearn.metrics import confusion_matrix cm= confusion_matrix(y_test, y_pred)
في الكود أعلاه، قمنا باستيراد الدالةfusion_matrix وقمنا بتسميتها باستخدام المتغير cm.
محاذاة الصور باستخدام CSS
انتاج: وبتنفيذ الكود أعلاه سنحصل على المصفوفة كما يلي:
في الصورة أعلاه، يمكننا أن نرى أن هناك 64+29= 93 تنبؤًا صحيحًا و3+4= 7 تنبؤات غير صحيحة، بينما في الانحدار اللوجستي، كان هناك 11 تنبؤًا غير صحيح. لذلك يمكننا القول أنه تم تحسين أداء النموذج باستخدام خوارزمية K-NN.
الآن، سوف نقوم بتصور نتيجة مجموعة التدريب لنموذج K-NN. سيبقى الرمز كما فعلنا في الانحدار اللوجستي، باستثناء اسم الرسم البياني. أدناه هو رمز لذلك:
#Visulaizing the trianing set result from matplotlib.colors import ListedColormap x_set, y_set = x_train, y_train x1, x2 = nm.meshgrid(nm.arange(start = x_set[:, 0].min() - 1, stop = x_set[:, 0].max() + 1, step =0.01), nm.arange(start = x_set[:, 1].min() - 1, stop = x_set[:, 1].max() + 1, step = 0.01)) mtp.contourf(x1, x2, classifier.predict(nm.array([x1.ravel(), x2.ravel()]).T).reshape(x1.shape), alpha = 0.75, cmap = ListedColormap(('red','green' ))) mtp.xlim(x1.min(), x1.max()) mtp.ylim(x2.min(), x2.max()) for i, j in enumerate(nm.unique(y_set)): mtp.scatter(x_set[y_set == j, 0], x_set[y_set == j, 1], c = ListedColormap(('red', 'green'))(i), label = j) mtp.title('K-NN Algorithm (Training set)') mtp.xlabel('Age') mtp.ylabel('Estimated Salary') mtp.legend() mtp.show()
انتاج:
بتنفيذ الكود أعلاه، سنحصل على الرسم البياني أدناه:
يختلف الرسم البياني الناتج عن الرسم البياني الذي حدث في الانحدار اللوجستي. ويمكن فهم ذلك في النقاط التالية:
- كما نرى الرسم البياني يظهر النقطة الحمراء والنقاط الخضراء. النقاط الخضراء مخصصة للمتغير الذي تم شراؤه (1) والنقاط الحمراء للمتغير الذي لم يتم شراؤه (0).
- يظهر الرسم البياني حدودًا غير منتظمة بدلاً من إظهار أي خط مستقيم أو أي منحنى لأنه خوارزمية K-NN، أي العثور على أقرب جار.
- قام الرسم البياني بتصنيف المستخدمين في الفئات الصحيحة حيث أن معظم المستخدمين الذين لم يشترو السيارة الرياضية متعددة الاستخدامات موجودون في المنطقة الحمراء والمستخدمون الذين اشتروا السيارة الرياضية متعددة الاستخدامات موجودون في المنطقة الخضراء.
- يظهر الرسم البياني نتيجة جيدة ولكن لا تزال هناك بعض النقاط الخضراء في المنطقة الحمراء ونقاط حمراء في المنطقة الخضراء. ولكن هذه ليست مشكلة كبيرة لأنه من خلال القيام بهذا النموذج يتم منعه من مشاكل التجهيز الزائد.
- ومن ثم فإن نموذجنا مدرب جيدًا.
بعد التدريب على النموذج، سنقوم الآن باختبار النتيجة عن طريق وضع مجموعة بيانات جديدة، أي مجموعة بيانات الاختبار. يظل الرمز كما هو باستثناء بعض التغييرات الطفيفة: مثل x_train وy_train سيتم استبداله x_test و y_test .
أدناه هو رمز لذلك:
#Visualizing the test set result from matplotlib.colors import ListedColormap x_set, y_set = x_test, y_test x1, x2 = nm.meshgrid(nm.arange(start = x_set[:, 0].min() - 1, stop = x_set[:, 0].max() + 1, step =0.01), nm.arange(start = x_set[:, 1].min() - 1, stop = x_set[:, 1].max() + 1, step = 0.01)) mtp.contourf(x1, x2, classifier.predict(nm.array([x1.ravel(), x2.ravel()]).T).reshape(x1.shape), alpha = 0.75, cmap = ListedColormap(('red','green' ))) mtp.xlim(x1.min(), x1.max()) mtp.ylim(x2.min(), x2.max()) for i, j in enumerate(nm.unique(y_set)): mtp.scatter(x_set[y_set == j, 0], x_set[y_set == j, 1], c = ListedColormap(('red', 'green'))(i), label = j) mtp.title('K-NN algorithm(Test set)') mtp.xlabel('Age') mtp.ylabel('Estimated Salary') mtp.legend() mtp.show()
انتاج:
يوضح الرسم البياني أعلاه مخرجات مجموعة بيانات الاختبار. كما نرى في الرسم البياني، فإن الناتج المتوقع جيد جدًا حيث أن معظم النقاط الحمراء موجودة في المنطقة الحمراء ومعظم النقاط الخضراء موجودة في المنطقة الخضراء.
ومع ذلك، هناك عدد قليل من النقاط الخضراء في المنطقة الحمراء وعدد قليل من النقاط الحمراء في المنطقة الخضراء. هذه هي الملاحظات غير الصحيحة التي لاحظناها في مصفوفة الارتباك (7 إخراج غير صحيح).