# পলিনমিয়াল রিগ্রেশন

লিনিয়ার রিগ্রেশনে আমরা দেখেছি ডিপেন্ডেন্ট এবং ইন্ডিপেন্ডেন্ট ভ্যারিয়েবলের সম্পর্ক হয় সরল রৈখিক বা লিনিয়ার, কিন্তু বাস্তব জীবনে আমরা অনেক ডেটাসেট পেয়ে থাকবো যার ডিপেন্ডেন্ট এবং ইন্ডিপেন্ডেন্ট ভ্যারিয়েবলের সম্পর্ক হয় সরল রৈখিক হবে না। এধরনের অ-সরল রৈখিক সম্পর্ককে আমরা নন-লিনিয়ার বা পলিনমিয়াল ইকুয়েশনের মাধ্যমে সমাধান করে থাকি।&#x20;

![ছবি - লিনিয়ার এবং বিভিন্ন ধরনের নন-লিনিয়ার রিলেশনশিপ ( সম্পাদিত )](https://3502995838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-La_TEtDsP7G3fMoFiNl%2F-M7lJ3nJUQk5HRHNMMHX%2F-M7lKFNff7Oli60GgTCs%2Ffunctions.jpg?alt=media\&token=4289cb58-002f-42c1-8b68-8d35a1072c06)

উপরের ছবিতে আমরা বিভিন্ন ধরনের নন-লিনিয়ার ফাংশনের চেহারা দেখতে পাই, এখান থেকে খুব সহজেই বোঝা যায় এধরনের নন-লিনিয়ার রিলেশনশিপকে কখনোই লিনিয়ার ফাংশনের মাধ্যমে সঠিক ভাবে ব্যখ্যা করা সম্ভব নয়।&#x20;

**পলিনমিয়াল  রিগ্রেশনের কিছু বৈশিষ্ট্য**

* যেসকল ডেটাসেট লিনিয়ার মডেলে ভালোভাবে ফিট হয় না, পলিনমিয়াল মডেলের মাধ্যমে তাদেরকে বেশ ভালো করেই ফিট করা যায়।
* খুব সহজেই হাই অর্ডারের ফাংশনের মাধ্যমে মডেল তৈরি করা যায়
* ডেটায় আউটলেয়ার থাকলে মডেল প্রভাবিত হয়।
* পলিনমিয়াল অর্ডার খুব বেশী হলে মডেল ওভারফিট করতে পারে।

&#x20;**বাংলাদেশের জিএনপি'র পলিনমিয়াল রিগ্রেশন**

পলিনমিয়াল রিগ্রেশন বোঝার জন্য আমরা বাংলাদেশের জিএনপি'র ডেটাসেট ব্যবহার করবো। এই ডেটাসেটে ১৯৮০ থেকে ২০১৯ সাল পর্যন্ত বাংলাদেশের জনসংখ্যা ও জিএনপি'র  আকার বিলিয়ন টাকায়  দেয়া আছে।&#x20;

```
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn import metrics
from sklearn.metrics import r2_score

url='https://raw.githubusercontent.com/FazlyRabbiBD/Data-Science-Book/master/data-tax-gnp-bd.csv'
df = pd.read_csv(url)
df.head()
```

আমাদের ডেটাসেটটি দেখতে অনেকটা এরকম,

![](https://3502995838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-La_TEtDsP7G3fMoFiNl%2F-M7m0besFX_pcHIytZ0i%2F-M7m0pOhKkvagEMKkbyf%2Fimage.png?alt=media\&token=592093dd-15ca-4f8a-ae2b-759a23e0470b)

বাংলাদেশের জনসংখ্যা এবং জিএনপি'র আকারের সাথে আমরা যদি রিগ্রেশন প্লট আঁকি তাহলে আমরা দেখতে পাই জনসংখ্যা বৃদ্ধি এবং জিএনপি বৃদ্ধির হার অনেকটা এক্সপোনেনশিয়াল ফাংশনের মত। অপরদিকে লিনিয়ার রিগ্রেশন লাইন কোন ভাবেই এই রিলেশনশিপকে ফিট করতে পারে না। একারনেই আমাদের অবশ্যই কোন নন-লিনিয়ার ফাংশনের মাধ্যমে এই রিলেশনশিপেকে ফিট করবো।&#x20;

```
sns.regplot(x=df.POPULATION, y=df.GDP)
```

![](https://3502995838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-La_TEtDsP7G3fMoFiNl%2F-M7lJ3nJUQk5HRHNMMHX%2F-M7lkbkgACw6ogRazsTZ%2Fimage.png?alt=media\&token=f71cacf3-9b11-46bf-a83b-542e11dbf1ff)

আমরা ২ ডিগ্রী অর্ডারে পলিনমিয়াল ফাংশনের মাধ্যমে রিগ্রেশন লাইনকে আমাদের ডেটাসেটে ফিট করলে আমরা দেখতে পাই রিগ্রেশন লাইন আগের তুলনায় বক্র রৈখিক হয়েছে এবং ডেটা পয়েন্ট গুলোর সাথে আগের চেয়ে বেশী ফিট হয়েছে।&#x20;

```
sns.regplot(x=df.POPULATION, y=df.GDP, data=df, order=2)
```

![](https://3502995838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-La_TEtDsP7G3fMoFiNl%2F-M7lJ3nJUQk5HRHNMMHX%2F-M7lkkqVIu5T7MXH1qL9%2Fimage.png?alt=media\&token=7589df37-32f7-4efd-a919-aaafae6b3a2d)

এবার ৩ ডিগ্রি ডিগ্রী অর্ডার পলিনমিয়াল ফাংশন  ব্যবহার করলে আমরা দেখতে পাই রিগ্রেশন লাইন ডেটা পয়েন্ট গুলোর সাথে প্রায় পুরোপুরি ফিট হয়েছে। &#x20;

```
ax = sns.regplot(x=df.Year, y=df.Value, data=df, order=3)
```

![](https://3502995838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-La_TEtDsP7G3fMoFiNl%2F-M7lJ3nJUQk5HRHNMMHX%2F-M7lkvfNm-jo3MMKRcPw%2Fimage.png?alt=media\&token=1fa26435-a656-470c-ac64-d80c62f404ba)

সুতরাং আমরা বুঝতে পারলাম পলিনমিয়াল অর্ডার ৩ ব্যবহার করলে সেটা আমাদের ডেটার সাথে সবথেকে ভালোভাবে ফিট হবে। এবার ৩ ডিগ্রী অর্ডারে পলিনমিয়াল রিগ্রেশনের জন্য আমরা আমাদের ডেটাসেটকে ট্রান্সফরমেশন করে নেব,

```
x = df['POPULATION'].values.reshape(-1,1)
y = df['GDP'].values.reshape(-1,1)
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25, random_state=5)

from sklearn.preprocessing import PolynomialFeatures
pf = PolynomialFeatures(degree=3)
x_ = pf.fit_transform(x)
x_test_ = pf.fit_transform(x_test)
```

```
ax = sns.regplot(x=df.Year, y=df.Value, data=df, order=4)
```

পলিনমিয়াল রিগ্রেশনের জন্য আলাদা কোন ফাংশন নেই। ডেটাকে ট্রান্সফরমেশনের মাধ্যমে পলিনমিয়াল ফিচার সেট করে , লিনিয়ার ফাংশনের মাধ্যমেই পাইথনে পলিনমিয়াল রিগ্রেশন করা হয়।&#x20;

```
poly = LinearRegression()
poly.fit(x_, y)
poly.coef_
```

আমাদের মডেল এখন তৈরি। এবার অ্যাকুরেসি চেক করার পালা।&#x20;

```
predictions = poly.predict(x_test_)

print('Coefficients:', poly.coef_)
print('Intercept:', poly.intercept_)
print('MAE:', metrics.mean_absolute_error(y_test, predictions))
print('MSE:', metrics.mean_squared_error(y_test, predictions))
print('RMSE:', np.sqrt(metrics.mean_squared_error(y_test, predictions)))
accuracy = poly.score(x_test_,y_test)
print('AccuracyII:',accuracy*100,'%')
```

![](https://3502995838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-La_TEtDsP7G3fMoFiNl%2F-M7lJ3nJUQk5HRHNMMHX%2F-M7lo7qeGRzjAu9ohJFC%2Fimage.png?alt=media\&token=0b2b34f1-6098-45a9-b8c1-574fca549b21)

আমরা দেখতে পাচ্ছি আমাদের পলিনমিয়াল মডেল প্রায় ৯৯% নির্ভুল ভাবে প্রেডিকশন করতে পেরেছে।&#x20;

এবার এই মডেল দিয়ে প্রিডিকশনের পালা, মনে করুন আমাদের জনসংখ্যা ২০০ মিলিয়ন (২০ কোটি) হলে আমাদের জিএনপি'র আকার কত হবে ?

```
yhat= {'POPULATION':['200']}
yhatDf = pd.DataFrame(yhat)
yhatDfReshape=yhatDf['POPULATION'].values.reshape(-1,1)

polyFit = pf.fit_transform(yhatDfReshape)

poly.predict(polyFit)
```

array(\[\[32780.39276548]])&#x20;

অর্থাৎ বাংলাদেশের জনসংখ্যা ২০০ মিলিয়ন হলে তখন আমাদের জিএনপি'র  আকার হবে ৩২৭২৮০.৩৯ বিলিয়ন টাকা ।&#x20;

**লিনিয়ার রিগ্রেশনের সাথে পারফরম্যান্স তুলনা**&#x20;

আমরা যদি একই ডেটাসেট ব্যবহার করি লিনিয়ার রিগ্রেশন মডেল তৈরি করে তাহলে দেখতে পাবো লিনিয়ার মডেলের অ্যাকুরেসি মাত্র ৬৭% , সুতরাং এটা খুব সহজেই বোঝা যাচ্ছে নন-লিনিয়ার ডেটার ক্ষেত্রে পলিনমিয়াল মডেল কতখানি কার্যকর ।&#x20;

```
linreg = LinearRegression()
linreg.fit(x_train, y_train)

predictionsLN = linreg.predict(x_test)

print('Coefficients:', linreg.coef_)
print('Intercept:', linreg.intercept_)
print('MAE:', metrics.mean_absolute_error(y_test, predictionsLN))
print('MSE:', metrics.mean_squared_error(y_test, predictionsLN))
print('RMSE:', np.sqrt(metrics.mean_squared_error(y_test, predictionsLN)))
accuracy = linreg.score(x_test,y_test)
print('AccuracyII:',accuracy*100,'%')
```

![](https://3502995838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-La_TEtDsP7G3fMoFiNl%2F-M7lJ3nJUQk5HRHNMMHX%2F-M7lq4_-WU3wYQl2XAQ4%2Fimage.png?alt=media\&token=588241c9-d99d-4e07-bea4-5e6ba6e3042f)

![](https://3502995838-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-La_TEtDsP7G3fMoFiNl%2F-M9c17lNtJFIs7o9H4_q%2F-M9c5ZxJ-_9Is0rHx0Id%2Fimage.png?alt=media\&token=5fa30072-f29d-4e1e-bdda-ce9409d0d5f2)
