آموزش

دسته‌بندی K-Nearest Neighbors (KNN) با scikit-learn

This article covers how and when to use k-nearest neighbors classification with scikit-learn. Focusing on concepts, workflow, and examples. We also cover distance metrics and how to select the best value for k using cross-validation.

تاریخ انتشار:
30 خرداد 1405
پایتون
14 دقیقه
یادگیری ماشین
کاربرهای فینکا در چه شرکت‌هایی مشغول به کار هستند؟

این آموزش، نحوه پیاده‌سازی و مثال‌هایی از الگوریتم k-nearest neighbors (KNN) رو پوشش می‌ده. این مدل، یک مدل نظارت‌شده محبوبه که هم برای دسته‌بندی و هم برای رگرسیون استفاده می‌شه و راه مفیدی برای درک توابع فاصله، سیستم‌های رای‌گیری و بهینه‌سازی هایپرپارامترهاست.

برای بیشترین استفاده از این آموزش، بهتره دانش پایه‌ای از پایتون و تجربه کار با دیتافریم‌ها داشته باشی. همچنین داشتن کمی تجربه با نحوه کدنویسی scikit-learn می‌تونه کمک‌کننده باشه. معمولا KNN با روش بدون نظارت k-Means Clustering اشتباه گرفته می‌شه. اگر به اون علاقه‌مندی، خیلی خوبه که نگاهی به خوشه‌بندی k-Means در پایتون با scikit-learn بندازی. همچنین می‌تونی همین الان با ثبت‌نام در دوره‌های یادگیری ماشین در پایتون فینکا که KNN رو با جزئیات بیشتری توضیح می‌ده، شروع کنی. 

با این تمرین عملی دسته‌بندی KNN رو تمرین کن.

با اینکه KNN می‌تونه هم برای دسته‌بندی و هم رگرسیون استفاده بشه، این آموزش روی ساخت یک مدل دسته‌بندی تمرکز داره. دسته‌بندی در یادگیری ماشین یک کار یادگیری نظارت‌شده‌ست که شامل پیش‌بینی یک برچسب دسته‌ای برای یک داده ورودی مشخصه. الگوریتم روی یک مجموعه داده برچسب‌دار آموزش می‌بینه و از ویژگی‌های ورودی استفاده می‌کنه تا نقشه بین ورودی‌ها و برچسب‌های کلاس مربوطه رو یاد بگیره. ما می‌تونیم از مدل آموزش‌دیده برای پیش‌بینی داده‌های جدید و دیده‌نشده استفاده کنیم.

مروری بر K-Nearest Neighbors

الگوریتم KNN می‌تونه به عنوان یک سیستم رای‌گیری در نظر گرفته بشه، که در اون برچسب کلاس اکثریت، نشون‌دهنده برچسب کلاس یک داده جدید در بین k همسایه نزدیک (که k یک عدد صحیحه) در فضای ویژگی‌هاست. تصور کن در یک روستای کوچک با چند صد ساکن زندگی می‌کنی و باید تصمیم بگیری که به چه حزب سیاسی رای بدی. برای این کار، ممکنه به سراغ نزدیک‌ترین همسایه‌هات بری و بپرسی که اون‌ها از چه حزبی حمایت می‌کنن. اگر بیشتر k همسایه نزدیکت از حزب A حمایت کنن، پس تو هم به احتمال زیاد به حزب A رای می‌دی. این کار شبیه به نحوه کار الگوریتم KNN هست، که در اون برچسب کلاس اکثریت، برچسب کلاس یک داده جدید رو در بین k همسایه نزدیکش تعیین می‌کنه.

بیا با یک مثال دیگه دقیق‌تر بررسی کنیم. تصور کن اطلاعاتی درباره میوه‌ها، به‌طور خاص انگور و گلابی داری. برای هر میوه یک امتیاز گِردی و قطر داری. تصمیم می‌گیری این‌ها رو روی یک نمودار رسم کنی. اگر کسی یک میوه جدید بهت بده، می‌تونی اون رو هم روی نمودار بکشی، سپس فاصله رو تا k نقطه نزدیک اندازه بگیری تا تصمیم بگیری که چه میوه‌ایه. در مثال زیر، اگر انتخاب کنیم سه نقطه رو اندازه بگیریم، می‌تونیم بگیم سه نقطه نزدیک گلابی هستن، پس من ۱۰۰٪ مطمئنم که میوه جدید، یک گلابیه. اگر انتخاب کنیم چهار نقطه نزدیک رو در نظر بگیریم، سه تا گلابی هستن و یکی انگور، پس می‌تونیم بگیم ۷۵٪ مطمئنیم که میوه جدید، یک گلابیه. در ادامه یاد می‌گیریم که چطور بهترین مقدار رو برای k پیدا کنیم و راه‌های مختلف اندازه‌گیری فاصله رو بررسی می‌کنیم.

دیتاست

برای درک بهتر الگوریتم KNN، بیا روی یک مطالعه موردی کار کنیم که ممکنه وقتی به عنوان یک دانشمند داده کار می‌کنی باهاش روبرو بشی. فرض کن یک دانشمند داده در یک خرده‌فروشی آنلاین هستی و وظیفه تشخیص تراکنش‌های جعلی بهت داده شده. تنها ویژگی‌هایی که در این مرحله داری عبارتند از:

  • dist_from_home: فاصله بین محل زندگی کاربر و جایی که تراکنش انجام شده.
  • purchase_price_ratio: نسبت بین قیمت آیتم خریداری شده در این تراکنش به میانگین قیمت خریدهای قبلی همون کاربر.

داده‌ها شامل ۳۹ مشاهده ان. در این آموزش، ما دیتاستی رو در متغیر df بهت دادیم، که شبیه اینه:

 
0
2.1
6.4
0
1
3.8
2.2
1
2
15.7
4.4
2
3
26.7
4.6
3
4
10.7
4.9
4

 

گردش کار k-Nearest Neighbors

برای برازش و آموزش این مدل، ما از اینفوگرافیک گردش کار یادگیری ماشین پیروی می‌کنیم.

با این حال، چون داده‌های ما نسبتا تمیز هستن، نیاز نیست همه مراحل رو انجام بدیم. ما کارهای زیر رو انجام می‌دیم:

  • مهندسی ویژگی‌ها
  • تقسیم داده‌ها
  • آموزش مدل
  • تنظیم ابرپارامترها
  • ارزیابی عملکرد مدل

مصورسازی داده‌ها

بیا با مصورسازی داده‌ها به کمک matplotlib شروع کنیم؛ می‌تونیم دو ویژگی خودمون رو در یک نمودار پراکندگی (scatterplot) رسم کنیم.

همون‌طور که می‌بینی، یک تفاوت واضح بین این تراکنش‌ها وجود داره، به‌طوری که تراکنش‌های جعلی در مقایسه با میانگین سفارشات مشتریان، ارزش بسیار بیشتری دارن. روند مربوط به فاصله از خانه کمی برای تفسیر سخته، چرا که تراکنش‌های غیرجعلی معمولا به خانه نزدیک‌ترن اما با چند داده پرت همراه هستن.

نرمال‌سازی و تقسیم داده‌ها

وقتی هر مدل یادگیری ماشین رو آموزش می‌دیم، مهمه که داده‌ها رو به داده‌های آموزشی و تست تقسیم کنیم. داده‌های آموزشی برای برازش مدل استفاده می‌شن. الگوریتم از داده‌های آموزشی استفاده می‌کنه تا رابطه بین ویژگی‌ها و هدف رو یاد بگیره. این مدل تلاش می‌کنه یک الگو در داده‌های آموزشی پیدا کنه که بشه از اون برای پیش‌بینی داده‌های جدید و دیده‌نشده استفاده کرد. داده‌های تست برای ارزیابی عملکرد مدل استفاده می‌شن. مدل روی داده‌های تست سنجیده می‌شه، به این صورت که از اون برای پیش‌بینی استفاده می‌کنیم و این پیش‌بینی‌ها رو با مقادیر واقعی هدف مقایسه می‌کنیم.

هنگام آموزش یک دسته‌بندی‌کننده KNN، ضروریه که ویژگی‌ها رو نرمال‌سازی کنیم. دلیلش اینه که KNN فاصله بین نقاط رو اندازه‌گیری می‌کنه. فاصله پیش‌فرض مورد استفاده، فاصله اقلیدسیه که برابر با ریشه دوم مجموع مربعات تفاوت بین دو نقطه‌ست. در دیتافریم ما، purchase_price_ratio بین ۰ و ۸ هست در حالی که dist_from_home خیلی بزرگ‌تره. اگر این مقدارها رو نرمال‌سازی نکنیم، محاسبات ما به شدت تحت تاثیر مقدار dist_from_home قرار می‌گیره چون اعدادش بزرگ‌ترن.

ما باید داده‌ها رو بعد از تقسیم به مجموعه‌های آموزشی و تست، نرمال‌سازی کنیم. این کار برای جلوگیری از «نشت داده» انجام می‌شه چون اگه همه داده‌ها رو یکجا نرمال‌سازی کنیم، فرآیند نرمال‌سازی اطلاعات اضافه‌ای درباره مجموعه تست به مدل می‌ده.

کد زیر داده‌ها رو به بخش‌های آموزشی/تست تقسیم می‌کنه، سپس با استفاده از standard scaler در scikit-learn اون‌ها رو نرمال‌سازی می‌کنه. اول .fit_transform() رو روی داده‌های آموزشی فراخوانی می‌کنیم، که scaler ما رو با میانگین و انحراف معیار داده‌های آموزشی مطابقت می‌ده. سپس می‌تونیم با فراخوانی .transform()، که از مقادیر یاد گرفته شده قبلی استفاده می‌کنه، این نرمال‌سازی رو روی داده‌های تست اعمال کنیم.

برازش و ارزیابی مدل

حالا آماده‌ایم تا مدل رو آموزش بدیم. برای این کار، از یک مقدار ثابت ۳ برای k استفاده می‌کنیم، اما بعدا نیاز داریم اون رو بهینه‌سازی کنیم. در ابتدا یک نمونه از مدل KNN می‌سازیم، سپس اون رو روی داده‌های آموزشی خودمون برازش می‌کنیم. ما هم ویژگی‌ها و هم متغیر هدف رو به مدل می‌دیم تا مدل بتونه یاد بگیره.

مدل حالا آموزش دیده! ما می‌تونیم روی دیتاست تست پیش‌بینی‌هایی رو انجام بدیم تا بعدا از اون‌ها برای امتیازدهیِ مدل استفاده کنیم.

ساده‌ترین راه برای ارزیابی این مدل، استفاده از معیاری به نام دقت (Accuracy) هست. ما پیش‌بینی‌ها رو با مقادیر واقعی در مجموعه تست مقایسه می‌کنیم و تعداد مواردی رو که مدل درست حدس زده، می‌شماریم.

خروجی
Accuracy: 0.875

این یک امتیاز خیلی خوبه! با این حال، ممکنه بتونیم با بهینه‌سازی مقدار k عملکرد بهتری هم داشته باشیم.

استفاده از اعتبارسنجی متقاطع برای پیدا کردن بهترین مقدار k

متأسفانه، هیچ راه جادویی برای پیدا کردن بهترین مقدار برای k وجود نداره. ما باید در یک حلقه مقادیر مختلف رو چک کنیم و بعد از بهترین نتیجه استفاده کنیم.

در کد زیر، ما محدوده‌ای از مقادیر رو برای k انتخاب می‌کنیم و یک لیست خالی برای ذخیره نتایجمون می‌سازیم. ما از اعتبارسنجی متقاطع (cross-validation) استفاده می‌کنیم تا امتیازهای دقت رو پیدا کنیم، یعنی نیاز نیست که داده‌ها رو به دو بخش آموزشی و تست تقسیم کنیم، اما باید داده‌هامون رو مقیاس‌بندی کنیم. سپس روی مقادیر حلقه می‌زنیم و امتیازها رو به لیست خودمون اضافه می‌کنیم.

برای پیاده‌سازی اعتبارسنجی متقاطع، از تابع cross_val_score در scikit-learn استفاده می‌کنیم. ما یک نمونه از مدل KNN رو همراه با داده‌ها و تعداد تقسیم‌هایی که باید انجام بشه پاس می‌دیم. در کد زیر، از پنج تقسیم استفاده می‌کنیم که به این معنیه که مدل داده‌ها رو به پنج گروه مساوی تقسیم می‌کنه و از ۴ بخش برای آموزش و از ۱ بخش برای تستِ نتیجه استفاده می‌کنه. حلقه روی هر گروه تکرار می‌شه و یک امتیاز دقت می‌ده، که ما میانگین اون‌ها رو می‌گیریم تا بهترین مدل رو پیدا کنیم.

می‌تونیم با استفاده از کد زیر نتایج رو رسم کنیم:

با نگاهی به نمودار می‌بینیم که k = ۹، ۱۰، ۱۱، ۱۲، ۱۳ همه امتیاز دقتی کمی کمتر از ۹۵٪ دارن. با توجه به اینکه این مقادیر برای گرفتن بهترین امتیاز یکسان عمل کردن، توصیه می‌شه از مقدار کوچک‌تری برای k استفاده بشه. دلیلش اینه که با استفاده از مقادیر بیشتر برای k، مدل از نقاط داده بیشتری استفاده می‌کنه که فاصله بیشتری از نقطه اصلی دارن. یک راهکار دیگه اینه که سایر معیارهای ارزیابی رو هم بررسی کنی.

معیارهای ارزیابی بیشتر

حالا می‌تونیم با کمک کد زیر، مدلمون رو با استفاده از بهترین مقدار k آموزش بدیم.

خروجی
Accuracy: 0.875
Precision: 0.75
Recall: 1.0

یک قدم فراتر

اشتراک‌گذاری
فهرست مطالب
  • مروری بر K-Nearest Neighbors
  • دیتاست
  • گردش کار k-Nearest Neighbors
  • مصورسازی داده‌ها
  • نرمال‌سازی و تقسیم داده‌ها
  • برازش و ارزیابی مدل
  • استفاده از اعتبارسنجی متقاطع برای پیدا کردن بهترین مقدار k
  • معیارهای ارزیابی بیشتر
  • یک قدم فراتر

دریافت اپلیکیشن فینکا

با اپلیکیشن فینکا، به بیشتر دوره‌ها و مسیرها روی موبایل دسترسی دارید، تمرین می‌کنید و یادگیری رو هم‌زمان روی موبایل و دسکتاپ ادامه می‌دید.