دليل لخوارزمية K-Nearest Neighbours في Python و Scikit-Learn PlatoBlockchain Data Intelligence. البحث العمودي. عاي.

توجه إلى K-Nearest Neighbours Algorithm في Python و Scikit-Learn

المُقدّمة

K- أقرب الجيران (KNN) الخوارزمية هي نوع من خوارزمية التعلم الآلي الخاضعة للإشراف المستخدمة في التصنيف والانحدار وكذلك الكشف عن العوامل الخارجية. من السهل جدًا تنفيذه في أبسط أشكاله ولكن يمكنه أداء مهام معقدة إلى حد ما. إنها خوارزمية تعليمية كسولة لأنها لا تحتوي على مرحلة تدريب متخصصة. بدلاً من ذلك ، يستخدم جميع البيانات للتدريب أثناء تصنيف (أو تراجع) نقطة بيانات أو مثيل جديد.

KNN هو ملف خوارزمية التعلم غير البارامترية، مما يعني أنه لا يفترض أي شيء عن البيانات الأساسية. هذه ميزة مفيدة للغاية لأن معظم بيانات العالم الحقيقي لا تتبع في الواقع أي افتراض نظري مثل الفصل الخطي والتوزيع المنتظم وما إلى ذلك.

في هذا الدليل ، سنرى كيف يمكن تنفيذ KNN مع مكتبة Python Scikit-Learn. قبل ذلك سنستكشف أولاً كيف يمكننا استخدام KNN وشرح النظرية الكامنة وراءه. بعد ذلك ، سنلقي نظرة على ملف مجموعة بيانات الإسكان في كاليفورنيا سنستخدمها لتوضيح خوارزمية KNN والعديد من أشكالها المختلفة. بادئ ذي بدء ، سنلقي نظرة على كيفية تنفيذ خوارزمية KNN للانحدار ، متبوعًا بتطبيقات تصنيف KNN والاكتشاف الخارجي. في النهاية ، سنختتم ببعض إيجابيات وسلبيات الخوارزمية.

متى يجب استخدام KNN؟

لنفترض أنك أردت استئجار شقة واكتشفت مؤخرًا أن جارة صديقك قد تطرح شقتها للإيجار في غضون أسبوعين. نظرًا لأن الشقة ليست على موقع إيجار بعد ، كيف يمكنك محاولة تقدير قيمتها الإيجارية؟

لنفترض أن صديقك يدفع إيجارًا قدره 1,200 دولار. قد تكون قيمة الإيجار الخاصة بك حول هذا الرقم ، لكن الشقق ليست هي نفسها تمامًا (الاتجاه ، المنطقة ، جودة الأثاث ، إلخ) ، لذلك سيكون من الجيد الحصول على مزيد من البيانات حول الشقق الأخرى.

من خلال سؤال الجيران الآخرين والنظر إلى الشقق من نفس المبنى التي تم إدراجها على موقع الإيجار ، فإن أقرب ثلاثة إيجارات للشقق المجاورة هي 1,200 دولار و 1,210 دولار و 1,210 دولار و 1,215 دولار. تقع هذه الشقق في نفس المبنى والأرض لشقة صديقك.

شقق أخرى بعيدة ، في نفس الطابق ، ولكن في مبنى مختلف ، تبلغ إيجاراتها 1,400 دولار ، و 1,430 دولارًا ، و 1,500 دولارًا ، و 1,470 دولارًا. يبدو أنها أكثر تكلفة بسبب وجود المزيد من ضوء الشمس في المساء.

بالنظر إلى قرب الشقة ، يبدو أن إيجارك المقدر سيكون حوالي 1,210،XNUMX دولارًا. هذه هي الفكرة العامة لما K- أقرب الجيران (KNN) الخوارزمية! إنه يصنف البيانات الجديدة أو يتراجع عنها بناءً على قربها من البيانات الموجودة بالفعل.

ترجم المثال إلى نظرية

عندما تكون القيمة المقدرة رقمًا مستمرًا ، مثل قيمة الإيجار ، يتم استخدام KNN تراجع. ولكن يمكننا أيضًا تقسيم الشقق إلى فئات بناءً على الحد الأدنى والحد الأقصى للإيجار ، على سبيل المثال. عندما تكون القيمة منفصلة ، مما يجعلها فئة ، يتم استخدام KNN لها تصنيف.

هناك أيضًا إمكانية لتقدير الجيران المختلفين جدًا عن الآخرين لدرجة أنهم سيتوقفون على الأرجح عن دفع الإيجار. هذا هو نفس اكتشاف نقاط البيانات البعيدة جدًا بحيث لا تتناسب مع أي قيمة أو فئة ، وعندما يحدث ذلك ، يتم استخدام KNN من أجل الكشف الخارجى.

في مثالنا ، عرفنا أيضًا إيجارات كل شقة ، مما يعني أنه تم تصنيف بياناتنا. تستخدم KNN البيانات المصنفة مسبقًا ، مما يجعلها ملف خوارزمية التعلم تحت الإشراف.

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

في كل مرة يتم فيها إضافة نقطة جديدة إلى البيانات ، تستخدم KNN جزءًا واحدًا فقط من البيانات لتحديد القيمة (الانحدار) أو الفئة (التصنيف) لتلك النقطة المضافة. نظرًا لأنه لا يتعين عليه النظر إلى جميع النقاط مرة أخرى ، فإن هذا يجعله ملف خوارزمية التعلم الكسول.

لا تفترض KNN أيضًا أي شيء عن خصائص البيانات الأساسية ، ولا تتوقع أن تتناسب البيانات مع نوع من التوزيع ، مثل التوحيد ، أو أن تكون قابلة للفصل خطيًا. هذا يعني أنه ملف خوارزمية التعلم غير البارامترية. هذه ميزة مفيدة للغاية لأن معظم بيانات العالم الحقيقي لا تتبع أي افتراض نظري.

تصور الاستخدامات المختلفة لـ KNN

كما تم توضيحه ، فإن الحدس الكامن وراء خوارزمية KNN هو واحد من أكثر خوارزميات التعلم الآلي الخاضعة للإشراف. تقوم الخوارزمية أولاً بحساب مسافة نقطة بيانات جديدة لجميع نقاط بيانات التدريب الأخرى.

ملحوظة: يمكن قياس المسافة بطرق مختلفة. يمكنك استخدام Minkowski ، الإقليديةأو صيغة Manhattan أو Mahalanobis أو Hamming ، على سبيل المثال لا الحصر. مع البيانات عالية الأبعاد ، تبدأ المسافة الإقليدية في كثير من الأحيان بالفشل (الأبعاد العالية ... غريبة) ، وتستخدم مسافة مانهاتن بدلاً من ذلك.

بعد حساب المسافة ، تختار KNN عددًا من أقرب نقاط البيانات - 2 أو 3 أو 10 أو أي عدد صحيح بالفعل. هذا العدد من النقاط (2 ، 3 ، 10 ، إلخ) هو K في K- أقرب الجيران!

في الخطوة الأخيرة ، إذا كانت مهمة انحدار ، فسيقوم KNN بحساب متوسط ​​المجموع المرجح لأقرب نقاط K للتنبؤ. إذا كانت مهمة تصنيف ، فسيتم تعيين نقطة البيانات الجديدة للفئة التي تنتمي إليها غالبية نقاط K الأقرب المحددة.

دعنا نتخيل الخوارزمية وهي تعمل بمساعدة مثال بسيط. ضع في اعتبارك مجموعة بيانات ذات متغيرين و K لـ 3.

عند إجراء الانحدار ، تتمثل المهمة في العثور على قيمة نقطة بيانات جديدة ، بناءً على متوسط ​​المجموع المرجح لأقرب ثلاث نقاط.

KNN مع K = 3، عندما تستخدم للانحدار:

دليل لخوارزمية K-Nearest Neighbours في Python و Scikit-Learn PlatoBlockchain Data Intelligence. البحث العمودي. عاي.

ستبدأ خوارزمية KNN بحساب مسافة النقطة الجديدة من جميع النقاط. ثم يجد النقاط الثلاث الأقل مسافة للنقطة الجديدة. يظهر هذا في الشكل الثاني أعلاه ، حيث أقرب ثلاث نقاط ، 47, 58و 79 تم تطويقها. بعد ذلك ، تحسب المجموع المرجح لـ 47, 58 و 79 - في هذه الحالة ، تكون الأوزان مساوية لـ 1 - نحن نعتبر جميع النقاط متساوية ، ولكن يمكننا أيضًا تعيين أوزان مختلفة بناءً على المسافة. بعد حساب المجموع المرجح ، تكون قيمة النقطة الجديدة 61,33.

وعند إجراء تصنيف ، فإن مهمة KNN لتصنيف نقطة بيانات جديدة ، في "Purple" or "Red" فئة.

KNN مع K = 3، عندما تستخدم للتصنيف:

دليل لخوارزمية K-Nearest Neighbours في Python و Scikit-Learn PlatoBlockchain Data Intelligence. البحث العمودي. عاي.
دليل لخوارزمية K-Nearest Neighbours في Python و Scikit-Learn PlatoBlockchain Data Intelligence. البحث العمودي. عاي.

ستبدأ خوارزمية KNN بنفس الطريقة السابقة ، عن طريق حساب مسافة النقطة الجديدة من جميع النقاط ، وإيجاد أقرب ثلاث نقاط مع أقل مسافة إلى النقطة الجديدة ، وبعد ذلك ، بدلاً من حساب رقم ، تقوم بتعيين النقطة الجديدة للفصل الذي تنتمي إليه غالبية أقرب ثلاث نقاط ، الطبقة الحمراء. لذلك سيتم تصنيف نقطة البيانات الجديدة على أنها "Red".

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

ملاحظات: تم تنفيذ واختبار الكود الموجود في هذا البرنامج التعليمي مع ما يلي دفتر جوبيتر.

مجموعة بيانات الإسكان Scikit-Learn California

نحن ذاهبون لاستخدام مجموعة بيانات الإسكان في كاليفورنيا لتوضيح كيفية عمل خوارزمية KNN. تم اشتقاق مجموعة البيانات من تعداد الولايات المتحدة لعام 1990. يمثل صف واحد من مجموعة البيانات تعداد مجموعة كتلة واحدة.

في هذا القسم ، سنتطرق إلى تفاصيل مجموعة بيانات الإسكان في كاليفورنيا ، حتى تتمكن من اكتساب فهم بديهي للبيانات التي سنعمل معها. من المهم جدًا التعرف على بياناتك قبل البدء في العمل عليها.

A منع المجموعة هي أصغر وحدة جغرافية ينشر عنها مكتب الإحصاء الأمريكي بيانات العينة. إلى جانب مجموعة الكتل ، هناك مصطلح آخر مستخدم هو الأسرة ، والأسرة هي مجموعة من الأشخاص المقيمين داخل المنزل.

تتكون مجموعة البيانات من تسع سمات:

  • MedInc - متوسط ​​الدخل في مجموعة الكتل
  • HouseAge - متوسط ​​عمر المنزل في مجموعة الكتل
  • AveRooms - متوسط ​​عدد الغرف (لكل أسرة)
  • AveBedrms - متوسط ​​عدد غرف النوم (لكل أسرة)
  • Population - كتلة مجموعة السكان
  • AveOccup - متوسط ​​عدد أفراد الأسرة
  • Latitude - كتلة خط العرض
  • Longitude - كتلة خط الطول
  • MedHouseVal - متوسط ​​قيمة المنزل لمقاطعات كاليفورنيا (مئات الآلاف من الدولارات)

مجموعة البيانات هي بالفعل جزء من مكتبة Scikit-Learn، نحتاج فقط إلى استيراده وتحميله كإطار بيانات:

from sklearn.datasets import fetch_california_housing

california_housing = fetch_california_housing(as_frame=True)

df = california_housing.frame

استيراد البيانات مباشرة من Scikit-Learn ، يستورد أكثر من مجرد الأعمدة والأرقام ويتضمن وصف البيانات كملف Bunch كائن - لذلك قمنا للتو باستخراج ملف frame. تتوفر مزيد من التفاصيل عن مجموعة البيانات هنا.

دعنا نستورد Pandas ونلقي نظرة خاطفة على صفوف البيانات القليلة الأولى:

import pandas as pd
df.head()

سيؤدي تنفيذ الكود إلى عرض الصفوف الخمسة الأولى من مجموعة البيانات الخاصة بنا:

	MedInc  HouseAge  AveRooms  AveBedrms  Population  AveOccup   Latitude  Longitude  MedHouseVal
0 	8.3252 	41.0 	  6.984127 	1.023810   322.0 	   2.555556   37.88 	-122.23    4.526
1 	8.3014 	21.0 	  6.238137 	0.971880   2401.0 	   2.109842   37.86 	-122.22    3.585
2 	7.2574 	52.0 	  8.288136 	1.073446   496.0 	   2.802260   37.85 	-122.24    3.521
3 	5.6431 	52.0 	  5.817352 	1.073059   558.0 	   2.547945   37.85 	-122.25    3.413
4 	3.8462 	52.0 	  6.281853 	1.081081   565.0 	   2.181467   37.85 	-122.25    3.422

في هذا الدليل ، سوف نستخدم MedInc, HouseAge, AveRooms, AveBedrms, Population, AveOccup, Latitude, Longitude ليتنبأ MedHouseVal. شيء مشابه لسرد الدافع لدينا.

دعنا الآن ننتقل مباشرة إلى تنفيذ خوارزمية KNN للانحدار.

الانحدار مع K-Nearest Neighbours مع Scikit-Learn

حتى الآن ، تعرفنا على مجموعة البيانات الخاصة بنا ويمكننا الآن المضي قدمًا في خطوات أخرى في خوارزمية KNN.

المعالجة المسبقة للبيانات لانحدار KNN

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

بالنسبة للانحدار ، نحتاج إلى توقع قيمة منزل وسيطة أخرى. للقيام بذلك ، سنقوم بتعيين MedHouseVal إلى y وجميع الأعمدة الأخرى إلى X فقط عن طريق السقوط MedHouseVal:

y = df['MedHouseVal']
X = df.drop(['MedHouseVal'], axis = 1)

بالنظر إلى أوصاف المتغيرات الخاصة بنا ، يمكننا أن نرى أن لدينا اختلافات في القياسات. لتجنب التخمين ، دعنا نستخدم امتداد describe() طريقة التحقق:


X.describe().T

وينتج عنه:

			count 	  mean 		   std 			min 		25% 		50% 		75% 		max
MedInc 		20640.0   3.870671 	   1.899822 	0.499900 	2.563400 	3.534800 	4.743250 	15.000100
HouseAge 	20640.0   28.639486    12.585558 	1.000000 	18.000000 	29.000000 	37.000000 	52.000000
AveRooms 	20640.0   5.429000 	   2.474173 	0.846154 	4.440716 	5.229129 	6.052381 	141.909091
AveBedrms 	20640.0   1.096675 	   0.473911 	0.333333 	1.006079 	1.048780 	1.099526 	34.066667
Population 	20640.0   1425.476744  1132.462122 	3.000000 	787.000000 	1166.000000 1725.000000 35682.000000
AveOccup 	20640.0   3.070655 	   10.386050 	0.692308 	2.429741 	2.818116 	3.282261 	1243.333333
Latitude 	20640.0   35.631861    2.135952 	32.540000 	33.930000 	34.260000 	37.710000 	41.950000
Longitude 	20640.0   -119.569704  2.003532    -124.350000 -121.800000 	-118.490000 -118.010000 -114.310000

هنا ، يمكننا أن نرى أن ملف mean قيمة MedInc ما يقرب من 3.87 و mean قيمة HouseAge حوالي 28.64، مما يجعلها أكبر بـ 7.4 مرات من MedInc. تحتوي الميزات الأخرى أيضًا على اختلافات في المتوسط ​​والانحراف المعياري - لمعرفة ذلك ، انظر إلى mean و std القيم ولاحظ كيف أنها بعيدة عن بعضها البعض. إلى عن على MedInc std ما يقرب من 1.9، ل HouseAge, std is 12.59 وينطبق الشيء نفسه على الميزات الأخرى.

نحن نستخدم خوارزمية تعتمد على مسافة وتعاني الخوارزميات القائمة على المسافة بشكل كبير من البيانات التي ليست على نفس النطاق ، مثل هذه البيانات. قد يؤدي مقياس النقاط (وعمليًا ، دائمًا تقريبًا) إلى تشويه المسافة الحقيقية بين القيم.

لأداء ميزة تحجيم الميزات ، سوف نستخدم Scikit-Learn's StandardScaler فئة في وقت لاحق. إذا طبقنا القياس في الوقت الحالي (قبل تقسيم اختبار التدريب) ، فسيتضمن الحساب بيانات الاختبار بشكل فعال تسريب اختبار معلومات البيانات في بقية خط الأنابيب. هذا النوع من تسرب البيانات للأسف يتم تخطيها بشكل شائع ، مما يؤدي إلى نتائج غير قابلة للتكرار أو وهمية.

تقسيم البيانات إلى تدريب ومجموعات اختبار

لنكون قادرين على توسيع نطاق بياناتنا دون تسرب ، ولكن أيضًا لتقييم نتائجنا وتجنب الإفراط في التركيب ، سنقسم مجموعة البيانات الخاصة بنا إلى تقسيمات تدريب واختبار.

طريقة مباشرة لإنشاء تقسيمات القطار والاختبار هي train_test_split طريقة من Scikit-Learn. لا ينقسم الانقسام خطيًا في مرحلة ما ، ولكنه يأخذ عينات X٪ و Y٪ عشوائيًا. لجعل هذه العملية قابلة للتكرار (لجعل الطريقة دائمًا تأخذ عينات من نفس نقاط البيانات) ، سنقوم بتعيين ملف random_state حجة معينة SEED:

from sklearn.model_selection import train_test_split

SEED = 42
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=SEED)

هذا الجزء من الكود يأخذ عينات 75٪ من البيانات للتدريب و 25٪ من البيانات للاختبار. عن طريق تغيير test_size إلى 0.3 ، على سبيل المثال ، يمكنك التدريب باستخدام 70٪ من البيانات والاختبار بنسبة 30٪.

باستخدام 75٪ من البيانات للتدريب و 25٪ للاختبار ، من أصل 20640 سجلًا ، تحتوي مجموعة التدريب على 15480 ومجموعة الاختبار تحتوي على 5160. يمكننا فحص هذه الأرقام بسرعة عن طريق طباعة أطوال مجموعة البيانات الكاملة والبيانات المنقسمة :

len(X)       
len(X_train) 
len(X_test)  

رائعة! يمكننا الآن احتواء مقياس البيانات على ملف X_train مجموعة وقياس كليهما X_train و X_test دون تسريب أي بيانات من X_test إلى X_train.

ميزة التحجيم لانحدار KNN

عن طريق الاستيراد StandardScalerمن خلال إنشاء مثيل لها وتناسبها وفقًا لبيانات القطار الخاصة بنا (منع التسرب) ، وتحويل كل من مجموعات بيانات القطار والاختبار ، يمكننا إجراء تحجيم الميزات:

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()

scaler.fit(X_train)


X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

ملحوظة: منذ اتصالك في كثير من الأحيان scaler.fit(X_train) تليها scaler.transform(X_train) - يمكنك استدعاء واحد scaler.fit_transform(X_train) تليها scaler.transform(X_test) لجعل المكالمة أقصر!

الآن يتم تحجيم بياناتنا! يحافظ أداة القياس على نقاط البيانات فقط ، وليس أسماء الأعمدة ، عند تطبيقها على ملف DataFrame. دعنا ننظم البيانات في DataFrame مرة أخرى بأسماء الأعمدة واستخدامها describe() لمراقبة التغييرات في mean و std:

col_names=['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']
scaled_df = pd.DataFrame(X_train, columns=col_names)
scaled_df.describe().T

هذا سوف يعطينا:

			count 		mean 			std 		min 		25% 		50% 		75% 		max
MedInc 		15480.0 	2.074711e-16 	1.000032 	-1.774632 	-0.688854 	-0.175663 	0.464450 	5.842113
HouseAge 	15480.0 	-1.232434e-16 	1.000032 	-2.188261 	-0.840224 	0.032036 	0.666407 	1.855852
AveRooms 	15480.0 	-1.620294e-16 	1.000032 	-1.877586 	-0.407008 	-0.083940 	0.257082 	56.357392
AveBedrms 	15480.0 	7.435912e-17 	1.000032 	-1.740123 	-0.205765 	-0.108332 	0.007435 	55.925392
Population 	15480.0 	-8.996536e-17 	1.000032 	-1.246395 	-0.558886 	-0.227928 	0.262056 	29.971725
AveOccup 	15480.0 	1.055716e-17 	1.000032 	-0.201946 	-0.056581 	-0.024172 	0.014501 	103.737365
Latitude 	15480.0 	7.890329e-16 	1.000032 	-1.451215 	-0.799820 	-0.645172 	0.971601 	2.953905
Longitude 	15480.0 	2.206676e-15 	1.000032 	-2.380303 	-1.106817 	0.536231 	0.785934 	2.633738

لاحظ كيف أصبحت جميع الانحرافات المعيارية الآن 1 وأصبحت الوسائل أصغر. هذا ما يجعل بياناتنا أكثر اتساقا! دعونا ندرب ونقيم الانحدار القائم على KNN.

التدريب والتنبؤ بانحدار KNN

تجعل واجهة برمجة التطبيقات البديهية والمستقرة من Scikit-Learn عوامل الانحدار والمصنفات التدريبية واضحة للغاية. دعنا نستورد ملف KNeighborsRegressor الطبقة من sklearn.neighbors الوحدة النمطية ، وإنشاء مثيل لها ، وتناسبها مع بيانات القطار لدينا:

from sklearn.neighbors import KNeighborsRegressor
regressor = KNeighborsRegressor(n_neighbors=5)
regressor.fit(X_train, y_train)

في الكود أعلاه ، فإن ملف n_neighbors هي قيمة K، أو عدد الجيران التي ستأخذها الخوارزمية في الاعتبار عند اختيار قيمة منزل وسيطة جديدة. 5 هي القيمة الافتراضية لـ KNeighborsRegressor(). لا توجد قيمة مثالية لـ K ويتم تحديدها بعد الاختبار والتقييم ، ومع ذلك ، للبدء ، 5 هي قيمة شائعة الاستخدام لـ KNN وبالتالي تم تعيينها كقيمة افتراضية.

الخطوة الأخيرة هي عمل تنبؤات على بيانات الاختبار الخاصة بنا. للقيام بذلك ، قم بتنفيذ البرنامج النصي التالي:

y_pred = regressor.predict(X_test)

يمكننا الآن تقييم مدى نجاح نموذجنا في التعميم على البيانات الجديدة التي لدينا تسميات (حقيقة أساسية) - مجموعة الاختبار!

تقييم خوارزمية انحدار KNN

مقاييس الانحدار الأكثر استخدامًا لتقييم الخوارزمية هي متوسط ​​الخطأ المطلق (MAE) ومتوسط ​​الخطأ التربيعي (MSE) والخطأ التربيعي لمتوسط ​​الجذر (RMSE) ومعامل التحديد (R2):

  1. متوسط ​​الخطأ المطلق (MAE): عندما نطرح القيم المتوقعة من القيم الفعلية ، نحصل على الأخطاء ، ونجمع القيم المطلقة لتلك الأخطاء ونحصل على متوسطها. يعطي هذا المقياس فكرة عن الخطأ الإجمالي لكل توقع للنموذج ، وكلما كان أصغر (أقرب إلى 0) كان ذلك أفضل:

$$
mae = (frac {1} {n}) sum_ {i = 1} ^ {n} يسار | الفعلي - الحق المتوقع |
$$

ملحوظة: قد تواجه أيضًا y و ŷ (اقرأ كـ y-hat) في المعادلات. ال y يشير إلى القيم الفعلية و ŷ للقيم المتوقعة.

  1. متوسط ​​الخطأ التربيعي (MSE): إنه مشابه لمقياس MAE ، لكنه يربّع القيم المطلقة للأخطاء. أيضًا ، كما هو الحال مع MAE ، كلما كان أصغر أو أقرب إلى 0 ، كان ذلك أفضل. يتم تربيع قيمة MSE لجعل الأخطاء الكبيرة أكبر. هناك شيء واحد يجب الانتباه إليه عن كثب ، وهو أنه عادةً ما يكون من الصعب تفسيره نظرًا لحجم قيمه وحقيقة أنها ليست في نفس نطاق البيانات.

$$
mse = sum_ {i = 1} ^ {D} (فعلي - متوقع) ^ 2
$$

  1. جذر متوسط ​​الخطأ التربيعي (RMSE): يحاول حل مشكلة التفسير التي أثيرت مع MSE عن طريق الحصول على الجذر التربيعي لقيمته النهائية ، وذلك لإعادة تصغيره إلى نفس وحدات البيانات. من الأسهل التفسير وجيد عندما نحتاج إلى عرض أو إظهار القيمة الفعلية للبيانات مع الخطأ. يوضح مدى اختلاف البيانات ، لذلك ، إذا كان لدينا RMSE يبلغ 4.35 ، يمكن أن يرتكب نموذجنا خطأ إما لأنه أضاف 4.35 إلى القيمة الفعلية ، أو يحتاج إلى 4.35 للوصول إلى القيمة الفعلية. كلما اقتربنا من 0 ، كان ذلك أفضل أيضًا.

$$
rmse = sqrt {sum_ {i = 1} ^ {D} (فعلي - متوقع) ^ 2}
$$

mean_absolute_error() و mean_squared_error() طرق sklearn.metrics يمكن استخدامها لحساب هذه المقاييس كما يمكن رؤيته في المقتطف التالي:

from sklearn.metrics import mean_absolute_error, mean_squared_error

mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = mean_squared_error(y_test, y_pred, squared=False)

print(f'mae: {mae}')
print(f'mse: {mse}')
print(f'rmse: {rmse}')

يبدو إخراج البرنامج النصي أعلاه كما يلي:

mae: 0.4460739527131783 
mse: 0.4316907430948294 
rmse: 0.6570317671884894

آر2 يمكن حسابها مباشرة باستخدام score() الأسلوب:

regressor.score(X_test, y_test)

أي نواتج:

0.6737569252627673

تظهر النتائج أن خوارزمية KNN الخطأ الإجمالي والخطأ المتوسط ​​موجودان 0.44و 0.43. أيضًا ، يوضح RMSE أنه يمكننا تجاوز القيمة الفعلية للبيانات أو خفضها عن طريق الإضافة 0.65 أو طرح 0.65. كم هو جيد ذلك؟

دعنا نتحقق من شكل الأسعار:

y.describe()
count    20640.000000
mean         2.068558
std          1.153956
min          0.149990
25%          1.196000
50%          1.797000
75%          2.647250
max          5.000010
Name: MedHouseVal, dtype: float64

يعني 2.06 والانحراف المعياري عن المتوسط ​​هو 1.15 لذلك درجاتنا ~0.44 ليس ممتازًا حقًا ، لكنه ليس سيئًا للغاية.

مع R2، الأقرب إلى 1 نحصل عليه (أو 100) ، كان ذلك أفضل. يقع R2 يوضح مقدار التغييرات في البيانات أو البيانات فرق يتم فهمها أو شرح بواسطة KNN.

$$
R ^ 2 = 1 - frac {sum (فعلي - متوقع) ^ 2} {sum (فعلي - المتوسط ​​الفعلي) ^ 2}
$$

بقيمة 0.67، يمكننا أن نرى أن نموذجنا يشرح 67٪ من تباين البيانات. إنها بالفعل أكثر من 50٪ ، وهو أمر جيد ، لكنه ليس جيدًا. هل هناك أي طريقة يمكننا القيام بها بشكل أفضل؟

لقد استخدمنا K محددًا مسبقًا بقيمة 5، لذلك ، نستخدم 5 جيران للتنبؤ بأهدافنا والتي ليست بالضرورة أفضل رقم. لفهم العدد المثالي من Ks ، يمكننا تحليل أخطاء الخوارزمية واختيار K الذي يقلل الخسارة.

العثور على أفضل K لانحدار KNN

من الناحية المثالية ، سترى المقياس الأكثر ملاءمة لسياقك - ولكن من المثير للاهتمام عادةً اختبار جميع المقاييس. كلما تمكنت من اختبارهم جميعًا ، قم بذلك. سنعرض هنا كيفية اختيار أفضل K باستخدام متوسط ​​الخطأ المطلق فقط ، ولكن يمكنك تغييره إلى أي مقياس آخر ومقارنة النتائج.

للقيام بذلك ، سننشئ نماذج حلقة for ونماذج تشغيل بها من 1 إلى X من الجيران. في كل تفاعل ، سنحسب MAE ونرسم عدد Ks جنبًا إلى جنب مع نتيجة MAE:

error = []


for i in range(1, 40):
    knn = KNeighborsRegressor(n_neighbors=i)
    knn.fit(X_train, y_train)
    pred_i = knn.predict(X_test)
    mae = mean_absolute_error(y_test, pred_i)
    error.append(mae)

الآن ، دعنا نرسم errors:

import matplotlib.pyplot as plt 

plt.figure(figsize=(12, 6))
plt.plot(range(1, 40), error, color='red', 
         linestyle='dashed', marker='o',
         markerfacecolor='blue', markersize=10)
         
plt.title('K Value MAE')
plt.xlabel('K Value')
plt.ylabel('Mean Absolute Error')

دليل لخوارزمية K-Nearest Neighbours في Python و Scikit-Learn PlatoBlockchain Data Intelligence. البحث العمودي. عاي.

بالنظر إلى قطعة الأرض ، يبدو أن أقل قيمة MAE تكون عندما يكون K. 12. دعنا نلقي نظرة فاحصة على الحبكة للتأكد من خلال رسم بيانات أقل:

plt.figure(figsize=(12, 6))
plt.plot(range(1, 15), error[:14], color='red', 
         linestyle='dashed', marker='o',
         markerfacecolor='blue', markersize=10)
plt.title('K Value MAE')
plt.xlabel('K Value')
plt.ylabel('Mean Absolute Error')

دليل لخوارزمية K-Nearest Neighbours في Python و Scikit-Learn PlatoBlockchain Data Intelligence. البحث العمودي. عاي.

تحقق من دليلنا العملي العملي لتعلم Git ، مع أفضل الممارسات ، والمعايير المقبولة في الصناعة ، وورقة الغش المضمنة. توقف عن أوامر Googling Git وفي الواقع تعلم ذلك!

يمكنك أيضًا الحصول على أقل خطأ وفهرس لتلك النقطة باستخدام المدمج min() دالة (تعمل على القوائم) أو تحويل القائمة إلى مصفوفة NumPy واحصل على الامتداد argmin() (فهرس العنصر بأقل قيمة):

import numpy as np 

print(min(error))               
print(np.array(error).argmin()) 

لقد بدأنا في عد الجيران على 1 ، بينما المصفوفات تعتمد على 0 ، وبالتالي فإن المؤشر الحادي عشر هو 11 متجاورًا!

هذا يعني أننا بحاجة إلى 12 جيرانًا حتى نتمكن من التنبؤ بنقطة بها أقل خطأ MAE. يمكننا تنفيذ النموذج والمقاييس مرة أخرى مع 12 جيرانًا لمقارنة النتائج:

knn_reg12 = KNeighborsRegressor(n_neighbors=12)
knn_reg12.fit(X_train, y_train)
y_pred12 = knn_reg12.predict(X_test)
r2 = knn_reg12.score(X_test, y_test) 

mae12 = mean_absolute_error(y_test, y_pred12)
mse12 = mean_squared_error(y_test, y_pred12)
rmse12 = mean_squared_error(y_test, y_pred12, squared=False)
print(f'r2: {r2}, nmae: {mae12} nmse: {mse12} nrmse: {rmse12}')

نواتج الكود التالية:

r2: 0.6887495617137436, 
mae: 0.43631325936692505 
mse: 0.4118522151025172 
rmse: 0.6417571309323467

مع وجود 12 جارًا ، يشرح نموذج KNN الآن 69٪ من التباين في البيانات ، وقد فقد أقل قليلاً ، من 0.44 إلى 0.43, 0.43 إلى 0.41و 0.65 إلى 0.64 مع المقاييس ذات الصلة. إنه ليس تحسنًا كبيرًا ، لكنه تحسن مع ذلك.

ملحوظة: المضي قدمًا في هذا التحليل ، قد يساعد إجراء تحليل البيانات الاستكشافية (EDA) جنبًا إلى جنب مع التحليل المتبقي في تحديد الميزات وتحقيق نتائج أفضل.

لقد رأينا بالفعل كيفية استخدام KNN للانحدار - ولكن ماذا لو أردنا تصنيف نقطة بدلاً من التنبؤ بقيمتها؟ الآن ، يمكننا النظر في كيفية استخدام KNN للتصنيف.

التصنيف باستخدام K-Nearest Neighbours مع Scikit-Learn

في هذه المهمة ، بدلاً من توقع قيمة مستمرة ، نريد أن نتنبأ بالفئة التي تنتمي إليها مجموعات الكتل هذه. للقيام بذلك ، يمكننا تقسيم متوسط ​​قيمة المنزل للمقاطعات إلى مجموعات ذات نطاقات مختلفة لقيمة المنزل أو صناديق.

عندما تريد استخدام قيمة مستمرة للتصنيف ، يمكنك عادةً تخزين البيانات في سلة المهملات. بهذه الطريقة ، يمكنك التنبؤ بالمجموعات ، بدلاً من القيم.

المعالجة المسبقة للبيانات من أجل التصنيف

لنقم بإنشاء سلال البيانات لتحويل قيمنا المستمرة إلى فئات:


df["MedHouseValCat"] = pd.qcut(df["MedHouseVal"], 4, retbins=False, labels=[1, 2, 3, 4])

بعد ذلك ، يمكننا تقسيم مجموعة البيانات الخاصة بنا إلى سماتها وتسمياتها:

y = df['MedHouseValCat']
X = df.drop(['MedHouseVal', 'MedHouseValCat'], axis = 1)

منذ أن استخدمنا ملف MedHouseVal عمود لإنشاء سلال ، نحتاج إلى إسقاط MedHouseVal العمود و MedHouseValCat أعمدة من X. بهذه الطريقة ، فإن DataFrame سيحتوي على أول 8 أعمدة من مجموعة البيانات (أي السمات والميزات) بينما y سيحتوي فقط على MedHouseValCat التسمية المخصصة.

ملحوظة: يمكنك أيضًا تحديد الأعمدة باستخدام .iloc() بدلا من إسقاطهم. عند السقوط ، فقط كن مدركًا أنك بحاجة إلى التخصيص y القيم قبل التعيين X القيم ، لأنه لا يمكنك تعيين عمود تم إسقاطه من a DataFrame إلى كائن آخر في الذاكرة.

تقسيم البيانات إلى تدريب ومجموعات اختبار

كما حدث مع الانحدار ، سنقسم مجموعة البيانات أيضًا إلى أقسام تدريب واختبار. نظرًا لأن لدينا بيانات مختلفة ، نحتاج إلى تكرار هذه العملية:

from sklearn.model_selection import train_test_split

SEED = 42
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=SEED)

سنستخدم قيمة Scikit-Learn القياسية 75٪ من بيانات القطار و 25٪ من بيانات الاختبار مرة أخرى. هذا يعني أنه سيكون لدينا نفس عدد التسجيلات واختبارها كما في الانحدار من قبل.

تحجيم الميزة من أجل التصنيف

نظرًا لأننا نتعامل مع نفس مجموعة البيانات غير المعالجة ووحدات القياس المتغيرة الخاصة بها ، فسنقوم بتوسيع نطاق الميزات مرة أخرى ، بنفس الطريقة التي فعلنا بها مع بيانات الانحدار الخاصة بنا:

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
scaler.fit(X_train)

X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

التدريب والتنبؤ للتصنيف

بعد تجميع البيانات وتقسيمها وتوسيع نطاقها ، يمكننا أخيرًا تركيب مصنف عليها. للتنبؤ ، سوف نستخدم 5 جيران مرة أخرى كخط أساس. يمكنك أيضًا إنشاء مثيل لـ KNeighbors_ فئة بدون أي حجج وستستخدم تلقائيًا 5 جيران. هنا ، بدلاً من استيراد ملف KNeighborsRegressor، سنقوم باستيراد ملف KNeighborsClassifier، صف دراسي:

from sklearn.neighbors import KNeighborsClassifier

classifier = KNeighborsClassifier()
classifier.fit(X_train, y_train)

بعد تركيب KNeighborsClassifier، يمكننا التنبؤ بفئات بيانات الاختبار:

y_pred = classifier.predict(X_test)

حان الوقت لتقييم التوقعات! هل سيكون التنبؤ بالفصول الدراسية طريقة أفضل من التنبؤ بالقيم في هذه الحالة؟ دعونا نقيم الخوارزمية لنرى ماذا سيحدث.

تقييم KNN للتصنيف

لتقييم مصنف KNN ، يمكننا أيضًا استخدام score لكنها تنفذ مقياسًا مختلفًا نظرًا لأننا نسجل مصنفًا وليس رجعيًا. المقياس الأساسي للتصنيف هو accuracy - يصف عدد التنبؤات التي حصل عليها المصنف بشكل صحيح. أقل قيمة دقة هي 0 وأعلى قيمة هي 1. وعادة ما نضرب هذه القيمة في 100 للحصول على نسبة مئوية.

$$
دقة = فارك {نص {عدد التنبؤات الصحيحة}} {نص {العدد الإجمالي للتنبؤات}}
$$

ملحوظة: من الصعب للغاية الحصول على دقة بنسبة 100٪ لأي بيانات حقيقية ، إذا حدث ذلك ، فاحذر من حدوث بعض التسرب أو حدوث خطأ ما - لا يوجد إجماع على قيمة الدقة المثالية كما أنها تعتمد على السياق. يعتمد على تكلفة الخطأ (كم هو سيئ إذا كنا نثق في المصنف واتضح أنه خاطئ) ، فقد يكون معدل الخطأ المقبول 5٪ أو 10٪ أو حتى 30٪.

دعنا نسجل المصنف الخاص بنا:

acc =  classifier.score(X_test, y_test)
print(acc) 

بالنظر إلى النتيجة الناتجة ، يمكننا أن نستنتج أن المصنف لدينا حصل على 62٪ من فصولنا بشكل صحيح. يساعد هذا بالفعل في التحليل ، على الرغم من معرفة ما حصل عليه المصنف بشكل صحيح فقط ، من الصعب تحسينه.

هناك 4 فصول في مجموعة البيانات الخاصة بنا - ماذا لو حصل المصنف لدينا 90٪ من الصفوف 1 و 2 و 3 صحيح، لكن فقط 30٪ من الدرجة 4 صحيح?

يمكن أن يؤدي الفشل المنهجي لبعض الفئات ، على عكس الفشل المتوازن المشترك بين الفئات ، إلى الحصول على درجة دقة تبلغ 62٪. الدقة ليست مقياسًا جيدًا حقًا للتقييم الفعلي - ولكنها تعمل كبديل جيد. في كثير من الأحيان ، مع مجموعات البيانات المتوازنة ، يتم توزيع دقة بنسبة 62 ٪ بشكل متساوٍ نسبيًا. أيضًا ، في كثير من الأحيان ، مجموعات البيانات غير متوازنة ، لذلك عدنا إلى المربع الأول مع الدقة في كونها مقياسًا غير كافٍ.

يمكننا أن ننظر بشكل أعمق في النتائج باستخدام مقاييس أخرى لنكون قادرين على تحديد ذلك. تختلف هذه الخطوة أيضًا عن الانحدار ، وهنا سنستخدم:

  1. الارتباك مصفوفة: لمعرفة مقدار ما حصلنا عليه من صواب أو خطأ كل فئة. يتم استدعاء القيم التي كانت صحيحة ومتوقعة بشكل صحيح ايجابيات حقيقية تسمى تلك التي تم توقعها على أنها إيجابية ولكنها لم تكن إيجابية ايجابيات مزيفة. نفس التسمية السلبيات الحقيقية و السلبيات الكاذبة يستخدم للقيم السالبة ؛
  2. دقة: لفهم قيم التنبؤ الصحيحة التي اعتبرها المصنف صحيحًا. الدقة سوف تقسم تلك القيم الإيجابية الحقيقية على أي شيء تم توقعه على أنه إيجابي ؛

$$
الدقة = frac {text {true positive}} {text {true positive} + text {false إيجابي}}
$$

  1. تذكر: لفهم عدد الإيجابيات الحقيقية التي حددها المصنف لدينا. يتم حساب الاسترجاع بقسمة الإيجابيات الحقيقية على أي شيء كان ينبغي توقعه على أنه إيجابي.

$$
استدعاء = فارك {نص {صحيح إيجابي}} {نص {صحيح إيجابي} + نص {خطأ سلبي}}
$$

  1. نتيجة F1: هل هو متوازن ام الوسط التوافقي من الدقة والاستدعاء. أدنى قيمة هي 0 وأعلى قيمة هي 1. متى f1-score تساوي 1 ، فهذا يعني أنه تم توقع جميع الفئات بشكل صحيح - هذه درجة صعبة للغاية للحصول عليها باستخدام بيانات حقيقية (توجد استثناءات دائمًا تقريبًا).

$$
text {f1-score} = 2 * frac {text {دقة} * نص {استدعاء}} {نص {دقة} + نص {استدعاء}}
$$

ملحوظة: توجد أيضًا درجة F1 مرجحة ، وهي مجرد F1 لا تطبق نفس الوزن على جميع الفئات. عادة ما تملي الطبقات الوزن الدعم - كم عدد الحالات التي "تدعم" درجة F1 (نسبة الملصقات التي تنتمي إلى فئة معينة). كلما انخفض الدعم (قل عدد مرات الفصل) ، انخفض F1 الموزون لتلك الفئة ، لأنه لا يمكن الاعتماد عليها بدرجة أكبر.

confusion_matrix() و classification_report() طرق لل sklearn.metrics يمكن استخدام الوحدة النمطية لحساب وعرض كل هذه المقاييس. ال confusion_matrix يتم تصورها بشكل أفضل باستخدام خريطة التمثيل اللوني. يقدم لنا تقرير التصنيف بالفعل accuracy, precision, recallو f1-score، ولكن يمكنك أيضًا استيراد كل من هذه المقاييس من sklearn.metrics.

للحصول على المقاييس ، قم بتنفيذ المقتطف التالي:

from sklearn.metrics import classification_report, confusion_matrix

import seaborn as sns


classes_names = ['class 1','class 2','class 3', 'class 4']
cm = pd.DataFrame(confusion_matrix(yc_test, yc_pred), 
                  columns=classes_names, index = classes_names)
                  

sns.heatmap(cm, annot=True, fmt='d');

print(classification_report(y_test, y_pred))

يبدو إخراج البرنامج النصي أعلاه كما يلي:

دليل لخوارزمية K-Nearest Neighbours في Python و Scikit-Learn PlatoBlockchain Data Intelligence. البحث العمودي. عاي.

              precision    recall  f1-score   support

           1       0.75      0.78      0.76      1292
           2       0.49      0.56      0.53      1283
           3       0.51      0.51      0.51      1292
           4       0.76      0.62      0.69      1293

    accuracy                           0.62      5160
   macro avg       0.63      0.62      0.62      5160
weighted avg       0.63      0.62      0.62      5160

أظهرت النتائج أن KNN كانت قادرة على تصنيف جميع السجلات البالغ عددها 5160 في مجموعة الاختبار بدقة 62٪ ، وهي أعلى من المتوسط. الدعامات متساوية إلى حد ما (التوزيع المتساوي للفئات في مجموعة البيانات) ، لذا فإن F1 المرجح و F1 غير الموزون سيكونان متماثلين تقريبًا.

يمكننا أيضًا رؤية نتيجة المقاييس لكل فئة من الفئات الأربع. من ذلك ، يمكننا أن نلاحظ ذلك class 2 كان أقل دقة وأقل recall، والأدنى f1-score. Class 3 خلفك مباشرة class 2 للحصول على أقل الدرجات ، وبعد ذلك ، لدينا class 1 مع أفضل الدرجات تليها class 4.

بالنظر إلى مصفوفة الارتباك ، يمكننا أن نرى ما يلي:

  • class 1 كان مخطئًا في الغالب class 2 في 238 حالة
  • class 2 For class 1 في 256 إدخالات و class 3 في 260 حالة
  • class 3 كان مخطئًا في الغالب class 2و 374 إدخالات و class 4، في 193 حالة
  • class 4 تم تصنيفها بشكل خاطئ على أنها class 3 لـ 339 إدخالات ، و class 2 في 130 حالة.

لاحظ أيضًا أن القطر يعرض القيم الإيجابية الحقيقية ، عند النظر إليه ، من الواضح أن نرى ذلك class 2 و class 3 لديها أقل القيم المتوقعة بشكل صحيح.

من خلال هذه النتائج ، يمكننا التعمق في التحليل من خلال إجراء مزيد من الفحص عليها لمعرفة سبب حدوث ذلك ، وكذلك فهم ما إذا كانت 4 فئات هي أفضل طريقة لتخزين البيانات. ربما من القيم class 2 و class 3 كانوا قريبين جدًا من بعضهم البعض ، لذلك أصبح من الصعب التمييز بينهم.

حاول دائمًا اختبار البيانات بعدد مختلف من الحاويات لترى ما سيحدث.

إلى جانب العدد التعسفي لصناديق البيانات ، هناك أيضًا رقم تعسفي آخر اخترناه ، وهو عدد الجيران K. يمكن تطبيق نفس التقنية التي طبقناها على مهمة الانحدار على التصنيف عند تحديد عدد Ks التي تزيد أو تقلل من قيمة المقياس.

العثور على أفضل K لتصنيف KNN

دعنا نكرر ما تم القيام به للانحدار ونرسم الرسم البياني لقيم K والقياس المقابل لمجموعة الاختبار. يمكنك أيضًا اختيار المقياس الأنسب لسياقك ، هنا ، سنختار f1-score.

بهذه الطريقة ، سنقوم برسم ملف f1-score للقيم المتوقعة لمجموعة الاختبار لجميع قيم K بين 1 و 40.

أولاً ، نقوم باستيراد ملف f1_score تبدأ من sklearn.metrics ثم احسب قيمته لجميع تنبؤات مصنف K-Nearest Neighbours ، حيث تتراوح K من 1 إلى 40:

from sklearn.metrics import f1_score

f1s = []


for i in range(1, 40):
    knn = KNeighborsClassifier(n_neighbors=i)
    knn.fit(X_train, y_train)
    pred_i = knn.predict(X_test)
    
    f1s.append(f1_score(y_test, pred_i, average='weighted'))

الخطوة التالية هي رسم ملف f1_score القيم مقابل قيم K. الاختلاف عن الانحدار هو أنه بدلاً من اختيار قيمة K التي تقلل الخطأ ، سنختار هذه المرة القيمة التي تزيد من f1-score.

قم بتنفيذ البرنامج النصي التالي لإنشاء المؤامرة:

plt.figure(figsize=(12, 6))
plt.plot(range(1, 40), f1s, color='red', linestyle='dashed', marker='o',
         markerfacecolor='blue', markersize=10)
plt.title('F1 Score K Value')
plt.xlabel('K Value')
plt.ylabel('F1 Score')

يبدو الرسم البياني الناتج كما يلي:

دليل لخوارزمية K-Nearest Neighbours في Python و Scikit-Learn PlatoBlockchain Data Intelligence. البحث العمودي. عاي.

من الإخراج ، يمكننا أن نرى أن ملف f1-score هي الأعلى عندما تكون قيمة K. 15. دعنا نعيد تدريب المصنف الخاص بنا مع 15 من الجيران ونرى ما يفعله بنتائج تقرير التصنيف الخاص بنا:

classifier15 = KNeighborsClassifier(n_neighbors=15)
classifier15.fit(X_train, y_train)
y_pred15 = classifier15.predict(X_test)
print(classification_report(y_test, y_pred15))

هذا ينتج:

              precision    recall  f1-score   support

           1       0.77      0.79      0.78      1292
           2       0.52      0.58      0.55      1283
           3       0.51      0.53      0.52      1292
           4       0.77      0.64      0.70      1293

    accuracy                           0.63      5160
   macro avg       0.64      0.63      0.64      5160
weighted avg       0.64      0.63      0.64      5160

لاحظ أن مقاييسنا قد تحسنت مع 15 من الجيران ، لدينا دقة بنسبة 63٪ وأعلى precision, recallو f1-scores، ولكننا ما زلنا بحاجة إلى مزيد من البحث في الحاويات لمحاولة فهم سبب وجود ملف f1-score للفصول 2 و 3 لا يزال منخفضًا.

إلى جانب استخدام KNN للانحدار وتحديد قيم الكتلة وللتصنيف ، لتحديد فئات الكتلة - يمكننا أيضًا استخدام KNN لاكتشاف قيم الكتل المتوسطة التي تختلف عن معظمها - تلك التي لا تتبع ما تفعله معظم البيانات. بمعنى آخر ، يمكننا استخدام KNN لـ كشف القيم المتطرفة.

تنفيذ KNN للاكتشاف الخارجي باستخدام Scikit-Learn

الكشف الناشز يستخدم أسلوبًا آخر يختلف عما فعلناه سابقًا للانحدار والتصنيف.

هنا ، سنرى مدى بعد كل من الجيران عن نقطة البيانات. دعنا نستخدم 5 جيران الافتراضي. بالنسبة إلى نقطة البيانات ، سنحسب المسافة إلى كل من أقرب جيران K. للقيام بذلك ، سنقوم باستيراد خوارزمية KNN أخرى من Scikit-Learn والتي ليست خاصة بالانحدار أو التصنيف الذي يسمى ببساطة NearestNeighbors.

بعد الاستيراد ، سننشئ ملف NearestNeighbors فئة بها 5 جيران - يمكنك أيضًا إنشاء مثيل لها مع 12 جيرانًا لتحديد القيم المتطرفة في مثال الانحدار الخاص بنا أو مع 15 ، لفعل الشيء نفسه لمثال التصنيف. سنقوم بعد ذلك بملاءمة بيانات القطار الخاصة بنا واستخدام ملف kneighbors() طريقة للعثور على المسافات المحسوبة لدينا لكل نقطة بيانات وفهارس الجيران:

from sklearn.neighbors import NearestNeighbors

nbrs = NearestNeighbors(n_neighbors = 5)
nbrs.fit(X_train)

distances, indexes = nbrs.kneighbors(X_train)

لدينا الآن 5 مسافات لكل نقطة بيانات - المسافة بينها وبين جيرانها الخمسة ، والفهرس الذي يحددهم. دعنا نلقي نظرة خاطفة على النتائج الثلاث الأولى وشكل المصفوفة لتصور هذا بشكل أفضل.

لإلقاء نظرة على شكل المسافات الثلاث الأولى ، نفّذ:

distances[:3], distances.shape
(array([[0.        , 0.12998939, 0.15157687, 0.16543705, 0.17750354],
        [0.        , 0.25535314, 0.37100754, 0.39090243, 0.40619693],
        [0.        , 0.27149697, 0.28024623, 0.28112326, 0.30420656]]),
 (3, 5))

لاحظ أن هناك 3 صفوف كل منها 5 مسافات. يمكننا أيضًا الاطلاع على فهارس الجيران:

indexes[:3], indexes[:3].shape

وينتج عنه:

(array([[    0,  8608, 12831,  8298,  2482],
        [    1,  4966,  5786,  8568,  6759],
        [    2, 13326, 13936,  3618,  9756]]),
 (3, 5))

في الإخراج أعلاه ، يمكننا أن نرى فهارس كل من الجيران الخمسة. الآن ، يمكننا الاستمرار في حساب متوسط ​​المسافات الخمس ورسم رسم بياني يحسب كل صف على المحور السيني ويعرض كل مسافة متوسطة على المحور ص:

dist_means = distances.mean(axis=1)
plt.plot(dist_means)
plt.title('Mean of the 5 neighbors distances for each data point')
plt.xlabel('Count')
plt.ylabel('Mean Distances')

دليل لخوارزمية K-Nearest Neighbours في Python و Scikit-Learn PlatoBlockchain Data Intelligence. البحث العمودي. عاي.

لاحظ أن هناك جزءًا من الرسم البياني يكون فيه للمسافات المتوسطة قيم موحدة. نقطة المحور Y التي لا تكون فيها الوسائل عالية جدًا أو منخفضة جدًا هي بالضبط النقطة التي نحتاج إلى تحديدها لقطع القيم الخارجية.

في هذه الحالة ، يكون متوسط ​​المسافة 3. دعنا نرسم الرسم البياني مرة أخرى بخط منقط أفقي لنتمكن من تحديده:

dist_means = distances.mean(axis=1)
plt.plot(dist_means)
plt.title('Mean of the 5 neighbors distances for each data point with cut-off line')
plt.xlabel('Count')
plt.ylabel('Mean Distances')
plt.axhline(y = 3, color = 'r', linestyle = '--')

دليل لخوارزمية K-Nearest Neighbours في Python و Scikit-Learn PlatoBlockchain Data Intelligence. البحث العمودي. عاي.

يشير هذا الخط إلى متوسط ​​المسافة التي تتفاوت فوقها جميع القيم. هذا يعني أن جميع النقاط بامتداد mean المسافة أعلاه 3 هي القيم المتطرفة لدينا. يمكننا معرفة فهارس تلك النقاط باستخدام np.where(). ستخرج هذه الطريقة أيضًا True or False لكل فهرس فيما يتعلق ب mean فوق 3 شرط:

import numpy as np


outlier_index = np.where(dist_means > 3)
outlier_index

نواتج الكود أعلاه:

(array([  564,  2167,  2415,  2902,  6607,  8047,  8243,  9029, 11892,
        12127, 12226, 12353, 13534, 13795, 14292, 14707]),)

الآن لدينا فهارسنا الخارجية. دعنا نحدد موقعهم في dataframe:


outlier_values = df.iloc[outlier_index]
outlier_values

وينتج عنه:

		MedInc 	HouseAge AveRooms 	AveBedrms 	Population 	AveOccup 	Latitude 	Longitude 	MedHouseVal
564 	4.8711 	27.0 	 5.082811 	0.944793 	1499.0 	    1.880803 	37.75 		-122.24 	2.86600
2167 	2.8359 	30.0 	 4.948357 	1.001565 	1660.0 	    2.597809 	36.78 		-119.83 	0.80300
2415 	2.8250 	32.0 	 4.784232 	0.979253 	761.0 	    3.157676 	36.59 		-119.44 	0.67600
2902 	1.1875 	48.0 	 5.492063 	1.460317 	129.0 	    2.047619 	35.38 		-119.02 	0.63800
6607 	3.5164 	47.0 	 5.970639 	1.074266 	1700.0 	    2.936097 	34.18 		-118.14 	2.26500
8047 	2.7260 	29.0 	 3.707547 	1.078616 	2515.0 	    1.977201 	33.84 		-118.17 	2.08700
8243 	2.0769 	17.0 	 3.941667 	1.211111 	1300.0 	    3.611111 	33.78 		-118.18 	1.00000
9029 	6.8300 	28.0 	 6.748744 	1.080402 	487.0 		2.447236 	34.05 		-118.78 	5.00001
11892 	2.6071 	45.0 	 4.225806 	0.903226 	89.0 		2.870968 	33.99 		-117.35 	1.12500
12127 	4.1482 	7.0 	 5.674957 	1.106998 	5595.0 		3.235975 	33.92 		-117.25 	1.24600
12226 	2.8125 	18.0 	 4.962500 	1.112500 	239.0 		2.987500 	33.63 		-116.92 	1.43800
12353 	3.1493 	24.0 	 7.307323 	1.460984 	1721.0 		2.066026 	33.81 		-116.54 	1.99400
13534 	3.7949 	13.0 	 5.832258 	1.072581 	2189.0 		3.530645 	34.17 		-117.33 	1.06300
13795 	1.7567 	8.0 	 4.485173 	1.120264 	3220.0 		2.652389 	34.59 		-117.42 	0.69500
14292 	2.6250 	50.0 	 4.742236 	1.049689 	728.0 		2.260870 	32.74 		-117.13 	2.03200
14707 	3.7167 	17.0 	 5.034130 	1.051195 	549.0 		1.873720 	32.80 		-117.05 	1.80400

تم الانتهاء من اكتشافنا الخارجة. هذه هي الطريقة التي نرصد بها كل نقطة بيانات تنحرف عن اتجاه البيانات العام. يمكننا أن نرى أن هناك 16 نقطة في بيانات القطار الخاصة بنا والتي ينبغي النظر فيها بمزيد من التفصيل ، والتحقيق فيها ، وربما معالجتها ، أو حتى إزالتها من بياناتنا (إذا تم إدخالها عن طريق الخطأ) لتحسين النتائج. قد تكون هذه النقاط ناتجة عن أخطاء في الكتابة ، أو عدم اتساق قيم الكتلة المتوسطة ، أو حتى كليهما.

إيجابيات وسلبيات KNN

في هذا القسم ، سنقدم بعض إيجابيات وسلبيات استخدام خوارزمية KNN.

الايجابيات

  • إنه سهل التنفيذ
  • إنها خوارزمية تعليمية كسولة وبالتالي لا تتطلب تدريبًا على جميع نقاط البيانات (فقط باستخدام K-أقرب جيران للتنبؤ). هذا يجعل خوارزمية KNN أسرع بكثير من الخوارزميات الأخرى التي تتطلب التدريب مع مجموعة البيانات بأكملها مثل دعم آلات مكافحة ناقلات, الانحدارالخطي، الخ.
  • نظرًا لأن KNN لا يتطلب أي تدريب قبل إجراء التنبؤات ، يمكن إضافة بيانات جديدة بسلاسة
  • هناك معلمتان فقط مطلوبتان للعمل مع KNN ، أي قيمة K ودالة المسافة

سلبيات

  • لا تعمل خوارزمية KNN بشكل جيد مع البيانات عالية الأبعاد لأنه مع وجود عدد كبير من الأبعاد ، تصبح المسافة بين النقاط "غريبة" ، ولا تصمد مقاييس المسافة التي نستخدمها
  • أخيرًا ، لا تعمل خوارزمية KNN جيدًا مع الميزات الفئوية نظرًا لأنه من الصعب العثور على المسافة بين الأبعاد ذات الميزات الفئوية

المضي قدمًا - مشروع باليد من البداية إلى النهاية

دليل لخوارزمية K-Nearest Neighbours في Python و Scikit-Learn PlatoBlockchain Data Intelligence. البحث العمودي. عاي.

في هذا المشروع الموجه - ستتعلم كيفية بناء نماذج تعلم الآلة التقليدية القوية بالإضافة إلى نماذج التعلم العميق ، واستخدام مجموعة التعلم وتدريب المتعلمين الفوقيين للتنبؤ بأسعار المنازل من حقيبة من نماذج Scikit-Learn و Keras.

باستخدام Keras ، واجهة برمجة التطبيقات للتعلم العميق المبنية على قمة Tensorflow ، سنقوم بتجربة البنى وإنشاء مجموعة من النماذج المكدسة وتدريب المتعلم الفوقي الشبكة العصبية (نموذج المستوى الأول) لمعرفة سعر المنزل.

يعد التعلم العميق أمرًا مذهلاً - ولكن قبل اللجوء إليه ، يُنصح أيضًا بمحاولة حل المشكلة بأساليب أبسط ، مثل باستخدام التعلم الضحل الخوارزميات. سيعتمد أداء خط الأساس لدينا على أ الانحدار العشوائي للغابات الخوارزمية. بالإضافة إلى ذلك - سنستكشف إنشاء مجموعات من النماذج من خلال Scikit-Learn عبر تقنيات مثل التعبئة و  تصويت.

هذا مشروع شامل ، ومثل جميع مشاريع التعلم الآلي ، سنبدأ به تحليل البيانات استكشافية، تليها معالجة البيانات و اخيرا مبنى ضحل و  نماذج التعلم العميق لتتناسب مع البيانات التي اكتشفناها ونظفناها سابقًا.

وفي الختام

KNN هي خوارزمية بسيطة لكنها قوية. يمكن استخدامه للعديد من المهام مثل الانحدار أو التصنيف أو الكشف عن العوامل الخارجية.

تم استخدام KNN على نطاق واسع للعثور على تشابه المستندات والتعرف على الأنماط. كما تم استخدامه لتطوير أنظمة التوصية ولتقليل الأبعاد وخطوات المعالجة المسبقة لرؤية الكمبيوتر - وخاصة مهام التعرف على الوجوه.

في هذا الدليل - لقد مررنا بالانحدار والتصنيف والاكتشاف الخارجي باستخدام تطبيق Scikit-Learn لخوارزمية K-Nearest Neighbor.

الطابع الزمني:

اكثر من ستاكابوز