ماشین لرنینگ

دوره آموزش ماشین لرنینگ – قسمت هشتم

آموزش رگرسیون خطی چندگانه (چند متغیره)، مرحله به مرحله و با مثال

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

  • در ابتدا به مرور حل کردن مسایل رگرسیون خطی ساده (Simple Linear Regression) با استفاده از روش از روش “Ordinary Least Squares (OLS)” یا «کمترین مربعات معمولی» که در قسمت سوم از دوره آموزش ماشین لرنینگ آموزش داده شد، می پردازیم.
  • سپس رگرسیون خطی چندگانه (Multiple Linear Regression) را برای یک مثال پیش بینی قیمت خانه پیاده سازی می کنیم.
  • در ادامه با استفاده از کتابخانه sklearn رگرسیون خطی ساده و چند متغیره را بر روی دیتاست دیگری پیاده سازی می کنیم.
  • در پایان عملکرد رگرسیون خطی چندگانه را بدون استفاده از sklearn و با استفاده از آن مقایسه می کنیم.

یادآوری رگرسیون خطی ساده

جدول زیر را در نظر بگیرید. این جدول از دو ستون شامل مساحت و قیمت چند خانه تشکیل شده است.

مقالات تحقیقاتی برای رگرسیون خطی ساده
مقالات تحقیقاتی برای رگرسیون خطی ساده

در این جدول مقادیر متراژ خانه‌ ها به عنوان متغیرهای مستقل (X) درنظر گرفته می‌ شوند. در مقابل قیمت هرخانه نیز به عنوان یک متغیر وابسته (Y) شناخته می‌ شود.
چنانچه بین متغیرهای مستقل (dependent variable) و متغیرهای وابسته (independent variable) در یک مسئله، رابطه خطی وجود داشته باشد، می‌ توان از رگرسیون خطی استفاده کرد تا برای متغیرهای مستقل جدید، متغیرهای وابسته متناسب با آن‌ ها را پیش‌ بینی کرد.

اگر داده‌های جدول بالا را در قالب یک نمودار نشان دهیم، به تصویر زیر می رسیم.

رابطه خطی بین متغیرها
شکل شماره (1) رابطه خطی بین متغیرها

کد مربوط به این شکل، در کدهای گیت هاب مربوط به قسمت هشتم از دوره آموزش ماشین لرنینگ در دسترس است.

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

معادله خط را به خاطر دارید؟

حالت کلی معادله یک خط به صورت زیر است:

y = ax+b

در این معادله به a شیب خط (slop) و به b عرض از مبدا (intercept) می‌ گویند.
شیب خط مقدار زاویه خط با محور افقی و عرض از مبدا، فاصله نقطه شروع خط از محور y را مشخص می‌ کند.
مثلا :

y = 2x + 1

برای رسم این خط کافی است برای مقادیر مختلف x مقدار y را محاسبه کنیم و سپس نقاط را به هم وصل کنیم.

Y = (2 * -2) + 1= -3
Y = (2 * -1) + 1= -1
Y = (2 * 0) + 1= 1
Y = (2 * 1) + 1= 3
Y = (2 * 2) + 1= 5
Y = (2 * 3) + 1= 7

رگرسیون خطی ساده — مفهوم و محاسبات به زبان ساده
رگرسیون خطی ساده — مفهوم و محاسبات به زبان ساده

نمایش داده های بالا بر روی محورهای مختصات به صورت زیر است:

آموزش رگرسیون خطی ساده، مرحله به مرحله و با مثال
آموزش رگرسیون خطی ساده، مرحله به مرحله و با مثال

به مثال مربوط به قیمت خانه‌ها باز می گردیم.

رگرسیون خطی ساده و چندگانه چیست؟
رگرسیون خطی ساده و چندگانه چیست؟

آیا می‌ توانید معادله خط مربوط به این داده ها را به دست آورید و خطی را رسم کنید که با تمامی نقاط کمترین فاصله را داشته باشد؟ (به عبارتی دیگر، کمترین خطا را داشته باشد.)
با توجه به داده‌های مسئله، حتی به صورت چشمی نیز می‌توان خط صافی را رسم که دقیقا از روی تمامی نقاط عبور کند.

ر
ارزیابی خطای مدل رگرسیونی

نکته و یادآوری: (همانطور که در مباحث مربوط به ارزیابی خطای مدل توضیح داده شد، این حالت که خط رسم شده کمترین فاصله را از نقاط داشته باشد، بهترین حالت خط رگرسیون است.)
در قسمت از سوم دوره آموزش ماشین لرنینگ بخش ارزیابی مدل رگرسیون خطی ساده
در قسمت هفتم از دوره آموزش ماشین لرنینگ

معادله این خط رگرسیونی رسم شده نیز حالتی از y = ax+b است اما چگونه a و b را پیدا کنیم که بتوانیم برای xهای جدید نیز y آن ها را محاسبه کنیم؟

مثلا y را برای x=40 محاسبه کنیم که با توجه به مثال مورد بحث، می‌شود قیمت خانه‌ای با متراژ40 متر مربع.

برای حل این مثل از رگرسیون خطی ساده (Simple linear regression) استفاده می‌ کنیم.

چرا از پسوند “ساده” در این عبارت استفاده کرده‌ایم؟
به طور کلی اگر در محاسبه رگرسیون خطی، برای متغیر وابسته (y)، بیشتر از یک متغیر مستقل (x) را در نظر بگیریم، رگرسیون خطی ما از نوع چندگانه (Multiple Linear Regression) است. پس وقتی فقط یک نوع x ورودی داشته باشیم رگرسیون خطی ساده (Simple linear regression) خواهد بود.

رگرسیون خطی چندگانه (Multiple Linear Regression)
رگرسیون خطی چندگانه (Multiple Linear Regression)

فرمول کلی رگرسیون خطی ساده همان y = ax+b است که به طور معمول به جای a و b از θ0 (تتا صفر) و θ1 (تتا یک) استفاده می‌ کنیم.

y = θ0 + θ1 x

برای محاسبه θ0 و θ1 نیز به صورت زیر عمل می‌کنیم:

فرمول محاسبه تتا در رگرسیون خطی ساده
فرمول محاسبه تتا در رگرسیون خطی ساده

با محاسبه X̅ و Ȳ شروع می کنیم که به معنی میانگین داده های x و y است.

مقالات تحقیقاتی برای رگرسیون خطی ساده
مقالات تحقیقاتی برای رگرسیون خطی ساده

 

(10 + 15 + 20 + 25 + 30)/5 = 20
(500 + 750 + 1000 + 1250 + 1500)/5 = 1000

کد پیاده سازی این قسمت به صورت زیر است

 
Area = [10,15,20,25,30]
Price = [1,3,3,2,5]
input_size = len(Area)
x = Area
y = Price

def avg(avg_input):
      my_temp = 0
      for i in range (0, input_size):
            my_temp = my_temp + avg_input[i]
      return(my_temp/input_size)

avg_x = avg(x)
avg_y = avg(y)

print("Average of x: ", avg_x)
print("Average of y: ", avg_y)

خروجی کد بالا به این صورت است:

Average of x: 20.0
Average of y: 2.8

در ادامه مطابق فرمول θ1 هر مقدار از x و y را از میانگین آن کم می کنیم.

فرمول محاسبه تتا یک در رگرسیون خطی ساده
فرمول محاسبه تتا یک در رگرسیون خطی ساده
کلیات رگرسیون خطی ساده (فرمولها)
کلیات رگرسیون خطی ساده (فرمولها)

حالا که θ1 به دست آمده θ0 را به صورت زیر محاسبه می کنیم.

فرمول محاسبه تتا صفر در رگرسیون خطی
فرمول محاسبه تتا صفر در رگرسیون خطی

 

پس با توجه به مقادیر بالا، معادله خط مورد نظر به صورت زیر به دست می‌آید:

y = θ0 + θ1 x
y = 0 + 50 x

یعنی تابع yما در این مثال هر x ورودی را در 50 ضرب می‌کند و به خروجی می‌دهد.

ارزیابی خطای مدل رگرسیونی
ارزیابی خطای مدل رگرسیونی
 
### --- بخش مربوط به محاسبه میانگین --- start

Area = [10,15,20,25,30]
Price = [500,750,1000,1250,1500]

input_size = len(Area)
x = Area
y = Price

def avg(avg_input):
     my_temp = 0
     for i in range (0, input_size):
          my_temp = my_temp + avg_input[i]
     return(my_temp/input_size)

avg_x = avg(x)
avg_y = avg(y)
print("Average of x: ", avg_x)
print("Average of y: ", avg_y)

### --- بخش مربوط به محاسبه میانگین --- end


### --- بخش مربوط به محاسبه تتا1 و تتا2 --- start

def teta1():
     teta1_numerator = 0
     teta1_denumerator = 0
     for i in range (0, input_size):
          teta1_numerator = teta1_numerator + ((x[i] - avg_x)*(y[i] - avg_y))
          teta1_denumerator = teta1_denumerator + ((x[i] - avg_x)**2)
     return(teta1_numerator/teta1_denumerator)

print("θ₁ = ", teta1())

teta0 = avg_y - (teta1() * avg_x)
print("θ₀ = ", avg_y , "-" , "(" , teta1() , "*" , avg_x , ") =" , teta0)

### --- بخش مربوط به محاسبه تتا0 و تتا1 --- end

خروجی کد بالا به این صورت است:

Average of x: 20.0
Average of y: 1000.0
θ₁ = 50.0
θ₀ = 1000.0 – ( 50.0 * 20.0 ) = 0.0

حالا می‌توانیم به راحتی قیمت یک خانه 40 متری نیز محاسبه کنیم.

y = θ0 + θ1 x

X = 40
y = 0 + 50 x
y = 0 + (50* 40) = 2000

قیمت پیش‌بینی شده برای x=40، کاملا روی خط رگرسیونی است که آن را محاسبه کرده‌ایم.

 خط رگرسیونی
خط رگرسیونی

خب، در مثالی که مطرح شد نقاط کاملا روی یک خط مستقیم قرار می‌گیرند، اما آیا همیشه چیدمان نقاط به همین شکل است؟
جواب: خیییییییر 🙂

به مثال زیر دقت کنید:

مثال قیمت خانه در رگرسیون خطی
مثال قیمت خانه در رگرسیون خطی

در این جدول نیز همانند مثال قبلی، مقادیر متراژ خانه‌ها به عنوان متغیرهای مستقل (X) و قیمت هرخانه نیز به عنوان یک متغیر وابسته (Y) شناخته می‌شود. اگر داده‌های جدول بالا را در قالب یک نمودار نشان دهیم:

مثال رگرسیون خطی
مثال رگرسیون خطی

 

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

در ادامه چند خط رگرسیون فرضی را رسم می‌کنیم. آیا می‌توانید با اطمینان 100% بگویید که یکی از این خط ها بهترین خط ممکن است؟

جزوه رگرسیون
جزوه رگرسیون

راه حل سادست، همون مقادیر θ0 و θ1 را محاسبه کنید تا به جواب‌های ممکن برسید.

تا این بخش مباحث مربوط به رگرسیون خطی ساده را مرور کردیم که در قسمت سوم از دوره آموزش ماشین لرنینگ آموزش داده شده بودند. اما برسیم به مبحث اصلی این مطلب یعنی:

موضوع اصلی قسمت هشتم از دوره آموزش ماشین لرنینگ یعنی رگرسیون خطی چندگانه (Multiple Linear Regression)

آموزش رگرسیون خطی چندگانه(Multiple Linear Regression)، مرحله به مرحله و با مثال

در مثال متراژ و قیمت‌ خانه‌ها اگر به جای یک متغیر مستقل X بیشتر از یک متغیر مستقل داشته باشیم، چه می‌شود؟ مثلا قیمت خانه‌ها برگرفته از متراژ و سال ساخت باشد. یا مثلا قیمت یک اتومبیل بر اساس قدرت آن و کیلومتر طی شده محاسبه شود.

اگر کدهای مربوط به پیش بینی قیمت خانه با استفاده از sklearn را که در قسمت دوم دوره آموزش ماشین لرنینگ و همینطور قسمت های بعدی از آن استفاده کردیم. ما چندین ویژگی خانه ها را از دیتاست به عنوان ورودی به مدل انتخاب می کردیم.

feature_columns = [‘LotArea’, ‘YearBuilt’, ‘1stFlrSF’, ‘2ndFlrSF’, ‘FullBath’, ‘BedroomAbvGr’, ‘TotRmsAbvGrd’]

بدین ترتیب در این مثال ها ما از رگرسیون خطی چند متغیره استفاده می کرده ایم.

رگرسیون خطی ساده و چندگانه چیست؟

به طور کلی اگر در محاسبه رگرسیون خطی، برای متغیر وابسته (y)، بیشتر از یک متغیر مستقل (x) را در نظر بگیریم، رگرسیون خطی ما از نوع چندگانه (Multiple Linear Regression) است.
متوجه تفاوت رگرسیون خطی ساده (Simple Linear Regression) و رگرسیون خطی چندگانه (Multiple Linear Regression) شدید؟

رگرسیون خطی چندگانه (Multiple Linear Regression)
رگرسیون خطی چندگانه (Multiple Linear Regression)

خب، بریم سراغ یک مثال از رگرسیون خطی چندگانه (یا چندمتغیره) و حل این مثال به صورت مرحله به مرحله.

رگرسیون خطی چندگانه (Multiple Linear Regression) چیست
رگرسیون خطی چندگانه (Multiple Linear Regression) چیست

 

  • در این مثال مقادیر X1، تنها برای سادگی به صورت 1 و 2 و 3 و 4 در نظر گرفته شده‌اند و ارتباطی با شماره ردیف و … ندارد.
  • دقت کنید که در برخی از منابع آموزشی، ممکن است اعدادی به صورت کوچک، بالا و سمت راست X‌ها نوشته شوند، این اعداد توان X‌ها نیستند، بلکه ایندکس آن متغیر مستقل هستند.

همچنین اعداد کوچکی نیز پایین سمت راست‌ Xها نوشته می‌شوند که به معنی ایندکس ردیف مورد نظر از جدول کلی اطلاعات هستند، مثلا با توجه به اطلاعات مثال ارایه شده:

آموزش رگرسیون خطی چندگانه، مرحله به مرحله و با مثال
آموزش رگرسیون خطی چندگانه، مرحله به مرحله و با مثال

البته در این مطلب آموزشی ما ایندکس متغیر مستقل (اینکه متغیر چندم ما است) را پایین سمت راست می‌نویسم، و اعداد در جایگاه توان به معنی توان هستند.

معادله کلی خط در حالت رگرسیون خطی چندگانه با توجه به اینکه تعداد Xها بیشتر از یک است، به صورت زیر محاسبه می‌شود:

فرمول رگرسیون خطی چندگانه
فرمول رگرسیون خطی چندگانه

در صورتی که از معادله بالا مشتق جزئی نسبت به متغیرها بگیریم، به معادلات زیر می‌رسیم:

معادله رگرسیون خطی چندگانه
معادله رگرسیون خطی چندگانه

برای حل این معادلات به غیر از مقادیر θ1، θ0 و θ2 می‌ توانیم سایر مقادیر را با توجه به داده‌های ارایه شده در صورت مسئله محاسبه کنیم.
منظور از m نیز، تعداد ردیف‌های جدول اطلاعات است؛ در این مثل m=4

آشنایی با رگرسیون خطی چندگانه و استفاده از آن
آشنایی با رگرسیون خطی چندگانه و استفاده از آن

برای محاسبه این عبارات می توانید از کد زیر استفاده نمایید.

 
x1 = [1,2,3,4]
x2 = [10,1,2,3]
y = [12,18,24,30]

input_size = len(x1)

def paramcalc(x1,x2,y):
     x1y = []
     x2y = []
     x1x2 = []
     x1power2 = []
     x2power2 = []

     sum_x1 = 0
     sum_x2 = 0
     sum_y = 0
     sum_x1y = 0
     sum_x2y = 0
     sum_x1x2 = 0
     sum_x1power2 = 0
     sum_x2power2 = 0
     
     for i in range(0, input_size):
          x1y.append(x1[i]*y[i])
          x2y.append(x2[i]*y[i])
          x1x2.append(x1[i]*x2[i])
          x1power2.append(x1[i]**2)
          x2power2.append(x2[i]**2)

     for i in range(0, input_size):
          sum_x1 = sum_x1 + x1[i]
          sum_x2 = sum_x2 + x2[i]
          sum_y =  sum_y + y[i]
          sum_x1y = sum_x1y + x1y[i]
          sum_x2y = sum_x2y + x2y[i]
          sum_x1x2 = sum_x1x2 + x1x2[i]
          sum_x1power2 = sum_x1power2 + x1power2[i]
          sum_x2power2 = sum_x2power2 + x2power2[i]

     print("x1y = ",x1y , "sum_x1y = ",sum_x1y)
     print("x2y = ",x2y , "sum_x2y = ",sum_x2y)
     print("x1x2 = ",x1x2 ,"sum_x1x2 = ",sum_x1x2)
     print("x1power2 = ",x1power2 , "sum_x1power2 = ",sum_x1power2)
     print("x2power2 = ",x2power2 , "sum_x2power2 = ",sum_x2power2)

     print("sum_x1 = ", sum_x1)
     print("sum_x2 = ", sum_x2)
     print("sum_y = ", sum_y)

paramcalc(x1,x2,y)

خروجی کد بالا به این صورت است:

x1y = [12, 36, 72, 120] sum_x1y = 240
x2y = [120, 18, 48, 90] sum_x2y = 276
x1x2 = [10, 2, 6, 12] sum_x1x2 = 30
x1power2 = [1, 4, 9, 16] sum_x1power2 = 30
x2power2 = [100, 1, 4, 9] sum_x2power2 = 114
sum_x1 = 10
sum_x2 = 16
sum_y = 84

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

انجام رگرسیون خطی چنذگانه
انجام رگرسیون خطی چنذگانه

با مرتب‌ کردن عبارت بالا به معادلات زیر می رسیم

تحلیل رگرسیون خطی چندگانه
تحلیل رگرسیون خطی چندگانه

در این مرحله سه معادله و سه مجهول داریم. برای حل کردن این مسئله می‌ توانیم از دو روش حذف متغیر یا روش کرامر (Cramer rule) استفاده کنیم.
از آنجاییکه طبق تجربه پیاده‌سازی روش کرامر، در یک برنامه کامپیوتری، اغلب راحت‌ تر و قابل‌ فهم‌ تر هست از روش کرامر برای حل این معادلات استفاده می کنیم.

طبق روش کرامر، ما می‌توانیم سه متغیر مورد نظرمان را به صورت زیر محاسبه کنیم:

استفاده از روش کرامر در رگرسیون چند متغیره
استفاده از روش کرامر در رگرسیون چند متغیره

صورت و مخرج کسرها در تصویر بالا به معنی دترمینان آن ماتریس هستند.

برای مثالی که مشغول حل کردن آن هستیم، مقادیر به صورت زیر جایگذاری می‌شوند:

آموزش تحلیل رگرسیون خطی چندگانه
آموزش تحلیل رگرسیون خطی چندگانه

یادآوری دترمینان (Determinant)

برای محاسبه دترمینان یک ماتریس 3*3 به صورت زیر عمل می‌کنیم:

آموزش حل دترمینان ماتریس
آموزش حل دترمینان ماتریس

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

آموزش رگرسیون خطی چندگانه و نحوه انجام آن
آموزش رگرسیون خطی چندگانه و نحوه انجام آن

با جایگزاری θ1، θ0 و θ2 در فرمول زیر خواهیم داشت:

فرمول رگرسیون خطی چندگانه
فرمول رگرسیون خطی چندگانه

که می شود:

این معادله خط رگرسیون در مثال مورد بحث است. برای محاسبه مقادیر جدید نیز تنها کافی است ورودی x را در معادله جایگزین کنیم تا y متناسب با آن به دست بیاید.

کد پیاده سازی این قسمت به صورت زیر است (کدهای بخش قبلی نیز برای ایجاد پیوستگی در کدهای نوشته، مجدد گپی شده اند.)

 
### --- تکرار بخش مربوط به محاسبه متغیرهای معادله در رگرسیون خطی چندگانه--- start

def paramcalc(x1,x2,y,input_x1,input_x2):
     x1y = []
     x2y = []
     x1x2 = []
     x1power2 = []
     x2power2 = []

     sum_x1 = 0 
     sum_x2 = 0
     sum_y = 0
     sum_x1y = 0
     sum_x2y = 0
     sum_x1x2 = 0
     sum_x1power2 = 0
     sum_x2power2 = 0

     for i in range(0, input_size):
          x1y.append(x1[i]*y[i])
          x2y.append(x2[i]*y[i])
          x1x2.append(x1[i]*x2[i])
          x1power2.append(x1[i]**2)
          x2power2.append(x2[i]**2)

     for i in range(0, input_size):
          sum_x1 = sum_x1 + x1[i]
          sum_x2 = sum_x2 + x2[i]
          sum_y =  sum_y + y[i]
          sum_x1y = sum_x1y + x1y[i]
          sum_x2y = sum_x2y + x2y[i]
          sum_x1x2 = sum_x1x2 + x1x2[i]
          sum_x1power2 = sum_x1power2 + x1power2[i]
          sum_x2power2 = sum_x2power2 + x2power2[i]

     print("x1y = ",x1y , "sum_x1y = ",sum_x1y)
     print("x2y = ",x2y , "sum_x2y = ",sum_x2y)
     print("x1x2 = ",x1x2 ,"sum_x1x2 = ",sum_x1x2)
     print("x1power2 = ",x1power2 , "sum_x1power2 = ",sum_x1power2)
     print("x2power2 = ",x2power2 , "sum_x2power2 = ",sum_x2power2)

     print("sum_x1", sum_x1)
     print("sum_x2", sum_x2)
     print("sum_y", sum_y)

### --- تکرار کدهای بخش مربوط به محاسبه متغیرهای معادله در رگرسیون خطی چندگانه--- end

### --- بخش مربوط به محاسبه تتا0، تتا1 و تتا2 در رگرسیون خطی چندگانه--- start

     orginal_m = [[input_size,sum_x1,sum_x2],
                          [sum_x1,sum_x1power2,sum_x1x2],
                          [sum_x2,sum_x1x2,sum_x2power2]
                         ]
     teta0_numerator = [[sum_y,sum_x1,sum_x2],
                                     [sum_x1y,sum_x1power2,sum_x1x2],
                                     [sum_x2y,sum_x1x2,sum_x2power2]
                                    ]
     teta1_numerator = [[input_size,sum_y,sum_x2],
                                     [sum_x1,sum_x1y,sum_x1x2],
                                     [sum_x2,sum_x2y,sum_x2power2]
                                    ]
     teta2_numerator = [[input_size,sum_x1,sum_y],
                                     [sum_x1,sum_x1power2,sum_x1y],
                                     [sum_x2,sum_x1x2,sum_x2y]
                                    ]

     teta0 = det(teta0_numerator)/det(orginal_m)
     teta1 = det(teta1_numerator)/det(orginal_m)
     teta2 = det(teta2_numerator)/det(orginal_m)

     print("\nθ₀ = " , teta0)
     print("θ₁ = " , teta1)
     print("θ₂ = " , teta2)

     predicted_value = teta0 + (teta1 * input_x1) +  (teta2 * input_x2) 
     print("predicted value for x1=",input_x1, "and x2=",input_x2,"=", predicted_value)


def det(m):
     det_result = (m[0][0] * ((m[1][1] * m[2][2]) - (m[1][2] * m[2][1]))) -(m[0][1] * ((m[1][0] * m[2][2]) - (m[1][2] * m[2][0]))) +(m[0][2] * ((m[1][0] * m[2][1]) - (m[1][1] * m[2][0])))
     return (det_result)


x1 = [1,2,3,4]
x2 = [10,1,2,3]
y = [12,18,24,30]
input_size = len(x1)
input_x1 = 0
input_x2 = 0

paramcalc(x1,x2,y,input_x1,input_x2)

### --- بخش مربوط به محاسبه تتا0، تتا1 و تتا2 در رگرسیون خطی چندگانه--- end

خروجی کد بالا به این صورت است:

x1y = [12, 36, 72, 120] sum_x1y = 240
x2y = [120, 18, 48, 90] sum_x2y = 276
x1x2 = [10, 2, 6, 12] sum_x1x2 = 30
x1power2 = [1, 4, 9, 16] sum_x1power2 = 30
x2power2 = [100, 1, 4, 9] sum_x2power2 = 114
sum_x1 10
sum_x2 16
sum_y 84

θ₀= 6.0
θ₁ = 6.0
θ₂ = 0.0
predicted value for x1= 0 and x2= 0 = 6.0

پیاده سازی رگرسیون خطی ساده و چند متغیره با استفاده از sklearn

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

دیتاست زیر به عنوان dataset.csv برای این مثال ها در نظر گرفته شده است. این فایل از لینک گیت هاب معرفی شده در پایان مطلب قابل دانلود است.

پیاده سازی رگرسیون خطی ساده و چند متغیره با استفاده از sklearn
پیاده سازی رگرسیون خطی ساده و چند متغیره با استفاده از sklearn

ستون اول شناسه کاربران است که در این مطلب از آن ها استفاده ای نمی کنیم. ستون دوم با نام “Hours” تعداد ساعت مطالعه، ستون سوم با نام “Amount” تعداد تمرین های انجام شده و ستون آخر با نام “Grade” هم نمره کسب شده کاربر است.

پیاده سازی رگرسیون خطی ساده

ابتدا رگرسیون خطی ساده (Simple linear regression) را برای این داده ها با استفاده از sklearn پیاده سازی می کنیم.

 
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
import pandas as pd

file_path = 'dataset.csv'

df = pd.read_csv(file_path)

y = df.Grade
features = ['Hours']
X = df[features]

train_X, val_X, train_y, val_y = train_test_split(X, y, random_state=1)

dt_model = LinearRegression()
dt_model.fit(train_X, train_y)


val_predictions = dt_model.predict(val_X)

print("Orginal values: \n",val_y)

print("\nPredicted values:", val_predictions)

print("\ny = θ₀ + θ₁X₁")
print("θ₀ =",dt_model.intercept_)
print("θ₁ =",dt_model.coef_)

همانطور که مشاهده می شود فقط مقادیر ستون “Hours” را به عنوان ورودی مدل در نظر گرفته ایم.
نتیجه اجرای این کدها به صورت زیر است:

Orginal values:
2 11.0
9 52.0
6 37.0
Name: Grade, dtype: float64

Predicted values: [12.69660678 65.36019438 32.14892292]

y = θ₀ + θ₁X₁
θ₀ = 6.054352490743856
θ₁ = [2.37223368]

پیاده سازی رگرسیون چندگانه

برای پیاده سازی رگرسیون خطی چندگانه (Multiple linear regression) علاوه بر ویژگی “Hours” مقادیر ستون سوم با نام “Amount” را نیر به مدل ارایه می کنیم.

 
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
import pandas as pd

file_path = 'dataset.csv'

df = pd.read_csv(file_path)

y = df.Grade
features = ['Hours','Amount']
X = df[features]

train_X, val_X, train_y, val_y = train_test_split(X, y, random_state=1)

dt_model = LinearRegression()
dt_model.fit(train_X, train_y)


val_predictions = dt_model.predict(val_X)

print("Orginal values: \n",val_y)

print("\nPredicted values:", val_predictions)

print("\ny = θ₀ + θ₁X₁ + θ₂X₂")
print("θ₀ =",dt_model.intercept_)
print("θ₁ =",dt_model.coef_[0])
print("θ₂ =",dt_model.coef_[1])

نتیجه اجرای این کدها به صورت زیر است:

Orginal values:
2 11.0
9 52.0
6 37.0
Name: Grade, dtype: float64

Predicted values: [13.17068114 57.13643236 35.74845671]

y = θ₀ + θ₁X₁ + θ₂X₂
θ₀ = -1.86162412661065
θ₁ = 0.5674705690643309
θ₂ = 4.481129225853119

اگر نتایج کسب شده را به صورت جدول ارایه دهیم، خواهیم داشت:

نتیجه اجرای کد رگرسیون خطی چندمتغیره با sklearn
نتیجه اجرای کد رگرسیون خطی چندمتغیره با sklearn

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

با توجه به اینکه مطابق train_test_split سه ردیف از 10 ردیف داده های دیتاست، برای ارزیابی انتخاب شده اند و آموزش مدل تنها بر روی 7 ردیف انجام شده است. ما هم سه ردیف انتخاب شده برای test را حذف می کنیم و محاسبات را با توجه به همان 7 ردیف مجموعه train انجام می دهیم.

پس به این ترتیب داده های ورودی عبارتند از:

x1 = [2,2.2,4,7,8,12,21]

x2 = [1,2,4,5,6,8,9]

y = [7,8,15,22,29,45.7,49]

و داده های ارزیابی عملکرد نیز به صورت است:

x1_list= [2.8,25,11]

x2_list = [3,10,7]

Train و Test در رگرسیون خطی
Train و Test در رگرسیون خطی
 
### --- بخش مربوط به محاسبه متغیرهای معادله در رگرسیون خطی چندگانه --- start
 
def paramcalc(x1,x2,y,input_x1,input_x2):
     x1y = []
     x2y = []
     x1x2 = []
     x1power2 = []
     x2power2 = []
 
     sum_x1 = 0 
     sum_x2 = 0
     sum_y = 0
     sum_x1y = 0
     sum_x2y = 0
     sum_x1x2 = 0
     sum_x1power2 = 0
     sum_x2power2 = 0
 
     for i in range(0, input_size):
          x1y.append(x1[i]*y[i])
          x2y.append(x2[i]*y[i])
          x1x2.append(x1[i]*x2[i])
          x1power2.append(x1[i]**2)
          x2power2.append(x2[i]**2)
 
     for i in range(0, input_size):
          sum_x1 = sum_x1 + x1[i]
          sum_x2 = sum_x2 + x2[i]
          sum_y =  sum_y + y[i]
          sum_x1y = sum_x1y + x1y[i]
          sum_x2y = sum_x2y + x2y[i]
          sum_x1x2 = sum_x1x2 + x1x2[i]
          sum_x1power2 = sum_x1power2 + x1power2[i]
          sum_x2power2 = sum_x2power2 + x2power2[i]

### --- کدهای بخش مربوط به محاسبه متغیرهای معادله در رگرسیون خطی چندگانه --- end
 
### --- بخش مربوط به محاسبه تتا1، تتا2 و تتا3 در رگرسیون خطی چندگانه --- start
 
     orginal_m = [[input_size,sum_x1,sum_x2],
                          [sum_x1,sum_x1power2,sum_x1x2],
                          [sum_x2,sum_x1x2,sum_x2power2]
                         ]
     teta0_numerator = [[sum_y,sum_x1,sum_x2],
                                     [sum_x1y,sum_x1power2,sum_x1x2],
                                     [sum_x2y,sum_x1x2,sum_x2power2]
                                    ]
     teta1_numerator = [[input_size,sum_y,sum_x2],
                                     [sum_x1,sum_x1y,sum_x1x2],
                                     [sum_x2,sum_x2y,sum_x2power2]
                                    ]
     teta2_numerator = [[input_size,sum_x1,sum_y],
                                     [sum_x1,sum_x1power2,sum_x1y],
                                     [sum_x2,sum_x1x2,sum_x2y]
                                    ]
 
     teta0 = det(teta0_numerator)/det(orginal_m)
     teta1 = det(teta1_numerator)/det(orginal_m)
     teta2 = det(teta2_numerator)/det(orginal_m)
 
     print("\nθ₀ = " , teta0)
     print("θ₁ = " , teta1)
     print("θ₂ = " , teta2)
     print("y = θ₀ + θ₁X₁ + θ₂X₂")
     temp_print = teta0 + (teta1*input_x1) + (teta2*input_x2)
     print("y = ",teta0,"+(",teta1,"*",input_x1,")+(",teta2,"*",input_x2,")=",temp_print)
 
     predicted_value = teta0 + (teta1 * input_x1) +  (teta2 * input_x2) 
     print("predicted value for x1=",input_x1, "and x2=",input_x2,"=", predicted_value)
 
 
def det(m):
     det_result = (m[0][0] * ((m[1][1] * m[2][2]) - (m[1][2] * m[2][1]))) -(m[0][1] * ((m[1][0] * m[2][2]) - (m[1][2] * m[2][0]))) +(m[0][2] * ((m[1][0] * m[2][1]) - (m[1][1] * m[2][0])))
     return (det_result)
 
 
x1 = [2,2.2,4,7,8,12,21]
x2 = [1,2,4,5,6,8,9]
y = [7,8,15,22,29,45.7,49]
input_size = len(x1)


x1_list= [2.8,25,11]
x2_list = [3,10,7]
for i in range(0,3):
    paramcalc(x1,x2,y,x1_list[i],x2_list[i])
 
### --- بخش مربوط به محاسبه تتا1، تتا2 و تتا3 در رگرسیون خطی چندگانه --- end

نتیجه اجرای کد بالا به این صورت است:

پیاده سازی رگرسیون خطی چندگانه با پایتون
پیاده سازی رگرسیون خطی چندگانه با پایتون

مقایسه نتایج رگرسیون چندگانه با استفاده از sklearn و بدون استفاده از آن

نتایج کسب شده در این مثال با استفاده از sklearn و بدون استفاده از آن به صورت زیر است:

مقایسه نتایج رگرسیون خطی چندگانه با استفاده از sklearn و بدون استفاده از آن
مقایسه نتایج رگرسیون خطی چندگانه با استفاده از sklearn و بدون استفاده از آن

از لحاظ پارامترهای معادله خط نیز مقادیر θ₀، θ₁ و θ₂ به صورت زیر است:

مقایسه پارامترهای معادله خط ومقادیر θ₀، θ₁ و θ₂
مقایسه پارامترهای معادله خط ومقادیر θ₀، θ₁ و θ₂

فایل های مرتبط:

تمام کدهای مربوط به این قسمت از لینک زیر قابل دسترس هستند:

https://github.com/alifallahi/MachineLearning_Warmup/tree/master/Session8-multiple_linear_regression

علی فلاحی

علاقه مند به ماشین لرنینگ و ریکامندر سیستم.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *


The reCAPTCHA verification period has expired. Please reload the page.

دکمه بازگشت به بالا