|
|
# ساخت یک مدل رگرسیون با استفاده از Scikit-learn: چهار روش رگرسیون
|
|
|
|
|
|
## نکته مبتدی
|
|
|
|
|
|
رگرسیون خطی زمانی استفاده میشود که بخواهیم یک **مقدار عددی** پیشبینی کنیم (برای مثال، قیمت خانه، دما یا فروش).
|
|
|
این مدل با یافتن یک خط راست که بهترین نماینده رابطه بین ویژگیهای ورودی و خروجی باشد، کار میکند.
|
|
|
|
|
|
در این درس، تمرکز ما بر درک مفهوم است قبل از کاوش روشهای پیشرفتهتر رگرسیون.
|
|
|

|
|
|
> اینفوگرافیک توسط [داسانی مادیپالی](https://twitter.com/dasani_decoded)
|
|
|
## [آزمون قبل از درس](https://ff-quizzes.netlify.app/en/ml/)
|
|
|
|
|
|
> ### [این درس در R نیز موجود است!](../../../../2-Regression/3-Linear/solution/R/lesson_3.html)
|
|
|
### مقدمه
|
|
|
|
|
|
تا اینجا بررسی کردهاید رگرسیون چیست با داده نمونه جمعآوری شده از مجموعه داده قیمت کدو تنبل که در طول این درس استفاده خواهیم کرد. همچنین آن را با استفاده از Matplotlib مصورسازی کردهاید.
|
|
|
|
|
|
اکنون آمادهاید عمیقتر در رگرسیون برای یادگیری ماشین فرو بروید. در حالی که مصورسازی به شما اجازه میدهد دادهها را درک کنید، قدرت واقعی یادگیری ماشین از _آموزش مدلها_ میآید. مدلها روی دادههای تاریخی آموزش میبینند تا به طور خودکار وابستگیهای داده را به دست آورند، و به شما اجازه میدهند نتایج دادههای جدید را پیشبینی کنید که مدل قبلا ندیده است.
|
|
|
|
|
|
در این درس، شما درباره دو نوع رگرسیون بیشتر خواهید آموخت: _رگرسیون خطی پایه_ و _رگرسیون چندجملهای_، همراه با بخشی از ریاضیات پشت این تکنیکها. این مدلها به ما اجازه میدهند قیمت کدو تنبل را بر اساس دادههای ورودی مختلف پیشبینی کنیم.
|
|
|
|
|
|
[](https://youtu.be/CRxFT8oTDMg "یادگیری ماشین برای مبتدیان - درک رگرسیون خطی")
|
|
|
|
|
|
> 🎥 برای تماشای ویدئوی کوتاه مرور رگرسیون خطی روی تصویر بالا کلیک کنید.
|
|
|
|
|
|
> در طول این دوره، فرض میکنیم دانش ریاضی حداقلی است و تلاش میکنیم برای دانشجویان از رشتههای دیگر قابل دسترس باشد، پس مراقب یادداشتها، اشارههای 🧮، نمودارها و ابزارهای یادگیری دیگر برای کمک به فهم باشید.
|
|
|
|
|
|
### پیشنیاز
|
|
|
|
|
|
شما باید اکنون با ساختار داده کدو تنبل که بررسی میکنیم آشنا باشید. این داده در فایل _notebook.ipynb_ این درس به صورت پیشبارگذاری و پیشپاکسازی شده موجود است. در این فایل، قیمت کدو تنبل به ازای هر بوشل در یک داده فریم جدید نمایش داده شده است. مطمئن شوید میتوانید این نوتبوکها را در کرنلهای Visual Studio Code اجرا کنید.
|
|
|
|
|
|
### آمادهسازی
|
|
|
|
|
|
به عنوان یادآوری، شما این داده را بارگذاری میکنید تا بتوانید سوالهایی از آن بپرسید.
|
|
|
|
|
|
- بهترین زمان خرید کدو تنبل کی است؟
|
|
|
- چه قیمت را انتظار میتوانم برای یک جعبه کدو تنبل مینیاتوری داشته باشم؟
|
|
|
- آیا باید آنها را در سبدهای نیم بوشل بخرم یا در جعبه 1 1/9 بوشل؟
|
|
|
بیایید بیشتر در این دادهها کاوش کنیم.
|
|
|
|
|
|
در درس قبلی، یک داده فریم Pandas ایجاد کردید و آن را با بخشی از مجموعه داده اصلی پر کردید، قیمتگذاری را بر اساس بوشل معیار قرار دادید. اما با این کار تنها توانستید حدود 400 نقطه داده و فقط برای ماههای پاییز به دست آورید.
|
|
|
|
|
|
نگاهی به دادههایی بیندازید که در نوتبوک همراه این درس پیشبارگذاری شده است. دادهها پیشبارگذاری شدهاند و یک پراکندگی اولیه برای نشان دادن دادههای ماه رسم شده است. شاید بتوانیم با پاکسازی بیشتر، جزئیات بیشتری درباره ماهیت دادهها داشته باشیم.
|
|
|
|
|
|
## یک خط رگرسیون خطی
|
|
|
|
|
|
همانطور که در درس 1 آموختید، هدف یک تمرین رگرسیون خطی این است که بتوانیم یک خط ترسیم کنیم که:
|
|
|
|
|
|
- **نشاندهنده رابطه متغیرها باشد**. نشان دادن رابطه بین متغیرها
|
|
|
- **پیشبینی انجام دهد**. پیشبینی دقیق جایی که نقطه داده جدید نسبت به آن خط قرار میگیرد.
|
|
|
|
|
|
معمول است که این نوع خط توسط **رگرسیون کمترین مربعات** رسم شود. اصطلاح "کمترین مربعات" به فرآیند کمینه کردن کل خطا در مدل ما اشاره دارد. برای هر نقطه داده، فاصله عمودی (که به آن باقیمانده میگویند) بین نقطه واقعی و خط رگرسیون ما اندازهگیری میشود.
|
|
|
|
|
|
ما این فاصلهها را دو دلیل اصلی مربع میکنیم:
|
|
|
|
|
|
1. **قدر بیش از جهت:** میخواهیم خطای -5 به اندازه خطای +5 حساب شود. مربع گرفتن همه مقادیر را مثبت میکند.
|
|
|
2. **جریمه دادن به نقاط پرت:** مربع کردن وزن بیشتری به خطاهای بزرگ میدهد و خط را مجبور میکند نزدیکتر به نقاط دور شود.
|
|
|
|
|
|
سپس همه این مقادیر مربعی را جمع میکنیم. هدف ما یافتن خط خاصی است که این مجموع نهایی کمترین مقدار ممکن را داشته باشد — بنابراین نام "کمترین مربعات" است.
|
|
|
|
|
|
> **🧮 ریاضی را به من نشان بده**
|
|
|
>
|
|
|
> این خط، که _خط بهترین برازش_ نامیده میشود، میتواند با [یک معادله](https://en.wikipedia.org/wiki/Simple_linear_regression) بیان شود:
|
|
|
>
|
|
|
> ```
|
|
|
> Y = a + bX
|
|
|
> ```
|
|
|
>
|
|
|
> `X` متغیر توضیحی است. `Y` متغیر وابسته است. شیب خط `b` است و `a` عرض از مبدأ در محور y است، که مقدار `Y` را وقتی `X = 0` است نشان میدهد.
|
|
|
>
|
|
|
> 
|
|
|
>
|
|
|
> ابتدا شیب `b` را محاسبه کنید. اینفوگرافیک توسط [جن لوپر](https://twitter.com/jenlooper)
|
|
|
>
|
|
|
> به عبارت دیگر، و با اشاره به سوال اصلی داده کدو تنبل ما: "پیشبینی قیمت کدو تنبل به ازای هر بوشل بر اساس ماه"، `X` اشاره به قیمت دارد و `Y` به ماه فروش.
|
|
|
>
|
|
|
> 
|
|
|
>
|
|
|
> مقدار Y را محاسبه کنید. اگر حدود 4 دلار پرداخت میکنید، باید آوریل باشد! اینفوگرافیک توسط [جن لوپر](https://twitter.com/jenlooper)
|
|
|
>
|
|
|
> ریاضی که خط را محاسبه میکند باید شیب خط را نشان دهد، که همچنین به عرض از مبدأ یا جایی که `Y` وقتی `X = 0` است بستگی دارد.
|
|
|
>
|
|
|
> میتوانید روش محاسبه این مقادیر را در سایت [ریاضیات سرگرمکننده](https://www.mathsisfun.com/data/least-squares-regression.html) مشاهده کنید. همچنین به [این ماشین حساب کمترین مربعات](https://www.mathsisfun.com/data/least-squares-calculator.html) مراجعه کنید تا ببینید چگونه مقادیر اعداد بر خط تاثیر میگذارند.
|
|
|
|
|
|
## همبستگی
|
|
|
|
|
|
یک اصطلاح دیگر برای فهمیدن، **ضریب همبستگی** بین متغیرهای X و Y است. با استفاده از نمودار پراکندگی، میتوانید این ضریب را به سرعت مشاهده کنید. نموداری که نقاط داده مرتب در یک خط منظم پخش شدهاند همبستگی بالایی دارند، اما نموداری که نقاط داده در تمام محدوده بین X و Y پراکنده هستند همبستگی کمی دارد.
|
|
|
|
|
|
یک مدل رگرسیون خطی خوب مدلی است که ضریب همبستگی بالایی (نزدیک به 1 بیشتر از 0) با استفاده از روش کمترین مربعات و خط رگرسیون داشته باشد.
|
|
|
|
|
|
✅ نوتبوک همراه این درس را اجرا کنید و نمودار پراکندگی ماه به قیمت را نگاه کنید. آیا داده همبستگی بالایی یا پایینی بین ماه و قیمت فروش کدو تنبل دارد بر اساس تفسیر بصری خود از نمودار پراکندگی؟ آیا اگر به جای `Month` از معیار دقیقتری مثل *روز سال* (یعنی تعداد روزها از آغاز سال) استفاده کنید، تغییر میکند؟
|
|
|
|
|
|
در کد زیر فرض میکنیم داده را پاکسازی کردهایم و داده فریمی به نام `new_pumpkins` بدست آوردیم، مشابه این:
|
|
|
|
|
|
ID | ماه | روز_سال | نوع | شهر | بستهبندی | قیمت پایین | قیمت بالا | قیمت
|
|
|
---|---|---|---|---|---|---|---|---
|
|
|
70 | 9 | 267 | نوع پای | بالتیمور | جعبههای 1 1/9 بوشل | 15.0 | 15.0 | 13.636364
|
|
|
71 | 9 | 267 | نوع پای | بالتیمور | جعبههای 1 1/9 بوشل | 18.0 | 18.0 | 16.363636
|
|
|
72 | 10 | 274 | نوع پای | بالتیمور | جعبههای 1 1/9 بوشل | 18.0 | 18.0 | 16.363636
|
|
|
73 | 10 | 274 | نوع پای | بالتیمور | جعبههای 1 1/9 بوشل | 17.0 | 17.0 | 15.454545
|
|
|
74 | 10 | 281 | نوع پای | بالتیمور | جعبههای 1 1/9 بوشل | 15.0 | 15.0 | 13.636364
|
|
|
|
|
|
> کد پاکسازی داده در [`notebook.ipynb`](notebook.ipynb) موجود است. ما مراحل پاکسازی مشابه درس قبلی را انجام دادهایم، و ستون `DayOfYear` را با استفاده از عبارت زیر محاسبه کردیم:
|
|
|
|
|
|
```python
|
|
|
day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days)
|
|
|
```
|
|
|
|
|
|
حالا که درک درستی از ریاضی پشت رگرسیون خطی دارید، بیایید یک مدل رگرسیون بسازیم تا ببینیم آیا میتوانیم پیشبینی کنیم کدام بسته کدو تنبل بهترین قیمتها را دارد. کسی که برای یک جشنواره کدو تنبل خرید میکند ممکن است بخواهد این اطلاعات را داشته باشد تا خریدهای خود را بهینه کند.
|
|
|
|
|
|
## جستجوی همبستگی
|
|
|
|
|
|
[](https://youtu.be/uoRq-lW2eQo "یادگیری ماشین برای مبتدیان - جستجوی همبستگی: کلید رگرسیون خطی")
|
|
|
|
|
|
> 🎥 برای تماشای ویدئوی کوتاه مرور همبستگی روی تصویر بالا کلیک کنید.
|
|
|
|
|
|
شما احتمالاً در درس قبلی دیدهاید که میانگین قیمتها برای ماههای مختلف به این صورت است:
|
|
|
|
|
|
<img alt="میانگین قیمت بر اساس ماه" src="../../../../translated_images/fa/barchart.a833ea9194346d76.webp" width="50%"/>
|
|
|
|
|
|
این نشان میدهد باید نوعی همبستگی وجود داشته باشد، و ما میتوانیم مدل خطی رگرسیون را برای پیشبینی رابطه بین `ماه` و `قیمت`، یا بین `روز سال` و `قیمت` آموزش دهیم. اینجا نمودار پراکندگی که رابطه دوم را نشان میدهد دیده میشود:
|
|
|
|
|
|
<img alt="نمودار پراکندگی قیمت نسبت به روز سال" src="../../../../translated_images/fa/scatter-dayofyear.bc171c189c9fd553.webp" width="50%" />
|
|
|
|
|
|
بیایید ببینیم آیا همبستگی با استفاده از تابع `corr` وجود دارد:
|
|
|
|
|
|
```python
|
|
|
print(new_pumpkins['Month'].corr(new_pumpkins['Price']))
|
|
|
print(new_pumpkins['DayOfYear'].corr(new_pumpkins['Price']))
|
|
|
```
|
|
|
|
|
|
به نظر میرسد همبستگی نسبتاً کوچک است، -0.15 نسبت به `ماه` و -0.17 نسبت به `روز ماه`، اما ممکن است رابطه مهم دیگری وجود داشته باشد. به نظر میرسد خوشههای مختلف قیمت مرتبط با انواع مختلف کدو وجود دارد. برای تایید این فرض، اجازه دهید هر دسته کدو را با رنگ متفاوت رسم کنیم. با ارسال آرگومان `ax` به تابع نمودار پراکندگی میتوانیم تمام نقاط را روی یک گراف نشان دهیم:
|
|
|
|
|
|
```python
|
|
|
ax=None
|
|
|
colors = ['red','blue','green','yellow']
|
|
|
for i,var in enumerate(new_pumpkins['Variety'].unique()):
|
|
|
df = new_pumpkins[new_pumpkins['Variety']==var]
|
|
|
ax = df.plot.scatter('DayOfYear','Price',ax=ax,c=colors[i],label=var)
|
|
|
```
|
|
|
|
|
|
<img alt="نمودار پراکندگی قیمت نسبت به روز سال با رنگهای متفاوت" src="../../../../translated_images/fa/scatter-dayofyear-color.65790faefbb9d54f.webp" width="50%" />
|
|
|
|
|
|
بررسی ما نشان میدهد که نوع کدو اثر بیشتری بر قیمت کل دارد نسبت به تاریخ فروش واقعی. میتوانیم این را با نمودار میلهای ببینیم:
|
|
|
|
|
|
```python
|
|
|
new_pumpkins.groupby('Variety')['Price'].mean().plot(kind='bar')
|
|
|
```
|
|
|
|
|
|
<img alt="نمودار میلهای قیمت نسبت به نوع" src="../../../../translated_images/fa/price-by-variety.744a2f9925d9bcb4.webp" width="50%" />
|
|
|
|
|
|
در حال حاضر فقط روی یک نوع کدو، یعنی 'نوع پای' تمرکز کنیم و ببینیم تاریخ فروش چه تاثیری بر قیمت دارد:
|
|
|
|
|
|
```python
|
|
|
pie_pumpkins = new_pumpkins[new_pumpkins['Variety']=='PIE TYPE']
|
|
|
pie_pumpkins.plot.scatter('DayOfYear','Price')
|
|
|
```
|
|
|
|
|
|
<img alt="نمودار پراکندگی قیمت نسبت به روز سال برای کدو نوع پای" src="../../../../translated_images/fa/pie-pumpkins-scatter.d14f9804a53f927e.webp" width="50%" />
|
|
|
|
|
|
اگر اکنون همبستگی بین `قیمت` و `روز سال` را با تابع `corr` محاسبه کنیم، چیزی حدود `-0.27` بدست میآوریم – که یعنی آموزش یک مدل پیشبینی منطقی است.
|
|
|
|
|
|
> قبل از آموزش مدل رگرسیون خطی، مهم است مطمئن شویم دادههای ما تمیز هستند. رگرسیون خطی با مقادیر خالی خوب کار نمیکند، بنابراین بهتر است همه سلولهای خالی حذف شوند:
|
|
|
|
|
|
```python
|
|
|
pie_pumpkins.dropna(inplace=True)
|
|
|
pie_pumpkins.info()
|
|
|
```
|
|
|
|
|
|
راه دیگر پر کردن مقادیر خالی با میانگینهای ستون مربوطه است.
|
|
|
|
|
|
## رگرسیون خطی ساده
|
|
|
|
|
|
[](https://youtu.be/e4c_UP2fSjg "یادگیری ماشین برای مبتدیان - رگرسیون خطی و چندجملهای با Scikit-learn")
|
|
|
|
|
|
> 🎥 برای تماشای ویدئوی کوتاه مرور رگرسیون خطی و چندجملهای روی تصویر بالا کلیک کنید.
|
|
|
|
|
|
برای آموزش مدل رگرسیون خطی خود، از کتابخانه **Scikit-learn** استفاده خواهیم کرد.
|
|
|
|
|
|
```python
|
|
|
from sklearn.linear_model import LinearRegression
|
|
|
from sklearn.metrics import mean_squared_error
|
|
|
from sklearn.model_selection import train_test_split
|
|
|
```
|
|
|
|
|
|
ابتدا با جدا کردن مقادیر ورودی (ویژگیها) و خروجی مورد انتظار (برچسب) به آرایههای numpy جداگانه شروع میکنیم:
|
|
|
|
|
|
```python
|
|
|
X = pie_pumpkins['DayOfYear'].to_numpy().reshape(-1,1)
|
|
|
y = pie_pumpkins['Price']
|
|
|
```
|
|
|
|
|
|
> توجه داشته باشید که مجبور شدیم روی داده ورودی `reshape` انجام دهیم تا پکیج رگرسیون خطی آن را به درستی بفهمد. رگرسیون خطی آرایه دو بعدی را به عنوان ورودی انتظار دارد، که هر ردیف آن یک بردار از ویژگیهای ورودی باشد. در مورد ما، چون تنها یک ورودی داریم، به آرایهای با شکل N×1 نیاز داریم که N اندازه داده است.
|
|
|
|
|
|
سپس باید داده را به مجموعههای آموزشی و آزمایشی تقسیم کنیم، تا بتوانیم مدل خود را بعد از آموزش اعتبارسنجی کنیم:
|
|
|
|
|
|
```python
|
|
|
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
|
|
|
```
|
|
|
|
|
|
در نهایت، آموزش مدل رگرسیون خطی واقعی تنها دو خط کد نیاز دارد. شیء `LinearRegression` را تعریف میکنیم و با استفاده از متد `fit` آن را روی دادههای خود تطبیق میدهیم:
|
|
|
|
|
|
```python
|
|
|
lin_reg = LinearRegression()
|
|
|
lin_reg.fit(X_train,y_train)
|
|
|
```
|
|
|
|
|
|
شیء `LinearRegression` پس از اجرای `fit` شامل تمام ضرایب رگرسیون است که میتوان به آنها از طریق خاصیت `.coef_` دسترسی داشت. در مورد ما، فقط یک ضریب وجود دارد که باید حدود `-0.017` باشد. این یعنی قیمتها به نظر میرسد که با گذر زمان کمی کاهش مییابند، اما نه خیلی زیاد، حدود ۲ سنت در روز. همچنین میتوانیم نقطه تلاقی رگرسیون با محور Y را با استفاده از `lin_reg.intercept_` بدست آوریم — که در مورد ما حدود `21` خواهد بود و نشاندهنده قیمت در ابتدای سال است.
|
|
|
|
|
|
برای دیدن دقت مدل، میتوانیم قیمتها را روی دادههای تست پیشبینی کنیم، و سپس بسنجیم چقدر پیشبینیهایمان به مقادیر مورد انتظار نزدیک هستند. این کار را میتوان با استفاده از معیار خطای میانگین مربعات جذر (RMSE) انجام داد، که جذر میانگین تمام اختلافهای مربعی بین مقدار پیشبینی شده و مورد انتظار است.
|
|
|
|
|
|
```python
|
|
|
pred = lin_reg.predict(X_test)
|
|
|
|
|
|
rmse = np.sqrt(mean_squared_error(y_test,pred))
|
|
|
print(f'RMSE: {rmse:3.3} ({rmse/np.mean(pred)*100:3.3}%)')
|
|
|
```
|
|
|
|
|
|
خطای ما حدود ۲ واحد است که تقریباً ~۱۷٪ است، نه چندان خوب. یک شاخص دیگر از کیفیت مدل، **ضریب تعیین** است که میتوان آن را به این صورت به دست آورد:
|
|
|
|
|
|
```python
|
|
|
score = lin_reg.score(X_train,y_train)
|
|
|
print('Model determination: ', score)
|
|
|
```
|
|
|
اگر مقدار برابر ۰ باشد، یعنی مدل دادههای ورودی را در نظر نمیگیرد و مانند *بدترین پیشبینیکننده خطی* عمل میکند، که به سادگی مقدار میانگین خروجیها است. مقدار ۱ یعنی میتوانیم دقیقاً همه خروجیهای مورد انتظار را پیشبینی کنیم. در مورد ما، ضریب حدود ۰.۰۶ است که نسبتاً پایین است.
|
|
|
|
|
|
همچنین میتوانیم دادههای تست را همراه با خط رگرسیون رسم کنیم تا بهتر ببینیم رگرسیون در مورد ما چگونه عمل میکند:
|
|
|
|
|
|
```python
|
|
|
plt.scatter(X_test,y_test)
|
|
|
plt.plot(X_test,pred)
|
|
|
```
|
|
|
|
|
|
<img alt="Linear regression" src="../../../../translated_images/fa/linear-results.f7c3552c85b0ed1c.webp" width="50%" />
|
|
|
|
|
|
## رگرسیون چندجملهای
|
|
|
|
|
|
نوع دیگری از رگرسیون خطی، رگرسیون چندجملهای است. در حالی که گاهی بین متغیرها رابطه خطی وجود دارد - هر چه حجم کدو تنبل بیشتر باشد، قیمت بالاتر است - گاهی این روابط قابل ترسیم با یک صفحه یا خط مستقیم نیستند.
|
|
|
|
|
|
✅ اینجا [چند مثال دیگر](https://online.stat.psu.edu/stat501/lesson/9/9.8) از دادههایی است که میتوانند از رگرسیون چندجملهای استفاده کنند.
|
|
|
|
|
|
دوباره به رابطه بین تاریخ و قیمت نگاه کنید. آیا این نمودار پراکندگی به نظر میرسد که حتما باید با یک خط مستقیم تحلیل شود؟ آیا قیمتها نمیتوانند نوسان کنند؟ در این حالت، میتوانید رگرسیون چندجملهای را امتحان کنید.
|
|
|
|
|
|
✅ چندجملهایها عبارتهای ریاضی هستند که ممکن است شامل یک یا چند متغیر و ضرایب باشند.
|
|
|
|
|
|
رگرسیون چندجملهای یک منحنی ایجاد میکند تا دادههای غیرخطی را بهتر تطبیق دهد. در مورد ما، اگر متغیر مربعشده `DayOfYear` را به دادههای ورودی اضافه کنیم، باید بتوانیم دادهها را با یک منحنی سهمی شکل تطبیق دهیم که حداقل آن در نقطهای از سال باشد.
|
|
|
|
|
|
کتابخانه Scikit-learn شامل یک [رابط برنامهنویسی خط لوله (pipeline API)](https://scikit-learn.org/stable/modules/generated/sklearn.pipeline.make_pipeline.html?highlight=pipeline#sklearn.pipeline.make_pipeline) مفید برای ترکیب مراحل مختلف پردازش دادهها با هم است. یک **خط لوله** زنجیرهای از **برآوردگرها** است. در مورد ما، خط لولهای خواهیم ساخت که ابتدا ویژگیهای چندجملهای را به مدل اضافه میکند و سپس رگرسیون را آموزش میدهد:
|
|
|
|
|
|
```python
|
|
|
from sklearn.preprocessing import PolynomialFeatures
|
|
|
from sklearn.pipeline import make_pipeline
|
|
|
|
|
|
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
|
|
|
|
|
|
pipeline.fit(X_train,y_train)
|
|
|
```
|
|
|
|
|
|
استفاده از `PolynomialFeatures(2)` به این معناست که همه چندجملهایهای درجه دوم از دادههای ورودی را شامل میشود. در مورد ما فقط به معنای `DayOfYear`<sup>2</sup> است، اما اگر دو متغیر ورودی X و Y داشته باشیم، این شامل X<sup>2</sup>، XY و Y<sup>2</sup> هم خواهد بود. همچنین میتوانیم درجههای بالاتر چندجملهای را استفاده کنیم اگر بخواهیم.
|
|
|
|
|
|
خط لولهها میتوانند به همان شیوه شیء اصلی `LinearRegression` استفاده شوند، یعنی میتوانیم `fit` خط لوله را اجرا کنیم و سپس از `predict` برای دریافت نتایج پیشبینی استفاده کنیم. در اینجا نمودار دادههای تست و منحنی تقریب آورده شده است:
|
|
|
|
|
|
<img alt="Polynomial regression" src="../../../../translated_images/fa/poly-results.ee587348f0f1f60b.webp" width="50%" />
|
|
|
|
|
|
با استفاده از رگرسیون چندجملهای، میتوانیم مقداری کاهش در MSE و افزایش در ضریب تعیین بدست آوریم، اما نه به صورت چشمگیر. باید ویژگیهای دیگر را نیز در نظر بگیریم!
|
|
|
|
|
|
> میبینید که حداقل قیمتهای کدو تنبل تقریباً حوالی هالووین مشاهده میشود. چگونه میتوانید این را توضیح دهید؟
|
|
|
|
|
|
🎃 تبریک، شما به تازگی یک مدل ساختهاید که میتواند قیمت کدو تنبل پای را پیشبینی کند. احتمالاً میتوانید همین روند را برای تمام انواع کدو تکرار کنید، اما این کار خستهکننده خواهد بود. حالا بیایید یاد بگیریم چگونه تنوع کدو را در مدل خود لحاظ کنیم!
|
|
|
|
|
|
## ویژگیهای دستهای
|
|
|
|
|
|
در دنیای ایدهآل، میخواهیم بتوانیم قیمتها را برای انواع مختلف کدو با استفاده از همان مدل پیشبینی کنیم. اما ستون `Variety` کمی متفاوت از ستونهایی مثل `Month` است، چون حاوی مقادیر غیرعددی است. چنین ستونهایی **دستهای** نامیده میشوند.
|
|
|
|
|
|
[](https://youtu.be/DYGliioIAE0 "ML for beginners - Categorical Feature Predictions with Linear Regression")
|
|
|
|
|
|
> 🎥 برای دیدن یک ویدیوی کوتاه درباره استفاده از ویژگیهای دستهای، روی تصویر بالا کلیک کنید.
|
|
|
|
|
|
در اینجا میبینید که قیمت متوسط چگونه به نوع کدو بستگی دارد:
|
|
|
|
|
|
<img alt="Average price by variety" src="../../../../translated_images/fa/price-by-variety.744a2f9925d9bcb4.webp" width="50%" />
|
|
|
|
|
|
برای لحاظ کردن نوع کدو، ابتدا باید آن را به شکل عددی تبدیل کنیم، یا **رمزگذاری** کنیم. چند روش برای این کار وجود دارد:
|
|
|
|
|
|
* رمزگذاری ساده عددی یک جدول از انواع مختلف ایجاد میکند، و سپس نام نوع را با اندیس آن در آن جدول جایگزین میکند. این ایده بهترین گزینه برای رگرسیون خطی نیست، چون رگرسیون خطی مقدار عددی اندیس را گرفته و با ضریب خاصی ضرب کرده و به نتیجه اضافه میکند. در مورد ما، رابطه بین شماره اندیس و قیمت به وضوح غیرخطی است، حتی اگر مطمئن شویم که اندیسها به ترتیب خاصی مرتب شدهاند.
|
|
|
* **رمزگذاری تکگرمی (one-hot encoding)** ستون `Variety` را با ۴ ستون مختلف جایگزین میکند، یکی برای هر نوع کدو. هر ستون شامل `1` است اگر ردیف مربوطه از آن نوع باشد و `0` در غیر این صورت. این یعنی در رگرسیون خطی چهار ضریب وجود دارد، یکی برای هر نوع کدو، که مسئول "قیمت شروع" (یا به عبارت دقیقتر "قیمت اضافی") برای آن نوع خاص است.
|
|
|
|
|
|
کد زیر نشان میدهد چگونه میتوان یک نوع کدو را با روش one-hot کدگذاری کرد:
|
|
|
|
|
|
```python
|
|
|
pd.get_dummies(new_pumpkins['Variety'])
|
|
|
```
|
|
|
|
|
|
ID | FAIRYTALE | MINIATURE | MIXED HEIRLOOM VARIETIES | PIE TYPE
|
|
|
----|-----------|-----------|--------------------------|----------
|
|
|
70 | 0 | 0 | 0 | 1
|
|
|
71 | 0 | 0 | 0 | 1
|
|
|
... | ... | ... | ... | ...
|
|
|
1738 | 0 | 1 | 0 | 0
|
|
|
1739 | 0 | 1 | 0 | 0
|
|
|
1740 | 0 | 1 | 0 | 0
|
|
|
1741 | 0 | 1 | 0 | 0
|
|
|
1742 | 0 | 1 | 0 | 0
|
|
|
|
|
|
برای آموزش رگرسیون خطی با استفاده از نوع کدو one-hot، فقط کافی است `X` و `y` را به درستی مقداردهی اولیه کنیم:
|
|
|
|
|
|
```python
|
|
|
X = pd.get_dummies(new_pumpkins['Variety'])
|
|
|
y = new_pumpkins['Price']
|
|
|
```
|
|
|
|
|
|
باقیمانده کد همان است که قبلاً برای آموزش رگرسیون خطی استفاده کردیم. اگر آن را اجرا کنید، خواهید دید که میانگین مربعات خطا مشابه است اما ضریب تعیین خیلی بالاتری (~۷۷٪) بدست میآید. برای دریافت پیشبینیهای حتی دقیقتر، میتوانیم ویژگیهای دستهای بیشتری را به همراه ویژگیهای عددی مانند `Month` یا `DayOfYear` لحاظ کنیم. برای داشتن یک آرایه بزرگ از ویژگیها، میتوانیم از تابع `join` استفاده کنیم:
|
|
|
|
|
|
```python
|
|
|
X = pd.get_dummies(new_pumpkins['Variety']) \
|
|
|
.join(new_pumpkins['Month']) \
|
|
|
.join(pd.get_dummies(new_pumpkins['City'])) \
|
|
|
.join(pd.get_dummies(new_pumpkins['Package']))
|
|
|
y = new_pumpkins['Price']
|
|
|
```
|
|
|
|
|
|
در اینجا ما همچنین `City` و نوع `Package` را نیز در نظر میگیریم، که MSE برابر 2.84 (۱۰٪) و ضریب تعیین 0.94 به ما میدهد!
|
|
|
|
|
|
## همه چیز را کنار هم بگذاریم
|
|
|
|
|
|
برای ساخت بهترین مدل، میتوانیم دادههای ترکیبی (دستهای کدگذاری شده به صورت one-hot + عددی) از مثال بالا را همراه با رگرسیون چندجملهای استفاده کنیم. در اینجا کد کامل برای راحتی شما آمده است:
|
|
|
|
|
|
```python
|
|
|
# تنظیم دادههای آموزشی
|
|
|
X = pd.get_dummies(new_pumpkins['Variety']) \
|
|
|
.join(new_pumpkins['Month']) \
|
|
|
.join(pd.get_dummies(new_pumpkins['City'])) \
|
|
|
.join(pd.get_dummies(new_pumpkins['Package']))
|
|
|
y = new_pumpkins['Price']
|
|
|
|
|
|
# تقسیمبندی آموزش و آزمون
|
|
|
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
|
|
|
|
|
|
# تنظیم و آموزش خط لوله
|
|
|
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
|
|
|
pipeline.fit(X_train,y_train)
|
|
|
|
|
|
# پیشبینی نتایج برای دادههای آزمون
|
|
|
pred = pipeline.predict(X_test)
|
|
|
|
|
|
# محاسبه MSE و تعیین ضریب
|
|
|
mse = np.sqrt(mean_squared_error(y_test,pred))
|
|
|
print(f'Mean error: {mse:3.3} ({mse/np.mean(pred)*100:3.3}%)')
|
|
|
|
|
|
score = pipeline.score(X_train,y_train)
|
|
|
print('Model determination: ', score)
|
|
|
```
|
|
|
|
|
|
این باید بهترین ضریب تعیین حدود ۹۷٪ و MSE=2.23 (~۸٪ خطای پیشبینی) را به ما بدهد.
|
|
|
|
|
|
| مدل | MSE | ضریب تعیین |
|
|
|
|-------|-----|---------------|
|
|
|
| `DayOfYear` خطی | 2.77 (۱۷.۲٪) | 0.07 |
|
|
|
| `DayOfYear` چندجملهای | 2.73 (۱۷.۰٪) | 0.08 |
|
|
|
| `Variety` خطی | 5.24 (۱۹.۷٪) | 0.77 |
|
|
|
| تمام ویژگیها خطی | 2.84 (۱۰.۵٪) | 0.94 |
|
|
|
| تمام ویژگیها چندجملهای | 2.23 (۸.۲۵٪) | 0.97 |
|
|
|
|
|
|
🏆 عالی! شما چهار مدل رگرسیون را در یک درس ساختید و کیفیت مدل را تا ۹۷٪ بهبود دادید. در بخش نهایی درباره رگرسیون، با رگرسیون لجستیک برای تعیین دستهها آشنا خواهید شد.
|
|
|
|
|
|
---
|
|
|
## 🚀چالش
|
|
|
|
|
|
تعدادی متغیر مختلف را در این دفترچه تست کنید تا ببینید همبستگی چگونه با دقت مدل مربوط میشود.
|
|
|
|
|
|
## [کوییز پس از درس](https://ff-quizzes.netlify.app/en/ml/)
|
|
|
|
|
|
## مرور و خودآموزی
|
|
|
|
|
|
در این درس درباره رگرسیون خطی یاد گرفتیم. انواع مهم دیگری از رگرسیون وجود دارد. درباره روشهای Stepwise، Ridge، Lasso و Elasticnet مطالعه کنید. یک دوره خوب برای یادگیری بیشتر، دوره [یادگیری آماری دانشگاه استنفورد](https://online.stanford.edu/courses/sohs-ystatslearning-statistical-learning) است.
|
|
|
|
|
|
## تمرین
|
|
|
|
|
|
[ساخت مدل](assignment.md)
|
|
|
|
|
|
---
|
|
|
|
|
|
<!-- CO-OP TRANSLATOR DISCLAIMER START -->
|
|
|
**سلب مسئولیت**:
|
|
|
این سند با استفاده از سرویس ترجمه هوش مصنوعی [Co-op Translator](https://github.com/Azure/co-op-translator) ترجمه شده است. در حالی که ما برای دقت تلاش میکنیم، لطفاً توجه داشته باشید که ترجمههای خودکار ممکن است شامل خطاها یا نواقصی باشند. سند اصلی به زبان بومی آن باید به عنوان منبع معتبر در نظر گرفته شود. برای اطلاعات حیاتی، توصیه میشود از ترجمه حرفهای انسانی استفاده شود. ما مسئول هیچ گونه سوءتفاهم یا تفسیر نادرستی که ناشی از استفاده از این ترجمه باشد، نیستیم.
|
|
|
<!-- CO-OP TRANSLATOR DISCLAIMER END --> |