الگوریتم های خط مبنا (Baseline) در پایتون — راهنمای کاربردی
در این مطلب، الگوریتم «پیشبینی تصادفی» (Random Prediction) و «قاعده صفر» (Zero Rule) که هر دو از جمله الگوریتمهای «خط مبنا» (Baseline) هستند، مورد بررسی قرار گرفتهاند. به منظور آشنایی هر چه بهتر مخاطبان با مفهوم خط مبنا (Baseline) در یادگیری ماشین، ابتدا این مبحث شرح داده میشود و سپس دو الگوریتم بیان شده با استفاده از زبان برنامهنویسی پایتون، پیادهسازی میشوند.
خط مبنا (Baseline) در یادگیری ماشین
خط مبنا «baseline»، به روشها (و در واقع به نوعی سنجههایی) گفته میشود که از «اکتشاف» (heuristic)، «آمارههای ساده» (Simple Summary Statistics)، «تصادفی بودن» (Randomness) و یا «یادگیری ماشین» (Machine Learning) برای انجام پیشبینی در مجموعه داده استفاده میکنند. کاربر میتواند از این پیشبینیها برای اندازهگیری کارایی مبنا (برای مثال صحت) استفاده کند. این سنجهها به منظور مقایسه الگوریتم با دیگر روشهای یادگیری ماشین مورد استفاده قرار میگیرند. در واقع، یک الگوریتم یادگیری ماشین در تلاش برای یادگیری تابعی است که روابط بین ورودی داده (ویژگی) و «متغیر هدف» (Target Variable) (یا برچسب) را مدلسازی میکند.
هنگام «آزمودن» (Test) این الگوریتمها، میتوان کارایی را به یکی از روشهای موجود ارزیابی کرد. برای مثال، الگوریتم ممکن است ۷۵٪ صحت داشته باشد. اما این یعنی چه؟ میتوان معنای این بیان را با مقایسه نتایج حاصل از ارزیابی مدل با کارایی خط مبنا تفسیر کرد. در ادامه، انواع خط مبنا (Baseline) در یادگیری ماشین مورد بررسی قرار گرفته است. انواع خط مبنا (Baseline) در یادگیری ماشین، شامل مواردی میشود که توسط «برآوردگرهای مجازی» (Dummy Estimators) «سایکیتلِرن» (Scikit-learn) مورد استفاده قرار میگیرند. مبناهای «دستهبندی» (Classification) و «رگرسیون» (Regression) در زیر بیان شدهاند.
خط مبناهای دستهبندی عبارتند از:
- «طبقهبندی شده» (Stratified): پیشبینیها را با توجه به توزیع کلاس مجموعههای آموزش تولید میکند.
- «بیشترین تکرار» (Most Frequent): برچسبهایی با بیشترین تکرار در مجموعههای آموزش را پیشبینی میکند.
- (پیشین) «Prior»: دستهای که پیشین کلاس را بیشینه میسازد، پیشبینی میکند.
- «یکنواخت» (Uniform): پیشبینیها را به صورت یکنواخت در حالت تصادفی محاسبه میکند.
- «ثابت» (Constant): یک برچسب ثابت را که توسط کاربر فراهم شده است، پیشبینی میکند. این کار برای «سنجههایی» (metrics) که یک کلاس غیر اکثریت را ارزیابی میکنند مفید است.
خط مبناهای رگرسیون عبارتند از:
- «میانه» (Median): میانه مجموعه داده آموزش را محاسبه میکند.
- «چندک» (Quantile): چندک تعیین شده مجموعه داده آموزش را که با پارامتر چندک ارائه شده است پیشبینی میکند.
- «ثابت» (Constant): یک مقدار ثابت را که توسط کاربر فراهم شده است پیشبینی میکند.
به طور کلی، کاربر معمولا میخواهد که رویکرد برگزیدهاش بهتر از مبناهایی که انتخاب کرده عمل کنند. در مثال بالا، کاربر میخواهد که صحت ٪۷۵ به دست آمده، از همه مبناهایی که روی دادههای مشابه اجرا شده بهتر باشد. در نهایت، اگر کاربر با دامنه خاصی از یادگیری ماشین سر و کار دارد (مانند سیستم توصیهگر)، میتواند مبناهایی را برگزیند که در حال حاضر state-of-the-art هستند. زیرا کاربر همواره تمایل دارد که نشان دهد رویکرد او بهتر از این روشها عمل میکند.
برای مثال، در حالی که کاربر یک الگوریتم «پالایش گروهی» (Collaborative Filtering) جدید را ارزیابی میکند، ممکن است بخواهد آن را با فاکتورگیری ماتریس مقایسه کند که خود یک الگوریتم یادگیری است. البته این الگوریتم در حال حاضر جزو الگوریتمهای مبنای محبوب به شمار میآید، زیرا در پژوهشهای «سیستمهای توصیهگر» (Recommender System) موفق واقع شده است.
پیادهسازی الگوریتمهای مبنا از پایه با پایتون
داشتن یک کارایی مبنا در مسائل مدلسازی پیشبین بسیار حائز اهمیت است. یک مبنا، نقطه مقایسهای برای روشهای پیشرفتهتری را فراهم میکند که کاربر بعدا برای ارزیابی مدل خود از آنها استفاده میکند. الگوریتمهای یادگیری ماشین زیادی وجود دارند که میتوان از میان آنها انتخاب کرد. ولی کاربر نیاز دارد بداند که پیشبینی انجام شده توسط یک الگوریتم خوب است یا نه. اما چگونه میتوان این را فهمید؟ پاسخ این است که کاربر باید از یک الگوریتم پیشبینی مبنا استفاده کند. یک الگوریتم پیشبینی مبنا مجموعهای از پیشبینیها را فراهم میکند که میتوان مدل را با بهرهگیری از آنها ارزیابی کرد. برای مثال، در ارزیابی صحت «دستهبندی» (Classification) از «خطای جذر میانگین مربعات» (Root-mean-square Deviation | RMSE) استفاده میشود.
امتیاز فراهم شده توسط الگوریتمهای مبنا، یک نقطه مقایسه برای همه الگوریتمهای یادگیری ماشین فراهم میکنند. دو نوع از الگوریتمهای مبنایی که استفاده از آنها متداول است عبارتند از «الگوریتم پیشبینی تصادفی» (Random Prediction Algorithm) و «الگوریتم قاعده صفر» (Zero Rule Algorithm). هنگام آغاز مسالهای که نسبت به یک مساله دستهبندی یا رگرسیون مرسوم پیچیدهتر است، استفاده از یک الگوریتم پیشبینی تصادفی در درجه اول برای مساله پیشبینی مناسب است. بعدا میتوان این الگوریتم را بهبود داد و یک الگورتیم قاعده صفر را طراحی کرد.
الگوریتم پیشبینی تصادفی
الگوریتم پیشبینی تصادفی، خروجی تصادفی را چنانکه در دادههای آموزش مشاهده میشود پیشبینی میکند. این الگوریتم احتمالا یکی از سادهترین الگوریتمها برای پیادهسازی است. الگوریتم پیشبینی تصادفی نیاز دارد که کاربر همه مقادیر خروجیهای متمایز را در دادههای آموزش ذخیره کند که میتواند یک مساله رگرسیون بزرگ با مقادیر متمایز بسیار زیاد باشد. به دلیل آنکه اعداد تصادفی برای انجام پیشبینی مورد استفاده قرار میگیرند، بهتر است که ابتدا یک «سید عدد تصادفی» (Random Number Seed) پس از انتخاب الگوریتم تعیین شود. این کار برای حصول اطمینان از آن است که مجموعه اعداد تصادفی مشابهی دریافت میشوند و به نوبه خود تصمیمات مشابهی در هر بار اجرای الگوریتم اتخاذ میشود.
در ادامه، پیادهسازی الگوریتم پیشبینی تصادفی در تابعی با نام ()random_algorithm پیادهسازی شده است. تابع، هم مجموعه داده آموزش را که شامل مقادیر تصادفی است و هم مجموعه داده آزمون را که مقادیر خروجی باید برای آنها پیشبینی شود را دریافت میکند. این تابع هم برای مسائل دستهبندی و هم برای رگرسیون کار میکند. تابع پیشبینی تصادفی چنین فرض میکند که مقدار خروجی در دادههای آموزش، ستون نهایی برای هر سطر است. ابتدا، مجموعهای از مقادیر خروجی یکتا از دادههای آموزش گردآوری میشوند. سپس، یک مقدار خروجی انتخاب شده به صورت تصادفی از مجموعه برای هر سطر در مجموعه آزمون انتخاب میشود.
1# Generate random predictions
2def random_algorithm(train, test):
3 output_values = [row[-1] for row in train]
4 unique = list(set(output_values))
5 predicted = list()
6 for row in test:
7 index = randrange(len(unique))
8 predicted.append(unique[index])
9 return predicted
میتوان برای سادگی، این تابع را با یک مجموعه داده کوچک که تنها شامل ستون خروجی است مورد آزمون قرار داد. مقادیر خروجی در مجموعه داده آموزش «۰» یا «۱» هستند، بدین معنا که مجموعه پیشبینیهایی که الگوریتم انتخاب میکند {۰، ۱} هستند. مجموعه داده تست مادامی که پیشبینیها شناخته شده نیستند، شامل یک ستون یکتا، بدون هیچ دادهای است.
1from random import seed
2from random import randrange
3
4# Generate random predictions
5def random_algorithm(train, test):
6 output_values = [row[-1] for row in train]
7 unique = list(set(output_values))
8 predicted = list()
9 for row in test:
10 index = randrange(len(unique))
11 predicted.append(unique[index])
12 return predicted
13
14seed(1)
15train = [[0], [1], [0], [1], [0], [1]]
16test = [[None], [None], [None], [None]]
17predictions = random_algorithm(train, test)
18print(predictions)
با اجرای مثال، پیشبینیهای تصادفی برای مجموعه داده آزمون محاسبه میشوند و برنامه این پیشبینیها را پرینت میکند.
1[0, 0, 1, 0]
پیادهسازی الگوریتم پیشبینی تصادفی آسان و اجرای آن سریع است، اما میتوان مبناهای بهتری را نیز مورد استفاده قرار داد.
الگوریتم قاعده صفر
الگوریتم قاعده صفر، نسبت به الگوریتم پیشبینی تصادفی، مبنای بهتری را فراهم میکند. این الگوریتم از اطلاعات بیشتری پیرامون یک مساله داده شده برای ساخت یک قاعده به منظور انجام پیشبینی استفاده میکند. این قاعده بسته به نوع مساله متفاوت است. در ادامه، کار با الگوریتم دستهبندی به منظور پیشبینی برچسب یک کلاس مورد استفاده قرار میگیرد.
دستهبندی
برای مسائل دستهبندی، قاعده اول، پیشبینی مقدار دستهای است که در مجموعه داده آموزش متداولتر است. این یعنی اگر مجموعه داده آموزش دارای ۹۰ درصد نمونهها از کلاس «۰» باشد و ۱۰ درصد از کلاس «۱» باشد، الگوریتم «۰» را پیشبینی میکند و صحت مبنای ۹۰/۱۰۰ یا ۹۰ درصد را به دست میآورد. این خروجی، بسیار بهتر از الگوریتم پیشبینی تصادفی است که تنها صحت ۸۲٪ را به طور میانگین به دست میآورد. برای جزئیات بیشتر پیرامون اینکه این مقدار چگونه برای جستوجوی تصادفی تخمینزده میشود محاسبات لازم در ادامه انجام شده است.
1= ((0.9 * 0.9) + (0.1 * 0.1)) * 100
2= 82%
در زیر، از تابعی با نام ()zero_rule_algorithm_classification استفاده شده است که این الگوریتم را برای مسائل دستهبندی پیادهسازی میکند.
1# zero rule algorithm for classification
2def zero_rule_algorithm_classification(train, test):
3 output_values = [row[-1] for row in train]
4 prediction = max(set(output_values), key=output_values.count)
5 predicted = [prediction for i in range(len(test))]
6 return predicted
تابع بالا، از تابع ()max با خصیصه کلیدی استفاده میکند که کمی هوشمندانه است. با دادن لیستی از مقادیر کلاس مشاهده شده در مجموعه داده آموزش، تابع ()max مجموعهای از مقادیر کلاس یکتا را دریافت میکند و Count را روی لیست مقادیر کلاس برای هر مقدار کلاس در مجموعه فراخوانی میکند. نتیجه آن است که مقدار کلاسی که دارای بیشترین Count در لیست مقادیر کلاس مشاهده شده در مجموعه داده آموزش است را باز میگرداند.
اگر همه مقادیر کلاس دارای Count مشابهی بودند، اولین مقدار کلاس در مجموعه داده مشاهده شده انتخاب میشود. هنگامی که یک مقدار کلاس انتخاب میشود، برای انجام پیشبینی برای هر سطر در مجموعه داده تست مورد استفاده قرار میگیرد. کد زیر، مثالی با یک مجموعه داده ساختگی است که شامل چهار مثال از دسته «۰» و دو مثال از دسته «۱» است. انتظار میرود که الگوریتم مقدار کلاس «۰» را به عنوان پیشبینی برای هر سطر در مجموعه داده تست انتخاب کند.
1from random import seed
2from random import randrange
3
4# zero rule algorithm for classification
5def zero_rule_algorithm_classification(train, test):
6 output_values = [row[-1] for row in train]
7 prediction = max(set(output_values), key=output_values.count)
8 predicted = [prediction for i in range(len(train))]
9 return predicted
10
11seed(1)
12train = [['0'], ['0'], ['0'], ['0'], ['1'], ['1']]
13test = [[None], [None], [None], [None]]
14predictions = zero_rule_algorithm_classification(train, test)
15print(predictions)
با اجرای این مثال، پیشبینیها انجام و خروجیها روی صفحه نمایش پرینت میشوند. همانطور که انتظار میرفت، مقدار کلاس «۰» انتخاب و پیشبینی شد.
1['0', '0', '0', '0', '0', '0']
در ادامه، نحوه استفاده و پیادهسازی الگوریتم قاعده صفر برای مسائل رگرسیون بیان شده است.
رگرسیون
مسائل رگرسیون نیازمند پیشبینی یک مقدار واقعی هستند. یک پیشبینی پیشفرض خوب آن است که «معیار مرکزی» (Central Tendency) پیشبینی شود. این معیار مرکزی میتواند میانگین یا میانه باشد. یک پیشفرض خوب، استفاده از میانگین مقدار خروجی مشاهده شده در مجموعه داده آموزش است.
این مانند آن است که خطای کمتری نسبت به پیشبینی تصادفی وجود داشته باشد که هر مقدار خروجی مشاهده شدهای را باز میگرداند. در زیر، تابعی برای انجام این کار ارائه شده که نام آن ()zero_rule_algorithm_regression است. این تابع، با محاسبه مقدار میانگین برای مقادیر خروجی مشاهده شده، کار میکند.
1mean = sum(value) / total values
پس از انجام محاسبات، میانگین برای هر سطر در مجموعه داده آموزش پیشبینی میشود.
1from random import randrange
2
3# zero rule algorithm for regression
4def zero_rule_algorithm_regression(train, test):
5 output_values = [row[-1] for row in train]
6 prediction = sum(output_values) / float(len(output_values))
7 predicted = [prediction for i in range(len(test))]
8 return predicted
این تابع میتواند با یک مثال ساده مورد آزمون قرار بگیرد. میتوان یک مجموعه داده کوچک را ساخت که مقدار میانگین آن برابر با ۱۵ است.
110
215
312
415
518
620
7mean = (10 + 15 + 12 + 15 + 18 + 20) / 6
8mean = 90 / 6
9mean = 15
در ادامه، یک مثال کامل ارائه شده است. انتظار میرود که مقدار میانگین ۱۵ برای هر چهار سطر در مجموعه داده تست ۴ باشد.
1from random import seed
2from random import randrange
3
4# zero rule algorithm for regression
5def zero_rule_algorithm_regression(train, test):
6 output_values = [row[-1] for row in train]
7 prediction = sum(output_values) / float(len(output_values))
8 predicted = [prediction for i in range(len(test))]
9 return predicted
10
11seed(1)
12train = [[10], [15], [12], [15], [18], [20]]
13test = [[None], [None], [None], [None]]
14predictions = zero_rule_algorithm_regression(train, test)
15print(predictions)
با اجرای مثال بالا، مقادیر خروجی پیشبینی شده محاسبه و روی صفحه نمایش چاپ میشوند.
همانطور که انتظار میرفت، مقدار میانگین ۱۵ برای هر سطر تست در مجموعه داده آزمون محاسبه میشود.
1[15.0, 15.0, 15.0, 15.0, 15.0, 15.0]
اگر نوشته بالا برای شما مفید بوده، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای آمار، احتمالات و دادهکاوی
- آموزش هوش مصنوعی
- مجموعه آموزشهای برنامه نویسی پایتون (Python)
- داده کاوی (Data Mining) — از صفر تا صد
- یادگیری علم داده (Data Science) با پایتون — از صفر تا صد
- معرفی منابع جهت آموزش یادگیری عمیق (Deep Learning) — راهنمای کامل
^^