رگرسیون خطی یا Linear regression یک روش خطی برای مدل کردن رابطه بین متغیر وابسته (متغیر هدف) و یک (رگرسیون ساده) یا چندتا (رگرسیون چندگانه) متغیر مستقل است.
پایتون کتابخانه های مختلفی دارد که به ما امکان می دهد مجموعه ای از داده ها را ترسیم کنیم و رابطه بین متغیرها را تحلیل کنیم. در صورت مشاهده یک روند خطی در داده ها، می توانیم خطی را که بیانگر روند داده های ماست، محاسبه کنیم و با استفاده از این خط پیش بینی هایی انجام دهیم. علاوه بر این ، می توانیم با استفاده از ضریب همبستگی (correlation coefficients)، قدرت رابطه بین دو متغیر و همچنین با استفاده از میانگین خطای مربع (mean square error)، کیفیت مدل رگرسیون را اندازه گیری کنیم. بیایید شروع کنیم
معرفی و تحلیل dataset مورد استفاده
مجموعه داده (dataset) مورد استفاده در این مقاله از وبسایت Kaggle گرفته شده است. Kaggle یک جامعه آنلاین از متخصصین تحلیل داده و یادگیری ماشین است که در آن می توان طیف گسترده ای از مجموعه داده ها را یافت. مجموعه داده ای که انتخاب کرده ایم، شامل قد و وزن ۵۰۰۰ مرد و ۵۰۰۰ زن است و در لینک های زیر قابل دسترس است:
- از وبسایت Kaggle
https://www.kaggle.com/mustafaali96/weight-height/version/1 - دانلود مستقیم (۱۶۷ کیلوبایت)
weight-height
اولین قدم خواندن و وارد کردن داده ها با استفاده از Pandas است. Pandas یک کتابخانه منبع باز پایتون برای علوم داده است که به ما امکان می دهد به راحتی با داده های ساخت یافته (دارای ساختار مشخص) مانند فایل های CSV ، جداول SQL یا اکسل کار کنیم.
پس از خواندن فایل csv ، می توانیم با کدهای زیر، پنج ردیف اول مجموعه داده خود ، نوع داده های هر ستون و همچنین تعداد مقادیر تهی را چاپ کنیم.
import pandas as pd # Read the csv file. df=pd.read_csv('weight-height.csv') # Print the first 5 rows of the data set. df.head()
# Shape of the dataframe. df.shape # Data type of each column. df.dtypes # Number of null values. df.info()
# Number of unique values of column Gender df.Gender.nunique() # 2 # Unique values of column Gender df.Gender.unique() # array(['Male', 'Female'], dtype=object)
همانطور که می توانیم به راحتی مشاهده کنیم ، dataframe شامل سه ستون: جنسیت ، قد و وزن است. ستون جنسیت شامل دو مقدار منحصر به فرد است: مرد یا زن. از نوع داده float هم در ستون های قد و وزن استفاده شده است. از آنجا که dataframe حاوی مقادیر تهی نیست و نوع داده ها برای زبان پایتون استاندارد و شناخته شده هستند ، بنابراین نیازی به تمیز کردن داده ها نیست.
رسم نمودارهای هیستوگرام و پراکندگی داده ها
برای درک بهتر توزیع مقادیر قد و وزن ، می توانیم به سادگی هر دو مجموعه مقادیر را با استفاده از هیستوگرام (histogram) ترسیم کنیم. هیستوگرام ها نمودار هایی هستند که توزیع یک متغیر عددی را نشان می دهد و داده ها را در بازه یا گروه هایی دسته بندی می کند. ارتفاع هر نوار (مستطیل) نشان دهنده تعداد مشاهدات در بازه یا گروه است.
import matplotlib.pyplot as plt plt.style.use('ggplot') # Histogram of the height df.Height.plot(kind='hist',color='purple',edgecolor='black',figsize=(10,7)) plt.title('Distribution of Height', size=24) plt.xlabel('Height (inches)', size=18) plt.ylabel('Frequency', size=18) # Histogram of the weight df.Weight.plot(kind='hist',color='purple',edgecolor='black',figsize=(10,7)) plt.title('Distribution of Weight', size=24) plt.xlabel('Weight (pounds)', size=18) plt.ylabel('Frequency', size=18);
نمودارهای قبلی نشان می دهد که هر دو متغیر قد و وزن توزیع طبیعی دارند. همچنین به عنوان بخشی از تجزیه و تحلیل آموزشی ما، ترسیم توزیع به صورت جداگانه برای زن و مرد می تواند جداگانه جالب باشد (برای هر دو مجموعه قد و وزن).
# Histogram of the height males and females df[df['Gender']=='Male'].Height.plot(kind='hist',color='blue',edgecolor='black',alpha=0.5,figsize=(10,7)) df[df['Gender']=='Female'].Height.plot(kind='hist',color='magenta',edgecolor='black',alpha=0.5,figsize=(10,7)) plt.legend(labels=['Males','Females']) plt.title('Distribution of Height', size=24) plt.xlabel('Height (inches)', size=18) plt.ylabel('Frequency', size=18);
# Histogram of the weight males and females df[df['Gender']=='Male'].Weight.plot(kind='hist',color='blue',edgecolor='black',alpha=0.5,figsize=(10,7)) df[df['Gender']=='Female'].Weight.plot(kind='hist',color='magenta',edgecolor='black',alpha=0.5,figsize=(10,7)) plt.legend(labels=['Males','Females']) plt.title('Distribution of Weight', size=24) plt.xlabel('Weight (pounds)', size=18) plt.ylabel('Frequency', size=18);
همانطور که گفتیم نمودارهای قبلی نشان می دهد که هم مقادیر وزن و هم مقادیر قد برای مردان و زنان توزیع نرمال دارد. اگرچه میانگین هر دو توزیع قد و وزن برای مردها بزرگتر است ، اما پراکندگی توزیع ها برای هر دو جنسیت مشابه است. Pandas متدی بنام
()describeرا ارائه می کند که باعث می شود بتوانیم مقادیر توصیف آماری از یک مجموعه داده (تمایل مرکزی ، پراکندگی و شکل) را تولید کنیم.
به کد زیر و نتیجه اجرای آن دقت کنید:
# Descriptive statistics male statistics_male = df[df['Gender']=='Male'].describe() statistics_male.rename(columns=lambda x:x+'_male',inplace=True) # Descriptive statistics female statistics_female = df[df['Gender']=='Female'].describe() statistics_female.rename(columns=lambda x:x+'_female',inplace=True) # Dataframe that contains statistics for both male and female statistics = pd.concat([statistics_male,statistics_female], axis=1) statistics
تجزیه و تحلیل داده اکتشافی شامل تحلیل ویژگی های اصلی یک مجموعه داده است که معمولاً از طریق دو روش نمایش داده ها و ایجاد خلاصه های آماری انجام می شود.
هدف این است که داده ها را درک کنیم ، الگوها و ناهنجاری ها (anomaly) را کشف کنیم و پیش از انجام ارزیابی های بیشتر ، فرض های خودمان را بررسی کنیم.
پس از انجام تحلیل اکتشافی ، می توان نتیجه گرفت که قد و وزن به طور طبیعی توزیع می شوند. توزیع مردان مقادیر میانگین بیشتری را نشان می دهد ، اما پراکندگی توزیع ها آن ها با توزیع های قد و وزن زنان مشابه است.
اما شاید در این مرحله از خود بپرسید: آیا بین قد و وزن رابطه وجود دارد؟ آیا می توانم از قد یک شخص برای پیش بینی وزن خود استفاده کنم؟
پاسخ هر دو سوال مثبت است! بیایید ادامه دهیم.
نمودارهای پراکندگی با Matplotlib و رگرسیون خطی با Numpy
یک نمودار پراکندگی، نمایش و تجسم دوبعدی داده هاست که توزیع داده های نمونه نسبت به دو متغیر عددی (مثلاً قد و وزن) را نشان می دهد (یک متغیر در امتداد محور x و دیگری ترسیم شده در امتداد محور y). کتابخانه Matplotlib یک کتابخانه پایتون برای رسم نمودارهای ۲D است که شامل یک تابع تعریف شده برای ایجاد نمودارهای پراکندگی است. تابع مذکور
()matplotlib.pyplot.scatterاست.
نمودار زیر رابطه بین قد و وزن را برای مردان و زنان نشان می دهد. این نمودار، شامل ۱۰۰۰۰ نمونه است به همین دلیل ما شاهد overplotting هستیم. overplotting زمانی اتفاق می افتد که داده ها در نمودار همپوشانی دارند و نمایش تک به تک نقاط داده ها دشوار می شوند. البته یکی از دلایل آن زیاد بودن تعداد داده هاست که در اینجا نقاط داده ۵۰۰۰ مرد و ۵۰۰۰ زن است. دلیل دیگر می تواند کم بودن مقادیر منحصر به فرد برای یک متغیر باشد. به عنوان مثال ، وقتی یکی از متغیرهای نمودار پراکندگی متغیر گسسته است.
# Scatter plot of Height and Weight ax1= df[df['Gender']=='Male'].plot(kind='scatter', x='Height',y='Weight', color='blue',alpha=0.5, figsize=(10,7)) df[df['Gender']=='Female'].plot(kind='scatter', x='Height',y='Weight', color='magenta',alpha=0.5, figsize=(10,7),ax=ax1) plt.legend(labels=['Males','Females']) plt.title('Relationship between Height and Weight', size=24) plt.xlabel('Height (inches)', size=18) plt.ylabel('Weight (pounds)', size=18);
در نمودار زیر ، قد و وزن ۵۰۰ خانم را به طور تصادفی انتخاب کرده ایم. حالا این یکی نمودار دارای overplotting نیست و ما می توانیم نقاط مربوط به هر فرد را بهتر تشخیص دهیم.
# Scatter plot of 500 females sample_females = df[df['Gender']=='Female'].sample(500) sample_females.plot(kind='scatter', x='Height',y='Weight', color='magenta',alpha=0.5, figsize=(10,7)) plt.legend(labels=['Females']) plt.title('Relationship between Height and Weight (sample of 500 females)', size=20) plt.xlabel('Height (inches)', size=18) plt.ylabel('Weight (pounds)', size=18);
همانطور که می توانیم در نمودارهای قبلی مشاهده کنیم ، وزن زنان و مردان با بالا رفتن قد، بالا می رود که می توان گفت در هر دو مورد یک رابطه خطی نشان می دهد.
رگرسیون خطی ساده یک رویکرد خطی برای مدل سازی رابطه بین یک متغیر وابسته و یک متغیر دیگر (مستقل) است و به دست آوردن خطی که بیانگر داده ها باشد.
y = a + bx
که x متغیر مستقل (قد) است ، y متغیر وابسته (وزن) است ، b شیب است ، و a عرض از مبدا است. a (عرض از مبدا)، مقدار y را وقتی x برابر ۰ است، نشان می دهد و b (شیب) نشانگر شیب خط است. هدف بدست آوردن خطی است که بیانگر روند و ارتباط داده های ما باشد (خطی که مجموع خطای مربعات یا squared errors را به حداقل می رساند). خطا تفاوت بین مقدار واقعی y و مقدار پیش بینی شده است (مقدار پیش بنی شده همان مقدار به دست آمده با استفاده از معادله خطی محاسبه شده است). یعنی:
(error = y(real)-y(predicted) = y(real)-(a+bx
ما به راحتی می توانیم این خط را با استفاده از Numpy بدست آوریم. Numpy یک بسته کتابخانه ای Python برای محاسبات علمی است که آرایه های چند بعدی با کارایی بالا را فراهم می کند.
تابع polyfit با نوشتار
(numpy.polyfit(x ، y ، degبا استفاده از مجموعه نقاط (x ، y) یک چندجمله ای که با بیشترین دقت، بیانگر و متناسب با نقاط است را پیدا می کند. درجه چندجمله ای همان است که به عنوان پارامتر سوم به تابع داده شده است (یعنی deg). این تابع ضرایب چندجمله ای را به عنوان نتیجه بر می گرداند.
در کد زیر، ما چندجمله ای خط رگرسیون را برای مردان و زنان به دست آورده ایم.
import numpy as np # Best fit polynomials. df_males = df[df['Gender']=='Male'] df_females = df[df['Gender']=='Female'] # Polynomial males. male_fit = np.polyfit(df_males.Height,df_males.Weight,1) # array([ 5.96177381, -224.49884071]) # Polynomial females. female_fit = np.polyfit(df_females.Height,df_females.Weight,1) # array([ 5.99404661, -246.01326575])
حالا می خواهیم این خطوط را به نمودارهای پراکندگی قبلی اضافه کنیم:
# Scatter plots and regression lines. # Males and Females dataframes. df_males = df[df['Gender']=='Male'] df_females = df[df['Gender']=='Female'] # Scatter plots. ax1= df_males.plot(kind='scatter', x='Height',y='Weight', color='blue',alpha=0.5, figsize=(10,7)) df_females.plot(kind='scatter', x='Height',y='Weight', color='magenta',alpha=0.5, figsize=(10,7),ax=ax1) # Regression lines. plt.plot(df_males.Height,male_fit[0]*df_males.Height+male_fit[1], color='darkblue', linewidth=2) plt.plot(df_females.Height,female_fit[0]*df_females.Height+female_fit[1], color='deeppink', linewidth=2) # Regression equations. plt.text(65,230,'y={:.2f}+{:.2f}*x'.format(male_fit[1],male_fit[0]),color='darkblue',size=12) plt.text(70,130,'y={:.2f}+{:.2f}*x'.format(female_fit[1],female_fit[0]),color='deeppink',size=12) # Legend, title and labels. plt.legend(labels=['Males Regresion Line','Females Regresion Line', 'Males','Females']) plt.title('Relationship between Height and Weight', size=24) plt.xlabel('Height (inches)', size=18) plt.ylabel('Weight (pounds)', size=18);
حاصل به شکل زیر است:
نمودارهای پراکندگی و خط رگرسیون خطی با کتابخانه Seaborn
Seaborn یک کتابخانه نمایش و تجسم داده ها است که بر اساس matplotlib ساخته شده است. با استفاده از تابع seaborn.regplot می توانیم به راحتی نمودارهای رگرسیون را ایجاد کنیم. کار با این کتابخانه راحت تر است و تعداد خطوط کد مورد نیاز نسبت به روش قبلی بسیار کمتر است.
import seaborn as sns # Regression plot using seaborn. fig = plt.figure(figsize=(10,7)) sns.regplot(x=df_males.Height,y=df_males.Weight,color='blue', marker='+') sns.regplot(x=df_females.Height,y=df_females.Weight,color='magenta', marker='+') # Legend, title and labels. plt.legend(labels=['Males','Females']) plt.title('Relationship between Height and Weight', size=24) plt.xlabel('Height (inches)', size=18) plt.ylabel('Weight (pounds)', size=18);
نتیجه به شکل زیر است:
نمودار بالا دارای overplotting است، دلیل آن هم این است که تعداد نقاط بسیار زیاد است. برای نمایش بهتر یک نمودار رگرسیون، آن را با ۳۰۰ نمونه تصادفی از هر کدام از مجموعه های مردان و زنان دوباره رسم می کنیم. دقت داشته باشید که نمودار رابطه مثبت خطی بین قد و وزن را برای مردان و زنان نشان می دهد.
import seaborn as sns # Samples df_males_sample= df[df['Gender']=='Male'].sample(300) df_females_sample= df[df['Gender']=='Female'].sample(300) # Regression plot using seaborn. fig = plt.figure(figsize=(10,7)) sns.regplot(x=df_males_sample.Height,y=df_males_sample.Weight,color='blue', marker='+') sns.regplot(x=df_females_sample.Height,y=df_females_sample.Weight,color='magenta', marker='+') # Legend, title and labels. plt.legend(labels=['Males','Females']) plt.title('Relationship between Height and Weight', size=24) plt.xlabel('Height (inches)', size=18) plt.ylabel('Weight (pounds)', size=18);
نمودار حاصله به شکل زیر است:
ایجاد مدل خطی ساده با استفاده از sklearn
Scikit-Learn یک کتابخانه یادگیری ماشین رایگان برای پایتون است. ما به راحتی می توانیم با استفاده از کلاس LinearRegression ، رگرسیون خطی را با Scikit-learn پیاده سازی کنیم. پس از ایجاد یک شی از LinearRegression ، می توانیم با فراخوانی تابع fit و دادن مقادیر قد و وزن به عنوان x و y ، خطی را که به بهترین وجه بیانگر و متناسب با داده های ما است ، بدست آوریم.
from sklearn.linear_model import LinearRegression df_males = df[df['Gender']=='Male'] # Create linear regression object. lr_males= LinearRegression() # Fit linear regression. lr_males.fit(df_males[['Height']], df_males['Weight']) # Get the slope and intercept of the line best fit. print(lr_males.intercept_) # -224.49884070545772 print(lr_males.coef_) # 5.96177381 df_females = df[df['Gender']=='Female'] # Create linear regression object. lr_females= LinearRegression() # Fit linear regression. lr_females.fit(df_females[['Height']], df_females['Weight']) # Get the slope and intercept of the line best fit. print(lr_females.intercept_) # -246.01326574667277
مقادیر به دست آمده با استفاده از رگرسیون خطی Sklearn مطابق با مقادیر به دست آمده از تابع polyfit کتابخانه Numpy است؛ زیرا هر دو روش خطی را پیدا می کنند که مجموع خطای مربع را به حداقل می رساند. همانطور که قبلاً نیز اشاره شد ، خطا تفاوت بین مقدار واقعی متغیر وابسته و مقدار پیش بینی شده توسط مدل خطی است. با به حداقل رساندن مجموع خطاهای مربع ، می توانیم مطمئن باشیم که ضرایب بهینه برای چندجمله ای رگرسیون خطی به دست آمده است.
پس از تعیین مدل خطی و به دست آوردن معادله رگرسیون آن، می توانیم مقادیر وابسته را با توجه به مقادیر متغیر مستقل، پیش بینی کنیم. در Numpy هم با استفاده از تابع polyval می توان پیش بینی کرد. پیش بینی های به دست آمده با استفاده از Scikit-Learn و Numpy یکسان هستند زیرا در هر دو کتابخانه روش یکسانی برای به دست آوردن خط استفاده می شود.
df_females = df[df['Gender']=='Female'] # Fit the model using numpy. female_fit = np.polyfit(df_females.Height,df_females.Weight,1) # Predictions using numpy. print(np.polyval(female_fit,[60])) # [113.62953114] # Fit the model using scikit learn. lr_females= LinearRegression() lr_females.fit(df_females[['Height']], df_females['Weight']) # Predictions using scikit learn. print(lr_females.predict([[60]])) # [113.62953114]
ضریب همبستگی پیرسون
همبستگی یا Correlation میزان وابستگی و ارتباط دو متغیر را اندازه گیری می کند. برای اندازه گیری قدرت و جهت رابطه خطی بین دو متغیر از ضریب همبستگی پیرسون (Pearson correlation coefficient) استفاده می شود. این ضریب با تقسیم کواریانس متغیرها بر ضرب انحراف معیار آن ها محاسبه می شود و دارای یک مقدار بین ۱+ تا ۱- است ، که ۱ همبستگی کامل خطی مثبت است ، ۰ هیچ همبستگی خطی ندارد و ۱- همبستگی کامل خطی منفی است.
با استفاده از تابع
()corr.(+) می توانیم ضریب همبستگی متغیرهای یک dataframe را بدست آوریم. به طور پیش فرض ، ضریب همبستگی پیرسون محاسبه می شود. با این حال ، سایر ضرایب همبستگی را می توان محاسبه کرد ، مانند Kendall یا Spearman.
ضریب همبستگی پیرسون برای قد و وزن زنان:
# Dataframe containing only females. df_females = df[df['Gender']=='Female'] # Correlation coefficients df_females.corr()
ضریب همبستگی پیرسون برای قد و وزن مردان:
# Dataframe containing only males. df_males = df[df['Gender']=='Male'] # Correlation coefficients df_males.corr()
یک قانون سرانگشتی برای تفسیر مقدار ضریب همبستگی به دست آمده به شرح زیر است:
- ۰.۸ تا ۱ : بسیار قوی
- ۰.۶ تا ۰.۷۹۹ : قوی
- ۰.۴ تا ۰.۵۹۹ : متوسط
- ۰.۲ تا ۰.۳۹۹ : ضعیف
- ۰ تا ۰.۱۹۹ : بسیار ضعیف
در محاسبات قبلی ، ما ضریب همبستگی پیرسون بزرگتر از ۰.۸ به دست آمده است ، بدین معنی که قد و وزن برای مردان و خانمها به شدت همبستگی دارد.
همچنین می توانیم ضریب همبستگی پیرسون را از طریق توابع آماری Scipy یا scipy.stats به دست آوریم. تابع
(scipy.stats.pearsonr(x, y(+) دو مقدار ضریب همبستگی پیرسون و p-value را بر می گرداند.
from scipy import stats # Dataframe containing only females. df_females = df[df['Gender']=='Female'] # Pearson correlation coefficient and p-value pearson_coef, p_value = stats.pearsonr(df_females.Height, df_females.Weight) print(pearson_coef) # 0.849608591418601 # Dataframe containing only males. df_males = df[df['Gender']=='Male'] # Pearson correlation coefficient and p-value pearson_coef, p_value = stats.pearsonr(df_males.Height, df_males.Weight) print(pearson_coef) # 0.8629788486163176
همانطور که مشاهده می شود ، ضرایب همبستگی به دست آمده از Pandas و Scipy یکسان هستند:
- ضریب همبستگی برای مقادیر قد و وزن زنان: ۰.۸۴۹۶۰۸
- ضریب همبستگی برای مقادیر قد و وزن مردان: ۰.۸۶۲۹۷۸۸
نمودارهای Residual
ما می توانیم از مقادیر عددی مانند ضریب همبستگی پیرسون یا ابزارهای تجسم مانند نقشه پراکندگی برای ارزیابی اینکه آیا رگرسیون خطی ، برای پیش بینی داده ها مناسب است یا خیر ، استفاده کنیم. راه دیگر برای انجام این ارزیابی استفاده از نمودارهای Residual است. نمودارهای Residual تفاوت بین مقادیر واقعی و پیش بینی شده را نشان می دهد.
در واقع، اگر نقاط در یک نمودار Residual به طور تصادفی در اطراف محور افقی پراکنده شوند ، یک مدل رگرسیون خطی برای باین روند داده ها مناسب است. در غیر این صورت ، یک مدل غیرخطی مناسب تر است.
ما می توانیم از Seaborn برای ایجاد نمودارهای residual استفاده کنیم. به کد زیر دقت کنید:
برای زنان
import seaborn as sns # Dataframe containing only females. df_females = df[df['Gender']=='Female'].sample(500) # Residual plot 500 females. fig = plt.figure(figsize=(10,7)) sns.residplot(df_females.Height, df_females.Weight, color='magenta') # Title and labels. plt.title('Residual plot 500 females', size=24) plt.xlabel('Height (inches)', size=18) plt.ylabel('Weight (pounds)', size=18);
برای مردان
# Dataframe containing only males. df_males = df[df['Gender']=='Male'].sample(500) # Residual plot 500 males. fig = plt.figure(figsize=(10,7)) sns.residplot(df_males.Height, df_males.Weight, color='blue') # Title and labels. plt.title('Residual plot 500 males', size=24) plt.xlabel('Height (inches)', size=18) plt.ylabel('Weight (pounds)', size=18);
همانطور که می بینیم ، نقاط به طور تصادفی در حدود ۰ توزیع می شوند ، به این معنی که رگرسیون خطی یک مدل مناسب برای پیش بینی داده های ما است. اگر نمودار Residual یک خمیدگی ارائه دهد ، فرض خطی بودن ارتباط نادرست است. در این حالت ، یک تابع غیر خطی برای پیش بینی داده ها مناسب تر خواهد بود.
رگرسیون خطی چندگانه
رگرسیون خطی ساده از یک تابع خطی برای پیش بینی مقدار متغیر هدف y استفاده می کند ، که شامل عملکرد فقط یک متغیر مستقل x است. شکل و فرم آن هم اینگونه است:
y = b ₀+b ₁x ₁
بعد از پیدا کردن خطی که متناسب با روند داده های جمع آوری شده است، می توانیم مقادیر پارامترهای b₀ و b₁ را مجموع خطای مربع را حداقل کرده است، بدست آوریم.
پیش از این ، ما دو مدل خطی ، یکی برای آقایان و دیگری را برای زنان محاسبه کرده ایم تا وزن را بر اساس قد یک فرد پیش بینی کنیم و نتایج زیر را بدست آمد:
- Males → Weight = -224.50+5.96*Height
- Females → Weight = -246.01+5.99*Height
تاکنون از یک متغیر مستقل برای پیش بینی وزن فرد استفاده کرده ایم (به صورت Weight = f(Height)) که دو مدل متفاوت برای مردان و زنان ایجاد شد. اما آیا ما می توانیم یک مدل واحد بسازیم که وزن را بر اساس قد و جنسیت پیش بینی کند؟ به طور دقیق تر، آیا می شود مدلی داشت که جنسیت را هم به عنوان یک متغیر داخل خود مدل سازی کند و از این نکته که قد و جنسیت نسبت به هم مستقل هستند استفاده کرد؟ خب، جواب هر دو سوال مثبت است! و اینجاست که رگرسیون خطی چندگانه وارد عمل می شود!
رگرسیون خطی چندگانه از یک تابع خطی برای پیش بینی مقدار متغیر هدف y ، شامل متغیرهای مستقل [x = [x₁ ، x₂ ، x₃ ،… ، xₙ استفاده می کند. شکل معادله چندجمله ای آن به شکل زیر است:
y = b ₀+b ₁x ₁+b₂x₂+b₃x₃+…+bₙxₙ
ما مقادیر پارامترهای bᵢ را با استفاده از همان تکنیکی که در رگرسیون خطی ساده (حداقل خطای مربع) استفاده شد، بدست می آوریم. پس از پیدا کردن مدل ، می توان از معادله برای پیش بینی مقدار متغیر هدف y استفاده کرد. در مورد مثال و دیتاست ما ، از وزن و جنسیت برای پیش بینی وزن فرد وزن استفاده می کنیم (به صورت Weight = f(Height,Gender)).
متغیرهای دسته ای در رگرسیون خطی چندگانه
دو نوع متغیر در علم آمار استفاده می شود: متغیرهای عددی و دسته ای.
- متغیرهای عددی مقادیری را نشان می دهند که به ترتیب صعودی و نزولی مانند ارتفاع شخص قابل اندازه گیری و مرتب سازی هستند.
- متغیرهای دارای دسته بندی، مقادیری به خود می گیرند که می توانند در گروه ها یا دسته بندی هایی مانند جنسیت یک شخص طبقه بندی شوند.
رگرسیون خطی چندگانه نه تنها متغیرهای عددی بلکه متغیرهای طبقه ای را نیز می پذیرد. برای گنجاندن متغیر دسته ای در یک مدل رگرسیون، متغیر باید به عنوان یک متغیر باینری (متغیر ساختگی باینری) بیان و رمزگذاری شود. در Pandas ، ما به راحتی می توانیم با استفاده از تابع pandas.get_dummies ، یک متغیر دسته بندی شده را به یک متغیر ساختگی (مصنوعی و نه بر اساس اندازه گیری) تبدیل کنیم. این تابع داده های جدیدی را بر می گرداند که دو ستون ساختگی جنسیت مرد و جنسیت زن اضافه کرده که ۱ نشان دهنده حضور متغیر دسته ای در آن ردیف و ۰ عدم وجود آن است. نتیجه استفاده از تابع مذکور روی داده های ما به شکل زیر است:
اما این نوع بیان و کدگذاری مشکلاتی ایجاد خواهد کرد (multi-collinearity). چرا که بر خلاف تعریف رگرسیون خطی چندگانه که در ابتدا توضیح داده شد، متغیرهای Gender_Female و Gender_Male دیگر نسبت به هم مستقل نیستند و اگر یکی ۱ باشد، دیگری حتماً ۰ است. پس باید به جای این دو ستون، تنها یک ستون جنسیت داشته باشیم. پس یکی را حذف می کنیم و نام دیگری را به Gender تغییر می دهیم (فرقی نمی کند که کدام را حذف کنید، به هر حال هر دو ستون با صفر و یک جنسیت را مشخص کرده اند).
# Drop female column. df_dummy.drop('Gender_Female',axis=1,inplace=True) # Rename Gender_Male column. df_dummy.rename(columns={'Gender_Male':'Gender'}, inplace=True) # df_dummy dataframe first 5 columns. df_dummy.head()
سپس ، ما می توانیم از این dataframe استفاده کنیم تا یک مدل رگرسیون خطی چندگانه را با استفاده از Scikit-Learn بدست آوریم.
from sklearn.linear_model import LinearRegression # Create linear regression object. mlr= LinearRegression() # Fit linear regression. mlr.fit(df_dummy[['Height','Gender']], df_dummy['Weight']) # Get the slope and intercept of the line best fit. print(mlr.intercept_) # -244.92350252069903 print(mlr.coef_) # [ 5.97694123 19.37771052]
بعد از ایجاد معادله خطی، مدل رگرسیون خطی چندگانه زیر بدست می آید:
Weight = -244.9235+5.9769*Height+19.3777*Gender
اگر می خواهیم وزن یک مرد را پیش بینی کنیم ، مقدار متغیر جنسیت ۱ است ، و با جایگذاری معادله زیر را بدست می آوریم:
Male → Weight = -244.9235+5.9769*Height+19.3777*1= -225.5458+5.9769*Height
برای زنان ، مقدار متغیر جنسیت ۰ است. با جایگذاری خواهیم داشت:
Female → Weight = -244.9235+5.9769*Height+19.3777*0 =-244.9235+5.9769*Height
اگر مدل های خطی ساده را با مدل خطی چندگانه مقایسه کنیم ، مشاهده می شود که متغیر جنسیت مدل رگرسیون خطی چندگانه فقط عرض از مبدا خط را تغییر می دهد. و در هر دو می توان نتایج پیش بینی مشابه به دست آورد.
نکات کلیدی جمع بندی
- رگرسیون خطی ساده یک رویکرد خطی برای مدل سازی رابطه بین یک متغیر وابسته و یک متغیر مستقل است.
- رگرسیون خطی چندگانه از یک تابع خطی برای پیش بینی مقدار متغیر وابسته از رابطه ای دارای n متغیر مستقل از هم استفاده می کند.
- تجزیه و تحلیل اکتشافی داده ها شامل تجزیه و تحلیل ویژگی های اصلی یک مجموعه داده (dataset) است که معمولاً از طریق روش های نمایش و خلاصه سازی آماری (میانگین، انحراف از معیار، کواریانس و …) انجام می شود.
- هیستوگرام ها نمودارهایی هستند که توزیع یک متغیر عددی را نشان می دهد و داده ها را در بازه هایی دسته بندی می کنند.
- Pandas توابعی را برای تجزیه و تحلیل اکتشافی داده ها فراهم می کند. مانند: Dataframe.describe() و Dataframe.info() و Dataframe.dtypes و Dataframe.shape.
- نمودارهای پراکندگی نمایش دوبعدی داده ه هستند که توزیع داده ها نسبت به دو متغیر عددی را نشان می دهند؛ یکی ترسیم شده در امتداد محور x و دیگری ترسیم شده در امتداد محور y. کتابخانه های Matplotlib و Seaborn توابعی را برای ترسیم نمودارهای پراکندگی ساخته اند.
- ما می توانیم با استفاده از کتابخانه هایی مانند Numpy یا Scikit-Learn یک مدل رگرسیون خطی ساده داشته باشیم.
- همبستگی میزان ارتباط دو متغیر را اندازه گیری می کند. برای اندازه گیری قدرت و جهت رابطه خطی بین دو متغیر از ضریب همبستگی پیرسون استفاده می شود.
- نمودارهای Residual می تواند برای تجزیه و تحلیل این که آیا یک مدل رگرسیون خطی برای داده ها مناسب است یا نه، مورد استفاده قرار گیرد.
- برای استفاده از مقادیر دسته ای (دسته بندی شده ، مثل جنسیت) در مدل رگرسیون خطی چندگانه ، باید متغیرهای دسته ای به متغیرهای ساختگی تبدیل و مقادیر آن ها کدگذاری شوند.
ممنونیم که تا انتها با ما همراه بودید.
منبع: