معرفی
La K-نزدیکترین همسایه (KNN) الگوریتم نوعی از الگوریتم یادگیری ماشینی نظارت شده است که برای طبقه بندی، رگرسیون و همچنین تشخیص موارد دور از دسترس استفاده می شود. اجرای آن در ابتدایی ترین شکل آن بسیار آسان است اما می تواند کارهای نسبتاً پیچیده ای را انجام دهد. این یک الگوریتم یادگیری تنبل است زیرا فاز آموزشی تخصصی ندارد. در عوض، از تمام داده ها برای آموزش استفاده می کند، در حالی که یک نقطه یا نمونه داده جدید را طبقه بندی (یا پسرفت) می کند.
KNN یک است الگوریتم یادگیری ناپارامتریک، به این معنی که چیزی در مورد داده های اساسی فرض نمی کند. این یک ویژگی بسیار مفید است زیرا بیشتر دادههای دنیای واقعی واقعاً از هیچ فرض نظری پیروی نمیکنند، مانند جداییپذیری خطی، توزیع یکنواخت و غیره.
در این راهنما، خواهیم دید که چگونه KNN را می توان با کتابخانه Scikit-Learn پایتون پیاده سازی کرد. قبل از آن، ابتدا بررسی خواهیم کرد که چگونه می توانیم از KNN استفاده کنیم و تئوری پشت آن را توضیح دهیم. پس از آن، ما نگاهی به مجموعه داده مسکن کالیفرنیا ما برای نشان دادن الگوریتم KNN و چندین تغییر آن استفاده خواهیم کرد. اول از همه، ما نگاهی به نحوه پیاده سازی الگوریتم KNN برای رگرسیون خواهیم داشت، به دنبال آن پیاده سازی طبقه بندی KNN و تشخیص نقاط دورتر. در پایان با برخی از مزایا و معایب الگوریتم نتیجه گیری می کنیم.
چه زمانی باید از KNN استفاده کنید؟
فرض کنید می خواستید یک آپارتمان اجاره کنید و اخیراً متوجه شده اید که همسایه دوست شما ممکن است آپارتمان او را تا 2 هفته دیگر اجاره کند. از آنجایی که آپارتمان هنوز در وب سایت اجاره ای قرار ندارد، چگونه می توانید ارزش اجاره آن را تخمین بزنید؟
فرض کنید دوست شما 1,200 دلار اجاره می دهد. ارزش اجاره شما ممکن است در حدود این عدد باشد، اما آپارتمان ها دقیقاً یکسان نیستند (جهت، مساحت، کیفیت مبلمان و غیره)، بنابراین، خوب است که اطلاعات بیشتری در مورد سایر آپارتمان ها داشته باشید.
با پرسیدن از سایر همسایگان و مشاهده آپارتمانهای همان ساختمان که در یک وبسایت اجاره فهرست شدهاند، نزدیکترین سه اجاره آپارتمان همسایه 1,200 دلار، 1,210 دلار، 1,210 دلار و 1,215 دلار است. آن آپارتمان ها در همان بلوک و طبقه آپارتمان دوست شما هستند.
آپارتمانهای دیگر، که دورتر هستند، در همان طبقه، اما در بلوکهای متفاوت، 1,400 دلار، 1,430 دلار، 1,500 دلار و 1,470 دلار اجاره دارند. به نظر می رسد به دلیل داشتن نور بیشتر از خورشید در عصر گران تر هستند.
با توجه به نزدیکی آپارتمان، به نظر می رسد اجاره شما حدود 1,210 دلار باشد. این ایده کلی از آنچه است K-نزدیکترین همسایگان (KNN) الگوریتم انجام می دهد! داده های جدید را بر اساس نزدیکی به داده های موجود طبقه بندی یا پسرفت می کند.
مثال را به تئوری تبدیل کنید
هنگامی که ارزش تخمینی یک عدد پیوسته است، مانند ارزش اجاره، KNN برای آن استفاده می شود رگرسیون. اما ما همچنین میتوانیم آپارتمانها را بر اساس حداقل و حداکثر اجاره به عنوان مثال تقسیم کنیم. هنگامی که مقدار گسسته است و آن را به یک دسته تبدیل می کند، KNN برای آن استفاده می شود طبقه بندی.
همچنین این امکان وجود دارد که تخمین بزنیم کدام همسایه ها آنقدر با دیگران تفاوت دارند که احتمالاً از پرداخت اجاره منصرف می شوند. این همانند تشخیص اینکه کدام نقاط داده آنقدر دور هستند که در هیچ مقدار یا دستهای قرار نمیگیرند، زمانی که این اتفاق میافتد، از KNN برای تشخیص بیرونی.
در مثال ما، ما قبلاً اجاره هر آپارتمان را میدانستیم، به این معنی که دادههای ما برچسبگذاری شده بودند. KNN از دادههای برچسبگذاریشده قبلی استفاده میکند، که باعث میشود یک الگوریتم یادگیری تحت نظارت.
پیادهسازی KNN در ابتداییترین شکل آن بسیار آسان است، و در عین حال وظایف کاملاً پیچیدهای را انجام میدهد، طبقهبندی، رگرسیون، یا تشخیص نقاط پرت.
هر بار که یک نقطه جدید به داده ها اضافه می شود، KNN فقط از یک قسمت از داده ها برای تصمیم گیری در مورد مقدار (رگرسیون) یا کلاس (طبقه بندی) آن نقطه اضافه شده استفاده می کند. از آنجایی که لازم نیست دوباره به همه نکات نگاه کند، این باعث می شود که یک الگوریتم یادگیری تنبل.
KNN همچنین هیچ چیزی در مورد ویژگی های داده های زیربنایی فرض نمی کند، انتظار ندارد داده ها در برخی از انواع توزیع، مانند یکنواخت، یا به صورت خطی قابل تفکیک قرار گیرند. این بدان معنی است که یک است الگوریتم یادگیری ناپارامتریک. این یک ویژگی بسیار مفید است زیرا بیشتر داده های دنیای واقعی واقعاً از هیچ فرض نظری پیروی نمی کنند.
تجسم کاربردهای مختلف KNN
همانطور که نشان داده شد، شهود پشت الگوریتم KNN یکی از مستقیم ترین الگوریتم های یادگیری ماشینی تحت نظارت است. الگوریتم ابتدا مقدار را محاسبه می کند فاصله یک نقطه داده جدید به تمام نقاط داده آموزشی دیگر.
توجه داشته باشید: فاصله را می توان به روش های مختلف اندازه گیری کرد. می توانید از Minkowski استفاده کنید، اقلیدسیمنهتن، ماهالانوبیس یا فرمول همینگ، برای نام بردن چند معیار. با دادههای ابعادی بالا، فاصله اقلیدسی اغلب شروع به شکست میکند (بعد بالا… عجیب است)، و به جای آن از فاصله منهتن استفاده میشود.
پس از محاسبه فاصله، KNN تعدادی از نزدیکترین نقاط داده را انتخاب می کند - 2، 3، 10، یا واقعاً، هر عدد صحیح. این تعداد امتیاز (2، 3، 10، و غیره) برابر است K در K-Nearest Neighbors!
در مرحله آخر، اگر یک کار رگرسیونی باشد، KNN میانگین وزنی مجموع K-نزدیک ترین نقاط را برای پیش بینی محاسبه می کند. اگر یک کار طبقه بندی باشد، نقطه داده جدید به کلاسی که اکثر K-نزدیک ترین نقاط انتخاب شده به آن تعلق دارند، اختصاص داده می شود.
بیایید با کمک یک مثال ساده الگوریتم را در عمل مجسم کنیم. مجموعه داده ای را با دو متغیر و K 3 در نظر بگیرید.
هنگام انجام رگرسیون، وظیفه یافتن مقدار یک نقطه داده جدید، بر اساس میانگین مجموع وزنی 3 نزدیکترین نقطه است.
KNN با K = 3
، زمانی که برای رگرسیون استفاده می شود:
الگوریتم KNN با محاسبه فاصله نقطه جدید از تمام نقاط شروع می شود. سپس 3 نقطه با کمترین فاصله تا نقطه جدید را پیدا می کند. این در شکل دوم بالا نشان داده شده است که در آن سه نزدیکترین نقطه، 47
, 58
و 79
محاصره شده اند. پس از آن، مجموع وزنی را محاسبه می کند 47
, 58
و 79
– در این حالت وزن ها برابر با 1 هستند – همه نقاط را مساوی در نظر می گیریم، اما می توانیم وزن های مختلفی را بر اساس فاصله نیز تعیین کنیم. پس از محاسبه جمع وزنی، مقدار امتیاز جدید می باشد 61,33
.
و هنگام انجام یک طبقه بندی، وظیفه KNN برای طبقه بندی یک نقطه داده جدید، در "Purple"
or "Red"
کلاس.
KNN با K = 3
، زمانی که برای طبقه بندی استفاده می شود:
الگوریتم KNN مانند قبل با محاسبه فاصله نقطه جدید از تمام نقاط، یافتن 3 نزدیکترین نقطه با کمترین فاصله از نقطه جدید شروع می شود و سپس به جای محاسبه عدد، اختصاص می دهد. نقطه جدید به کلاسی که اکثریت سه نقطه نزدیک به آن تعلق دارد، کلاس قرمز. بنابراین نقطه داده جدید به عنوان طبقه بندی می شود "Red"
.
فرآیند تشخیص پرت با هر دو بالا متفاوت است، در هنگام اجرای آن پس از اجرای رگرسیون و طبقه بندی بیشتر در مورد آن صحبت خواهیم کرد.
توجه داشته باشید: کد ارائه شده در این آموزش با موارد زیر اجرا و تست شده است دفترچه ژوپیتر.
مجموعه داده های مسکن کالیفرنیا Scikit-Learn
ما قصد داریم از مجموعه داده مسکن کالیفرنیا برای نشان دادن نحوه عملکرد الگوریتم 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
. جزئیات بیشتر از مجموعه داده در دسترس است اینجا کلیک نمایید.
بیایید پانداها را وارد کنیم و به چند ردیف اول داده نگاهی بیاندازیم:
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-نزدیکترین همسایگان با 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
و همین امر در مورد سایر ویژگی ها نیز صدق می کند.
ما از یک الگوریتم بر اساس استفاده می کنیم فاصله و الگوریتم های مبتنی بر فاصله از داده هایی که در یک مقیاس نیستند، مانند این داده ها، به شدت آسیب می بینند. مقیاس نقاط ممکن است (و در عمل، تقریباً همیشه) فاصله واقعی بین مقادیر را مخدوش کند.
برای اجرای Feature Scaling، از Scikit-Learn استفاده خواهیم کرد 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)
تا تماس کوتاه تر شود!
اکنون داده های ما مقیاس شده است! مقیاسکننده فقط نقاط داده را حفظ میکند، و نه نام ستونها را وقتی روی a اعمال میشود 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
API بصری و پایدار 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) و ضریب تعیین (R).2):
- میانگین خطای مطلق (MAE): وقتی مقادیر پیش بینی شده را از مقادیر واقعی کم می کنیم، خطاها را بدست می آوریم، مقادیر مطلق آن خطاها را جمع می کنیم و میانگین آنها را بدست می آوریم. این متریک تصوری از خطای کلی برای هر پیشبینی مدل ارائه میدهد، هرچه کوچکتر (نزدیک به 0) بهتر باشد:
$$
mae = (frac{1}{n})sum_{i=1}^{n}چپ | واقعی – درست پیش بینی شده |
$$
توجه داشته باشید: همچنین ممکن است با y
و ŷ
(به عنوان y-hat بخوانید) نماد در معادلات. را y
اشاره به مقادیر واقعی و ŷ
به مقادیر پیش بینی شده
- میانگین مربعات خطا (MSE): شبیه به متریک MAE است، اما مقادیر مطلق خطاها را مربع می کند. همچنین، مانند MAE، هرچه کوچکتر یا نزدیکتر به 0 باشد، بهتر است. مقدار MSE مربع است تا خطاهای بزرگ حتی بزرگتر شود. نکته ای که باید به آن دقت کرد، این است که معمولاً به دلیل اندازه مقادیر آن و به دلیل همسان نبودن آنها با داده ها، تفسیر آن سخت است.
$$
mse = sum_{i=1}^{D}(واقعی - پیش بینی شده)^2
$$
- ریشه میانگین مربعات خطا (RMSE): سعی می کند مشکل تفسیر مطرح شده با MSE را با به دست آوردن جذر مقدار نهایی آن حل کند تا آن را به همان واحدهای داده کاهش دهد. وقتی نیاز به نمایش یا نشان دادن ارزش واقعی داده ها با خطا داریم، تفسیر آسان تر و خوب است. این نشان میدهد که دادهها چقدر ممکن است متفاوت باشند، بنابراین، اگر RMSE 4.35 داشته باشیم، مدل ما میتواند خطا داشته باشد یا به این دلیل که 4.35 را به مقدار واقعی اضافه کرده است یا برای رسیدن به مقدار واقعی به 4.35 نیاز دارد. هرچه به 0 نزدیکتر باشد، بهتر است.
$$
rmse = sqrt{ sum_{i=1}^{D}(واقعی - پیش بینی شده)^2}
$$
La 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
R2 را می توان به طور مستقیم با 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)
اکنون، بیایید طرح را ترسیم کنیم error
s:
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')
با نگاهی به نمودار، به نظر می رسد کمترین مقدار 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')
راهنمای عملی و عملی ما برای یادگیری Git را با بهترین روش ها، استانداردهای پذیرفته شده در صنعت و برگه تقلب شامل بررسی کنید. دستورات Google 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 Neighbors با 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 درصد نسبتاً یکنواخت پخش می شود. همچنین، در اغلب موارد، مجموعه دادهها متعادل نیستند، بنابراین ما به نقطه اول بازگشتهایم و دقت یک معیار ناکافی است.
ما می توانیم با استفاده از معیارهای دیگر به نتایج عمیق تر نگاه کنیم تا بتوانیم آن را تعیین کنیم. این مرحله نیز با رگرسیون متفاوت است، در اینجا ما استفاده خواهیم کرد:
- ماتریس سردرگمی: برای اینکه بدانیم چقدر درست یا غلط کردیم هر کلاس. مقادیری که درست و به درستی پیش بینی شده بودند نامیده می شوند نکات مثبت واقعی آنهایی که به عنوان مثبت پیش بینی شده بودند اما مثبت نبودند نامیده می شوند مثبت کاذب. همان نامگذاری از منفی های واقعی و منفی های کاذب برای مقادیر منفی استفاده می شود.
- دقت: برای درک اینکه چه مقادیر پیشبینی درستی توسط طبقهبندیکننده ما صحیح در نظر گرفته شده است. دقت آن مقادیر مثبت واقعی را بر هر چیزی که به عنوان مثبت پیش بینی شده بود تقسیم می کند.
$$
دقت = فرک{متن{مثبت واقعی}}{متن{مثبت واقعی} + متن{مثبت نادرست}}
$$
- به یاد بیاورید: برای درک اینکه چه تعداد از موارد مثبت واقعی توسط طبقه بندی کننده ما شناسایی شده است. فراخوان با تقسیم مثبت های واقعی بر هر چیزی که باید مثبت پیش بینی می شد محاسبه می شود.
$$
فراخوان = فراک{متن{مثبت واقعی}}{متن{مثبت واقعی} + متن{منفی نادرست}}
$$
- امتیاز F1: آیا متعادل یا میانگین هارمونیک دقت و یادآوری کمترین مقدار 0 و بیشترین مقدار 1 است. When
f1-score
برابر با 1 است، به این معنی است که همه کلاس ها به درستی پیش بینی شده اند - این یک امتیاز بسیار سخت برای به دست آوردن با داده های واقعی است (تقریبا همیشه استثنا وجود دارد).
$$
text{f1-score} = 2* frac{text{precision} * text{recall}}{text{precision} + text{recal}}
$$
توجه داشته باشید: یک امتیاز F1 وزنی نیز وجود دارد، و فقط یک F1 است که وزن یکسانی را برای همه کلاس ها اعمال نمی کند. وزن معمولاً توسط کلاس ها تعیین می شود پشتیبانی - چند نمونه از امتیاز F1 "پشتیبانی" می کنند (نسبت برچسب های متعلق به یک کلاس خاص). هرچه پشتیبانی کمتر باشد (نمونه های کمتری از یک کلاس)، وزن F1 برای آن کلاس کمتر است، زیرا غیرقابل اعتمادتر است.
La 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))
خروجی اسکریپت بالا به شکل زیر است:
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 بدون وزن تقریباً یکسان خواهند بود.
ما همچنین می توانیم نتیجه معیارهای هر یک از 4 کلاس را مشاهده کنیم. از آن جا، ما می توانیم متوجه آن شویم class 2
کمترین دقت، کمترین را داشت recall
، و کمترین f1-score
. Class 3
درست پشت سر است class 2
برای داشتن کمترین امتیاز، و پس از آن، ما داریم class 1
با بهترین نمرات به دنبال آن class 4
.
با نگاه کردن به ماتریس سردرگمی، می توانیم متوجه شویم که:
class 1
بیشتر اشتباه گرفته شدclass 2
در 238 موردclass 2
برای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
خیلی به هم نزدیک بودند، بنابراین تشخیص آنها از هم سخت شد.
همیشه سعی کنید داده ها را با تعداد سطل های مختلف تست کنید تا ببینید چه اتفاقی می افتد.
علاوه بر تعداد دلخواه bin های داده، تعداد دلخواه دیگری نیز وجود دارد که ما انتخاب کرده ایم، تعداد همسایگان K. همان تکنیکی را که برای کار رگرسیون به کار بردیم، میتوان در طبقهبندی هنگام تعیین تعداد Kهایی که یک مقدار متریک را به حداکثر یا حداقل میرسانند، اعمال کرد.
یافتن بهترین K برای طبقه بندی KNN
بیایید آنچه را که برای رگرسیون انجام شده است تکرار کنیم و نمودار مقادیر K و متریک مربوطه را برای مجموعه تست رسم کنیم. همچنین میتوانید معیاری را انتخاب کنید که با شرایط شما مطابقت دارد، در اینجا ما انتخاب میکنیم f1-score
.
به این ترتیب، ما طرح f1-score
برای مقادیر پیش بینی شده مجموعه تست برای همه مقادیر K بین 1 تا 40.
ابتدا ما وارد می کنیم f1_score
از جانب sklearn.metrics
و سپس مقدار آن را برای تمام پیشبینیهای طبقهبندیکننده K-Nearest Neighbors محاسبه کنید، که در آن 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')
نمودار خروجی به شکل زیر است:
از خروجی، می توانیم ببینیم که 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
.
پس از وارد کردن، a را نمونه می کنیم 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 فاصله برای هر نقطه داده داریم - فاصله بین خود و 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))
در خروجی بالا می توانیم شاخص های هر یک از 5 همسایه را مشاهده کنیم. اکنون میتوانیم به محاسبه میانگین 5 فاصله ادامه دهیم و نموداری رسم کنیم که هر ردیف را در محور X میشمارد و هر میانگین فاصله را در محور Y نشان میدهد:
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')
توجه داشته باشید که بخشی از نمودار وجود دارد که در آن فاصله های میانگین دارای مقادیر یکنواخت هستند. آن نقطه محور 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 = '--')
این خط میانگین فاصله ای را نشان می دهد که در بالای آن همه مقادیر متفاوت است. این بدان معنی است که تمام نقاط با a 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]),)
اکنون ما شاخص های نقطه پرت خود را داریم. بیایید آنها را در چارچوب داده پیدا کنیم:
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-Nearest همسایگان برای پیش بینی). این باعث می شود الگوریتم KNN بسیار سریعتر از الگوریتم های دیگر که نیاز به آموزش با کل مجموعه داده مانند پشتیبانی از ماشین های برداری, رگرسیون خطی، و غیره
- از آنجایی که KNN قبل از انجام پیشبینی نیازی به آموزش ندارد، میتوان دادههای جدید را بهطور یکپارچه اضافه کرد
- برای کار با KNN فقط دو پارامتر لازم است، یعنی مقدار K و تابع فاصله
منفی
- الگوریتم KNN با دادههای ابعادی بالا به خوبی کار نمیکند، زیرا با تعداد ابعاد زیاد، فاصله بین نقاط "عجیب" میشود و معیارهای فاصلهای که استفاده میکنیم ثابت نمیمانند.
- در نهایت، الگوریتم KNN با ویژگی های طبقه بندی به خوبی کار نمی کند زیرا یافتن فاصله بین ابعاد با ویژگی های طبقه بندی دشوار است.
رفتن به جلو - پروژه دستی به پایان
در این پروژه هدایتشده – شما یاد خواهید گرفت که چگونه مدلهای یادگیری ماشینی سنتی قدرتمند و همچنین مدلهای یادگیری عمیق بسازید، از Ensemble Learning استفاده کنید و فراآموزان را برای پیشبینی قیمت خانهها از مجموعهای از مدلهای Scikit-Learn و Keras آموزش دهید.
با استفاده از Keras، API یادگیری عمیق ساخته شده در بالای Tensorflow، معماری ها را آزمایش می کنیم، مجموعه ای از مدل های انباشته را می سازیم و آموزش می دهیم فرا یادگیرنده شبکه عصبی (مدل سطح 1) برای تعیین قیمت یک خانه.
یادگیری عمیق شگفتانگیز است – اما قبل از متوسل شدن به آن، توصیه میشود که با تکنیکهای سادهتر نیز سعی کنید مشکل را حل کنید. یادگیری سطحی الگوریتم ها عملکرد پایه ما بر اساس یک خواهد بود رگرسیون تصادفی جنگل الگوریتم علاوه بر این - ما ایجاد مجموعههایی از مدلها را از طریق Scikit-Learn از طریق تکنیکهایی مانند کیسه زدن و رای دادن.
این یک پروژه پایان به انتها است و مانند همه پروژه های یادگیری ماشینی، ما با آن شروع خواهیم کرد تجزیه و تحلیل داده های اکتشافی، به دنبال پردازش داده ها و در نهایت ساختمان کم عمق و مدل های یادگیری عمیق برای تناسب با داده هایی که قبلا کاوش و تمیز کرده ایم.
نتیجه
KNN یک الگوریتم ساده و در عین حال قدرتمند است. می توان از آن برای بسیاری از وظایف مانند رگرسیون، طبقه بندی، یا تشخیص پرت استفاده کرد.
KNN به طور گسترده برای یافتن شباهت اسناد و تشخیص الگو استفاده شده است. همچنین برای توسعه سیستمهای توصیهگر و برای کاهش ابعاد و مراحل پیش پردازش برای بینایی کامپیوتر - بهویژه وظایف تشخیص چهره، استفاده شده است.
در این راهنما - ما از طریق رگرسیون، طبقه بندی و تشخیص نقاط پرت با استفاده از پیاده سازی Scikit-Learn از الگوریتم K-Nearest Neighbor عبور کرده ایم.