امروز برای اولین بار میخوایم وارد دنیای یادگیری ماشین بشیم و با نوشتن یک الگوریتم ساده به کامپیوتر قدرت پیشبینی بین دو دستهبندی مختلف رو بدیم. در این آموزش سعی میکنیم که
نورون مصنوعی یکی از جذابترین ایدهها در دنیای الگوریتمهاست و توسعه اون باعث پیشرفت زیاد در حوزه یادگیری ماشینی شده. ایده پشت اون خیلی ساده است تلاش میکنه رفتار نورونهای مغزی رو تکرار کنه، نورون از چند ورودی تغذیه میشه و سیگنالها رو دریافت میکنه و بعد از پردازش اطلاعات رو به نورون بعدی میرسونه یا اگر خودش نورونی تنها باشه خروجی نهایی رو میده، چیزی شبیه به شکل زیر:
کاری که ما در این نوشته میخواهیم انجام بدیم ساخت یک مدل با یک نورون هست چیزی که بهش میگن مدل prectption ، مدل تعالی یافته اون Multi Layer Perception هست که یکی از مدلهای آغازین شبکه عصبی عمیق هست. برای اینکه میخوایم از numpy برای ساخت مدل استفاده کنیم لازم داریم که از نظر ریاضی این مدل رو بتونیم نمایش بدیم. در فرمولهای زیر x_i نشاندهنده ورودی i و w_i وزن هر ورودی است. و فی تابع تصمیمگیری است. در مدلی که ما دودستهای ما ۱+ نشانگر یک دستهبندی و ۱- برای دستهبندی دیگر استفاده میشه و شکل تابع فی به صورت زیر هست:
که در آن تتا آستانه تصمیمگیری هست، معمولا در مدلهای ماشینلرنینگ مسئله بهینهسازی با فرض صفر بودن تتا انجام میشه.کاری که در این الگوریتم باید انجام داد( و تقریبا اکثر الگوریتمهای یادگیری ماشین) پیدا کردن یک وزن مناسب -w- برای مدل هست بعد از یافتن وزنهای مناسب در مدل با دریافت ورودیها با فرایندی شبیه شکل زیر دادههای جدید رو دستهبندی میکنه.
برای یافتن وزنهای مناسب روشهای متفاوتی وجود داره و به صورت معمول هدف این روشها یافتن یک وزنهایی است که دادههای فعلی به بهترین حالت ممکن پیشبینی بشوند(maximum likelihood) برای اینکار در مدل perception از گامهای زیر پیروی میکنیم:
۱. مقدار پیششده تابع تصمیم y_hat رو محاسبه میکنیم.
۲. وزنها را با استفاده از روش زیر بروز میکنیم.
۳. مرحله ۲ را تا زمان همگرایی یا تعداد دفعات مشخص تکرار میکنیم.
(روشی که برای بروزرسانی استفاده میکنیم مشتق شده از روش gradiant decent هست. در این روش هدف این هست که تابع هزینه که در این مسئله مربع خطای پیشبینی هست رو حداقل کنه. این یک روش تکرارشونده برای بهینهسازی هست و در هر مرحله تلاش میکنه به جهتی حرکت کنه که بیشترین میزان کاهش هزینه را داشته باشه.)
بعد از انجام کمی محاسبات ریاضی و مشتق گرفتن تابعی که برای بروزرسانی این الگوریتم استفاده میشه بدست میاد:
در این رابطه y دستهبندی واقعی، yhat دستهبندی پیشبینی شده و «اتا» نرخ یادگیری است. نرخ یادگیری که از سمت ما تعیین میشه به الگوریتم میگه چه میزان در جهت حداقلسازی تابع حرکت کنه. معمولا نرخ یادگیری کمتر باعث همگرایی کندتر میشه ولی نرخ یادگیری زیاد ممکنه خیلی سریع همگرا بشه و یا در خیلی از موارد از همگرایی جلوگیری کنه، شکل زیر که از این مقاله دریافت شده به خوبی توضیح دهنده اثر نرخ یادگیری در همگرایی مدلهاست:
حالا وقت رسیدن به لحظه موعوده و پیادهسازی کدها. در این مرحله ما با ایده برنامهنویسی شیگرا و با الهام از مدلهای پیشبینی scikit-learn مدل خودمون را پیاده میکنیم.
کلاس Percetion یک تابع __init__ برای ساخته شدن داره که درون اون ساختار الگوریتم دستهبندی ما مشخص میشه. مواردی که تعریف شده نرخ یادگیری«اتا»، دفعات تکرار مراحل بروز رسانی و استیت رندم که برای باز تولید نتایج میتونه به کارمون بیاد.
تابع مهم بعدی تابع fit هست تابعی که در طی اون فرایند یادگیری برای مدل انجام میشه و وزنهای مناسب برای اون بدست میاد. روند کار در تابع به این صورته:
تابع net_input مقدار مطلق تابع «فی» را محاسبه میکنه و
تابع Predict هم ورودیهای دریافتی رو متناظرا به دو دستهبندی تعریف شده تخصیص میده.
حالا ما یک کلاس داریم که توانایی یادگیری دستهبندیهایی دوتایی را داره و میتونه دادههای جدید را برای ما پیشبینی کنه. مرحله بعدی آزمایش الگوریتم هست.
برای ارزیابی مدل ما از دادههای معروف گلهای زنبق استفاده میکنیم. برای اینکه نمایشدادهها راحتتر باشه. فقط از دو متغیر طول کاسبرگ «sepal» و طول گلبرگ«petal» استفاده میکنیم و البته فقط از دوگونه برای پیشبینی استفاده میکنیم.
دادهها رو از پایگاه داده معروف UCI بر میداریم.
df = pd.read_csv('https://archive.ics.uci.edu/ml/'
'machine-learning-databases/iris/iris.data', header=None)
در این مرحله دادههای مربوط به این دوگونه با طول کاسبرگ و گلبرگ متفاوت را ترسیم میکنیم.
# select setosa and versicolor
y = df.iloc[0:100, 4].values
y = np.where(y == 'Iris-setosa', -1, 1)
# extract sepal length and petal length
X = df.iloc[0:100, [0, 2]].values
# plot data
plt.scatter(X[:50, 0], X[:50, 1],
color='red', marker='o', label='setosa')
plt.scatter(X[50:100, 0], X[50:100, 1],
color='blue', marker='x', label='versicolor')
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.legend(loc='upper left')
plt.show()
بنظر میاد که الگوریتم ما کار سختی برای پیشبینی نداره.
#define the classifier
ppn = Perceptron(eta=0.1, n_iter=10)
# Train the classifier
ppn.fit(X, y)
plt.plot(range(1, len(ppn.errors_) + 1), ppn.errors_, marker='o')
plt.xlabel('Epochs')
plt.ylabel('Number of updates')
plt.show()
همونطور که مشاهده میکنید بعد از ۶ تلاش مدل بدون خطا میتونه پیشبینی خودش رو ارائه کنه.
در نهایت خوبه که ببینیم مدل چه جوری این فضای دوبعدی رو دستهبندی میکنه.« برای مشاهده کد میتونید به نوتبوک مربوط به این درس مراجعه کنید.»
و همونطور که دیدید این الگوریتم خطی ما به خوبی تونست پیشبینی خودش را برای دستهبندی گونههای مختلف گل زنبق ارائه بده.
ما توی این نوشته سعی کردیم یکی از سادهترین روشهای ممکن برای پیشبینیهای آتی را پیادهسازی کنیم. در این مسیر یادگرفتیم که
برای استفاده بهتر از این قسمت بهتون توصیه میکنم که حتما به گیتهاب این دوره سر بزنید، اونجا میتونید کدها رو به صورت کامل مشاهده کنید و با کلیک کردن روی آیکون binder در هر نوتبوک میتونید اون رو در مرورگرتون بدون نصب چیز جدیدی اجرا کنید.
در نهایت امیدوارم با قلبهاتون در ویرگول، ستارههاتون در گیتهاب و انتشار این دوره با دوستاتون برای ادامه این دوره در دوران قرنطینه به من انگیزه بدید.
ممنون میشم که اگر نکته، پیشنهاد یا سوالی داشتید، در اینجا، issueهای گیتهاب دوره و یا توییتر با من در میون بگذارید.
پ.ن:
بخش زیادی از محتوای این قسمت با استفاده از کتاب پایتون و یادگیری ماشین نوشته سباستین راسکا و وحیدمیرجلیلی آماده شد بود و در ادامه نیز این کتاب مرجع اصلی محتوا خواهد بود.
۲- پیاده سازی اولین مدل یادگیری ماشینی(همین پست)
۳- آشنایی با مدلهای scikit-learn(هفته اول فروردین ۹۹)