<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Amir Mohammad Piran</title>
        <link>https://virgool.io/feed/@AmirMohammadPiran</link>
        <description>دانشجوی کارشناسی مهندسی کامپیوتر تو دانشگاه شهید بهشتی؛ علاقمند به لینوکس؛ پایتون و هوش مصنوعی و امنیت (=</description>
        <language>fa</language>
        <pubDate>2026-06-07 18:16:08</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/1708177/avatar/q8MvFM.jpeg?height=120&amp;width=120</url>
            <title>Amir Mohammad Piran</title>
            <link>https://virgool.io/@AmirMohammadPiran</link>
        </image>

                    <item>
                <title>شبکه های عصبانی به زبان ساده! ?</title>
                <link>https://virgool.io/@AmirMohammadPiran/%D8%B4%D8%A8%DA%A9%D9%87-%D9%87%D8%A7%DB%8C-%D8%B9%D8%B5%D8%A8%D8%A7%D9%86%DB%8C-erup2wilzupw</link>
                <description>یه بار توی کامنتی از یکی از همین پست های ویرگولم، یه بنده خدایی منو به چالش توضیح دادن شبکه های عصبی مصنوعی (Artificial Neural Networks) دعوت کرد. بنده هم به مثال Barney توی سریال HIMYM، گفتم: «!!Challenge Accepted»?. احتمالا قراره این مطلب کمی طول بکشه ولی بهتون قول میدم که تاحالا این دیدگاه رو از شبکه های عصبی ندیدین! به جای شروع با توضیحات non-sense و گیج کننده مثل هر مطلب دیگه ای، باید یه مفهوم رو بهتون منتقل کنم! خب! بریم که رفتیم!شبکه ی عصبی مصنوعی چیه؟ اگه بگم الگوریتم، درست گفتم، اگه بگم روش محاسباتی درست گفتم و اگه بگم تابع هم درست گفتم. ولی بیاین بچسبیم به همین تعریف تابع طور. شبکه ی عصبی یه تابع خیلی گنده اس که ورودی ایکس رو میگیره و یه سری محاسبات عجیب و غریب انجام میده و ایگرگ رو خروجی میده. مثل هر الگوریتم Supervised دیگه ای! حالا این ایگرگ میتونه یه مقداری رو پیش بینی کنه (یعنی Regression) یا یه تشخیصی رو انجام بده (یعنی Classification) که بیشتر با این مورد دومی کار داریم. خب فعلا این تعاریف رو همینجا نگه داریم و بریم با یه وسیله خیلی باحال آشنا شیم که کلید یاد گرفتن مفهوم شبکه های عصبیه! تاحالا اسم تخته گالتون (Galton Board) به گوشتون خورده؟ اگه نه، گیف پایین رو نگاه کنین!تخته گالتون یه دستگاهه مثل یه ساعت شنی، با این تفاوت که به جای دونه های شن، تعداد زیادی گوی فلزی داره. این توپ ها از بالا رها میشن و از یه مسیر مثل عکس پایین عبور میکنن:گوی ها به اون موانع شیش ضلعی میخورن (موانع میتونن دایره ای یا مثلثی هم باشن) و مسیرشونو عوض میکنن و در نهایت میفتن توی یه سری مخزن. به طور کلی هم شکل قرارگیری نهایی گوی ها، توزیع گاوسی (Gaussian Distribution) یا همون توزیع نرمال (Normal Distribution) هست. اگه نمیدونین اینا چین، عیب نداره! اصن کاری با این دو عزیز نداریم! فقط کافیه بدونین که این دستگاه هم یه جور تابعه که گوی های ایکس رو از مسیرهایی میگذرونه و میریزه توی مخزن ایگرگ.حالا ببینین این دستگاه نسبتا نامربوط چقد قشنگ شبکه های عصبی رو توضیح میده:شبکه ی عصبی مجموعه ای از اون موانع شیش ضلعیه که میتونن گوی های فلزی ایکس رو دریافت کنن و پاس بدن به یه مانع شیش ضلعی دیگه توی لایه بعدی و اونقدر این پاس کاری رو ادامه بدن تا در نهایت بندازنش توی مخزن درست!حالا بیاین تخته گالتون رو یکم پیشرفته تر کنیم. نظرتون چیه شکل یکی از موانع شیش ضلعی رو مقداری عوض کنیم:طبق این عکس اگه تغییر کوچیکی توی شکل یه مانع ایجاد کنیم، میتونیم گوی های خاصی رو به جهتی که میخوایم هدایت کنیم. یه تغییر دیگه هم میتونیم ایجاد کنیم:توی این نوع تغییر هم گوی هایی که مسیر مستقیم میرن و به مانع برخورد نمیکنن، با بزرگتر کردن ابعاد به مانع میخورن و مسیرشون عوض میشه. همینطور برعکس! ینی اگه مانع کوچیکتر بشه گوی های که قبلا به مانع میخوردن ممکنه مسیر مستقیم برن. حالا چی میشه اگه این دو نوع تغییر رو بر حسب نیاز روی تمام موانع ایجاد کنیم!؟ میتونیم به کمکش توابع پیچیده تری به غیر از توزیع گاوسی ایجاد کنیم!! مثل عکس زیر:حالا هدف از بیان این ها چی بود؟ ما به کمک دو سوال ساده ی «گوی به مانع بخوره یا نه» و «اگه به مانع بخوره سمت چپ بره یا راست» میتونیم تصمیم بگیریم که چه نوع خروجی ای رو داشته باشیم. یه شبکه ی عصبی هم همین کار رو انجام میده. به کمک این دو سوال میتونیم دو تا مفهوم کلیدی توی شبکه های عصبی رو معنی کنیم. فرض کنید موانع همون نورون ها باشن. اولین مفهوم وزن (Weight) هست که یه عدده که میزان ارتباط هر نورون با نورون دیگه رو مشخص میکنه. با مثال تخته ی گالتون یعنی احتمال اینکه هر گوی بخوره به کدوم مانع توی لایه بعدی. هر چی این وزن بزرگتر باشه، ینی رفتن گوی از مسیری که ختم میشه به اون مانع، محتمل تره. این مفهومیه که میتونیم با تغییر شکل موانع تنظیمش کنیم. ینی مثلا یه بخش به سمت چپ مانع اضافه کنیم تا احتمال رفتن گوی ها به سمت راست بیشتر بشه و در نتیجه وزن مسیر های سمت راست. نکته ای که می مونه اینه که توی شبکه ی عصبی ممکنه از یه نورون بتونیم به هر نورونی توی لایه ی بعد بریم، درحالی که در عمل توی تخته ی گالتون، مانع میتونه فقط به مانع چپ یا راستی لایه بعدی منتهی بشه.نورون میتونه به هر نورونی تو لایه بعدی بره، ولی مانع فقط میره به مانع چپ یا راست توی لایه بعد!مفهوم دوم که مقداری پیچیده تره، فعالیت‌ (Activation) هر نورونه. با توجه به اسمش هم یعنی چه میزان اون نورون فعاله (و چقد اون مانع توی تصمیم گیری برای تغییر جهت مسیر گوی تاثیرگذاره). به طور تقریبی میتونیم این مفهومو همون اندازه ی مانع تعبیر کنیم. هرچی اندازه ی مانع بزرگتر باشه میتونه روی گوی های بیشتری تاثیر بذاره و برای مسیرشون تصمیم گیری کنه. برای اینکه مثال تخته ی گالتونی رو شبیه تر به شبکه ی عصبی کنم:طبق این عکس، مانع بزرگتر شده و مسیر یه گوی بیچاره رو جوری که ما میخوایم تغییر داده. اما این میزان فعالیت رو چجوری میتونیم تعریف کنیم؟ شبکه عصبی اینطور فعالیت هر نورون رو برامون تعریف میکنه:هر وزن رو با فعالیت اون نورونی که وزن ازش خارج شده ضرب کنید. حاصل ضرب هارو جمع کنید. به جمع یه عدد به اسم بایاس (Bias) اضافه کنید. این جمع رو از توی یه تابع فعالساز بگذرونید. خروجی میشه فعالیت اون نورون!خب. تعریف پیچیده ای شد. بیاین ساده ترش کنیم. به این عکس نگاه کنین:توی مثال تخته ی گالتون، یعنی بیاین برای به دست آوردن بزرگی یا فعالیت مانع شماره ی فلان، به صورت بازگشتی، فعالیت های موانع لایه قبلی رو در وزن مسیرشون به مانع کنونی ضرب کنین و این ضرب ها رو با یه مقداری به اسم بایاس جمع کنین (توضیحشو میذارم واسه ی بعد) و این حاصل جمع رو ورودی بدین به یه تابع. ما پس تونستیم میزان بزرگی و تاثیرگذاری یه مانع رو برحسب وزن ها و بزرگی موانع قبلش به دست بیاریم. منطقی هم هست. اگه موانع قبلی فعالیتشون بالا باشه (برای مسیر تعداد زیادی از گوی های تصمیم گیری کنن) و از طرفی وزن های وارد شده به این مانع بزرگ باشن (گوی ها شانس زیادی برای برخورد با این مانع داشته باشن) پس این مانع بزرگی (تاثیرگذاری) زیادی داره. پس این دوتا عامل توی بزرگیِ بزرگی(!) تاثیر مستقیم دارن. حالا اون تابع فعالساز یا ()g چیکاره اس؟اگه این تابع وجود نداشته باشه، شبکه ی عصبی ما عملا با رگراسیون خطی معادل میشه. ینی خروجی نهایی شبکه مون یه ترکیب خطی از ورودی میشه. توی مطلب بعدی با توضیح Forward Propagation میتونم کاملتر این مطلب رو توضیح بدم. فعلا بپذیرین که به شدتتت به این تابع نیاز داریم!?توابع فعالساز دو دسته ان: خطی و غیر خطی. خطی ینی y = x  و عملا ینی تابع فعالساز نداشته باشیم. دسته ی دوم هم که غیر خطی باشه، تابعیه مثل همین سیگموید. البته توی عمل میتونیم از توابع دیگه ای هم به عنوان تابع فعالساز استفاده کنیم که از سیگموید بهتر عمل میکنن. توابع غیر خطی مثل ReLU و Leaky ReLU و ... که خودتون میتونین بعدا راجبشون بخونین و اینجا بهتره بهشون نپردازم. کافیه بدونین که وظیفه ی این توابع غیر خطی، سازگار شدن با پیچیدگی های ورودیشونه. حالا مقداری از نحوه ی عملکرد شبکه های عصبی بگم. یه سوال بزرگ که احتمالا توی ذهنتون شکل گرفته اینه که، مگه ما میتونیم یه کار خیلی پیچیده ای مثل هدایت گوی ها به مخزن درست رو انجام بدیم؟ اصن مگه میشه بیایم به ازای هر گوی، مسیرشو ببینیم و موانع رو جوری تغییر بدیم که گوی بره به جای درستش؟ متاسفانه خیر؛ ما نمیتونیم این کار رو انجام بدیم. اما شبکه ی عصبی این توانایی رو داره که خودش رو با توجه به خواسته ی ما وفق بده. اینجا باید گریز بزنم به مفاهیم پایه یادگیری نظارت شده ماشین (Supervised Machine Learning). اگه مطالب قبلیمو خوندین، توی تمام اون ها ما مقداری داده به سیستم میدادیم تا الگوریتمی رو ازشون کشف کنه و بتونه پیش بینی هایی بر حسب اون چه که یاد گرفته انجام بده. تو شبکه های عصبی هم همینجوریه. ما داده هایی رو به شبکه ی عصبی میدیم، و شبکه ی عصبی خودش رو با توجه به اون وفق میده و میتونه برای دیتاهای جدید، پیش بینی رو انجام بده.خیلی راحت میشه این مفاهیم رو با مثال تخته ی گالتون توضیح داد. فرض کنین  یه تخته ی گالتون ورژن 2023 داریم که میتونه شکل و اندازه ی موانعش رو تغییر بده! یه گوی قرمز رنگ میندازیم داخل و به تخته میگیم که این گوی باید بره تو مخزن شماره یک. تخته موانعش رو جوری تغییر میده که به ازای هر گوی قرمزی که میگیره، هدایتش کنه به مخزن شماره یک. حالا یه گوی آبی میندازیم و به تخته میگیم این گوی رو بنداز تو مخزن شماره 2. همین کار رو برای یه گوی زرد هم انجام میدیم و مشخص میکنیم که بره به مخزن شماره ی 3. حالا تخته ی گالتون «یاد گرفته» که گوی قرمز میره مخزن یک، آبی میره مخزن دو و زرد میره مخزن سه. ما به اصطلاح مرحله تمرین دادن (Training) رو انجام دادیم. حالا میتونیم یه گوی با هر رنگی رو بندازیم داخل تخته و تخته با توجه به اینکه مقدار قرمز یا آبی یا زرد توی اون رنگ بیشتره، میندازتش توی مخزن درستش! اینجا مدل تخته ای مون رو تست (Test) کردیم. خب فکر میکنم برای این بخش کافی باشه چون میخواستم فقط به مفهومش بپردازم (= احتمالا یه مطلب دیگه هم بنویسم درباره ی Forward Propagation و Back Propagation که الگوریتمهایی هستن که باعث میشن شبکه عصبی بتونه وزن های خودشو تغییر بده و در نتیجه بتونه پیش بینی درستی رو انجام بده. منتظر بخش دوم باشین!</description>
                <category>Amir Mohammad Piran</category>
                <author>Amir Mohammad Piran</author>
                <pubDate>Tue, 20 Dec 2022 18:28:40 +0330</pubDate>
            </item>
                    <item>
                <title>رگراسیون لجستیک در پایتون!</title>
                <link>https://virgool.io/@AmirMohammadPiran/%D8%B1%DA%AF%D8%B1%D8%A7%D8%B3%DB%8C%D9%88%D9%86-%D9%84%D8%AC%D8%B3%D8%AA%DB%8C%DA%A9-%D8%AF%D8%B1-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-eimz3ems0w5i</link>
                <description>سلام! (= توی این مطلب میخوایم رگراسیون لجستیک (یا به قول بعضیا لاااجستیک!) رو به صورت وکتورایزد (vectorized) یا برداری شده پیاده کنیم! و البته! بدون استفاده از لایبرری sklearn! همش با خودمون! منظورم از وکتورایزد هم اینه که یه کاری کنیم که به جای اجرا شدن با لوپ و این نوع محاسبات وقتگیر، از محاسبات برداری و ماتریسی جبر خطی استفاده بشه که باعث میشه سرعت اجرا فوق العاده بالا بره. قبل از شروع، اگه با رگراسیون لجستیک به صورت تئوری آشنا نیستین، حتما این مطلبم درباره همین موضوع رو بخونین! خب! شروع کنیم!واسه ی شروع، از کتابخونه های نامپای (Numpy)، پانداز (Pandas) و مت پلات لیب (Matplotlib) استفاده میکنیم که به ترتیب واسه ی کار با ماتریس ها و بردارها، کار با دیتاست و نمایش نمودار استفاده میشن. این سه تا کتابخونه رو ایمپورت میکنیم:import numpy as np
import pandas as pd
import matplotlib.pyplot as pltاین لینک دیتافریمی هست که قراره ازش استفاده کنیم! که تشکیل شده از یه تعداد عدد به عنوان x و یه تعداد 0 و 1 به عنوان y. ینی این شکلی:هدف اینه که بتونیم یه تابع سیگموید (sigmoid) رو طوری روی این نمودار جا بدیم که به ازای مقادیر بزرگتر یا مساوی 25 (تقریبا!) مقدار تابع از 0.5 بزرگتر یا مساویش بشه (و در نتیجه جوابش رو 1 درنظر بگیریم)؛ و همینطور برای مقادیر کوچیکتر از اون مرز، مقدار تابع هم از 0.5 کوچیکتر باشه. خب. یه تابع  initializer تعریف میکنیم که دیتا رو برامون لود میکنه:def initializer():
    df = pd.read_csv(&#039;dataframe.csv&#039;)
    x = df.x.values.reshape(-1,1).T
    y = df.y.values.reshape(-1,1).T
    w = np.random.random((1,x.shape[0]))
    b = 0
    x = np.divide(x, 100)
    print(&#039;x shape:&#039;,x.shape,&#039;, w shape:&#039;,w.shape,&#039;, y shape:&#039;,y.shape)
    return x, y, w, bخب یه سری نکته هست که درباره ی این چند خط باید بگم. توی خط اول که تابع رو تعریف کردیم، توی خط دوم به کمک کتابخونه پانداز، دیتافریم رو لود کردیم و ریختیم توی یه متغیر؛ و اما دو خط بعدی. از اونجایی که تصمیم گرفتیم به صورت وکتورایزد عمل کنیم، از این روش واسه ی تعریف x و y استفاده کردیم. واسه ی این که دقیقتر متوجه بشین توی اون دو خط چه اتفاقی میفته، به اینجا دقت کنین. اگه فقط از عبارت  x = df.x.values استفاده کنیم، یه آرایه ی به ابعاد یک در m مثل [1,2,3] خروجی میده که m به تعداد ایکس های موجود در دیتافریمه. حالا اگه به صورت  x = df.x.values.reshape(-1,1) بنویسیمش، میاد هر عنصر رو توی یه سطر جا میده و ابعادش میشه m در یک. ینی مثلا:و اگه یه  T. به آخرش اضافه کنیم این بردار ترانهاده (Transpose) میشه و به فرم [[3] ,[2] ,[1]] درمیاد. حالا ممکنه بپرسین چرا این همه سختی به خرج دادیم و به این فرم درآوردیمش؟! مگه [1,2,3] چش بود؟! (=نکته توی خط 5 نهفته شده. ینی w (که همون θ₁ عه). به این صورت تعریفش کردیم که اولا رندوم باشه، دوما ابعادش یک در تعداد ستون های x باشه. حالا چرا؟ درواقع میتونستیم همون اول به جای عبارت  x.shape[0] بنویسیم یک؛ اما صورتی از مسئله رو درنظر بگیرین که هر ایکسمون به جای یه عدد، چندین عدد باشه. مثلا طبق مثال معروف فروش بستنی بر حسب دما، عوامل دیگه ای هم دخیل باشن، مثل طعم یا رنگ بستنی( اگه ذغالی باشه تو دمای 273- هم میشه خورد??). در اون حالت دیگه یه دونه w برای کل ایکس ها کافی نیست و باید تعدادش به تعداد فیچر (feature) های ایکس باشه. (مثال پیچیده(!): اگه ایکس 2 در 27 باشه ینی دوتا فیچر و 27 تا نمونه، پس w میشه 1 در 2. ینی دوتا دونه w! دقت کنین که ضرب ماتریس x در بردار w باید قابل انجام باشه!)در خط بعدی متغیر b (که همون θ₀ عه) رو مساوی صفر گذاشتیم، و یه خط مرموز! دلیل اینکه چرا تمام اعداد ایکس رو تقسیم بر 100 کردم رو بعدا بهتون میگم؛ فعلا بپذیرین (= و درنهایت هم چاپ ابعاد x و y و w و خروجی دادنشون به همراه b.x, y, w, b = initializer()
plt.scatter(x, y, color=&#039;red&#039;, s=60)
plt.xkcd()
plt.show()توی این 4 خط، اول تابع initializer رو صدا زدیم و خروجی هاشو ریختیم توی 4 تا متغیر، و درنهایت نمودار x و y  رو به کمک کتابخونه مت پلات لیب چاپ کردیم. (اون خط سوم باعث میشه نمودار کیوت نشون داده بشه! (= ) و خروجی به این صورت درمیاد:خب. حالا تابع فرض (hypothesis) که همون تابع سیگموید هست رو تعریف میکنیم:def sigmoid(x):
    return 1/(1 + np.exp(-x))یادتونه اون بالا مقادیر ایکس رو بر 100 تقسیم کردم؟ جوابش اینجاست! مشکلی که در صورت تقسیم نکردن پیش میاد، اینه که بخش np.exp(-x) فوق العاده کوچیک میشه (ینی مثلا e به توان منفی 100!!!) و این مقدار خیلی کوچیک به عنوان صفر تعبیر میشه و عملا خروجی تابع سیگموید مساوی یک میشه. این یک توی تابع هزینه (که عبارتی مثل log(1 - hθ(x)) داره) باعث میشه به log(0) بخوریم و به سوی بی نهایت و فراتر از آن! پس برای رفع این مشکل سعی میکنیم ایکس ها رو کوچیک کنیم و مثل اینجا تقسیم بر یه عدد کنیم؛ و یا روش دیگه ای به نام فیچر اسکیلینگ (Feature Scaling) که اصولی تره. خب. ادامه میدیم:def cost(y_h, y):
    m = y_h.shape[0]
    cost = 0
    cost = ((-y * np.log(y_h)) - (1 - y) * np.log(1 - y_h)) / m
    return cost.sum()اینجا تابع هزینه رگراسیون لجستیک رو به صورت کد درآوردیم. اگه یادتون باشه تابعش این شکلی بود:اگه هم احیانا فرم شرطی این فرمول رو دیده بودین ایرادی نداره. این همون تابعه؛ فقط اگه y مساوی صفر باشه، عبارت اولی حذف میشه و اگه مساوی یک باشه، عبارت دومی حذف میشه. توی کد بالا هم دوتا متغیر به عنوان ورودی پاس داده شدن که اولی y_h عه و همون حدسیه که سیستم زده (hθ(x)) و دومی y، که جواب اصلی اون نمونه هست. m تعداد نمونه ها رو میگیره و خط بعدی هم مقدار اولیه کاست رو مساوی صفر میذاره. تنها نکته ای که وجود داره اینه که کاست مساوی یه بردار میشه (چون y و y_h هم بردارن!) و ما درنهایت جمع عناصر این بردار رو خروجی میدیم. فقط یه عدد!حالا باید کدی رو بزنیم که قراره این تابع هزینه رو حداقل کنه. اینجا من کد گرادیان نزولی (Gradient Descent) رو زدم و اگه بخوام کامل توضیحش بدم، بهتره یه مطلب دیگه واسش بنویسم?. میتونین این بخش رو ران کنین و بگذرین ازش!def GD(w, b, y, iteration, alpha, limit):
    list_iter = []
    list_cost = []
    for i in range(iteration):
        w = w - alpha * np.sum((sigmoid(np.dot(w,x) + b) - y) * x)
        b = b - alpha * np.sum(sigmoid(np.dot(w,x) + b) - y)
        if i % limit == 0:
            list_iter.append(i)
            list_cost.append(cost(sigmoid(w.dot(x) + b), y))
    return w, b, list_cost, list_iterبه طور کلی کاری که این بخش کد انجام میده اینه که مقادیر وزن مثل w و b رو ورودی میگیره و طی یه حلقه، اونا رو یه طوری کم و زیاد میکنه که کاست حداقل بشه. همچنین دوتا لیست خالی هم در ابتداش تعریف کردم که به ازای هرچند بار اجرا شدن حلقه، مقدار تابع کاست و همون تعداد اجرا شدن حلقه رو داخلشون ذخیره کنه که بعدا بتونیم به تصویر بکشیمش. به کمک این کار میتونیم متوجه بشیم که آیا الگوریتم حداقل کردن کاست به درستی کار میکنه یا نه.حالا از تمام کد های قبلی به این صورت استفاده میکنیم:print(&#039;w and b before Gradient Decsent: &#039;, w, b)
w, b, list_cost, list_iter = GD(w, b, y, 1000, 0.1, 10)
print(&#039;w and b after Gradient Decsent: &#039;, w, b)
plt.plot(list_iter,list_cost)
plt.show()که این خروجی رو میده:توی این بخش از کد، اولا تابع گرادیان نزولی رو ران کردم و بعدش نمودار اون دوتا لیست کاست ها و شمارش ها رو چاپ کردم.همونطور که مشخصه، کاست بعد از تعدادی شمارش به حداقل رسیده و این ینی الگوریتم به درستی کار میکنه. و از اون مهمتر! ما w و b برای کشیدن اون تابع سیگمویدی که میخواستیم رو داریم! حالا نمودارشو رسم میکنیم:y_test = sigmoid(w.dot(x) + b)
plt.scatter(x, y_test, s=10, color=&#039;b&#039;)
plt.scatter(x, y, color=&#039;r&#039;)
plt.show()و خروجی رویایی:کاری که توی چند خط آخر کردم این بود که به ازای نمونه های ایکس، تابع سیگموید رو (به همراه w و b جدید!) فراخوانی کردم و ریختمشون توی y_test. حالا یه بار نمودار x و y_test رو کشیدم و یه بار x و y.حالا تنها کاری که لازمه اینه که یه شرط بذاریم برای اینکه آیا جواب از 0.5 کوچیکتره یا نه. اگه آره پس خروجی مساوی صفره، وگرنه مساوی یک. در هر صورت، بخش سخت کارو گذروندیم و بهتره مطلب رو از اینی که هست طولانی تر نکنم!?تبریک میگم! شما اولین کد رگراسیون لجستیکتون رو زدین!?</description>
                <category>Amir Mohammad Piran</category>
                <author>Amir Mohammad Piran</author>
                <pubDate>Fri, 18 Nov 2022 00:53:45 +0330</pubDate>
            </item>
                    <item>
                <title>رگراسیون لجستیک به زبان ساده</title>
                <link>https://virgool.io/@AmirMohammadPiran/%D8%B1%DA%AF%D8%B1%D8%A7%D8%B3%DB%8C%D9%88%D9%86-%D9%84%D8%AC%D8%B3%D8%AA%DB%8C%DA%A9-%D8%A8%D9%87-%D8%B2%D8%A8%D8%A7%D9%86-%D8%B3%D8%A7%D8%AF%D9%87-mehnb6dnmdy2</link>
                <description>سلام (= اگه به پست های قبلیم نگاهی انداخته باشین، درباره رگراسیون (Regression) توضیح دادم و لازم بود مطلبی هم درباره ی دسته بندی (Classification) بنویسم. یه مطلب برای مفهوم و یه مطلب هم برای پیاده سازی توی پایتون. اینجا قراره درباره مفهوم و فرایند کار رگراسیون لجستیک (Logistic Regression) حرف بزنیم. نه اشتباه نکنین! این رگراسیون با اون رگراسیون فرق داره -ــــ- رگراسیون لجستیک شاخه ای از دسته بندیه و هیچ ربطی هم به رگراسیون( که پیش بینی عددی و کمّی انجام میده) نداره! قبل از شروع پیشنهاد میکنم درباره ی رگراسیون خطی بخونین؛ چون خیلی به درک مفاهیم این مبحث کمک میکنه. اینجا خودم یه توضیح به زبان ساده براش گذاشتم(= خب، بریم سر اصل مطلب. طبق معمول یه دیتاست داریم که قراره بدیم به سیستم، سیستم اون رو بررسی کنه و به کمک الگوریتمی که ازش کشف کرده برای ما مقادیری رو پیش بینی کنه. توی رگراسیون پیش بینی به این صورت بود که یه عدد (که میتونست هرمقداری باشه) به ما خروجی میداد. مثلا دمای هوا رو به سیستم میدادیم و سیستم میزان فروش بستنی فروشی رو برامون حدس میزد. اما توی دسته بندی، قضیه یکم فرق داره. اینجا سیستم قراره از بین چندتا گزینه انتخابی رو انجام بده. مثلاً وزن و قد یه فرد رو بگیره، و جنسیتش رو حدس بزنه. پس سیستم اینجا قراره «انتخاب» کنه. مثالی که اینجا میخوایم بررسی کنیم، باز هم به بستنی مربوطه (= به نمودار پایین نگاه کنین:این نمودار بستنی خریدنِ آقای حیف نونه که تو دماهای مختلف ثبت شده! یک توی محور ایگرگ ها یعنی توی اون دما بستنی خریده و صفر یعنی نخریده. طبیعتاً هرچی دما بالاتر رفته احتمال بستنی خریدنش بیشتر شده. هرچند روزی هم بوده که سرد بوده ولی زده به سرش و بستنی خریده، و یا روزای گرمی که پول نداشته بستنی بخره! اما کلیت نمودار درستی رابطه دما با خرید بستنی رو نشون میده. خب؛ بیاین این رابطه رو پیدا کنیم. به نمودار دوباره نگاه کنین؛ از حوالی دمای 18 درجه و بیشتر، حیف نون غالباً بستنی خریده و برای قبل از اون حس کرده هوا زیادی سرده واسه بستنی خوردن (هرچند بستنی تو هر دمایی میچسبه (= ). پس الگوریتمی که قراره پیاده سازی کنیم باید این رو متوجه بشه و به ازای ورودی های بیشتر از 18 بگه بستنی خریده و برای ورودی های کمتر از 18 بگه نخریده. از اونجایی که رگراسیون خطی رو بلدیم، میتونیم ازش به عنوان یه مدل پیشبینی کننده استفاده کنیم. یعنی به صورت نمودار پایین:همونطوری که میبینین، میتونیم این خط رو رسم کنیم؛ نکته اینه که به ازای ورودی هایی که بهش میدیم، اگه خروجی از 0.5 بزرگتر یا مساویش باشه، سیستم اون رو یک درنظر میگیره (یعنی بستنی خریده) و به ازای خروجی های کوچیکتر از 0.5 هم 0 رو خروجی میده (یعنی بستنی نخریده). برنامه همونجوری که میخواستیم برای دماهای بیشتر از 18 به ما 1 خروجی میده و برای کمتر از اون هم 0 خروجی میده. تا اینجا به نظر میاد مشکل حل شده و ما با همون دانسته های قبلیمون از پس این مسئله هم براومدیم؛ اما یه مشکلی برای این مدل وجود داره! فرض کنین توی دمای 57 درجه که دمای عجیب و خیلی زیادیه، آقای حیف نون بستنی خریده. یعنی نمودار زیر:حالا اگه برای این حالت هم با کمک رگراسیون خطی یه خط بسازیم، بعضی از پیشبینی های درست قبلی از بین میره و دیگه اون مرز 18درجه رعایت نمیشه. درواقع به خاطر یه دیتای دورافتاده، تمام پیشبینی ها واسه دیتاهای دیگه دچار تغییر و بعضا اشتباه میشه. به این صورت:همونطور که می بینین مرز 18درجه به 20درجه تبدیل شده و به ازای ورودی های 18 و 20 جواب اشتباه 0 رو درنظر گرفته. پس رگراسیون خطی برای این نوع از مسئله پیشنهاد خوبی نیست؛ چون کافیه یه دیتای دورافتاده داشته باشیم تا درستی تمام حدسای قبلی زیرسوال بره. پس باید غیر از معادله خط ساده، یه تابعی داشته باشیم که برای مقادیر دورافتاده، بقیه مقادیر رو دچار مشکل نکنه و حدس معقولی هم بده. خوشبختانه، این تابع وجود داره و بهش میگیم تابع سیگموید (Sigmoid)! ببینین:از خواص خوب این تابع اینه که همیشه بین صفر و یک قرار میگیره و برای مسئله ما بی نقص به نظر میاد. با فرض اینکه با مفاهیم تابع فرض (hypothesis) و تابع هزینه (cost) آشنایی دارین یکم بیشتر درباره ی تابع سیگموید توضیح میدم. (اگه هم نمیدونین این دو تابع چی ان و به چه درد میخورن این مطلب رو بخونین =) ) تابع فرض توی رگراسیون خطی به صورت y = θ₀ + θ₁x بود و یه خط رو برامون می ساخت. اما اینجا تابع فرض رو مساوی تابع سیگموید میذاریم و اینجوری حدسی که سیستم میزنه همیشه بین 0 و 1 قرار میگیره. از طرفی اگه یه عدد دور افتاده مثل 57درجه رو ورودی بهش بدیم، با تقریب خیلی خوبی 1 حدس میزنه. پس این از تابع فرضمون. اما تابع هزینه چی؟ اگه از تابع هزینه توی رگراسیون خطی استفاده کنیم به نمودار عجیب و غریبی میرسیم که پر از مینیمم های موضعیه و ممکنه هیچوقت به مینیمم مطلق نرسیم:خب باز هم میگم، از قیافه فرمول بالا نترسین! ما اینجا کاری باهاش نداریم (= فقط بدونین اون بی ریخت، تابع هزینه برای رگراسیون خطیه! اما تابع هزینه برای رگراسیون لجستیک فرق میکنه. اینجا تابع هزینه یک تابع لگاریتمیه که فرمولش به این صورت نوشته میشه:خوشبختانه به اندازه ی فرمول قبلی ترسناک نیست (= اما به اندازه ی کافی گیج کننده هست! بذارین توضیحش بدم. ما توی رگراسیون خطی میومدیم فاصله ی هر نقطه روی نمودار با نقطه ای که برنامه حدس زده رو حساب میکردیم و جمع میزدیم و این جمع رو به حداقل میرسوندیم. اینجا اما لازم نیست فاصله دو نقطه رو حساب کنیم. نقاط روی نمودار یا صفر هستن یا یک و برای هرحالتشون یه تابع داریم. فرض کنیم برای نقطه ی 20درجه که y=1 هست (ینی تو دمای 20 درجه بستنی خریده)، قراره تابع هزینه رو حساب کنیم. میریم سراغ شرط اول و تابع هزینه مون میشه J = -log(hθ(x)) . اگه نمودار این تابع رو رسم کنیم این شکلی میشه:حالا این نمودار چه چیزی رو داره به ما میگه؟ میدونیم که توی این حالت جواب حقیقی 1 بوده (y=1). حالا هرچی اون hθ(x) (یا همون تابع فرض) به 1 نزدیک تر باشه مقدار تابع هزینه هم کمتر و کمتر میشه. تاجایی که اگه hθ(x) مساوی یک باشه، تابع هزینه مساوی صفر میشه (به نمودار نگاه کنین). این یعنی سیستم کاملاً درست جواب رو حدس زده! از طرف دیگه، هرچی پیشبینی از جواب حقیقی دورتر باشه (یعنی  hθ(x) به صفر نزدیک تر باشه) تابع هزینه هم بزرگتر میشه و یه جورایی داره میفهمونه که این جواب خوبی نیست. به همین شکل میتونیم حالت دوم تابع هزینه که به ازای y=0 هست رو توضیح بدیم. نمودارش رو براتون میذارم، اما تفسیر و توضیحش با خودتون! (=مابقی مراحل مثل رگراسیون خطیه. یعنی به حداقل رسوندن تابع هزینه، به همون صورتی انجام میشه که توی رگراسیون خطی انجام میدادیم. حالا با روشهایی مثل گرادیان نزولی (Gradient Descent) یا معادله ی نرمال (Normal Equation) و یا روش های دیگه. خب این مطلب هم تموم شد! توی مطلب بعدی قراره این الگوریتم رو توی پایتون پیاده سازی کنیم! (=</description>
                <category>Amir Mohammad Piran</category>
                <author>Amir Mohammad Piran</author>
                <pubDate>Fri, 05 Aug 2022 19:13:58 +0430</pubDate>
            </item>
                    <item>
                <title>رگراسیون خطی در پایتون، 14 خط!</title>
                <link>https://virgool.io/@AmirMohammadPiran/%D8%B1%DA%AF%D8%B1%D8%A7%D8%B3%DB%8C%D9%88%D9%86-%D8%AE%D8%B7%DB%8C-%D8%AF%D8%B1-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-14-%D8%AE%D8%B7-ylyfd3reaxvb</link>
                <description>بله، واقعا 14 خط نیاز دارین تا رگراسیون خطی رو پیاده سازی کنین! (البته با کثیف کردن کد، کمتر از این هم میشه ولی نظافت مهمتره ((= ). خیلی گشتم برای یه آموزش ساده از کد رگراسیون خطی توی پایتون و هیچ جا توضیح جامعی واسش پیدا نکردم. پس لازم دونستم خودم یه مطلب براش بنویسم. از اینجا میتونین پست قبلیم که درباره مفهوم رگراسیون خطی هست رو بخونین!خب! برای رسیدن به این نتیجه خارق العاده(!) چی نیاز داریم؟ پایتون، لایبرری های numpy , pandas matplotlib و sklearn و یه IDE که از jupyter notebook  پشتیبانی کنه (مثل VS Code) و اندکی حوصله. از همه مهمتر، دیتابیس فروش بستنی بر حسب دما که اینجا قرارش دادم (=قبل از شروع کار اجازه بدین درباره لایبرری های مورد نیاز یه توضیح بدم. اینجا نمیتونم مفصل هر کدوم رو توضیح بدم و اگه خودتون باهاشون آشنا بشین خیلی بهتره. درواقع مهمترین ابزارها توی یادگیری ماشین همین لایبرریا هستن. نامپای (NumPy) یه لایبرری برای کار با بردار ها و ماتریس هاست. یعنی به کمک نامپای میتونین ماتریس های مختلفی بسازین، عملیات های مختلفی روشون انجام بدین و خلاصه هرچیزی که برای تحلیل ماتریس لازم دارین. لایبرری پانداز (Pandas) برای کار با دیتافریم ها و خوندن و نوشتن دیتا توی دیتافریم هست. پس ارتباط با دیتای برنامه رو، پانداز برامون فراهم میکنه. لایبرری بعدی مت پلات لیب (Matplotlib) هست که برای رسم نمودار های مختلف به کارمون میاد و یه خروجی تصویری بهمون تحویل میده. برای اینکه این تصاویر بتونن نمایش داده بشن باید IDEتون بتونه فایل های ipynb یا همون نوت بوک های ژوپیتر رو بخونه (اگه با VS Code کار میکنین فقط اکستنشن Jupyter رو براش نصب کنین!). در نهایت لایبرری اس کی لرن (sklearn) رو نیاز داریم که برامون تمام الگوریتم رگراسیون خطی رو زده و ما فقط اجراش میکنیم! (لازم نیس چرخ رو دوباره اختراع کنیم که! (=  ) برای نصبشون از pip استفاده میکنیم:pip install numpy matplotlib sklearn pandasخب با فرض اینکه همه ی نیازمندی ها رو نصب کردین، میریم سراغ کد. قبل از توضیح هر بخش، میخوام کلیت کد رو توضیح بدم که قراره چه اتفاقی بیفته! یه دیتافریم داریم که مثل یه تابع، یه مقادیری رو به مقادیر دیگه نسبت داده. دقیقتر بگم نمونه هایی از دمای هوا و میزان فروشی که بستنی فروشی توی اون دما داشته. برنامه ما به این دیتافریم نگاه میکنه و الگوریتمش رو کشف میکنه و ابزاری رو دراختیارمون قرار میده که بتونیم باهاش هرمقدار دلخواهی رو پیشبینی کنیم. پس توی کد 4 مرحله داریم: 1- خوندن دیتافریم 2- تبدیل کردنش به فرمتی که برای متدهای رگراسیون خطی قابل استفاده باشه 3- ایجاد خط 4- تست کردن برنامه و نمایش نمودارقبل از هرکاری لایبرری های مورد نیاز رو ایمپورت میکنیم. احتمالا با دستور import آشنایی دارین ولی کلیدواژه as ممکنه براتون جدید باشه. as فقط اسم لایبرری رو داخل برنامه تغییر میده. مثلا به جای استفاده از ()pandas.read_csv مینویسیم ()pd.read_csv  . خیلی ساده تر و تمیزتر! اوکی، بریم سراغ ایمپورت کردنا:import numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom sklearn.linear_model import LinearRegressionخب. باید دیتافریم رو بخونیم و بخش هاییش رو جدا کنیم. لایبرری پانداز ابزار خوندن دیتافریم از فایل رو در اختیارمون میده. فرمت مورد استفاده برای دیتافریم csv هست که یه نوع دیتافریمه که توش مقادیر با کاما ( , ) از هم جدا شدن و در هر خط یه نمونه وجود داره. خط اول هم اسم هر ستون رو مشخص میکنه. توی این دیتافریم دو ستون دما و فروش رو داریم که نمودارش این شکلیه:به کمک این تابع از لایبرری پانداز، دیتافریم رو میخونیم و توی یه متغیر به اسم df ذخیره میکنیم:df = pd.read_csv(&#039;database.csv&#039;)اگه دوست داشتین میتونین این متغیر df رو پرینت کنین و ببینین که خیلی مرتب دیتا رو توی خودش جا داده! و یا میتونین اسم ستون مثل Sales رو بعد از df بنویسین و اون رو پرینت بگیرین. اینجوری:print(df.Sales)که این خروجی رو به ما میده: output:
 0     193
 1     210
 2     324
 3     318
 4     407
 5     415
 6     403
 7     410
 8     519
 9     445
 10    543
 11    609
 Name: Sales, dtype: int64 همونطور که میبینین تمام محتویات ستون Sales رو برامون با اندیس نمایش داده. نمایش خوشگل و مرتبیه اما هنوز قابل استفاده نیست (= اون خط آخر اضافیه و به اندیس هم نیازی نداریم. پس میتونیم به کمک values فقط مقادیر رو استخراج کنیم: print(df.Sales.values)که خروجیش میشه:output:   [193 210 324 318 407 415 403 410 519 445 543 609]آهاا ! این شد یه چیزی! (= اما هنوزم قابل استفاده نیست! چون کلاس رگراسیون خطی که ایمپورت کردیم از ما فقط یه آرایه دو بعدی (ماتریس) ورودی میگیره و آرایه الانیمون یه بعدیه (برداره). اما مشکلی پیش نمیاد و ما میتونیم همین مقادیر رو به صورت آرایه دوبعدی بنویسیم. یعنی اینجوری:output:
 [[193]
  [210]
  [324]
  [318]
  [407]
  [415]
  [403]
  [410]
  [519]
  [445]
  [543]
  [609]]برای رسیدن به این فرم از دیتا، فقط کلیدواژه (1,1-)reshape  رو به بخش قبلی اضافه میکنیم؛ ینی اینجوری:print(df.Sales.values.reshape(-1,1))حالا این دو ستون دما و فروش رو توی دوتا متغیر ذخیره میکنیم تا بعدا بتونیم به تابع موردنیاز پاس بدیم. اینها همون مقادیری هستن که برنامه اونا رو بررسی میکنه و الگوریتم رو ازشون کشف میکنه. به این صورت:X_train = df.Temperature.values.reshape(-1,1)Y_train = df.Sales.values.reshape(-1,1)خب. دیتامون حاضر شد. حالا فقط باید متدهای مورد نیاز برای خود الگوریتم رگراسیون خطی رو فراهم کنیم. از کلاس LinearRegression یه نمونه به اسم regressor میسازیم تا استفاده ازش ساده تر بشه. این نمونه (یا آبجکت) تمام متدهای رگراسیون خطی رو در اختیارمون قرار میده:regressor = LinearRegression()حالا این آبجکت باید ارتباط بین دما و فروش رو توی دیتا کشف کنه. متد fit دیتاهای موردنیاز رو از ما میگیره و ارتباط رو کشف میکنه و خط مورد نظر رو میسازه. به این صورت:regressor.fit(X_train,Y_train)حالا به تنها متدی که نیاز داریم، متدیه که از ما ورودی بگیره و پیشبینی رو خروجی بده! ینی این متد:regressor.predict()این متد هم یه آرایه دوبعدی ورودی میگیره. پس یه متغیر برای تست میسازیم و مقادیر دلخواهی رو توش میذاریم. به این صورت:X_test = [[21],[13],[25]]حالا این متغیر رو به تابع پردیکت پاس میدیم و خروجیش رو توی یه متغیر دیگه میریزیم و پرینت میکنیم:Y_test = regressor.predict(X_test)print(Y_test)و خروجی به ما این مقادیر رو میده:output: [[468.13244315]  [229.99061191]  [587.20335877]] خب! تا اینجاش که خوب به نظر میاد! ((= حالا بیاین به کمک نمودار بررسی کنیم که این مقادیر درست هستن یا نه! همونطوری که گفتم، برای رسم نمودار از لایبرری مت پلات لیب استفاده میکنیم. متد scatter میتونه دوتا ورودی بگیره(ایکس و ایگرگ) و نمودار اونها رو برای ما رسم کنه. قبل از هرچی نمودار خود دیتافریم رو رسم میکنیم:plt.scatter(X_train,Y_train)که این خروجی رو به ما میده:و به کمک متد plot هم میتونیم میتونیم تست هامونو رو نمایش بدیم. من رنگش رو تغییر دادم و کمی بزرگترش کردم تا مشخص باشه:plt.plot(X_test,Y_test,&#039;o&#039;,ms=10,color=&#039;red&#039;)تابع پیچیده ای به نظر میاد، اما کارکرد ساده ای داره. این تابع به طور خودکار نقاط رو به هم وصل میکنه،(تفاوتش با متد قبلی همینه) پس &#x27;o&#x27; رو گذاشتم که فقط نقاط رو نمایش بده، با ms (که مخفف marker size هست) سایز نقاط رو بزرگ کردم و رنگ هم مشخصه. خروجی به این صورت درمیاد:واو! تا اینجا هم فوق العاده به نظر میاد! حالا بیاین اون بخش &#x27;o&#x27;  رو حذف کنیم تا نقاط به هم وصل بشن و خروجی رو ببینیم:plt.plot(X_test,Y_test,ms=10,color=&#039;red&#039;)و خروجی رویایی:تبریک میگم شما اولین کد یادگیری ماشینتون رو افتتاح کردین! (درضمن برای اینکه این نمودار های کیوت براتون خروجی داده بشن، کافیه خط ()plt.xkcd  رو به کدتون اضافه کنین(((=  )</description>
                <category>Amir Mohammad Piran</category>
                <author>Amir Mohammad Piran</author>
                <pubDate>Fri, 29 Jul 2022 04:50:45 +0430</pubDate>
            </item>
                    <item>
                <title>رگراسیون خطی به زبان ساده</title>
                <link>https://virgool.io/CE-SHAHED-publication/%D8%B1%DA%AF%D8%B1%D8%A7%D8%B3%DB%8C%D9%88%D9%86-%D8%AE%D8%B7%DB%8C-%D8%A8%D9%87-%D8%B2%D8%A8%D8%A7%D9%86-%D8%B3%D8%A7%D8%AF%D9%87-pkfbvbpaj2cn</link>
                <description>سلام (= راستش تصمیم گرفتم هماهنگ با مطالعه های خودم توی حوزه ی هوش مصنوعی و یادگیری ماشین، یه سری مفاهیمی که ممکنه کمی پیچیده باشن رو به زبون ساده توضیح بدم. این پست درباره ی «Linear Regression» یا «رگراسیون خطی» هست که یکی از متدهای یادگیری ماشینه. قبل از اینکه برم سراغ مفاهیم و تعاریف، بهتره بگم اصن قضیه چیه و میخوایم چیکار کنیم! ما در واقع میخوایم به سیستم، یه دیتاست بدیم و سیستم اون رو بررسی کنه و الگویی رو ازش کشف کنه. حالا اگه یه داده ای که توی دیتای اولیه نیست رو از سیستم بخوایم، سیستم باید بتونه با توجه به الگوریتم هاش حدس مناسبی رو برای ما انجام بده، که با بقیه دیتاست همخوانی داشته باشه. به نمودار پایین نگاه کنین. این نمودار فرضی میزان فروش یه بستنی فروشی رو در دماهای مختلف در طول سال نشون میده:به طور کلی میتونیم حدس بزنیم که وقتی هوا سردتره، فروش بستنی کمتره و وقتی هوا گرمتر میشه، فروش هم بیشتر میشه. اما برای این قاعده فرمول دقیقی وجود نداره! از طرفی، برای میزان فروش در دماهایی مثل 21 یا 24 درجه سانتیگراد، اطلاعاتی در نمودار نیست و باید حدسشون بزنیم! این حدس رو میسپاریم به یادگیری ماشین! و اینجاست که رگراسیون خطی وارد میشه. قبل از شروع بذارید این ترکیب کلمات رو تعریف کنم. رگراسیون (Regression) یعنی پیشبینی مقداری که پیوستگی داره. حالا این ینی چی؟ بذارین نقطه مقابلش هم تعریف کنم: «طبقه بندی» یا «Classification» که یعنی پیشبینی مقداری که پیوستگی نداره و گسسته اس. رگراسیون با پیشبینی عدد سروکار داره و یه مقدار کمّی خروجی میده، درحالی که طبقه بندی بین دو یا چند چیز(مثل Yes و No، یا مرد و زن) که کیفی هستن تصمیم گیری میکنه. به این مثال دقت کنین:این یه نمونه از طبقه بندی هست که با توجه به میزان قد و وزن، جنسیت هر نفر رو حدس میزنه. نقاط مثلثی مرد و نقاط دایره ای زن هستن. پس سیستم بین این دو تصمیم میگیره. ولی ما اینجا با رگراسیون کار داریم، که قراره یه عدد برامون خروجی بده! مثلا دمای هوا رو به عنوان ورودی بگیره و میزان فروش رو حدس بزنه. و یا برعکسش! خب، حالا بریم سراغ رگراسیون خطی. به نمودار پایین دقت کنین:این همون نمودار فروش بستنی بر حسب دماییه که بالاتر داشتیم. اما اینجا یه خط به نمودار اضافه کردیم و این خط میتونه مقادیر مجهولمون(مثل فروش برای دمای 21 و 24 درجه سانتیگراد) رو حدس بزنه! اما این خط از کجا اومده و چرا این خط؟! ما به کمک رگراسیون خطی و یه سری الگوریتم میتونیم چنین خطی رو برای نمودارمون درنظر بگیریم که بتونه به ازای هر ورودی معتبر، حدس معقولی رو به ما تحویل بده. حالا این خط چه خصوصیاتی باید داشته باشه؟ منطقاً اینکه تا حد امکان به نقاط روی نمودار نزدیک باشه تا جواب عجیب و غریب بهمون تحویل نده! برای مثال، مشخصا خط های نمودار زیر انتخاب خوبی نیستن:برای اینکه خط مورد نظر تا حد امکان به نقاط نمودار نزدیک باشه و ازشون عبور کنه، یه تعریف داریم: مجموع فواصل نقاط تا خط باید حداقل باشد. که منطقی هم به نظر میاد. هرچی فاصله خط از نقاط کمتر، حدس دقیقتر! حالا چجوری این تعریف رو به زبان ریاضی بنویسیم؟ به این فرمول نگاه کنین:قبل از اینکه از قیافه ترسناک این فرمول ناامید شین و صفحه رو ببندین، اجازه بدین توضیحش بدم. قرار بود فاصله هر نقطه از خط رو حساب کنیم، جمعشون کنیم و حداقل این مجموع ها رو بین تمامی خطوط ممکن پیدا کنیم. عبارت توان دار توی فرمول هم فاصله هر نقطه ی y ⁽ⁱ⁾ روی نمودار رو از نقطه ای که خط براش پیشبینی کرده محاسبه میکنه. سیگما مجموع این فواصل رو به اندازه ی m (که تعداد داده ها یا همون نقطه ها باشه) رو محاسبه میکنه و ترم 1/2m هم این مقدار رو کوچیکتر و استانداردتر میکنه. به این تابع J( θ₀ , θ₁ ) میگیم تابع  هزینه یا کاست (Cost Function). ریاضی به ما میگه که مقدار این تابع عجیب به ازای θ₀ و θ₁  باید حداقل باشه. حالا این θ₀ و θ₁ چی هستن؟! تتا یک و تتا صفر ضرایبی هستن که به ترتیب شیب خط و مکان این خط در صفحه مختصات رو مشخص میکنن. و ما میتونیم معادله ی خط مورد نظرمون رو به کمک این دو عدد بنویسیم. یعنی به صورت مقابل : y = θ₀ + θ₁x . این معادله ی خطی که نوشتم، همون عبارت hθ توی فرمول بالاست. صرفا بدونین به این تابع که تابع خطمون هست میگیم فرض یا Hypothesis. خب حالا کافیه برای این تابع هزینه مون، یه مینیموم پیدا کنیم. الگوریتم هایی هست برای اینکه این مینیموم پیدا بشه؛ مثلا اینکه یه خط فرضی درنظر بگیریم، به یه جهت بچرخونیمش(یا درواقع θ₁ رو تغییر بدیم) و تابع هزینه رو حساب کنیم و تاجایی چرخش رو ادامه بدیم که به حداقل تابع هزینه برسیم. و حالا باید مکان این خط رو مشخص کنیم یا همون θ₀. به اندازه ای θ₀ رو تغییر بدیم تا تابع هزینه باز هم حداقل بشه. و درنهایت ما مینیمم تابع هزینه رو پیدا کردیم. روشهای خوشگلتری مثل کاهش گرادیانی (Gradient Descent) هم هست که خب، بهتره خودتون دربارش بخونید (= توی این پست هم پیاده سازی این الگوریتم رو در پایتون، مفصّصّصّل توضیح دادم (=</description>
                <category>Amir Mohammad Piran</category>
                <author>Amir Mohammad Piran</author>
                <pubDate>Thu, 21 Jul 2022 23:21:32 +0430</pubDate>
            </item>
            </channel>
</rss>