<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های میم چ نخعی</title>
        <link>https://virgool.io/feed/@mcnakhaee</link>
        <description>http://imuhammad.ir                                   علاقه مند به Data Science و Machine Learning</description>
        <language>fa</language>
        <pubDate>2026-06-07 06:32:47</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/7169/avatar/tHu8wk.png?height=120&amp;width=120</url>
            <title>میم چ نخعی</title>
            <link>https://virgool.io/@mcnakhaee</link>
        </image>

                    <item>
                <title>تحلیلی بر نظرسنجی سالیانه وضعیت کار و زندگی برنامه نویسان و مدیر سیستم های ایران در سال ۱۳۹۸</title>
                <link>https://virgool.io/dataio/programmerssurvey1398-bpbv1jti5qp3</link>
                <description>هفته پیش نظرسنجی سالیانه وضعیت کار و زندگی برنامه نویسان و مدیر سیستم های ایران در سال ۱۳۹۸ توسط جادی منتشر شد و این که امروز 13 سپتامبر روز برنامه نویس است بهانه ای شد برای من که داده های این نظرسنجی را با داده های سال های قبل ادغام، بررسی و رسم کنم. اطلاعات و آمار اولیه مربوط به این نظرسنجی  را در سایت جادی می توانید ببینید و من در این پست به آن ها نمی پردازم چون سعی من  این هست که تحلیلی کمی عمیق تر در خصوص این داده ها انجام بدهم. در نهایت من تمام تحلیل های این پست با استفاده از زبان برنامه نویسی R انجام دادم که کدش را در گیت هاب من می توانید.بررسی روند های کلیاولین نمودار، نمودار مقایسه تعداد برنامه نویس ها و مدیرهای سیستم ها به تفکیک استان ها بین سال های 1394 و 1398 است. طبق انتظار استان تهران با اختلاف زیادی بیشترین تعداد برنامه نویس را دارد. این اختلاف به قدری بالا بود که برای این که یک نمودار با معنی و قابل مقایسه رسم کنم مجبور شدم که از مقیاس لگاریتمی استفاده کنم. دوباره طبق انتظار استان های محروم تری مثل چهارمحال بختیاری و ایلام در طول این سال ها کمترین تعداد برنامه نویس و توسعه دهنده را داشته اند و بدتر از همه هیچ برنامه نویسی از استان کهگیلویه و بویر احمر در سال 1398 در این نظر سنجی شرکت نکرده است.بررسی جنسیت برنامه نویس ها به تفکیک استانحالا بگذارید نگاهی به جنسیت برنامه نویس ها به تفکیک استان ها نگاهی بیاندازیم. متاسفانه همانطور که پیداست شکاف بسیار زیادی بین تعداد برنامه نویس های مرد و زن وجود دارد و حتی در بعضی از استان ها مثل کرمانشاه یا چهارمحال بختیاری هیچ برنامه نویس خانم در نتایج این نظرسنجی وجود ندارد.بررسی درآمد برنامه نویس ها به تفکیک استاناگر به درآمد برنامه نویس ها به تفکیک استان نگاه بیاندازیم می توانیم باز هم ببینیم که در برخی از استان های عمدتا محروم درآمد یک برنامه نویس از یک حد مشخص بالاتر نخواهد بود.بررسی سن برنامه نویس ها به تفکیک استاناگر نگاهی به سن برنامه نویس ها به تفکیک استان نگاه بندازیم می توانیم نکات جالبی پیدا کنیم. در استان های محروم تر و مرزی اکثریت برنامه نویس ها را افراد بین 18 تا 22 یا زیر 18 سال تشکیل می دهند که این می تواند خبر خوبی باشد.بررسی میزان تجربه و برنامه نویس ها به تفکیک استانبررسی تجربه افراد شرکت کننده در نظرسنجی هم نتایج مشابه با بررسی سن را به ما نشان می دهد.تجربه و درآمدحالا که بحث تجربه شد بگذارید نگاهی کنیم به میزان درآمد و میزان تجربه برنامه نویس ها در کنار هم. یک نکته جالب در این جا وجود دارد: تعداد قابل توجهی برنامه نویس با تجربه زیر یکسال در این نظرسنجی کرده اند که حقوق های بالایی دارند. البته همانطور که در نمودار زیر هم پیداست به صورت کلی هر چه که تجربه بیشتر می شود حقوق هم بیشتر می شود یعنی نسبت افراد با تجربه ای که حقوق بیشتری دریافت می کنند بیشتر می شود. بررسی جنسیت و درآمد هم به ما می گوید که هر چه درآمد بیشتر می شود درصد کمتری از برنامه نویس ها خانم خواهند بود.بررسی روندهای برنامه نویسی، تکنولوژی و دیتابیس هاحالا بیایید کمی وارد بحث زبان های برنامه نویسی بشویم. نمودار زیر درصد توسعه دهنده های بعضی از زبان های برنامه نویسی را به ما نشان می دهد. نکته قابل توجه این است که به غیر از زبان های پایتون، Kotlin و Go درصد توسعه دهنده های بقیه زبان ها ریزش داشته است.نمودار زیر هم مربوط توزیع حقوق برنامه نویس های زبان های برنامه نویسی مختلف است. اگر به دنبال یاد گرفتن یک زبان برنامه نویسی هستید که درآمد بالایی برای شما به ارمغان بیاورد احتمالا این نمودار می تواند مرجع خوبی برای انتخاب مسیر شما باشد! :)  برنامه نویس ها معمولا با فقط یک زبان برنامه نویسی کد نمی زنند و از چندین زبان به صورت همزمان استفاده می کنند. یک تحلیل جالب با استفاده از مفهوم شبکه های اجتماعی و گراف ها می تواند این باشد که ببینیم که برنامه نویس ها از چه زبان های برنامه نویسی در کنار هم استفاده می کنند. جنسیت و زبان های برنامه نویسییک بحث مهم بررسی درصد توسعه دهندگان مرد و زن در هر کدام از زبان های برنامه نویسی است. می توانیم ببینم که برای بعضی از زبان های برنامه نویسی خاص مثل اسکالا هیچ توسعه دهنده خانمی وجود ندارد (یا در نظرسنجی شرکت نکرده است). بیشترین درصد برنامه نویس های خانم هم مربوط به زبان برنامه نویسی R است.تب یا اسپیسبه صورت کلی طرفدارهای استفاده از تب از طرفدارهای اسپیس بیشتر هستند ( در حدود 3 برابر) ولی این مساله و این نسبت برای همه برنامه نویس های زبان های برنامه نویسی مختلف صادق نیست!روند استفاده از دیتابیس هاروند استفاده از دیتابیس های مختلف هم در نمودار زیر پیداست و نیازی به تفسیر بیشتر من ندارد. روند استفاده از تکنولوژی های مختلفدر نمودار زیر  هم می توانید روند تغییرات درصد کاربران تکنولوژی های مختلف را ببینید. به غیر از بیگ دیتا که که در طول 5 سال کاهش داشته است و بیلد سیستم ها که تقریبا ثابت مانده، درصد کاربران بقیه تکنولوژی ها بیشتر شده است. مثلا در سال 98 حدود 70 درصد از کاربران از سورس کنترل (60 درصد در سال 1394)، 30 درصد از کانتینرها (15 درصد در سال 1394)، 20 درصد از کلاود و 15 درصد از هوش مصنوعی استفاده کردند ( نکته: یک برنامه نویس می تواند از بیشتر از یک تکنولوژی استفاده کند برای همین جمع این درصد ها بیشتر از 100 می شود)بررسی رضایت شغلی حالا بگذارید به یک مبحث جالب دیگر بپردازیم: رضایت شغلی!رضایت شغلی و جنسیتاول از همه بیایید رضایت شغلی برنامه نویس های مرد و زن را در طول زمان مقایسه کنیم. همانطور که در نمودار زیر می بینیم به صورت ثابتی رضایت برنامه نویس های مرد به طرز قابل توجهی در طول این 4 سال بیشتر از برنامه نویس های زن بوده است که متاسفانه خبر خوبی نیست! یک نکته جالب دیگر این است که برای هر دو جنسیت رضایت شغلی در سال 1398 بیشتر از سال های قبل بوده است که با توجه به شرایط اقتصادی کشور حداقل برای من عجیب به نظر می رسد.رضایت شغلی و سبک زندگیبعد از بررسی جنسیت و رضایت شغلی برای من یک سوال پیش آمد که چه عواملی دیگری بر روی رضایت شغلی یک برنامه نویس می توانند تاثیر بگذارند. برای همین نمودار مشابهی برای مقایسه سبک زندگی و رضایت شغلی ساختم که در شکل زیر می بینید. در این نمودار سبک زندگی ها بر اساس میانگین رضایت شغلی از بالاترین به پائین ترین نمایش داده شده اند.  به شخصه این نمودار برای من خیلی جالب و البته منطقی بود و به نظرم اگر به دنبال رضایت شغلی بیشتری هستیم حداقل باید از شر چند سبک زندگی آخر خلاص بشویم! البته لزوما اگر شما سبک زندگی های برتر نمودار بالا را داشته باشید به  این معنی نیست که رضایت شغلی بالایی خواهید داشت. مثلا بیایید به سبک زندگی برنامه نویس های زن و مرد نگاهی بیاندازیم. همانطور که می بینید در اکثر سبک زندگی های برتر نسبت  زنان از نسبت مردان بیشتر است و به صورت برعکس در اکثر سبک زندگی های نامطلوب تر (براساس نمودار بالا!) نسبت مردان بیشتر از زنان است ولی به صورت کلی دیدیم که رضایت شغلی مردان بیشتر از خانم ها است.حالا بگذارید به ترکیب رضایت شغلی، سبک زندگی و جنسیت برنامه نویس ها نگاه کنیم. همانطور که می بینید   به غیر از خانم های گیاه خوار و خانم های نماز خوان ها در بقیه سبک های زندگی رضایت مردان به طرز قابل توجهی بیشتر است.حالا بیاید رضایت شغلی، سبک زندگی و درآمد برنامه نویس را با هم مقایسه کنیم. همانطور که در نمودار زیر می بینید هر چه درآمد بیشتر می شود به صورت کلی میزان رضایت هم بیشتر می شود.  امکانات و تسهیلات شرکت و رضایت برنامه نویس هادر نهایت بگذارید تاثیر امکانات و تسهیلاتی که شرکت ها در اختیار برنامه نویس هاشون می گذارند را بر روی رضایت شغلی بررسی کنیم.  همانطور که میبینم بیمه کردن کمترین تاثیر را بر روی رضایت می گذارد ( چون که جز تسهیلات خیلی بدیهی است، نه؟). محیط های کاری با آموزش های خارج از شرکت و برنامه های تفریحی هم بیشترین رضایت بین برنامه نویس ها را دارند.کلام آخرنظرسنجی سالیانه برنامه نویس ها و مدیران سیستم پر از اطلاعات جالب هست و من به خاطر کمبود وقت فقط بخشی از آن ها را بررسی کردم. خیلی از متغیرهای دیگر در دیتاست مثل تحصیلات و ... هم به صورت مشابه قابل تحلیل هستند. </description>
                <category>میم چ نخعی</category>
                <author>میم چ نخعی</author>
                <pubDate>Sun, 13 Sep 2020 16:07:01 +0430</pubDate>
            </item>
                    <item>
                <title>دلگشا: کتابخانه ای برای رسم نمودارهای فارسی زیباتر</title>
                <link>https://virgool.io/@mcnakhaee/delgosha-nurjagxexthc</link>
                <description>بعد از چندین سال کار با ابزاری های مصورسازی زبان برنامه نویسی در پایتون و R می توانم با اطمینان بگویم که برای مصورسازی داده ها بهترین ابزار کتابخانه ggplot2 زبان برنامه نویسی R است. کتابخانه ggplot2 به طرز خارق العاده ای منعطف، قدرتمند و محبوب است. اگر قصد سرمایه گذاری در زمینه مصورسازی داده ها دارید ggplot2 بهترین گزینه موجود و یک سر و گردن بالاتر از بقیه ابزارها است. این محبوبیت و قدرت ggplot2 نه تنها در زمینه تعداد کاربران، بلکه  در زمینه تعداد زیاد افزونه و کتابخانه جانبی مثل ggtext، ggraph و ... هم بر اساس آن طراحی شده اند، نمود پیدا کرده است. خیلی از سازمان های خبری مثل بی بی سی، اکونومیست و ... از R  و ggplot2 به صورت روزانه در اخبار و تحلیل های منتشرشده خودشان استفاده می کنند و حتی قالب های مخصوصی برای نمودارهای خودشان در ggplot2 طراحی کرده اند. به طور مثال، اگر به صفحه اینستاگرام اکونومیست مراجعه کنید می بینید که بخش زیادی از پست های اکونومیست مربوط به نمودارها و data journalism است.متاسفانه استفاده از ggplot2 برای رسم نمودارهای به زبان فارسی و کلا زبان های راست به چپ چالش برانگیز است و نیازمند حجم قابل توجهی از تنظیمات است که برای خیلی از کاربران به خصوص تازه کار با R دشوار به نظر می رسد. بدتر از آن به خاطر این محدودیت ها و مسائل دیگری مثل در دسترس نبودن داده های آزاد ما تقریبا  در ایران و رسانه های ایران چیزی به نام data journalism نداریم و اکثر نمودارهای منتشرشده در رسانه های خبری اگر کپی نباشند حداکثر با نرم افزار اکسل و با کمترین کیفیت ممکن طراحی شده اند.  به همین دلیل من چند وقت پیش سرگرم توسعه یک دلگشا که یک کتابخان R  است شدم تا با استفاده از آن بتوانیم به راحتی نمودارهای زیبایی به زبان فارسی طراحی کنیم. استفاده از این کتابخانه بسیار راحت است و با یک خط کد می توانید یک نمودار ggplot2 را به صورت فارسی در بیاورید. به طور مثال فرض کنید که می خواهید از قالب فرش که در این کتابخانه گنجانده شده است برای فارسی کردن یک نمودار استفاده کنید، کافی است به نموداری که با ggplot2 ساخته اید این خط کد ()theme_farsh را اضافه کنید. برای کسب اطلاعات بیشتر در خصوص استفاده از این کتابخانه و دیدن مثال های متفاوت هم می توانید به گیت هاب این کتابخانه مراجعه کنید.در حال حاضر 7 قالب در این کتابخانه قرار داده شده اند. به طور مثال، قالب فرش با الهام از طراحی ارائه شده در این پست طراحی شده است.یک قالب دیگر قالب همشهری  است که بر اساس فونت روزنامه همشهری و رنگ های به کار رفته در لوگوی همشهری ایجاد شده است. متاسفانه بر اساس جستجو و مشاهده من در وب سایت روزنامه همشهری، آن ها از هیچ قالبی خاصی برای ایجاد نمودارها استفاده نمی کنند و برای همین این قالب به نوعی یک قالب طراحی شده خیالی است.یک قالب پایه فارسی هم در این کتابخانه وجود دارد که با آن می توانید قالب های از پیش طراحی شده توسط بقیه کتابخانه ها و کاربران برای ggplot2 را تبدیل به قالب های فارسی می کند.قالب دیجی کالا که بر اساس نمودارهای به کار رفته در گزارش سال 1398 دیجی کالا طراحی شده است.شما می توانید انواع مختلفی از نمودارها مثل گراف ها که با کتابخانه ggraph ساخته شده اند را با این کتابخانه فارسی کنید. برای ساخت این نمودار از مجموعه ای از ابزارها و افزونه های ggplot2 مثل کتابخانه gghighlight و geofacet استفاده شده است و نهایتا نمودار ساخته شده به وسیله یکی از قالب های دلگشا فارسی شده است. آیا این زیبا نیست؟در صورتی که پیشنهادی برای بهبود این کتابخانه دارید یا دوست دارید در ساخت آن مشارکت کنید به گیت هاب دلگشا بروید و آن را در آنجا در با من میان بگذارید.</description>
                <category>میم چ نخعی</category>
                <author>میم چ نخعی</author>
                <pubDate>Sun, 23 Aug 2020 20:31:59 +0430</pubDate>
            </item>
                    <item>
                <title>محبوب ترین، غم انگیزترین، شادترین و پرانرژی ترین آهنگ های فارسی در اسپاتیفای</title>
                <link>https://virgool.io/dataio/%D9%85%D8%AD%D8%A8%D9%88%D8%A8-%D8%AA%D8%B1%DB%8C%D9%86-%D8%BA%D9%85-%D8%A7%D9%86%DA%AF%DB%8C%D8%B2%D8%AA%D8%B1%DB%8C%D9%86-%D8%B4%D8%A7%D8%AF%D8%AA%D8%B1%DB%8C%D9%86-%D9%88-%D9%BE%D8%B1%D8%A7%D9%86%D8%B1%DA%98%DB%8C-%D8%AA%D8%B1%DB%8C%D9%86-%D8%A2%D9%87%D9%86%DA%AF-%D9%87%D8%A7%DB%8C-%D9%81%D8%A7%D8%B1%D8%B3%DB%8C-%D8%AF%D8%B1-%D8%A7%D8%B3%D9%BE%D8%A7%D8%AA%DB%8C%D9%81%D8%A7%DB%8C-venflbdi6fqr</link>
                <description>بسیاری از ما با اسپاتیفای آشنایی داریم و حتی به صورت روزانه از آن استفاده می کنیم. خوشبختانه اسپاتیفای مثل خیلی از شرکت های بزرگ اینترنتی دیگر API خود را برای استفاده در اختیار توسعه دهندگان قرار می دهد. با استفاده از API اسپاتیفای می توانیم به مجموعه زیادی از اطلاعات آهنگ ها دسترسی پیدا کنیم. به طور مثال، می توانیم 10 آهنگ خواننده ها (نوازندگان) مختلف با بیشترین محبوبیت را استخراج کنیم. از همه جذاب تر می توانیم به ویژگی های صوتی آهنگ های مختلف را که اسپاتیفای محاسبه کرده است (که در ادامه مفصل تر توضیح می دهم) دسترسی پیدا کنیم. در یک فرآیند طاقت فرسا  یک لیست از چهره های سرشناس موسیقی فارسی به وسیله من آماده و اطلاعات آن ها را از اسپاتیفای به وسیله این API جمع آوری و به یک دیتاست که شامل اطلاعات مختلفی است تبدیل شد. در این دیتاست اطلاعات بیش از 60 خواننده یا نوازنده به همراه مشخصات بیش از 1000 آهنگ شامل ویژگی های صوتی آن ها جمع آوری شده است. در این پست با استفاده از این دیتاست خواننده ها و آهنگ هایشان  از جنبه های مختلفی مثل شادی، محبوبیت، بلندی و ... با یکدیگر مقایسه شده اند.نگاهی دقیق تر به مشخصه های بررسی شدههمانطور که در بخش قبلی گفتم اسپاتیفای برای آهنگ هایی که در پایگاه داده خودش دارد ویژگی های صوتی مختلفی را محاسبه می کند که ما هم می توانیم به آن ها دسترسی پیدا کنیم. به طور خاص ویژگی های صوتی زیر در این پست بررسی شده اند: رقص آوری (Dancability): بر اساس یک سری معیار ها مثل ریتم آهنگ میزان مناسب بودن آن آهنگ برای رقص مشخص می شود. کمترین مقدار ۰ است و بالاترین مقدار این متغیر ۱ است که به این معناست که این قطعه خیلی برای رقص مناسب است!انرژی (Energy): این معیار نشان دهنده شدت و پویایی آهنگ است که معمولا متناظر با سرعت بلندی صدا است مثلا آهنگ های متال انرژی بالایی دارند و آهنگ های کلاسیک آرام بخش هم انرژی پائینی دارند. بلندی صدا(Loudness): بلندی صدا موسیقی به دسیبل. این معیار میانگینی از بلندی صدا در یک آهنگ است و برای همین برای مقایسه بلندی صدای آهنگ در مقایسه با هم خوب است. محدوده مقدار بلندی صدا بین -۶۰ تا ۰ است.گفتار (Speech): این متغیر بیان کلمات در آهنگ را تشخیص می دهد و اندازه گیری می کند. به طور مثال کتاب های صوتی بالاتر هستند ولی موسیقی های بی کلام معیار گفتاری پایینی دارند. اگر گفتار یک آهنگ مقداری بالاتر از ۰.۶۶ باشد یعنی این آهنگ احتمالا تماما از گفتار تشکیل شده است. عدد بین ۰.۳۳ تا ۰.۶۶ نشان دهنده این است که آهنگ هم از موسیقی و هم از گفتار تشکیل شده است. (مثل رپ) . مقادیر پایین تر هم آهنگ هایی با اکثریت موسیقی را نشان می دهند. آواشنودی /آکوستیک (Acoustic): معیار آکوستیک یک عدد بین ۰ تا ۱ را نشان می دهد و هر چه مقدار آن بیشتر به ۱ نزدیک تر باشد یعنی آهنگ آواشنودی بیشتری دارد. منظور از آواشنودی میزان استفاده از ابزارهای موسیقی است. هر چه در یک آهنگ از ابزارهای موسیقی بیشتر استفاده شود آواشنودی آن بالاتر تر است. به صورت برعکس موسیقی های الکترونیک از آواشنودی کمتری بر خودارند.شعف آفرینی (valence): من ترجمه فارسی خوبی برای کلمه valence پیدا نکردم و برای همین از کلمه شعف (شادی) آفرین استفاده می کنم. این معیار به صورت خلاصه میزان حس خوبی که یک آهنگ منتقل می کند را اندازه گیری می کند. طبیعتا آهنگ های با شعف آفرینی بالاتر حس مثبت بیشتری را منتقل می کنند. به همین شکل، آهنگ های با شعف آفرینی پاپینی حس ناراحت کننده و غم انگیز تری را منتقل می کنند.· ملودی/ اینسترومنتال(instrumental): بر اساس آن چه که من متوجه شدم این معیار میزان ملودی موجودی (جذابیت های صوتی) در یک آهنگ را اندازه گیری می کند.محبوبیت: میزان محبوبیت آهنگ ها بر اساس یک الگوریتم خاص اندازه گیری می شود. معیاری که اسپاتیفای برای اندازه گیری محبوبیت استفاده می کند بیشتر نشانگر محبوبیت اخیر یک آهنگ و خواننده است. محبوبیت فقط برای 10 آهنگ محبوب هر خواننده در دسترس است.حالا به بخش اصلی تحلیل می رسیم. اول از همه بیایید به محبوب ترین آهنگ ها و خواننده هان نگاهی بیاندازیم. نمودار زیر از میان 10 آهنگ محبوب هر خواننده؛ آهنگ های با بیشترین محبویت (آبی) و کمترین محبویت (قرمز) را نشان می دهد. به علاوه، خواننده ها بر اساس میانگین محبوبیت از بالا به پائین مرتب شده اند و این یعنی که (متاسفانه) «ساسی مانکن» محبوب ترین خواننده و «جنتلمن» محبوب ترین آهنگ فارسی است.همانطور که می بینید متاسفانه این نمودار نشان می دهد که فردی مثل تتلو که به صورت مشخصی از مشکلات روانی شدیدی رنج می برد در رتبه دومین خواننده محبوب فارسی در اسپاتیفای قرار دارد و این خود سوالات زیادی را برای ما ایجاد می کند.بررسی ویژگی های صوتیشادترین و غمگین ترین آهنگبرای بررسی کردن شادترین و غم انگیزترین آهنگ، 10 آهنگ با بیشترین میزان شعف آوری و 10 آهنگ با کمترین میزان شعف آوری انتخاب شده اند ( رنگ زرد) و آن ها در کنار شعف آوری محبوب ترین آهنگ های هر خواننده (رنگ سبز) که بر اساس این معیار مرتب شده اند قرار گرفته اند.این نمودار نشان می دهد که بعضی از محبوب ترین آهنگ های خواننده های مختلف در بین 10 شادترین آهنگ قرار دارند. البته باید مجددا تاکید کنم که اسپاتیفای برای محاسبه معیار شادی صرفا به ویژگی های صوتی توجه می کند و نه به محتوای متن آهنگ و برای همین آهنگ هایی که در فراق یار و عشق ساخته شده اند و از لحاظ محتوایی شاید خیلی شاد نباشند ممکن است از لحاظ صوتی امتیاز شادی بالایی داشته باشند. با این حال بر اساس تجربه شنیدن به 10 آهنگ غم انگیز این لیست می توانم بگویم که بر عکس این قضیه صادق نیست! به طور مثال،من برای امتحان به بعضی از این آهنگ های غمگین گوش کردم و می توانم تایید کنم که واقعا برای حفظ روحیه آدم مناسب نیستند!پر انرژی ترین و کم انرژی ترین آهنگ هادر وهله بعدی به صورت مشابه پرانرژی ترین و کم انرژی ترین آهنگ ها را با هم مقایسه کردم.تحلیل بالا صرفا معطوف به محبوب ترین آهنگ هر خواننده و 20 آهنگ دیگر بود که شاید معیار خوبی برای مقایسه خواننده ها با هم نباشد. بگذارید نگاهی کلی تر به آهنگ های هر خواننده داشته باشیم و ببنیم که توزیع آهنگ های هر خواننده بر اساس این معیار به چه شکل است.نمودار زیر توزیع میزان شادی آهنگ های برخی از خوانندگان منتخب را نشان می دهد. هر آهنگ به صورت یک نقطه زرد رنگ نشان داده شده اند. 10 آهنگ محبوب بارنگ قرمز و میانگین میزان شادی آهنگ های هر خواننده با رنگ نارنجی مشخص شده اند.این نمودار الگوهای جالبی را در خود دارد. همانطور که می بینید خواننده های سبک سنتی به صورت کلی شادی کمتر قابل توجهی در آهنگ های خود نسبت به خواننده های سبک پاپ دارند.به صورت مشابه نمودار بعدی نشان دهنده توزیع میزان انرژی آهنگ های خواننده ها است.به نظر می رسد انرژی و شادی با هم همبستگی بالایی دارند و برای همین باز هم می توان دید آهنگ های سبک پاپ به صورت کلی نسبت به آهنگ های سنتی انرژی بیشتری دارند.به صورت برعکس میزان آواشنودی آهنگ های سنتی به صورت بسیار قابل توجهی بالاتر است و یک دلیل خیلی واضح آن استفاده بیشتر از سازهای طبیعی در ساخت این نوع آهنگ هاست.و در نهایت آخرین معیار میزان رقص آوری آهنگ ها است!باز در این جا ما به صورت جداگانه هر معیار صوتی را برای خوانندگان مختلف بررسی کردیم ولی شاید بهتر باشد یک نگاه کلی تر داشته باشیم و همه معیارها را در کنار هم ببینیم. نمودار زیر یک نگاه کلی تر از تفاوت بین  خوانندگان مختلف را به ما می دهد. به طور مثال، میزان کمینه، میانگین و بیشینه رقص آوری آهنگ های محسن یگانه بسیار به هم نزدیک است و این یعنی یکی از ویژگی های ثابت (همه) آهنگ های محسن یگانه رقص آوری بالای آن ها است. همین مساله برای معیار آکوستیک علیرضا قربانی و یا بلندی صدای حامد همایون صادق است.همایون شجریان و محمدرضا شجریانهمیشه یکی از مباحث مطرح موسیقی سنتی این بوده هست که همایون شجریان و محمدرضا شجریان چقدر با هم تفاوت دارند یا به عبارتی دیگر همایون شجریان چقدر از پدر خودش در زمینه خوانندگی الهام گرفته است. شاید بررسی این ویژگی های صوتی بتواند کمی این مسئله را برای ما روشن تر کند. برای جواب به این سوال، در این جا میانگین ویژگی های صوتی 6 خواننده مطرح سنتی با هم مقایسه شد.همانطور که می بینید به صورت میانگین بلندی و رقص آوری آهنگ های همایون شجریان کمی از پدرش بیشتر است. با این حال، انرژی، شادی و ملودی آهنگ های محمد رضا شجریان به طرز قابل توجهی بالاتر از پسرش است. نکته قابل توجه دیگر، شباهت بیشتر ویژگی های صوتی آهنگ حسام الدین سراج که یکی از شاگردان سابق محمدرضا شجریان محسوب می شود، با ویژگی های صوتی آهنگ های محمدرضا شجریان نسبت به ویژگی های صوتی آهنگ های همایون شجریان است. این شاید به این معنا باشد که همایون شجریان توانسته تا حدی نسبت به دنبال کردن سبک منحصر خودش موفق باشد. شاید یک قطعه موسیقی که این تفاوت بین محمدرضا شجریان و همایون شجریان را به بهترین شکل ممکن نشان دهد اجرای جداگانه قطعه «با من صنما» توسط این دو نفر است.حرف های پایانییکی از چالش های این کار این بود ( و کماکان است) که تمامی آثار یک خواننده فارسی لزوما بر روی اسپاتیفای قرار ندارند. به علاوه API اسپاتیفای در برخی موارد آهنگ های نامربوطی را باز می گرداند یا به طور خاص بعضی از خواننده ها مانند حبیب را با خواننده ی عرب زبانی به نام حبیبی اشتباه می گرفت و همین باعث شد که بعضی از خواننده ها را به ناچار در این تحلیل در نظر گرفته نشوند. با این حال، بزرگترین چالش من برای آماده سازی این دیتاست تبدیل اسامی انگلیسی آهنگ ها در اسپاتیفای به اسامی فارسی اصلی آن ها بود که به صورت دستی انجام شد. این دیتاست را بر روی گوگل درایو برای دانلود قرار داده ام.تمامی تحلیل های صورت گرفته و نمودارهای ساخته شده در محیط R انجام شده که می توانید آن ها را در حساب گیت هاب من مشاهده کنید.نکته دیگر این است که لزوما نمی توان محبوبیت خواننده فارسی زبان در اسپاتیفای را به کل جامعه تعمیم داد. با توجه به محدودیت های موجود برای دسترسی به آن، بخش زیادی از کاربران فارسی زبان اسپاتیفای به احتمال بالایی افرادی در بازه سنی خاصی هستند که در خارج از کشور زندگی می کنند و برای همین نمی توانند نماینده خوبی برای نتیجه گیری در مورد کل جامعه باشند.</description>
                <category>میم چ نخعی</category>
                <author>میم چ نخعی</author>
                <pubDate>Sat, 11 Apr 2020 20:14:58 +0430</pubDate>
            </item>
                    <item>
                <title>چند درصد از شاهنامه فردوسی عربی است؟</title>
                <link>https://virgool.io/dataio/%DA%86%D9%86%D8%AF-%D8%AF%D8%B1%D8%B5%D8%AF-%D8%A7%D8%B2-%D8%B4%D8%A7%D9%87%D9%86%D8%A7%D9%85%D9%87-%D9%81%D8%B1%D8%AF%D9%88%D8%B3%DB%8C-%D8%B9%D8%B1%D8%A8%DB%8C-%D8%A7%D8%B3%D8%AA-rlaniipdqhbw</link>
                <description>چند وقت پیش و به جهت سرگرمی با دیتاستی از اسامی محبوب فارسی سر و کله می زدم و اسامی داخل آن را با متن شاهنامه تطبیق می دادم تا ببینم کدام یک از اسامی محبوب فعلی ما ایرانی ها از شخصیت های شاهنامه برگرفته شده اند. بعد از یک بررسی اولیه، یک نکته جالب توجه من را جلب کرد: تعداد قابل توجهی از اسامی تطبیق پیدا کرده اسامی با ریشه عربی مثل حمزه، محمد و ... بودند! همین مساله باعث شد که ناخودآگاه ذهن من به سمت دوگانه زبانی عربی-پارسی که سال ها ذهنم را مشغول کرده برود.احتمالا شما هم مثل من حداقل یک  بار داستان افرادی که از کلمات با ریشه عربی استفاده نمی کنند یا یا اساتید ادبیاتی که دانش آموزان و دانشجویان خودشان را مجبور به عدم استفاده از کلمات عربی می کنند را شنیده اید یا با آن ها برخورد داشته اید.  مدت ها پیش یکی از دوستانم برای من تعریف کرد که یکی از اساتید ادبیات یکی از دانشگاه های تهران هر دانشجویی که یک کلمه با ریشه عربی را در کلاس یا برگه امتحانی خودش به کار می برد را به شدت مجازات می کرد (تعیین صحت یاد عدم صحت داستان برای من مشخص نیست!). با تمام احترام به نظرات همه افراد، من این نوع رفتار را بیشتر مبتنی بر انگیزه های نژادپرستانه و نه لزوما مبتنی بر حفظ و صیانت از زبان کشورمان می دانم، چون هم زبان فارسی و هم زبان عربی در طول زمان با هم به صورت قابل توجهی آمیخته شده اند و به غنی تر شدن یکدیگر کمک کرده اند. همین موضوع باعث شد که  یک تحلیل انجام بدهم و ببینم که چه مقدار در شاهکارهای شعر فارسی ما و بزرگان ادبیات ما که به آن ها افتخار می کنیم از کلمات عربی بهره برده شده است و آیا اصلا امکان حذف آثار زبان عربی از فارسی امکان پذیر است یا خیر.طبیعتا راه اصلی برای این که به این سوال پاسخ بدهیم این است که یه صورت جداگانه عربی یا فارسی بودن هر کدام از کلمات در این آثار ادبی را تعیین کنیم، تعداد کلمات با ریشه فارسی و کلمات با ریشه عربی را بشمریم و نسبت آن ها به هم را محاسبه کنیم. همانطور که انتظار دارید انجام دادن این کار به صورت دستی برای تنها یک اثر ادبی بسیار طاقت فرساست چه برسد به کل آثار ادبی موجود. برای همین من تصمیم گرفتم که از این فرآیند را به صورت هوشمندتری و با استفاده از روش های مبتنی علم داده ها (Data Science)  انجام بدهم و به جای شمارش دستی، با استفاده از زبان های برنامه نویسی و ابزارهای پردازش زبان طبیعی ریشه هر کدام از کلمات را بررسی کنم.برای تخمین درصد کلمات عربی از دیتاست اشعار سایت گنجور که به صورت عمومی در این آدرس قابل دسترسی است استفاده کردم. در این دیتاست آثار معروف ترین شاعران و سخن وران فارسی متعلق به سبک های مختلفی مثل شعر نو، سبک خراسانی و ... ذخیره شده اند. اما پیش از این که از این دیتاست استفاده کنم باید یک راه حل برای تمایز کلمات عربی و فارسی پیدا می کردم. ایده آل ترین حالت برای این کار این بود که یک دیتاست «کامل» از کلمات عربی که در زبان (شعر) فارسی به کار برده می شوند (یا برعکس و یک دیتاست از کلمات فارسی) را در اختیار داشته باشیم، آن ها را با متن آثار ادبی مقایسه کنیم و تعداد کلمات عربی در آن متن را بشماریم. با این حال متاسفانه من موفق به پیدا کردن هیچ دیتاستی از کلمات با ریشه های عربی نشدم و این یعنی باید از روش های دیگری برای تخمین درصد کلمات عربی استفاده کنیم.بعد از کلی سر و کله زدن با انواع روش های مختلف من دو روش جایگزین دیگر که کمی هم دارای خطا هستند را برای این کار انتخاب کردم.1. در روش اول من از مجموعه ای از قواعد عمومی که برای تشخیص کلمات عربی و فارسی از یکدیگر وجود دارند و احتمالا شما هم از برخی از آن ها اطلاع دارید استفاده کردم. در زبان نوشتاری عربی حرف ها «پ»، «چ»، «گ» و «ژ» وجود ندارد. یعنی هر کلمه ای که در آثار ادبی فارسی پیدا می کنیم که دارای یکی از این حروف باشد قطعا غیرعربی است. به صورت بر عکس اصالتا در زبان نوشتاری فارسی حروف «ص»، «ث»، «ظ»، «ط»، «ح»، «ذ»، «ق» و «ض» وجود نداشته اند و هر کلمه ای که در آن ها یکی از حروف به کار رفته باشد عربی ( غیرفارسی) است (طبیعتا استثنائاتی هم وجود دارد مثل کیقباد).2. با این که قواعد کلی بالا مفید هستند ولی همه موارد را پوشش نمی دهند. به طور مثال، کلماتی مثل «غرب» یا «کتاب» کلماتی با ریشه عربی هستند که توسط این قواعد شناسایی نمی شوند. به همین دلیل، پس از کلی جستجو و بررسی روش های مختلف، به این نتیجه رسیدم که استفاده از کتابخانه تشخیص زبان گوگل بهترین گزینه به نظر می آید. خروجی این کتابخانه به صورت صددرصد قابل اطمینان نیست اما با تقریب خوبی جواب قابل قبولی به ما می دهد.هر دو این روش ها دارای خطا در تشخیص زبان کلمات هستند و برای همین علاوه بر آن ها، استفاده از روش های دیگری هم به ذهنم رسید که با دلایل مختلفی از پیاده سازی آن ها منصرف شدم. به طور مثال، احتمالا می دانید که اکثر کلمات عربی از سه حرف اصلی تشکیل می شوند مثل «حاکم» که از سه حرف ح.ک.م تشکیل می شود. یکی از روش هایی که به ذهن من رسیده بود که از یک دیتاست از حروف اصلی تشکیل دهنده کلمات عربی استفاده و آن را با کلمات آثار ادبی مقایسه کنم. با این حال، این روش هم از نظر محاسباتی و هم از نظر صحت ایرادات جدی داشت و از آن صرفه نظر کردم.نتیجه تشخیص زبان آثار هر کدام از مشاهیر در نمودار زیر قابل دیدن هست. همانطور که می دانید شعر فارسی به چند دوره و سبک زمانی مختلف تقسیم بندی می شود: دوره سبک خراسانی، دوره سبک عراقی، دوره سبک هندی و دوران معاصر. در این نمودار هم شعرا بر اساس قرن  فعالیت شان به هر کدام از این دوره ها تخصیص داده شده اند.همانطور که مشاهده می کنید حکیم ابوالقاسم فردوسی کمترین درصد از کلمات عربی در آثار خود به کار برده است اما با این حال حتی وی هم برای غنی تر شدن شاهنامه از کلمات عربی استفاده کرده است. تقریبا نیمی از اشعار حافظ و سعدی و مولوی از کلمات با ریشه عربی تشکیل شده اند. با این حال شعرای معاصر و شعر نو از نسبت کلمات عربی کمتری در اشعار خود استفاده کرده اند.نمودار زیر هم یک تصویر کلی تر از درصد کلمات عربی و فارسی در آثار بعضی از این مشاهیر ادبیات فارسی را نشان می دهد. در این نمودار هر مستطیل کوچک یک کلمه است و رنگ آن متناظر با زبان تشخیص داده شده آن است. برای ساختن نمودار زیر از یک نمونه تصادفی از کلمات به کار رفته در آثار هر کدام از این شعرا استفاده کرده ام.باید مجدد ذکر کنم که این تحلیل یک «تخمین» از نسبت کلمات عربی و فارسی به کار رفته در ادبیات فارسی است و این اعداد به صورت صددرصد دقیق نیستند چون هم کلمات عربی به صورت فارسی تشخیص داده شده اند و هم کلمات فارسی به صورت عربی تشخیص داده شده اند. به طور مثال، به ابرکلمات (wordcloud) زیر از اشعار حافظ و فردوسی دقت کنید.ابرکلمات آثار حافظ و ریشه زبانی هر کلمهابرکلمات آثار فردوسی و ریشه زبانی هر کلمهکمی جزئیات فنی تربه صورت کلی فرآیندی که برای آماده سازی این پست طی کردم را می توانم به سه قسمت تقسیم کنم:1. آماده سازی و پیش پردازش داده ها2. تشخیص زبان کلمات3. مصورسازی نتایجپیاده سازی دو قسمت اول را به وسیله زبان برنامه نویسی پایتون و پیاده سازی قسمت سوم را با Rانجام دادم.پیش از تعیین قواعد و مشخص کردن روش تشخیص زبان کلمات ، در مرحله اول اصلی ترین کار آماده سازی داده های متنی و پیش پردازش متن بود. اصلی عملیات این بخش، تشکیل توکن (کلمات) و حذف کلمات زائد (stop word) ها از متن بود. این کار با توجه به ذات متفاوت شعر از متن های امروزی فارسی کمی دشوار بود. اکثر دیتاست های حاوی کلمات زائد مناسب متن های استاندارد فارسی و امروزی هستند و از تشخیص کلمات زائد درون اشعار عاجز هستند. به عنوان مثال، یک کلمه زائد رایج در زبان رایج ما کلمه «دیگر» است ولی در اشعار فارسی معمولا از کلمه «دگر» مانند برو این دام بر مرغ دگر نه به عنوان معادل «دیگر» استفاده می کنیم. خروجی این بخش یک دیتافریم بود که هر سطر آن را یک کلمه و شاعری که از آن کلمه استفاده کرده بود تشکیل می داد.بعد از این مراحل نوبت به پیاده سازی رویکرد تشخیص زبان بر روی تک تک کلمات دیتافریم بود. برای این کار ابتدا من بررسی می کردم که آیا کلمات از قواعدی که در بالا ذکر کرده بوده ام پیروی می کند یا خیر. در صورت عدم پیروی ( مثلا کلمه ای مثل غیب) زبان آن کلمه توسط کتابخانه langdetect بررسی می شد. نکته جالب این بود که این کتابخانه برخی از کلمات مانند پیر را به عنوان کلمات زبان اردو تشخیص می داد که با توجه به مواردی که که من دیدم تصمیم گرفتم که این کلمات را به دسته کلمات فارسی اختصاص بدهم.در نهایت مصورسازی داده ها به وسیله R و به طور خاص توسط کتابخانه های ggplot، ggpage و wordcloud انجام شد. کدهای مربوط به این تحلیل در گیت هاب قابل دسترسی هستند.</description>
                <category>میم چ نخعی</category>
                <author>میم چ نخعی</author>
                <pubDate>Sat, 08 Feb 2020 16:13:04 +0330</pubDate>
            </item>
                    <item>
                <title>رسم داده ها بر روی نقشه ها با پایتون</title>
                <link>https://virgool.io/dataio/%D8%B1%D8%B3%D9%85-%D8%AF%D8%A7%D8%AF%D9%87-%D9%87%D8%A7-%D8%A8%D8%B1-%D8%B1%D9%88%DB%8C-%D9%86%D9%82%D8%B4%D9%87-%D9%87%D8%A7-%D8%A8%D8%A7-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-lg0jiwlywbx0</link>
                <description>مدتی هست که برای یک پروژه تفریحی data science سر و کارم با رسم داده ها بر روی نقشه ها و ابزارهای مختلف این کار افتاده است. اخیرا با یک کتابخانه پایتون به نام folium  آشنا شدم که به ما امکان رسم نقشه ها را با استفاده از کتابخانه leaflet.js جاوااسکریپت با API خود می دهد. برای نشان دادن قابلیت های این کتابخانه از یک دیتاست کاملا ایرانی استفاده می کنم. حدود 1.5 سال پیش شرکت اوبار  که در در زمینه ارسال سفارشات و حمل بار آنلاین ( فکر کنم عمدتا بین شهری) در ایران فعالیت می کند یک مسابقه یادگیری ماشین در پلتفرم kaggle برگزار کرد که در آن  به صورت خلاصه هدف آن این بود که با استفاده از یک مجموعه از اطلاعات و متغیرهای مکانی (spatial) مثل استان مبدا و  مقصد و غیرمکانی مثل وزن بار و نوع وسیله قیمت بارهای حمل شده در سطح ایران به درستی پیشبینی شود  تا بر اساس این پیش بینی یک سیاست گذاری ثابت برای قیمت گذاری بارها پیاده سازی شود.همانطور که گفتم در این مسابقه و دیتاست مربوط به آن انواع اطلاعات مکانی مثل عرض و طول و جغرافیایی مبدا و مقصد بار مشخص شده اند و همین این دیتاست را برای مثال این پست ایده آل می کند. (دیتاست مربوطه را می توانید از آدرس مسابقه در سایت کگل دانلود کنید)ubaar= pd.read_csv(&amp;quotdata/train.csv&amp;quot)

ubaar.head()با این وجود دیتاست اوبار در حدود50 هزار مشاهده مجزا دارد و اگر بخواهیم همه این مشاهدات را بر روی نقشه رسم کنیم به خاطر تعاملی بودن نقشه در بارگزاری آن دچار مشکل خواهیم شد. برای همین برای سادگی تنها یک بخشی از داده ها (1000 مشاهده) را برای ادامه کار انتخاب می کنیم.sample_ubaar = ubaar.head(1000)شروع به کارمثل همیشه ابتدا نیاز به  نصب کتابخانه مدنظرمان که در این جا folium  است داریم:pip install foliumبعد از نصب کتابخانه نوبت به اضافه کردن کتابخانه folium و یک نقشه از ایران می سازیم. برای ساخت یک نقشه نیاز به عرض جغرافیایی و طول جغرافیایی از مرکز ایران داریم. ( اگر با مقدار ورودی پارامتر zoom_start کمی بازی کنید متوجه کاربرد آن هم می شوید)import folium

iran_map = folium.Map(location = [32.4279,53.6880],zoom_start = 5)

iran_mapحالا هدف ما این است که نقاط مبدا و مقصد  حمل بار را بر روی  نقشه ای که ایجاد کرده ایم رسم کنیم. برای این کار از کلاس ()folium.CircleMarker  استفاده می کنیم که برای ما بر روی نقشه نقطه رسم می کند. برای رسم هر نقطه لازم است که عرض و جغرافیایی آن نقطه را به عنوان ورودی به این کلاس بدهیمعلاوه بر این می توانیم پارامترهای دیگری مثل رنگ، اندازه و ... هر نقطه را مشخص  کنیم. به طور مثال، برای نقاط مبدا از رنگ قرمز و برای نقاط مقصد از رنگ آبی استفاده میکنیم.در اینجا بر روی دیتاست نمونه ای که ایجاد کرده ایم حلقه for می زنیم و  عرض و طول جغرافیایی نقاط مبدا را به صورت مجزا به کلاس می دهیم و در انتها این  نقطه را با متد به نقشه قبلی که ایجاد کرده بودیم اضافه می کنیم تا این نقاط بر روی این نقشه رسم شوند.for lat, lng in zip(sample_ubaar.sourceLatitude,sample_ubaar.sourceLongitude):

folium.CircleMarker(

[lat, lng],

radius=2,

color=&#039;red&#039;,

fill=True,

fill_color=&#039;darkred&#039;,

fill_opacity=0.5 ).add_to(iran_map)

iran_mapبه صورت مشابه همین فرآیند را برای نقاط مقصد هم اجرا می کنیم.for lat, lng in zip(sample_ubaar.destinationLatitude,sample_ubaar.destinationLongitude):

folium.CircleMarker(

[lat, lng],

radius=2,

color=&#039;blue&#039;,

fill=True,

fill_color=&#039;blue&#039;,

fill_opacity=0.3 ).add_to(iran_map)

iran_mapدر نمودارهای قبلی می توانستیم تجمع اصلی مبدا و مقصد نقاط حمل بار را مشاهده کنیم ولی اطلاعاتی در خصوص قیمت حمل بار که اهمیت بالایی دارد مشخص نبود. حالا می توانیم یک کار جالب تر هم انجام بدهیم: به جای این که اندازه هر کدام از نقاط را ثابت و برابر با هم در نظر بگیریم اندازه نقاط را بر اساس هزینه نسبی حمل بار تغییر بدهیم. برای این کار ابتدا هزینه حمل بار را نرمال سازی می کنیم و سپس هزینه حمل هر نقطه را به عنوان ورودی به پارامتر radius کلاس می دهیم و به نقشه ایران اضافه می کنیم.دقت کنید که اینجا ابتدا لازم است که دوباره نقشه را از ابتدا ایجاد کنیم چون در غیر این صورت نقشه قبلی با تمام نقاطش مورد استفاده قرار می گیرد.iran_map = folium.Map(location = [32.4279,53.6880],zoom_start = 5)

برای نقاط مبدا به این صورت عمل می کنیم:

for row in range(sample_ubaar.shape[0]):

folium.CircleMarker(

location=[sample_ubaar.iloc[row,:][&#039;sourceLatitude&#039;], sample_ubaar.iloc[row,:][&#039;sourceLongitude&#039;]],

radius=sample_ubaar.iloc[row,:][&#039;price_normalized&#039;],

color=&#039;red&#039;,

fill=True,

fill_color=&#039;darkred&#039;,

fill_opacity = 0.7

).add_to(iran_map)

iran_mapبرای  نقاط مقصد هم  به صورت مشابه همین فرآیند را انجام می دهیم:for row in range(sample_ubaar.shape[0]):

folium.CircleMarker(

location=[sample_ubaar.iloc[row,:][&#039;destinationLatitude&#039;], sample_ubaar.iloc[row,:][&#039;destinationLongitude&#039;]],

radius=sample_ubaar.iloc[row,:][&#039;price_normalized&#039;],

color=&#039;blue&#039;,

fill=True,

fill_color=&#039;blue&#039;,

fill_opacity = 0.1

).add_to(iran_map)

iran_mapرسم تک تک نقطه ها بر روی نقشه با این که به ما کمک می کند تا  نقاط خاص  با حجم بیشتر حمل و نقل و قیمت بیشتر در کشور را شناسایی کنیم اما این به ما در خصوص مهم ترین خوشه های مکانی با حجم بالای حمل و نقل یک دید کلی و جامع نمی دهد.حالا می توانیم یک گام فراتر برویم و برای این که این دید کلی را هم داشته باشیم می توانیم از یک قابلیت فوق العاده دیگر کتابخانه folium استفاده کنیم و نقشه های گرمایی را به جای نقاط بر روی نقشه های جغرافیایی نشان دهیم. برای رسم نقشه های گرمایی در folium از کلاس ()HeatMap  استفاده می کنیم و علاوه بر عرض و طول جغرافیایی وزن هر نقطه که در این جا قیمت است را به عنوان ورودی به آن می دهیم. یک مزیت دیگر استفاده از نقشه های گرمایی در اینجا این است که می توانیم تعداد مشاهدات بیشتری را بر روی نقشه رسم کنیم. برای همین در این مثال به جای 1000 مشاهده 20000 مشاهده را رسم می کنم.iran_map = folium.Map(location = [32.4279,53.6880],zoom_start = 5)

from folium.plugins import HeatMap

iran_map = folium.Map(location = [32.4279,53.6880],zoom_start = 5)

iran_map

ubaar[&#039;price_normalized&#039;] = (ubaar[&#039;price&#039;] - ubaar[&#039;price&#039;].min())/ ubaar[&#039;price&#039;].max()



HeatMap(

    data=list(zip(ubaar.head(20000)[&#039;sourceLatitude&#039;],

                  ubaar.head(20000)[&#039;sourceLongitude&#039;],

                  ubaar.head(20000)[&#039;price_normalized&#039;])

             

             )   ,

    radius   = 12

).add_to(iran_map)

iran_map</description>
                <category>میم چ نخعی</category>
                <author>میم چ نخعی</author>
                <pubDate>Thu, 24 Oct 2019 22:35:17 +0330</pubDate>
            </item>
                    <item>
                <title>داده های مرتب (Tidy Data)، پایتون، پانداس</title>
                <link>https://virgool.io/dataio/%D8%AF%D8%A7%D8%AF%D9%87-%D9%87%D8%A7%DB%8C-%D9%85%D8%B1%D8%AA%D8%A8-tidy-data-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-%D9%BE%D8%A7%D9%86%D8%AF%D8%A7%D8%B3-daq5hol5cav0</link>
                <description> یکی از مفاهیم Data science که خیلی ها با آن آشنا نیستند مفهوم داده های مرتب یا Tidy Data هست.. مثلا من چند وقت پیش درگیر یک پروژه تحت نظر یکی از شرکت های بزرگ هلندی که بودجه چند ده میلیون دلاری و یک تیم اختصاصی Data Science داشت بودم و این شرکت یک دیتاست برای تحلیل به من داد. وقتی من دیتاست را دیدم متوجه شدم که این دیتاست از استاندارد داده های مرتب پیروی نمی کند و طبیعتا تمامی تحلیل های قبلی آن شرکت دارای عیب و ایراد بود.  جالب تر این بود که کسی در خصوص این مفهوم و این استاندارد نمی دانست و وقتی در خصوص این مساله به آن ها گفتم خیلی حال کردند و خوشحال شدند! برای هممین تصمیم گرفتم که پستی در این خصوص بنویسم چون احتمالا خیلی از ماها هم از وجود این استاندارد خبر نداریم.ما انسان ها تمایل داریم که برای نحوه اجرای انواع کارهای مختلفی که انجام می دهیم استاندارد تعریف کنیم. به عنوان مثال، فرآیند ذخیره سازی داده ها را در نظر بگیرید. برای ذخیره سازی داده ها از دیتابیس ها استفاده می کنیم. داده ها هم در دیتابیس ها بر اساس استاندارهای خاصی ذخیره می شوند. دیتابیس ها هم از استانداردهای خاصی برای ذخیره سازی داده ها استفاده می کنند (مثلا در دیتابیس های رابطه ای باید یک ستون ID داشته باشیم.)  اما حالا که برای ذخیره سازی داده ها، این داده ها باید از استاندارد تبعیت کنند این سوال پیش می آید که آیا استانداردی هم داریم که مشخص کند که داده ها برای عملیات های رایج دیتاساینس مثل پاکسازی، مصورسازی و مدل سازی چگونه باشند تا این کارها را راحت تر کنند؟به عبارت دیگر می خواهیم یک استاندارد وجود داشته باشد که قبل از این که شروع به کار و تحلیل داده ها کنیم، داده ها را بر اساس آن استاندارد آماده کنیم و آن ها را به صورت یک ساختار مناسب برای آن تحلیل در بیاوریم. خوشبختانه برای حل این مسئله، استانداردی در سال 2014 توسط یکی از توسعه دهنده های معروف زبان برنامه نویسی R و نویسنده کتابخانه هایی مانند ggplot2 ارائه شد. آقای Hadley Wickham در یک مقاله به نام «Tidy Data» معرفی شد. به همین خاطر، جای شگفتی هم نیست که اسم این استاندارد اصطلاحا Tidy Data یا «داده های مرتب» گذاشته شد. طبق مقاله آقای Wickham اگر داده های ما بر اساس این استاندارد به صورت tidy در بیایند بقیه عملیات های دیتاساینسی ما مثل پاکسازی داده ها، مصورسازی، مدل سازی و ... راحت تر و با معناتر می شوند.به علاوه از آن جا که Hadley Wickham یک توسعه دهنده زبان برنامه نویسی R بود، برای این که فرآیند تبدیل داده های نامرتب (messy) به tidy را در زبان برنامه نویسی R را راحت تر کند کتابخانه های reshape و reshape2 را هم نوشت که با آن ها می شود این کار را انجام. این مفهوم داده های مرتب و این کتابخانه ها بعدها به قدری مهم و تاثیر گذار شدند که مجموعه ای از کتابخانه های نوشته شده در زبان R موسوم به Tidyverse به وجود آمده است که بر اساس داده های ورودی که به صورت مرتب هستند انواع تحلیل ها را انجام می دهند که بعدا اگر فرصتی شد به صورت مفصل تری در خصوص آن ها صحبت می کند.حالا منظور از داده های tidy چیست؟ بر اساس این استاندارد هادلی ویکهام یک دیتاست را دیتاست tidy تعریف می کند که ساختار زیر را داشته باشد.هر متغیر به صورت یک ستون باشد و در آن مقادیر ذخیره شده باشند.هر مشاهده به صورت یک سطر در ذخیره باشدهر واحد مشاهده ای به صورت یک جدول جداگانه باشد.بر اساس این تعریف از داده های مرتب می توانیم مواردی که داده های ما به صورت مرتب نیستند را به صورت زیر دسته بندی کنیم:عنوان ستون های دیتاست ما به جای این که نام متغییر باشند در حقیقت مقدار یک متغیر دیگر است.اطلاعات چند متغیر به جای این که به صورت ستون های مجزا در دیتاست ذخیره شده باشند همگی به صورت همزمان در یک ستون ذخیره شده اند.متغیرها هم در ستون ها و هم در سطرها ذخیره شده باشند.چندین نوع از مشاهدات در یک جدول مشابه ذخیره شده اند.یک نوع مشاهده در چندین جدول ذخیره شده است.از آن جا که در اکثر موارد تنها با یکی از سه مورد ابتدایی بالا سر و کار داریم، در ادامه به تفکیک به بررسی یک مثال از هر کدام از این موارد می پردازیم و تحوه حل آن در پایتون و کتابخانه پانداس بررسی می کنیم. ( تمامی کدها و داده های این پست در این لینک قابل مشاهده هستند.)عنوان ستون های دیتاست به جای این که نام متغییر باشند در حقیقت مقدار یک متغیر دیگر هستند.برای شروع با اولین نشانه داده های نامرتب یعنی « عنوان ستون های دیتاست ما به جای این که نام متغییر باشند در حقیقت مقدار یک متغیر دیگر است.» و توضیح مثالی که خود آقای wickhom در مقاله اش برای تبین این مشکل بررسی کرده بود شروع می کنم. دیتاست زیر را در نظر بگیرید:این دیتاست حاوی اطلاعاتی در خصوص یک نظرسنجی در مورد مذهب افراد و میزان درآمد آن ها در ایالات متحده آمریکا است. همانطور که می بینیم سه متغیر در این دیتاست وجود دارد: نوع مذهب، میزان درآمد و فراوانی (تعداد اقراد). اما همانطور که در تصویر بالا مشاهده می کنیم مقادیر مختلف متغیر میزان درآمد هر کدام به صورت یک ستون جدا درآمده اند و تعداد افرادی که متناظر با هر کدام از این درآمدها هستند به صورت مقادیر این ستون ها ذخیره شده اند. این نوع ذخیره سازی داده ها از جهاتی می تواند منطقی باشد. به عنوان مثال، یکی از مزایای این نوع ذخیره سازی داده کم تر شدن حجم اشغال شده می باشد.طبق استاندارد آقای Wickham برای مرتب کردن این نوع دیتاست ها اصطلاحا باید آن ها را ذوب (melt) کنیم، به عبارت دیگر باید ستون های دارای این مشکل را تبدیل به سطر کنیم. به این کار اصطلاحا تبدیل یک دیتافریم عریض (wide) به یک دیتافریم طویل (long) می گوییم. به صورت دقیق تر، در مثال بالا، یک ستون جدید به نام income ایجاد می کنیم و مقادیر ستون های متناظر با درآمد را تبدیل به سطر های جدید و مقادیر این ستون می کنیم.با این که ابتدا این مفاهیم ابتدا در R پیاده سازی شده اند ولی مرتب کردن دیتاست های نامرتب با استفاده از پایتون و به طور خاص کتابخانه پانداس که اصلی ترین کتابخانه در پایتون برای کار با داده ها است هم  به راحتی امکان پذیر است. برای این کار پانداس یک تابع دارد که این کار را برای ما انجام می دهد. برای نشان دادن این قابلیت پانداس ابتدا مثال زیر  که یک دیتاست متفاوت است را در نظر بگیرید:import pandas as pd

data = pd.read_csv(&#039;538.tsv&#039;,sep =&#039;\t&#039;)

data = data.drop([&#039;TOTAL&#039;],axis = 1)

data.head()این دیتاست حاوی آمار و اطلاعاتی در خصوص یک بازی نقش آفرینی معروف و قدیمی به نام «Dungeons &amp; Dragons» است. در این بازی هر بازیکن قبل از شروع بازی باید یک نژاد (Race) و یک کلاس (Class) برای شخصیت خودش انتخاب کند. دیتاست فوق هم مربوط به تعداد بازیکن هایی هستند که ترکیب های مختلفی از نژاد و کلاس را در نسخه 5 این بازی انتخاب کرده اند. همانطور که می بینیم مقادیر متغیر کلاس بازیکن در این دیتاست به صورت مجموعه ای از ستون ها ذخیره شده اند که این با اصل داده های مرتب در تضاد است.حالا فرض کنید که بخواهید یک مدل یادگیری ماشین بسازید که بر اساس این داده ها پیشبینی کند که در نسخه 6 این بازی تعداد بازیکن ها برای هر کدام از ترکیب های نژاد و کلاس چقدر خواهد بود. اگر سعی کنید که یک مدل را بر اساس ساختار فعلی این دیتاست آموزش بدهید می بینید که این کار غیر ممکن است! به صورت واضح دلیل آن این است که این دیتاست به صورت مرتب ذخیره نشده است و باید آن را مرتب کنیم. کتابخانه پانداس هم یک تابع به نام ()pd.melt دارد که می تواند یک یک دیتاست نامرتب به یک دیتاست مرتب یا همان یک دیتافریم عریض را به یک دیتافریم طویل تبدیل کند (ذوب کند).برای این که از این تابع استفاده کنیم باید چند چیز را مشخص کنیم:frame : همان دیتافریمی (دیتاستی) است که می خواهیم تبدیل را بر روی آن انجام بدهیم و آن را مرتب کنیم.با id_vars  لیستی از ستون هایی که نمی خواهیم آن ها را تغییر دهیم (ذوب کنیم) را مشخص می کنیم.با val_vars  لیستی از ستون هایی که می خواهیم آن ها را تبدیل به سطر کنیم (ذوب کنیم) یا همان ستون هایی که مرتب نیستند را مشخص می نماییم. به صورت پیشفرض، هر ستونی را که در id_vars  در نظر نگیریم به صورت خودکار به عنوان یک ستون ورودی value_vars  در نظر گرفته می شود یعنی می توانیم یا ستون هایی که نمی خواهیم تغییر کنند را به عنوان ورودی به id_vars  مشخص کنیم یا ستون هایی که می خواهیم تغییر کنند را به عنوان ورودی به val_vars  بدهیم و لازم نیست حتما هر دو را مشخص کنیم.وقتی که یک دیتاست را ذوب می کنیم دو ستون جدید ایجاد می شوند: یک ستون که حاوی اسم ستون های ذوب شده و ستون دیگر حاوی مقادیر ذخیره شده بازای هر کدام از این ستون ها در دیتاست قبلی است. به صورت پیشفرض پانداس برای ستون های جدید ایجاد شده نام های key و value را قرار می دهد ولی این اسم ها خیلی جالب و مفید نیستند و برای همین بهتر است که برای هر کدام از این ستون ها یک نام با معنا انتخاب کنیم. برای این که نام هر کدام از این ستون ها را تغییر دهیم می توانیم پارامتر ورودی var_name  و value_name  را در تابع ()melt  مشخص کنیمبرای این دیتاست به خصوص ما می خواهیم همه ستون ها به غیر از ستون Race را ذوب کنیم و آن ها را به صورت یک ستون جدید به اسم Class در بیاوریم.  برای همین، ستون حاوی تعداد بازیکن های هر نژاد و کلاس را هم دریک ستون جدید به نام &#x27;Number of Players&#x27; ذخیره می کنیم.: data_tidy = pd.melt(data,id_vars=[&#039;Race&#039;],

var_name = &#039;Class&#039;,

value_name=&#039;Number of Players&#039;)

data_tidy.head()همانطور که در شکل بالا می بینیم حالا دیتاست ما مرتب شده و به طور خاص برای مدل سازی مناسب تر است. به طور مثال، الان می توانیم ستون تعداد بازیکن ها را به عنوان متغیر هدف و ستون های کلاس و نژاد را به عنوان ویژگی ها در یک مدل یادگیری ماشین استفاده کنیم. یا حالا فرض کنید که می خواهیم تعداد بازیکن ها را به ازای هر ترکیب خاص از نژاد و کلاس رسم کنیم. با دیتاست مرتب شده این کار با یک خط کد به راحتی قابل انجام است ولی انجام همین کار با دیتاست نامرتب مصیبت خواهد بود!plt.figure(figsize = (20,10))

sns.barplot(x = &#039;Race&#039;, y = &#039;Number of Players&#039;, hue = &#039;Class&#039;,

data = data_tidy, palette = &#039;Paired&#039;)

اطلاعات چند متغیر به جای این که به صورت ستون های مجزا در دیتاست ذخیره شده باشند همگی به صورت همزمان در یک ستون ذخیره شده اند.این مشکل هم همانند مشکل قبلی است با این تفاوت که به جای این که ما چند ستون مجزا را برای تعدادی از متغیرها تخصیص بدهیم همگی آن ها را در یک ستون ذخیره کرده ایم. بگذارید این مورد را با یک مثال به صورت مشخص تر توضیح بدهم. به عنوان دیتاست زیر را در نظر بگیرید که اطلاعات جمع آوری شده مربوط به شیوع بیماری ابولا در آفریقا را در بر دارد. این اطلاعات شامل متغیر های تاریخ (Date)، روز (Day)، کشور مورد بررسی، نوع گزارش (تعداد بیماری های گزارش شده (Case) و تعداد فوتی های (Death) ناشی از ابولا) و فراوانی است.ebola = pd.read_csv(&#039;ebola.csv&#039;)

ebola.head()

همانطور که می بینیم این دیتاست به صورت مرتب ذخیره نشده است و اکثر ستون های این دیتاست آمار فراوانی مشاهده شده برای ترکیب های مختلف دو متغیر کشور و نوع گزارش را به صورت همزمان در ستون های مختلف ذخیره کرده اند. در حالیکه ما باید به جای این همه ستون ، فقط سه ستون برای اسم کشور، نوع گزارش و فراوانی داشته باشیم.حل این مشکل نیز مشابه با قبل است و اینجا هم از تابع ()pd.melt  استفاده می کنیم تا این دیتاست عریض را به یک دیتاست طویل تبدیل کنیم. از آن جا که تعداد ستون های نامرتب خیلی زیاد است، منطقی است که فقط در این جا ستون هایی که نمی خواهیم تغییر پیدا کنند یعنی Date و Day را به عنوان ورودی به آرگومان id_vars  بدهیم و نیازی نیست که value_vars  را مشخص کنیم.ebola_tidy = ebola.melt( id_vars=[&#039;Date&#039;, &#039;Day&#039;],

var_name = &#039;Variable&#039;,

value_name= &#039;Frequency&#039;)

ebola_tidy.head()بعد از ذوب کردن این دیتافریم می بینیم که کماکان با یک مشکل موجه هستیم. ما ستون Frequency را ساخته ایم ولی هنوز ستون مجزایی برای کشور و نوع گزارش نداریم و اطلاعات این دو ستون به صورت همزمان در ستون Variable ذخیره شده است. این مورد حالت دقیق تر مشکل « اطلاعات چند متغیر به جای این که به صورت ستون های مجزا در دیتاست ذخیره شده باشند همگی به صورت همزمان در یک ستون ذخیره شده اند.» است. برای حل این مشکل باید ستون Variable را به دو ستون Report_Type و Country تقسیم کنیم. چون که این اطلاعات این دو متغیر در ستون Variable با یک _ از همدیگر جدا شده اند انجام این کار راحت است. از آن جا که مقادیر این ستون به صورت رشته های پایتون (string) ذخیره شده اند، می توانیم با استفاده از مشخصه str  به انواع متدهای کار با رشته های پایتون دسترسی داشته باشیم. در این جا هم از متد ()split  استفاده می کنیم تا مقادیر این ستون را بر اساس کاراکتر _ از هم جدا کنیم. اگر expand = True  مقادیر جدا شده به صورت ستون های جداگانه به دیتافریم اضافه می شوند که ما هم این دو ستون را به صورت &#x27;Report_Type&#x27;,&#x27;Country&#x27; به دیتاست اضافه می کنیم. به علاوه، دیگر هم نیازی به ستون &#x27;Variable&#x27; هم نداریم و آن را  هم حذف می کنیم.ebola_tidy[[&#039;Report_Type&#039;,&#039;Country&#039;]] = ebola_tidy[&#039;Variable&#039;].str.split(&#039;_&#039;, expand = True)

ebola_tidy.drop([&#039;Variable&#039;],axis = 1, inplace = True)

ebola_tidy.head()حالا یک دیتاست مرتب شده داریم و می توانیم انواع مدل سازی ها و تحلیل ها را بر روی انجام بدهیم.متغیرها هم در ستون ها و هم در سطرها ذخیره شده باشندطبق مقاله آقای Wickham این مسئله پیچیده ترین نوع داده های غیرمرتب است. برای نشان دادن این نوع از نامرتب بودن داده ها بگذارید به دیتاستی که در خود مقاله Tidy Data به عنوان مثال ذکر شده است نگاهی بیاندازیم. دیتاستی که در این مثال استفاده شده (شکل پائین) مربوط به اطلاعات جمع آوری شده روزانه حداقل و حداکثر دمای ایستگاه های مختلف سنجش وضعیت آب و هوا در مکزیک و در طول 5 ماه است.در این دیتاست ما با دو مشکل مواجه هستیم:اول از همه مثل دیتاست های قبلی که دیدیم بازای روزهای مختلف هر ماه یک ستون جداگانه داریم که یکی از نشانه های دیتاست نامرتب است. به طور خاص، در این جا چون بعضی از ماه ها 31 روز ندارند مقدار قرار گرفته برای مشاهدات در آن ماه ها در ستون مربوط به روز 31 ام به صورت NaN است ( در عکس بالا به صورت – نمایش داده شده اند!)  که این نحوه نمایش غیرمنطقی به نظر می رسد.به همین دلیل برای مرتب کردن این دیتاست باید ابتدا همانند قبل ستون های مربوط به روزهای مختلف را ذوب کنیم و همه مقادیر آن ها را در یک ستون جدید به نام day ذخیره کنیم.weather_molten = pd.melt(weather,

id_vars=[&#039;id&#039;,&#039;year&#039;,&#039;month&#039;,&#039;element&#039;],

var_name=&#039;day&#039;,

value_name=&#039;temperature&#039;)

weather_molten.head()

حالا دیتاست ما به وضعیت بهتری درآمده است اما کماکان یک مشکل دیگر داریم. مشکل دوم این دیتاست این است که در حقیقت ستون element در این دیتاست نشان دهنده یک متغیر نیست بلکه به صورت بر عکس حاوی متغیرهای دیگری به نام tmax (حداکثر دمای ثبت شده)  و tmin (حداقل دمای ثبت شده) است. برای همین در اینجا باید عملیات برعکس ذوب کردن را بر روی ستون element انجام بدهیم یعنی یک ستون جدید به نام tmax و یک ستون جدید دیگر به نام tmin بسازیم.به این عملیات مخالف ذوب کردن اصطلاحا چرخاندن (pivoting) گفته می شود. در ذوب کردن به دنبال این هستیم که ستون ها را به سطر تبدیل کنیم به صورت برعکس زمانی که می خواهیم عملیات چرخاندن را انجام بدهیم، به دنبال این هستیم که مقادیر یکتای موجود در یک ستون را به مجموعه ای از ستون های مجزا تبدیل کنیم (یعنی به ازای هر مقدار یکتا در یک ستون یک ستون مجزا ساخته می شود).انجام این عملیات در پانداس همانند ذوب کردن به راحتی انجام می پذیرد چون که هر دیتافریم در پانداس یک متد ()pivot_table  دارد که با آن می توانیم این عملیات را هم به راحتی انجام بدهیم. برای استفاده از این متد باید 3 آرگومان ورودی اصلی زیر را مشخص کنیم:مشابه با آرگومان id_vars در تابع ()melt  این متد یک آرگومان به نام index  دارد که با آن می توانیم ستون هایی که نمی خواهیم چرخانده شوند را مشخص کنیم. در این مثال می خواهیم ستون های id، year، month و day دست نخورده بمانند.آرگومان columns  یک آرگومان دیگر این متد برای مشخص کردن ستون هایی است که می خواهیم چرخانده شوند. در این مثال ما می خواهیم ستون element را بچرخانیم.در نهایت پارامتر values  مشخص می کند که مقادیر کدام ستون زمانی که یک ستون را می چرخانیم و چند ستون جدید تبدیل می کنیم برای پر کردن آن ستون ها استفاده شوند. در این مثال ما می خواهیم مقادیر موجود در ستون temperature در ستون های جدید ساخته شده بعد از چرخاندن استفاده شود.حالا بگذارید به صورت عملی نحوه پیاده سازی این تابع را بر روی این دیتاست ببینیم.weather_tidy = weather_molten.pivot_table(

index = [&#039;id&#039;,&#039;year&#039;,&#039;month&#039;,&#039;day&#039;],

columns = &#039;element&#039;,

values = &#039;temperature&#039;)

weather_tidy.head()

هر چند که دیتاست ما مرتب شده است و هر متغیر به صورت یک ستون ذخیره و هر مشاهده تشکیل یک سطر در دیتاست را می دهد، ولی این دیتاست هنوز به فرمت نهایی و مورد پسند در نیامده است و کمی باید آن را تغییر بدهیم. همانطور که می بینیم تمامی ستون هایی که به عنوان ورودی به پارامتر index متد ()pivot_table داده ایم، به index های جدید دیتاست ساخته شده تبدیل شده اند و برای همین ظاهر این دیتاست فعلی کمی عجیب و غریب شده است. به همین دلیل از متد ()reset_index  استفاده می کنیم تا این مشکل را بر طرف کنیم.weather_tidy.reset_index(inplace = True)

weather_tidy.head()حالا یک دیتاست با ظاهر بهتر داریم. البته می توانیم باز هم تغییراتی در این دیتاست انجام بدهیم. به طور مثال می توانیم که ستون element را حذف کنیم و یا یک ستون جدید برای تاریخ بسازیم که ترکیب ستون های سال، ماه و روز باشد. اما انجام این کار ها را به عهده خود شما می گذارم.</description>
                <category>میم چ نخعی</category>
                <author>میم چ نخعی</author>
                <pubDate>Fri, 24 May 2019 17:42:14 +0430</pubDate>
            </item>
                    <item>
                <title>چطور  با پایتون دوره های سایت Coursera و Edx را دانلود کنیم؟</title>
                <link>https://virgool.io/dataio/%DA%86%D8%B7%D9%88%D8%B1-%D8%A8%D8%A7-%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86-%D8%AF%D9%88%D8%B1%D9%87-%D9%87%D8%A7%DB%8C-%D8%B3%D8%A7%DB%8C%D8%AA-coursera-%D9%88-edx-%D8%B1%D8%A7-%D8%AF%D8%A7%D9%86%D9%84%D9%88%D8%AF-%DA%A9%D9%86%DB%8C%D9%85-wbfvoguxt3i5</link>
                <description> به عنوان کسی که مقطع کارشناسی و ارشدش را داخل دو تا از مطرح ترین دانشگاه های ایران سپری کرده بود و تقریبا هیچ چیز به درد بخوری از کلاس های دانشگاه یاد نگرفته، وبسایت های Coursera.org و Edx.org دو سایت حیاتی بودند که نه تنها از آن ها خیلی چیزها یاد گرفتم بلکه باعث شدند که هم مسیر کاری و هم مسیر آکادمیک من تغییر زیاد بکند. متاسفانه از حدود دو یا سه سال پیش، به دلیل تحریم ها کورسرا دسترسی به دوره های خودش را برای ایرانی ها خیلی سخت کرد ( به علاوه کورسرا پلتفرم خودش را به صورت کامل تغییر داد و به نظر خود همین هم خیلی باعث پیچیده تر بیشترش شد و هر کسی که برای اولین بار داخل این سایت می شد سرگیجه می گرفت.) برای همین، تقرییا از حدود ۱٫۵ سال پیش بود که تصمیم گرفتم که سایت مونیورسیتی را بسازم و دوره های سایت Coursera و Edx رو داخل اون آپلود کنم تا بقیه افراد هم بتونن به راحتی دوره های این سایت ها رو دانلود و استفاده کنند. آن زمان وقتی که سایت رو بالا آوردم هدف اصلیم این بود که تمام دوره های کورسرا و Edx با موضوعات مختلف رو داخل سایت قرار بدهم. خب طبیعتا بعد از مدتی متوجه شدم که این کار که بخوام حوزه های مختلف و متنوعی رو پوشش بدم ایده خیلی خوبی شاید نباشد و برای همین تصمیم گرفتم که صرفا دوره های مربوط به data science و یادگیری ماشین رو که مباحث مورد علاقه خودم هستند را داخل سایت قرار بدهم. با این وجود، حالا بعد از ۱٫۵ سال به خاطر این که دیگر در ایران نیستم و مشغله های کاریم به این نتیجه رسیدم که ادامه دادن فعالیت های سایت در این فاز زندگیم دیگر امکان پذیر نیست.با این حال، مدتی قبل و بعد از بسته شدن دائمی مونیورسیتی دوباره به این فکر می کردم که با توجه به این که دیگه در مونیورسیتی دوره های کورسرا و edx رو قرار نمی دهم چطور می تونم به نوعی به آموزش بقیه کمک کنم. تا این که از خودم بپرسیدم که چرا از اول به جای این همه هزینه هاست و سایت برای آپلود این دوره ها، آموزش دانلود دوره ها رو به بقیه یاد ندادم و شاید این طوری می تونستم تمرکز بیشتری روی معرفی و پیشنهاد دوره های خوب داشته باشم. ولی خب به نظرم هنوز دیر نشده و می خوام در اینجا آموزش دانلود این دوره ها رو به شما یاد بدهم.برای دانلود دوره های Coursera و Edx از دو کتابخانه پایتون به نام های coursera-dl  و edx-dl  استفاده می کنیم ولی ابدا لازم نیست که پایتون بلد باشید و صرفا لازم هست که پایتون رو نصب کنید. منتها اول از قبل از کاری برای دانلود دوره های کورسرا و edx باید برای هر دو سایت حساب کاربری ایجاد کنید.تفاوت اصلی Edx با کورسرا در دو مورد زیر هست:اولین تفاوت، تفاوت بین پلتفرمی هست که محتوای آموزشی این دو سایت روی هم قرار گرفتند. سایت Edx از یک فریمورک آموزشی متن باز که خودش توسعه داده است به نام OpenEdx برای محتواهای آموزشی اش استفاده می کند. به علاوه ویدئوهایی آموزشی سایت Edx روی سایت یوتیوب ذخیره شده اند( به صورت private، یعنی شما نمی توانید این ویدئوها را مستقیم داخل یوتیوب جستجو کنید.) این یعنی برای دانلود ویدئوهای Edx در حقیقت باید ویدئوهای یوتیوب را دانلود کنید.تفاوت دوم مهم این دو سایت در این هست که دوره های کورسرا همیشه در حال برگزاری و در دسترس هستند یعنی اگر شما نتوانستید که تکلیف های یک دوره را سر موقع و به صورت کامل انجام بدهید در سری بعدی که دوره مجددا ارائه می شود ( معمولا با فاصله زمانی یک ماهه) می توانید این تکالیف را در سری بعد تکمیل کنید.خب حالا که این چیزها را گفتم نوبت به اصل کار و آموزش نحوه دانلود دوره ها از این دو سایت می رسد و اول از همه با Edx شروع می کنم.دانلود کورس های سایت Edxسایت Edx هم مثل کورسرا دوره های مختلف آموزشی را داخل خودش دارد ولی با این حال کمی کمتر از کورسرا شناخته شده تر هست ولی با این وجود به شخصه دوره های فوق العاده خوبی داخل این سایت دیدم. برای دانلود ویدئوهای edx از یک کتابخانه پایتون به اسم edx-dl  استفاده می کنیم. این کتابخانه را با اجرای دستور زیر در محیط خط فرمان نصب می کنیم:pip install edx-dlالبته همانطور که گفتم ویدئوهای edx روی یوتیوب قرار دارند و برای دانلود آن ها باید اول از یک کتابخانه دیگر که ویدئوها را از یوتیوب دانلود می کند به نام youtube-dl استفاده کنیم. خوشبختانه وقتی که کتابخانه edx-dl  را نصب می کنیم این کتابخانه youtube-dl به صورت خودکار نصب و از آن استفاده می کند. البته طبق مستندات این کتابخانه بهتر است به صورت زیر هر از چندگاهی youtube-dl  را به روز رسانی کنیم چون ساختار یوتیوب هر از چندگاهی عوض می شود:pip install --upgrade youtube-dlتوجه: حواستان باشد که دسترسی مستقیم به یوتیوب از ایران امکان پذیر نیست! و برای استفاده از edx-dl و دانلود ویدئوها باید از ابزار دور زدن تحریم ها استفاده کنید!بعد از نصب این کتابخانه، برای دانلود کردن یک دوره خاص بعد از ثبت نام در آن دوره کافی است که دستور زیر را در محیط خط فرمان اجرا کنیم:edx-dl -u youremail -p yourpassword COURSE-URLدر اینجا باید آدرس ایمیل و پسورد که با آن به حساب edx خودتان وارد می شوید را به ترتیب به جای youremail و yourpassword وارد کنید.COURSE-URL  هم آدرس دوره ای است که می خواهید دانلود کنید. این آدرس، آدرس اولین صفحه ای است که بعد از وارد شدن به کورس می بینید. به طور مثال آدرس کورس  Data Science: Machine Learning همانطور که در تصویر زیر می بینید به صورت زیر است:https://courses.edx.org/courses/course-v1:HarvardX+PH125.8x+2T2018/course/بعد از اجرای دستور زیر، محتوای درون کورس در یک پوشه به نام Download که در دایرکتوری اصلی که محیط خط فرمان را باز کرده اید دانلود می شوند.علاوه بر این، می توانیم تنظیمات دیگری را هم برای دانلود ویدئوهای edx در نظر بگیریم که این تنظیمات را به عنوان پارامترهای دستوری که بالا اجرا کردیم مشخص می کنیم. لیست پارامترهای قابل تنظیم را هم می توانید با اجرای دستور edx-dl  در محیط خط فرمان ببینید.دانلود کورس های سایت کورسرامتاسفانه با توجه به تغییراتی که کورسرا در ساختار پلتفرم خودش و لاگین کردن به سایتش انجام داده است دانلود کورس های سایت کورسرا کمی پیچیده و سخت شده و عملا استفاده مستقیم از کتابخانه courseral-dl  امکان پذیر نیست. البته خوشبختانه برای این مشکل راه حلی پیدا شده است و من هم به طور مستقیم این راه حل را آموزش می دهم.ابتدا طبق معمول کتابخانه coursera-dl  را با اجرای دستور زیر نصب می کنیم.pip install coursera-dlحالا فایل coursera-dl.py که در این آدرس قرار دارد را دانلود می کنیم و با فایلی با همین نام که در دایرکتوری کتابخانه نصب شده coursera-dl  ( به طور مثال این دایرکتوری به صورت E:\ProgramData\Anaconda37\Lib\site-packages\coursera خواهد بود) جایگزین می کنیم.در مرحله بعدی افزونه cookiestxt را به مرورگر کروم اضافه می کنیم. حالا از طریق کروم به سایت کورسرا لاگین می کنیم و با این افزونه یک فایل به نام cookies.txt را به صورت شکل زیر دانلود می کنیم.حالا فایل cookies.txt را در دایرکتوری که می خواهیم دوره های دانلود شده قرار بگیرند می گذاریم و یک محیط خط فرمان را در آن دایرکتوری باز می کنیم. الان نوبت به دانلود کردن دوره ها می رسد. برای دانلود کردن دوره ها دستوری با ساختار زیر را اجرا می کنیم.coursera-dl -u youremail -p yourpassword COURSE-NAMEدر اینجا هم باید آدرس ایمیل و پسورد که با آن به حساب edx خودتان وارد می شوید را به ترتیب به جای youremail و yourpassword وارد کنید.پارامتر COURSE-NAME هم شناسه دوره ای است که می خواهید دانلود کنید که به صورت زیر می توانید شناسه دوره را در آدرس صفحه یک دوره به دست بیاورید:به طور مثال، شناسه دوره Neural Networks and Deep Learning به صورت « neural-networks-deep-learning» است.حالا می توانید دوره های کورسرا را هم به راحتی دانلود کنید و از آن ها لذت ببرید </description>
                <category>میم چ نخعی</category>
                <author>میم چ نخعی</author>
                <pubDate>Wed, 08 May 2019 15:14:39 +0430</pubDate>
            </item>
                    <item>
                <title>مجموعه کاملی از فوت و فن های کار با Jupyter Notebook - بخش 2/4 (دستورهای جادویی)</title>
                <link>https://virgool.io/@mcnakhaee/jupyter-notebook-2-yki2kdfcbtj5</link>
                <description>این پست بخش دوم از آموزش مجموعه فوت و فن هایی هست که من برای کار با ژوپیتر نوت بوک ها از منابع مختلف جمع کرده ام. در این بخش هم در خصوص دستورهای جادویی که یکی از ویژگی های فوق العاده کااربردی ژوپیتر حساب می شود صحبت می کنم. مجموعه کاملی از فوت و فن های کار با Jupyter Notebook - بخش 1/4مجموعه کاملی از فوت و فن های کار با Jupyter Notebook - بخش 2/4 (دستورهای جادویی)پست کامل، بروزتر و البته کمی از نظر بصری خواناتر در وبسایت شخصی خودمدستورهای جادویی ژوپیتریکی از اهداف اصلی ژوپتیر این هست که تمامی جنبه های کدنویسی تعاملی را برای ما راحت تر کند و تجربه کاربری بهتری را به ما بدهد. به طور مثال، اکثر ما دوست داریم که به جای این که هر بار یک کد رسم نمودار را اجرا می کنیم به جای این که نمودار در یک پنجره جدید باز و نمایش داده شود در همان محیطی که با آن کار کنیم به ما نشان داده شود. یا مثلا به جای این که هر بار یک که کتابخانه را نصب می کنیم یا تغییری که در یک ماژول اعمال می کنیم، برای استفاده از این تغییرات مجبور نباشیم که هر برنامه را ریستارت کنیم.ژوپیتر برای این که برخی از این مشکلات را برای ما حل کند از یک سری دستور به اسم توابع/دستور جادویی (Magic Functions/commands ) استفاده می کند. این دستورهای جادویی معمولا با علامت % شروع می شوند و آن ها را هم در سلول های کد اجرا می کنیم. در ادامه به طور مفصل بعضی از پرکاربردترین و مهم ترین دستورهای جادویی را به شما معرفی می کنم و توضیح می دهم و در آخر هم یک خلاصه از این دستورها به اضافه یک سری دستور جادویی دیگر را در جدولی به شما نشان خواهم داد.دستور جادویی  time%یک دستور جادویی کاربردی دستور time%  است که هر زمان که بخواهیم زمان اجرای یک خط کد در یکی از سلول های ژوپیتر را به دست آوریم از دستور جادویی  time%  در آن سلول و قبل از آن خط کد استفاده می کنیم. حالا وقتی که آن سلول را اجرا کنیم مدت زمانی که اجرای آن خط طول کشیده است به ما نشان داده می شود.12x=2%time for i in range(10000000): x=1+xWall time: 1.26 sاگر هم بخواهیم زمان اجرای چندین خط کد را به دست آوریم به جای % از دو علامت %% استفاده می کنیم. %%time
x = 2
for i in range(10000000):
x=1+x
for j in range(100000):
x = x*1.1Wall time: 1.28 sدقت کنید که به طور کلی دستورهای جادویی ژوپیتر نوت بوک می توانند هم برای اجرای تنها یک خط از کد به کار روند و یا می توانند کل کد موجود در سلول را اجرا کنند. در نوع اول قبل از دستورهای جادویی یک بار علامت % می آید و فقط خط کد بعد از دستور اجرا می شود. دستورهایی هم که برای اجرا کردن تمام کد سلول به کار می روند هم با دو علامت %% آغاز می شوند.دستور جادویی  matplotlib% احتمالا پرکاربردترین دستور جادویی که از آن در محیط ژوپیتر استفاده می کنیم دستور matplotlib inline%  است. از این دستور به طور خاص زمانی استفاده می کنیم که بخواهیم درون خود نوت بوک ها و بدون فراخوانی متد ()plt.show نمودارهایی که با کتابخانه matplotlib (و تقریبا هر کتابخانه مصوری سازی دیگر در پایتون) رسم کرده ایم را نمایش دهیم. در صورتی که از این دستور استفاده نکنیم نمودار درون نوت بوک نشان داده نمی شود و به صورت یک پنجره باز شده دیگر نمایش داده می شوند. معمولا این دستور را در ابتدای نوت بوک قرار می دهیم و یک بار اجرای آن برای نمایش دادن نمودارها در نوت بوک کافی است. %matplotlib inline
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
sns.set()
np.random.seed(123)
x = np.random.randn(100)
y = np.random.randn(100)
plt.scatter(x, y, color = &#039;indianred&#039;)
plt.show()دستور جادویی run% با استفاده از دستور run%  ما می توانیم هر نوع فایلی را به عنوان یک برنامه پایتون درون محیط Ipython اجرا کنیم. به عنوان مثال، فرض کنید که کد زیر را در فایل plot_func.py ذخیره کرده اید: import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
sns.set()
np.random.seed(123)
x = np.random.randn(100)
plt.hist(x, bins=20)
plt.show()حالا در محیط Ipython با استفاده از دستور run%  و نام و مسیر این فایل به صورت زیرمی توانیم آن را اجرا کنیم: %run test.py%matplotlib inline%run plot_func.pyمزیت دیگر این دستور جادویی این است که با اجرای آن تمامی متغیرهای، کلاس ها، توابع و سایر اشیاء های که درون اسکریپت هستند در محیط ژوپیتر قابل دسترسی خواهند بود. مثلا در مثال بالا، متغیر x  ای که درون اسکریپت فایل plot_func.py تعریف کرده ایم در محیط ژوپیتر هم موجود است.به علاوه مزیت دیگر دستور run%  این است که ما حتی می توانیم فایل های نوت بوک های دیگر را نیز با این دستور جادویی در یک نوت بوک دیگر اجرا کنیم.دستور جادویی load% برخی مواقع هم می خواهیم کد نوشته شده در یک فایل را بدون کپی و پیست کردن به نوت بوک اضافه اضافه کنیم، در این حالت از دستور load%  برای این کار استفاده می کنیم. بعد از اجرا، این دستور محتوای فایل اسکریپ را که می تواند در کامپیوتر شما یا بر روی اینترنت ذخیره شده باشد را درون سلول که در آن قرار دارد می ریزد. فایل مثال بالا را در نظر بگیرید اگر ما دستور loadplot_func.py% را درون یک سلول اجرا کنیم تمامی کد درون این اسکریپت در سلولی که قرار دارد بارگزاری می شود.دستور جادویی store% دستور مفید دیگری که می توانیم استفاده کنیم دستور store%  است که به ما امکان می دهد که از متغیرهای یک نوت بوک درنوتبوک دیگر استفاده کنیم یا به عبارتی دیگر داده های بین نوت بوک ها را انتقال بدهیم. به طور مثال فرض کنید که در یک نوت بوک آرایه نامپای x زیر که ساخته ایم را با دستور store% به صورت زیر ذخیره می کنیم.حالا می توانیم با دستور store –r%  در نوت بوک جدیدی که ساخته ایم بدون نیاز به هیچ کار دیگری از این متغیر x استفاده کنیم.لود کردن لحظه ای کتابخانه ها و ماژول هابعضی مواقع در حال کد زدن در ژوپیتر به موقعیتی می رسیم که نیاز می شود یک کتابخانه را نصب کنیم یا تغییری در یک ماژول ایجاد کنیم. وقتی که تغییری در کد یک ماژول می دهیم یا با استفاده از خط فرمان (خارج از محیط ژوپیتر) کتابخانه ای نصب می کنیم این تغییرات به صورت خودکار در ژوپیتر اعمال نمی شوند. مثلا فرض کنید که به یک جای کد رسیده اید که نیاز به بروزرسانی کتابخانه Pandas دارید ولی برای ابن کار فقط محیط خط فرمان و با دسترسی ادمین به روزرسانی را انجام دهید. در حالت عادی وقتی بروزرسانی را انجام دادیم برای استفاده از نسخه جدید کتابخانه Pandas باید یک بار نوت بوک را Shut down و سپس آن را ریستارت کنیم که کار بسیار مسخره ای است. به همین دلیل و برای این که این تغییرات به صورتی آنی در نوت بوک ما در نظر گرفته شوند می توانیم دو دستور جادویی زیر را به اول هر نوت بوک اضافه کنیم تا به صورت اتوماتیک هر تغییری که در سایر ماژول ها و کتابخانه ها اعمال شد نوت بوک ما هم به صورت خودکار به روزرسانی شود. این دستور هم خیلی به درد می خورد پس حواستان به آن باشد%reload_ext autoreload; %autoreload 2در جدول زیر بعضی دیگر از مهم ترین دستورهای جادویی که ممکن است سر و کار ما با آن ها بیفتد را می توانید مشاهده کنید. البته این تنها بخش کوچکی از دستورهای جادویی قابل استفاده برای ما است. برای دیدن لیست کامل دستورهای جادویی ژوپیتر می توانیم از یک دستور جادویی دیگر به نام lsmagic%  استفاده کنیم.به علاوه خودمان هم می توانیم دستورهای جادویی مخصوص خودمان را بسازیم که این موضوع البته از محدوده این آموزش خارج است و به آن نمی پردازیم ولی برای کسب اطلاعات بیشتر می توانید به این لینک مراجعه کنید. مستندات کامل مربوط به دستورات جادویی پیش فرض ژوپیتر هم در این لینک قابل مشاهده هستند. چند نکته مهم در خصوص دستورهای جادویی ژوپیتربه صورت پیشفرض دستورهای جادویی پایتون را می توان بدون استفاده از علامت % هم اجرا کرد البته تا زمانی که متغیر یا تابعی با نام مشابه آن ها در محیط برنامه تعریف نشده باشد.برای این که اطلاعات بیشتری در خصوص دستورهای جادویی Ipython اطلاع کسب کنیم و دیدن مستندات این دستورهای جادویی می توانیم مشابه با سایر دستورهای پایتون از ؟ پیش یا بعد از آن استفاده کنیم.</description>
                <category>میم چ نخعی</category>
                <author>میم چ نخعی</author>
                <pubDate>Thu, 29 Nov 2018 21:36:05 +0330</pubDate>
            </item>
                    <item>
                <title>مجموعه کاملی از فوت و فن های کار با Jupyter Notebook - بخش 1/4</title>
                <link>https://virgool.io/dataio/jupyter-notebook-kfyxhg9dghtu</link>
                <description>برای نوشتن کدهای پایتون محیط های متنوعی مثل Pycharm و VSCode وجود دارند که البته هر کدام از این ها هم کلی امکانات و قابلیت فوق العاده دارند. با این حال برای من که چندسالی هست که علاقه مند به Data science و Machin learning هستم این محیط ها خیلی جذاب نیستند و در عوض به خاطر  سادگی و قابلیت های منحصر به فرد،  من تقریبا فقط و فقط از Jupyter Notebook ها برای کدنویسی استفاده می کنم. حالا سوال پیش می آید که اصلا jupyter  (ژوپیتر) یعنی چی؟ جواب  این هست کهjupyter  از حرف های اول سه زبان برنامه نویسی پر کاربرد Julia، Python و R تشکیل شده است. چرا؟ چون که ژوپیتر در ابتدا و در اصل برای اجرا کردن کدهای این زبان های برنامه نویسی توسعه داده شده است. با این حال، در حال حاضر علاوه بر این سه زبان برنامه نویسی، ژوپیتر از زبان های مختلف دیگری هم (کمابیش) پشتیبانی می کند.حالا اگر بخواهیم به صورت ساده jupyter notebook را تعریف کنیم می توانیم بگوییم که ژوپیتر نوت بوک یک برنامه (یا کتابخانه) است که با آن می توانیم به صورت تعاملی در مرورگرمان یک فایل حاوی کد، عکس و … بسازیم و آن را در مرورگر ویرایش و اجرا کنیم. البته قابلیت های ژوپیتر فراتر از اجرا کردن یک کد با یک زبان برنامه نویسی خاص مثل پایتون است و با آن میتوانیم مجموعه متنوعی از کار ها را انجام بدهیم.ژوپیتر نوت بوک ها یکی از ابزارهای اصلی تقریبا همه متخصصین علم داده ها (Data Science) هستند و از دو جهت تاثیر گسترده ای بر حوزه علم داده ها داشته اند: اول از همه ژوپیتر نوت بوک ها فضایی برای تکرار و آزمایش فعالیت های مختلف علم داده ها را در اختیار ما قرار می دهند و همین پیاده سازی فرآیندهای تکرارشونده علم داده ها را برای ما راحت تر می کند. ثانیا دلیل دیگر تاثیرگذاری ژوپیتر نوت بوک این است که آن ها از زبان Markdown پشتیبانی می کنند؛ یعنی به عبارتی دیگر ما هم می توانیم در آن ها هم کد بنویسیم و هم می توانیم برای کدهایمان (فراتر از کامنت هایی که قبلا یا الان استفاده می کنیم) توضیحاتی مثل متن و شکل قرار دهیم. همین مساله باعث شده که به طور خاصی ژوپیتر نوت بوک ها در آموزش دادن مفاهیم علم داده ها، برنامه نویسی، پیاده سازی مقاله ها و … نقشی انقلابی داشته باشند.خود یک ژوپیتر نوت بوک هم از دو مولفه اصلی تشکیل می شوند: کرنل (Kernel) و داشبورد (Dashboard). کرنل وظیفه این را دارد که کدی که ما نوشته ایم را اجرا کند. به طور مثال، ژوپیتر نوت بوک ها به صورت پیشفرض دارای یک کرنل پایتون هستند که کدهای پایتون را اجرا می کند. داشبورد هم به ما این امکان را می دهد که نوت بوک ها را ببینیم، ویرایش کنیم و حتی کرنل مورد استفاده را تغییر دهیم یا ببندیم.حالا که این مقدمات نه چندان مهم را در خصوص ژوپیتر گفتم وارد اصل مطلب می شوم و ابتدا با مباحث ابتدایی مثل نحوه نصب و استفاده  شروع می کنم و در ادامه چندین نکته پیشرفته تر برای بهره بردن بهتر از ژوپیتر نوت بوک ها را به شما توضیح می دهم.نصب ژوپیتراگر از توزیع آناکوندا پایتون استفاده کنیم خبر خوش این است که کتابخانه ژوپیتر به صورت پیشفرض برای ما نصب شده است (به علاوه کلی کتابخانه دیگر که احتمالا به کار ما می آیند.) . اما در صورتی که از این توزیع استفاده نمی کنید مثل تقریبا بقیه کتابخانه های پایتون به سادگی و با دستور pip install jupyter می توانید آن را در محیط خط فرمان مثل شکل زیر نصب کنید.راه اندازی و استفاده از ژوپیتر نوت بوک هابرای بالا آوردن یک محیط ژوپیتر و استفاده از آن کافی است در محلی که می خواهیم فایل نوت بوک در آن ذخیره شود یک محیط خط فرمان را باز کنیم و دستور jupyter notebook را در آن اجرا کنیم. با اجرای این دستور یک وب سرور لوکال به صورت پیشفرض بر روی پورت ۸۸۸۸ ایجاد می شود که می توانیم آن را به صورت یک صفحه وب که البته به طور خودکار در مرورگر پیشفرض ما (مثلا گوگل کروم) بالا می آید هم ببینیم. اگر محیط ژوپیتر هم به صورت خودکار باز نشد می توانیم در مرورگر خودمان آدرسhttp://localhost:8888 را وارد کنیم.اگر هم به هر دلیلی نمی خواهیم که وقتی که ژوپیتر را راه اندازی می کنیم به صورت خودکار یک صحفه در مرورگر ما باز نشود می توانیم به صورت جایگزین دستور زیر را در محیط خط فرمان اجرا کنیم.jupyter notebook --no-browserصفحه ای که به صورت خودکار برای ما باز می شود صفحه ای به شکل زیر است:همانطور که می بینیم تب “Files” تمام فایل ها و فولدرهایی که در دایرکتوری که ژوپیتر نوت بوک را باز کرده ایم (دستور jupyter notebook را اجرا کرده ایم) نشان می دهد. تب Running هم به ما لیست تمامی نوت بوک های در حال اجرا و فعال را نشان می دهد. تب کلاستر هم برای کنترل موازی سازی به کار می رود و با آن معمولا کاری نداریم. برای ایجاد یک نوت بوک جدید در محیط ژوپیتر بر روی New کلیک می کنیم و بسته به نسخه پایتون نصب شده ( ۲ یا ۳ یا حتی زبان های برنامه نویسی دیگر که در ادامه به آن خواهیم رسید) نوت بوک جدیدی می سازیم ( من چون کرنل های مختلف ژوپیتر را قبلا نصب کرده ام در این جا گزینه های بیشتری می بینم ولی شما احتمالا فقط Python 3 یا Python 2 را خواهید دید.)بعد از ساخت نوت بوک با صفحه ای مثل عکس زیر مواجه می شویم که طبیعتا همانطور که انتظار داریم یک نوت بوک است!توجه کنید که احتمالا وقتی برای اولین بار ژوپیتر نوت بوک را اجرا می کنید گزینه هایی که که در تولبار محیط ژوپیتر عکس بالا می بینید با تولبار محیط ژوپیتر خودتان می بینید متفاوت است. دلیل هم افزونه هایی است که من برای محیط ژوپیتر خودم نصب کردم که انشاالله در بخش های بعدی طریقه نصب آن ها را هم به شما آموزش می دهم.نوت بوک های ژوپیتر اساسا از بلاک هایی به نام سلول (Cells) تشکیل می شوند. ما در این سلول ها می توانیم کد، متن، عکس و انواع مختلفی از محتواها را قرار دهیم. برای ایجاد یک سلول جدید بر روی علامت به اضافه در تولبار بالای صفحه کلیک می کنیم. به علاوه می توانیم با استفاده از دستور alt+enter سلول جدید بعد از سلول فعلی اضافه کنیم. وقتی که یک سلول جدید ساختیم با انتخاب یکی از گزینه های موجود شکل زیر نوع سلول را مثلا یا به صورت Code برای اجرای کدها، Markdown برای قرار دادن انواع محتوا ها و Header برای قرار دادن عنوان اصلی در نوت بوک در بیاوریم (با Raw NBConvert فعلا کاری نداریم)اجرای کد در سلول های ژوپیترحالا که یک سلول جدید ساختیم می توانیم در آن  هر کد پایتونی که می خواهیم را بنویسیم.  برای اجرا کردن آن کد هم می توانیم کلیدهای ctrl+enter را فشار دهیم یا از تولبار بالای نوت بوک بر روی گزینه Run کلیک کنیم. بعد از این کار ژوپیتر کد را اجرا می کند و در صورت وجود، خروجی را برای ما در همان نوت بوک چاپ می کند.به همین صورت اگر وقتی که در یک سلول هستیم shift+enter را فشار دهیم علاوه بر این که کد داخل آن سلول اجرا می شود به صورت مستقیم هم به سلول بعد می رویم. اگر shift+enter را بزنیم و سلولی بعد از سلول فعلی نداشته باشیم به صورت خودکار یک سلول جدید برای ما ساخته می شود.وقتی یک سلول را اجرا می کنیم در براکت سمت چپ آن سلول یک ستاره نشان داده می شود که به ما می گوید که سلول در حال اجرا، یا در صف انتظار برای اجرا شدن است.زمانی هم که اجرای یک سلول تمام شد، یک عدد درون براکت نشان داده می شود که به ما می گوید که این سلول بر اساس چه ترتیبی در این نوت بوک اجرا شده است.زمانی که کد در حال اجرا است و به هر دلیلی می خواهیم اجرا کد را متوقف کنیم ( مثلا زمان اجرا بیش از حد طولانی شده است) دکمه های Ctrl + C را بر روی کیبرد فشار می دهیم. در این حالت خطای موسوم به KeyboardInterrupt به ما باز گردانده می شود.چند میان بر خیلی کاربردییک ویژگی خوب دیگر ژوپیتر این است که می توانیم در آنمثل بسیاری از محیط های کدنویسی از قابلیت auto-completion کد استفاده کنیم تا هم در وقت خودمان صرفه جویی کنیم و هم اشتباهات تایپی کمتری داشته باشیم. برای استفاده از قابلیت auto-completion ژوپپتر مثل خیلی از محیط های ویرایش کد وقتی یک قسمت از کد را تایپ می کنیم با یک بار فشار دادن کلید Tab می توانیم ببینیم چه گزینه هایی در پیش رو داریم.یک ویژگی مرتبط که شاید منحصر به فرد ژوپیتر نوت بوک باشد این است که ما می توانیم با یک بار فشار دادن دکمه های shift+Tab آرگومان ها ورودی های مورد نیاز یک تابع را ببینیم. این دستور خیلی به درد می خورد و به نظر من کاربردی ترین ویژگی ژوپیتر است . مثلا تقریبا همیشه من از این دستور برای این که ببنیم توابع چه آرگومان هایی دارند یا حتی کپی کردن آرگومان ها استفاده می کنم.حالا با دو بار فشار دادن دکمه های shift+Tab می توانیم علاوه بر آرگومان ها ورودی های مورد نیاز یک تابع، مستندات آن تابع (docstring) را هم ببینیم.اگر در یک سلول و قبل از یک تابع علامت ?را قرار دهیم و آن سلول را اجرا کنیم خروجی مشابهی با دو بار فشار دادن دکمه های shift+Tab به ما در یک صفحه pop-up نمایش داده می شود.اگر دو علامت ?? را قبل از یک تابع قرار دهیم و آن را در ژوپیتر اجرا کنیم علاوه بر مستندات، سورس کد هم به ما نشان داده می شود.وقتی هم که یک سلول را انتخاب می کنیم با فشردن دکمه های که در جدول زیر می بینیم، رفتارهای مختلفی را می توانیم مشاهده کنیم (برای انتخاب سلول کافی است بر روی قسمت سمت چپ سلول کلیک کنیم):چاپ خروجی ها در ژوپیتر نوت بوکژوپیتر به صورت پیشفرض تنها نتیجه آخرین خط از سلول را به عنوان خروجی آن سلول چاپ می کند ( البته اگر نتیجه آخرین خطر کد در یک متغیر ذخیره نشده باشد.). یعنی دیگر بدون استفاده از دستور printهم می توانیم خروجی ها را چاپ کنیم.البته به صورت صریح هم می توانیم از تابع printاستفاده کنیم تا مقادیر متغیرها را بدون این که حتما در خط آخر کد باشند چاپ کنیم.یک راه جالب تر برای چاپ همزمان چندین متغیر در یک سلول که نیازی به دستور printهم ندارد این است که تنظیمات موسوم به ast_note_interactivity ژوپیتر نوت بوک را تغییر دهیم تا هر کدام از متغیرهایی را که می خواهیم بدون این که در آخرین خط از سلول باشند، چاپ کنیم. برای تغییر این گزینه می توانیم در یک سلول (ترجیحا سلول اول نوت بوک) کد زیر را اجرا کنیم.from IPython.core.interactiveshell import 
InteractiveShellInteractiveShell.ast_node_interactivity = &quot;all&quot;بعد از اجرای کد بالا، رفتاری مانند مثال عکس زیر مشاهده خواهیم کرد. یعنی مثلا حالا می توانیم ببینیم که اگر دو متغیر را در یک سلول فراخوانی کنیم مقدار هر دو متغیر چاپ می شود.اگر هم خروجی های یک سلول ما زیاد باشند (مثلا یک متن بلند) میتوانیم با یک بار کلیک کردن بر روی قسمت سمت چپ فضای حاوی خروجی آن را به یک پنجره کوچکتر و با قابلیت اسکرول تبدیل کنیم. به طور مثال در عکس زیر خروجی چاپ شده فضای زیادی را اشغال می کند و باعث بلندتر شدن بی جهت نوت بوک می شود.می توانیم با کلیک بر روی قسمت سمت چپ این سلول که با مستطیل قرمز در تصویر بالا نشان داده شده است فضایی که خروجی به ما نشان می دهد را بزرگ یا کوچک کنیم و مثلا به صورت جمع و جور تصویر پائین در بیاوریم.حالا اگر بخواهیم خروجی یک تابع یا دستور آخر یک سلول چاپ نشود می توانیم در انتهای آن دستور ; قرار دهیم. به طور خاص زمانی که می خواهیم نمودار های رسم شده را نمایش دهیم این کار به درد ما می خورد چون معمولا کتابخانه هایی مثل matplotlib در کنار نمودار رسم شده کلی متن اضافه هم تولید می کنند و نمایش می دهند که باعث بدریخت شدن نوت بوک می شود.مشکل روش بالا این است که برای زمانی که با حلقه for یا while کار می کنیم و به طور خاص زمانی که با این حلقه ها می خواهیم چندین نمودار رسم کنیم (مثل عکس زیر) این روش جواب نمی دهد.برای حل این مشکل مثل مثال زیر می توانیم با تخصیص خروجی نمودار به علامت _ که در پایتون  معمولا به عنوان نشانه متغیرهای بدرد نخور و بدون استفاده به کار برده می شود، این مشکل را حل کنیم.اگر هم به صورت کلی بخواهیم خروجی سلول نمایش داده نشود ( مثلا وقتی که داریم یک کتابخانه را نصب می کنیم یا زمانی که اضافه کردن یک کتابخانه به ما یک هشدار ( warning) می دهد (مثلا این هشدار که تابع فلان در نسخه بعدی کتابخانه منسوخ خواهد شد) می توانیم کد capture%% را که یک دستور جادویی ژوپیتر است و در بخش های بعدی به صورت مفصل تری با آن ها آشنا می شویم به ابتدای آن سلول اضافه کنیم.چاپ خروجی های زیباتربه صورت پیشفرض ژوپیتر فارغ از این که از دستور ()print استفاده کنیم یا نکنیم همیشه یک خروجی یکنواخت و با فونت و ساختار مشابه به ما می دهد. با این حال ممکن است بعضی وقت ها بخواهیم بخشی از خروجی ما متفاوت باشد ( مثلا مقدار یک متغیری که چاپ می کنیم بولد شده باشد.) باز یکی دیگر از قابلیت های منحصر به فرد ژوپیتر نوت بوک ها این است که می توانیم نحوه نمایش خروجی سلول ها را هم با استفاده از کدهای HTML و Markdown شخصی سازی کنیم. به طور مثال با اجرای کد زیر، خروجی که ژوپیتر نوت بوک به ما نمایش به صورت سبز و بولد خواهد بود.from IPython.display import Markdown,display Markdown(&#039;**&lt;div style= &quot;color:green&quot;&gt; Green and Bold&lt;/div&gt;** &#039;) متاسفانه نوشتن این جور مطالب فنی و کددار در ویرگول کمی طاقت فرسا هست و معمولا خروجی اون چیزی نمی شود که انتظار دارم. مثلا برای نوشتن همین مطلب به خاطر این که یک لحظه اینترنت قطع شد تمامی گام های بعدی که انجام دادم با وجود وصل شدن اینترنت ذخیره نشدند و برای همین مجبور شدم که از اول دوباره یک سری گام ها را انجام بدهم و البته بی خیال برخی از مطالب مثل magic functions برای این پست بشوم و آن مطالب را به صورت چند بخش در آینده منتشر کنم (امیدوارم!). با این وجود، پست اصلی در بلاگ شخصی خودم کمی به روزتر و البته به خاطر محدودیت های کدنویسی در ویرگول خواناتر و شاید زیباتر هست.</description>
                <category>میم چ نخعی</category>
                <author>میم چ نخعی</author>
                <pubDate>Sun, 25 Nov 2018 23:34:41 +0330</pubDate>
            </item>
                    <item>
                <title>یادگیری عمیق با کراس - بخش دوم (چطور با شبکه های عصبی ارقام دست نویس فارسی را بخوانیم)</title>
                <link>https://virgool.io/dataio/%DB%8C%D8%A7%D8%AF%DA%AF%DB%8C%D8%B1%DB%8C-%D8%B9%D9%85%DB%8C%D9%82-q7q1i0gnglhx</link>
                <description>  به  صورت سنتی Hello World  یادگیری عمیق، آموزش تشخیص ارقام دست نویس انگلیسی دیتاست معروف MNIST هست. مثلا اگر شما به اکثر مثال های آموزشی فریمورک های یادگیری عمیق مثل تنسورفلو و کراس نگاه کنید می بینید که اولین مثالی که زده شده نحوه تشخیص این ارقام دست نویس است. از اونجا که من  دوست دارم مثال هایی که می زنم با خودمون مرتبط تر  باشه تصمیم گرفتم که برای آموزش شبکه های عصبی در کراس از دیتاست اعداد دست نویس فارسی استفاده کنم. خوشبختانه دیتاست فارسی متناظر با MNIST هم به اسم «دیتاست هدی» وجود داره که اینجا از اون استفاده می کنم.از این جا به بعد به احترام حفظ زبان فارسی پست را با زبان فارسی رسمی می نویسم :)توجه: فایل ها و کدهای استفاده شده در این پست همگی در گیت هاب من موجود هستند.توجه 2: در این پست فرض کردم که خواننده با شبکه های عصبی و البته پایتون آشنایی داره و بنابراین اگر با مفاهیم شبکه های عصبی و زبان برنامه نویسی پایتون آشنا نیستید توصیه می کنم اول از آن ها شروع کنید و بعد این پست را بخوانید.همانطور که گفتم در این بخش یک مثال عملی از پیاده سازی شبکه عصبی در فریمورک کراس برای تشخیص تصاویر دیتاست اعداد دست نویس فارسی هدی را به شما یاد می دهم. مسئله ای که در این جا به وسیله کراس می‌خواهیم حل کنیم این است که مجموعه ای از تصاویر سیاه و سفید از اعداد دست نویس فارسی مانند شکل زیر داریم و می‌خواهیم با استفاده از این تصاویر یک مدل شبکه عصبی به وسیله کراس ایجاد کنیم تا اگر یک تصویر از یک عدد دست نویس فارسی به آن بدهیم بتواند به ما بگوید که این عکس چه عددی را نشان می‌دهد. در حقیقت در این جا شبکه عصبی یاد می‌گیرد که چطور تصاویر و برچسب‌های آن‌ها را به هم نگاشت کند. نمونه ای از تصاویر ارقام دست نویس فارسی دیتاست هدیبرای این کار فرآیندی که طی می‌کنیم این است که اول یک شبکه عصبی را با استفاده از فریمورک کراس می‌سازیم. سپس داده ها را تقسیم می کنیم و مجموعه ای از داده‌ها (تصویر به اضافه برچسب عدد متناظر با آن تصویر) که به آن‌ها مجموعه آموزشی می گوییم را به شبکه می‌دهیم و مجموعه دیگری از داده‌ها که یک گوشه نگه می‌داریم تا بعدا با آن عملکرد شبکه عصبی را بسنجیم و به آن مجموعه تست می گوییم. در نهایت شبکه را با مجموعه داده های آموزش، آموزش می‌دهیم تا یاد بگیرد که چطور تصاویر و برچسب‌های متناظر با آن‌ها را به هم نگاشت کند. در نهایت هم تصاویر مجموعه تست را به شبکه می‌دهیم تا شبکه برچسب آن‌ها پیشبینی کند و ما هم برای این که ببینیم مدل ما خوب بوده است آن‌ها را با برچسب واقعی‌شان مقایسه کنیم.خواندن داده‌هاپیش از این که وارد مدل سازی شبکه عصبی به وسیله کراس شویم لازم است که اول دیتاست تصاویر را بخوانیم و یک سری پیش پردازش بر روی داده‌ها انجام دهیم. برای این کار ابتدا کتابخانه‌های opencv، numpy، matplotlib، scipy را که برای ادامه کار لازم داریم به محیط پایتون اضافه می‌کنیم. کتابخانه opencv که یک کتابخانه پردازش تصویر برای پایتون است که طریقه نصب آن را می‌توانید در این لینک ببینید.import scipy.io
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import cv2داده‌های مربوط به تصاویر که می‌توانید در گیت هاب من دانلود کنید به صورت یک فایل با فرمت.mat (فرمت مخصوص ذخیره سازی داده‌های متلب) قرار دارند. برای این که این داده‌ها را بخوانیم از تابع ()loadmat ماژول scipy.io استفاده می‌کنیم و داده‌ها را در یک متغیر به نام hoda می‌ریزیم.hoda = scipy.io.loadmat(&#039;data\\Data_hoda_full.mat&#039;)اگر نوع داده متغیر hoda را بررسی کنیم می‌بینیم که این متغیر در اصل یک دیکشنری پایتون است.print(type(hoda))dictحالا اگر نگاهی به کلید های این دیکشنری بیاندازیم می‌بینیم که این دیکشنری دارای دو کلید به نام‌های Data و labels است که ما هم فقط با همین دو کار داریم.print(hoda.keys())dict_keys([&#x27;__header__&#x27;, &#x27;__version__&#x27;, &#x27;__globals__&#x27;, &#x27;Data&#x27;, &#x27;labels&#x27;])مقدار متناظر با کلید Data در حقیقت یک آرایه نامپای است که هر مؤلفه آن آرایه‌های پیکسل‌های تصویر هستند که اعدادی بین 0 تا 255 را می‌گیرند. اگر ابعاد این آرایه را هم بررسی کنیم می‌بینیم که در مجموع داده 60000 تصویر در این آرایه ذخیره شده‌اند.print(type(hoda[&#039;Data&#039;]))&lt;class &#x27;numpy.ndarray&#x27;&gt;print(hoda[&#039;Data&#039;].shape)(60000, 1)مقدار ذخیره شده در کلید labels هم یک آرایه نامپای دوبعدی شامل برچسب متناظر با عدد هر کدام از تصاویر است.print(type(hoda[&#039;labels&#039;]))&lt;class &#x27;numpy.ndarray&#x27;&gt;print(hoda[&#039;labels&#039;].shape)(60000, 1)برای ساده تر شدن ادامه کار آرایه نامپای متناظر با Data و labels تصاویر را به صورت یک آرایه یک بعدی (ستونی) در می‌آوریم.data= hoda[&#039;Data&#039;].reshape(-1)print(data.shape)(60000,)labels = hoda[&#039;labels&#039;].reshape(-1)print(labels.shape)(60000,)حالا به وسیله کتابخانه matplotlib و تابع ()plt.show سعی می‌کنیم به صورت نمونه یکی از تصاویر این دیتاست را رسم کنیم و برچسب متناظر با آن را با آن چک کنیم.pic1_data = data[1]
pic1_label = labels[1]
plt.figure(figsize = (5,5))
plt.axis(&#039;off&#039;)
plt.imshow(pic1_data,cmap= matplotlib.cm.Greys)
plt.show()همانطور که می‌بینیم این تصویر عدد 5 را نشان می‌دهد. حالا با چاپ برچسب آن صحت 5 بودن این تصویر را هم چک می‌کنیم!print(pic1_label)5پیش پردازش داده‌هاپیش از این که شبکه را آموزش دهیم لازم است که داده‌ها را پیش پردازش کنیم تا به صورت مناسبی که شبکه عصبی از داده های ورودی انتظار دارد تبدیل شوند. در این جا ما با چند چالش روبرو هستیم. اول از همه اندازه تصاویر درون دیتاست با هم متفاوت است و این برای شبکه عصبی ما مشکل ایجاد می‌کند. دلیل این مشکل این است تعداد پیکسل‌های تصاویر نیز در این حالت متفاوت است و در نتیجه ابعاد ورودی‌های ما هم متفاوت است ولی برای استفاده از شبکه‌های عصبی نیاز است که ابعاد ورودی‌های ما با هم برابر باشند و در غیر ما نمی‌توانیم از شبکه عصبی برای آموزش مدلی برای تشخیص عدد تصاویر استفاده کنیم. به طور مثال می‌توانیم ببنیم که اندازه چند تصویر اول دیتاست با هم متفاوت است:for i in range(1,6):
    print(data[i].shape)(20, 21) (10, 15) (36, 17) (36, 28) (12, 14)برای حل این مشکل از کتابخانه opencv و تابع ()resize آن به همراه قابلیت List Comprehension پایتون استفاده می‌کنیم تا همه تصاویر موجود در دیتاست را به یک اندازه 5 در 5 دربیاوریم.data_resized = np.array([cv2.resize(img, dsize=(5, 5)) for img in data])حالا اگر دوباره چک کنیم می‌بینیم که هم تصاویر ما به یک اندازه درآمده‌اند.for i in range(1,6):
print(data_resized[i].shape)(5, 5) (5, 5) (5, 5) (5, 5) (5, 5)حالا می‌توانیم به عنوان مثال یکی از این تصاویری که اندازه‌اش تغییر پیدا کرده است را رسم کنیم.plt.figure(figsize = (2,2))
plt.axis(&#039;off&#039;)
plt.imshow(data_resized[1],cmap= matplotlib.cm.Greys)
plt.show()خوب این چالش هم برطرف شد ولی چالش دیگر این است که مقادیر ذخیره شده مربوط به پیکسل های هر تصویر باید به یک مقیاس در بیایند چون شبکه های عصبی دوست دارند مقادیر ورودی به آن ها در یک محدوده ( مثلا 0 تا 1) باشد  و در غیر این صورت آموزش شبکه عصبی ما به خوبی انجام نخواهد شد. همانطور که گفتیم مقدار ذخیره شده در هر پیکسل عددی بین 0 تا 255 است. برای همین می‌توانیم با تقسیم آرایه هر تصویر بر 255 مقادیر ذخیره شده هر پیکسل آن را به صورت عددی بین 0 تا 1 در بیاوریم.data_norm = data_resized/255
data_norm[1]array([[0., 0., 1., 0., 0.],   [0., 1., 0.50196078, 1., 0.],    [0.8, 0.2, 0., 0.2, 0.8],     [1., 0., 1., 0., 1.],    [0.2, 0.89803922, 1., 0.6, 0.8]])حالا ابعاد آرایه داده‌های ورودی را بررسی می‌کنیم.data_norm.shape(60000, 5, 5)همانطور که می‌بینیم ابعاد این آرایه به صورت (5,5,60000) است. برای استفاده از این داده‌ها به عنوان ورودی به شبکه عصبی در کراس لازم است که ابعاد بردار پیسکل ها را تبدیل به (25,60000) کنیم یا اصطلاحاً بردار را به صورت تخت شده (flattened) در بیاوریم تا هر پیکسل از تصویر متناظر با یک نورون ورودی باشد.data_norm = data_norm.reshape(60000,25)
data_norm.shape(60000, 25)حالا نوبت به تقسیم داده‌ها به مجموعه تست و آموزش می‌رسد تا با استفاده از مجموعه آموزش مدل را آموزش دهیم و با استفاده از مجموعه تست عملکرد مدل را بر روی داده‌های دیده نشده بررسی کنیم. برای این کار از کتابخانه scikit-learn و تابع train_test_split آن استفاده می‌کنیم.from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(data_norm,labels)برای روشن شدن بیشتر ابعاد هر کدام از این مجموعه را هم بررسی می‌کنیم.print(&quot;size of training dataset is: &quot; + str(X_train.shape))
print(&quot;size of test dataset is: &quot; + str(X_test.shape))size of training dataset is: (45000, 25)size of test dataset is: (15000, 25)برای مدل سازی مسائل دسته بندی در کراس باید به ازای هر کدام کلاس باید یک ستون هدف ایجاد کنیم که این ستون‌های هدف شامل مقادیر 0 و 1 هستند. اصطلاحاً به این کار one-hot encoding گفته می‌شود که در شکل زیر هم یک مثال از آن را می توانید ببینید. روش one-hot-encodingهم در مسئله ما  10 ستون دیگر به ازای 10 کلاس عدد بین 0 تا 9 ساخته می‌شود. اگر مقدار برچسب یک مشاهده برابر با 5 بود مقدار متناظر با ستون کلاس 5 ساخته شده آن برابر با 1 و برای بقیه ستون‌ها برابر با 0 خواهد شد. انجام این کار در کراس بسیار ساده است و با استفاده از تابع ()np_utils.to_categorical می‌توانیم هر کدام از کلاس‌ها را به یک ستون 0 و 1 تبدیل می تماییم.n_classes = 10
y_train_cat = keras.utils.to_categorical(y_train, n_classes)
y_test_cat = keras.utils.to_categorical(y_train,n_classes)
y_train[1]array([0., 0., 1., 0., 0., 0., 0., 0., 0., 0.])ساخت مدل با کراستمام گام‌هایی که تا به الان طی کردیم گام‌های پیش پردازش داده‌ها بود. حالا نوبت این استف که از کراس برای ساخت شبکه عصبی و مدل سازی استفاده کنیم. پیش از شروع باید بگوییم که انواع مختلفی از شبکه‌های عصبی وجود دارند  ولی در این بخش ما از شبکه‌های تماماً متصل (fully connected) برای دسته بندی تصاویر اعداد دست نویس فارسی استفاده می‌کنیم. این نوع شبکه‌ها از مجموعه ای پشت از سرهم از لایه‌ها تشکیل شده‌اند که در آن‌ها هر نورون به تمامی نورون‌های لایه بعدی خودش متصل است. برای ساخت این شبکه‌ها در کراس از ماژول model که اصلی‌ترین ساختار در کراس است و لایه‌ها را سازماندهی می‌کند استفاده می‌کنیم. اصلی‌ترین و ساده‌ترین نوع مدل هم در این ماژول مدل Sequential (ترتیبی) است که به صورت یک مجموعه ترتیبی و خطی از لایه‌ها که هر لایه تنها با لایه بعد از خود ارتباط دارد تعریف می‌شود.شبکه های تماما متصلاین مدل به این خاطر ترتیبی نامیده می‌شود چون ابتدا یک شی خالی از این مدل می‌سازیم و به آن به صورت ترتیبی (Sequential) لایه‌های مختلف اضافه می‌کنیم و به عبارتی دیگر یک شبکه با انتشار رو به جلو می‌سازیم. برای استفاده از مدل باید آن را از ماژول keras.models به برنامه اضافه کنیم.بعد از این که یک شی خالی از مدل را ساختیم باید به تعدادی که مدنظر داریم به آن لایه اضافه کنیم. اضافه کردن لایه به یک شبکه عصبی در کراس بسیار راحت است کافی است که ابتدا از ماژول keras.layers نوع لایه مدنظر را انتخاب و به برنامه اضافه کنیم.. سپس با استفاده از متد add شی مدل ساخته شده استفاده کنیم تا آن لایه به شبکه اضافه اضافه شود. همانطور که گفته شد برای حل مسئله دسته بندی تصاویر اعداد فارسی در این مرحله ما از معماری شبکه عصبی تماماً متصل بهره می‌بریم. برای همین وقتی می‌خواهیم به مدل ترتیبی لایه اضافه کنیم از لایه‌های استاندارد Dense کراس استفاده می‌کنیم. به این لایه‌ها Dense می گوییم چون تمامی گره‌ها در یک لایه به تمام گره‌ها در لایه بعدی متصل می‌شوند. وقتی از لایه‌های Dense استفاده می‌کنیم ابتدا باید تعداد نورون‌ها هر لایه را مشخص کنیم. تعداد این نورون‌ها یک ابرپارامتر است که مقدار مناسب برای آن را می‌توانیم با سعی و خطا به دست آوریم. البته معمولاً هر چه تعداد نورون‌ها بیشتر شود صحت مدل نیز بیشتر می‌شود ولی از طرفی دیگر افزایش بیش از حد آن هم منجر به بیش برازش می‌شود. به علاوه، باید توجه کنیم که پیش از این که مقادیر خروجی شبکه  از یک لایه به لایه دیگر منتقل شوند باید از یک تابع فعالسازی غیرخطی عبور کنند چون در غیر این صورت شبکه ما قادر به یادگیری الگوهای غیرخطی موجود در داده ها نخواهد بود. کراس هم تقریباً از همه توابع فعالسازی استانداری که به صورت رایج هم در پژوهش‌ها و هم در کاربردهای عملی مورد استفاده قرار می‌گیرند پشتیبانی می‌کند و هم به ما این امکان را می‌دهد تا برای هر لایه یک تابع فعال سازی متفاوت را انتخاب کنیم. یکی از توابع فعالسازی مشهور که ما در اینجا از آن استفاده می کنیم تابع فعال سازی Relu است که اگر مقدار ورودی آن کوچکتر از 0 باشد(منفی باشد) عدد 0 را بازمی گرداند و اگر بزرگتر از 0 باشد خود آن مقدار را باز می گرداند. در شکل زیر می توانید ساختار تابع فعال سازی Relu را ببینید.تابع فعالسازی Reluدر نهایت، در لایه اول هم باید ابعاد داده‌های ورودی‌ها را مشخص کنیم. لایه آخر هم معمولاً بسته به نوع مسئله تعداد نورون‌های متفاوتی دارد مثلاً برای مسئله رگرسیون تعداد نورون‌های لایه آخر برابر با 1 است چون می‌خواهیم تنها یک مقدار را پیشبینی کنیم ولی برای مسئله دسته بندی تصاویر اعداد فارسی تعداد نورون‌ها برابر با 10 است چون می‌خواهیم 10 عدد (0 تا 9) را پیشبینی کنیم.فراتر از توابع فعال سازی، تعداد نورون‌ها و ابعاد ورودی، کراس از اعمال تغییرات بیشتر دیگری مانند تعریف کردن تابع برای وزن گره‌ها و توابع تنظیم سازی برای وزن‌های گره در هر لایه پشتیبانی می‌کند؛ اما یک اصل نانوشته در کراس وجود دارد که بهتر است از همان گزینه‌های پیشفرض استفاده کرد چون این پیشفرض ها بر اساس نتایج بهترین رویه‌های ممکن تعیین شده‌اند.برای این که شبکه را بر روی این دیتاست آموزش دهیم باید سه چیز دیگر را نیز مشخص کنیم: تابع زیان: تابع زیان عملکرد شبکه را بر روی داده‌های آموزش اندازه گیری می‌کند تا ببینیم که آیا جهتی که طی می‌کنیم جهت درستی است یا خیر؟· الگوریتم بهینه ساز: الگوریتم بهینه سازی بر اساس تابع زیان و داده‌ها جهتی که وزن‌های شبکه باید به روزرسانی شوند تا شبکه به بهینگی برسد را مشخص می‌کند. در این مثال ما از الگوریتم بهینه ساز ADAM (گرادیان نزولی تصادفی) استفاده می کنیم.· معیار ارزیابی: معمولاً برای مسائل دسته بندی از معیار صحت استفاده می‌کنیم که نسبت مشاهدات درست پیشبینی شده به کل داده‌ها است.خوب حالا به بحث ساخت و پیاده سازی مدل و اضافه کردن لایه‌های شبکه عصبی به آن در کراس می‌رسیم تا تمامی مواردی که در بخش قبلی گفتیم را در عمل هم اجرا کنیم. برای دسته بندی ارقام ما می‌خواهیم یک شبکه با دو لایه پنهان و یک لایه ورودی بسازیم که در هر لایه 50 نورون قرار دارد. برای شروع ابتدا کلاس‌های مربوط به مدل Sequential و لایه Dense را از ماژول‌های مختلف کراس به برنامه اضافه می‌کنیم.import keras
from keras.layers import Dense
from keras.models import Sequentialحالا یک نمونه خالی از مدل Sequential را به صورت زیر ایجاد می‌کنیم.model = Sequential()حالا گام به گام شروع به اضافه کردن لایه‌ها به مدل می‌کنیم. اولین چیزی که باید مشخص کنیم این است که ابعاد داده‌های ورودی و تعداد نورون‌های این لایه چقدر است. از آنجا که ابعاد بردار تصویر ورودی ما برابر با 25 است و نمی‌خواهیم محدودیتی بر روی تعداد تصاویر ورودی به شبکه داشته باشیم، آرگومان ابعاد ورودی را به صورت input_shape = (25,) قرار می‌دهیم که مولفه اول ابعاد تصاویر و مولفه دوم آن تعداد تصاویر ورودی است. همچنین باید در هر لایه تابع فعال سازی را هم مشخص کنیم که در کراس این کار با استفاده از آرگومان ورودی activation انجام می‌شود. در دو لایه اول از تابع فعال سازی Relu استفاده می‌کنیم ک. برای لایه آخر شبکه از تابع فعالسازی سافت مکس (softmax) استفاده می‌کنیم چون این تابع یک عدد بین 0 و 1 یا به عبارتی دیگر یک خروجی احتمالی به ما می‌دهد که با آن می‌توانیم احتمال تخصیص هر کدام از مشاهدات به کلاس‌ها را محاسبه کنیم.تابع فعالسازی softmaxmodel = Sequential()
model.add(Dense(50,activation = &#039;relu&#039;, input_shape = (25,)))
model.add(Dense(50,activation = &#039;relu&#039;))
model.add(Dense(50,activation = &#039;relu&#039;))
model.add(Dense(10, activation=&#039;softmax&#039;))بعد از مشخص کردن نوع مدل، نوع لایه و تعداد نورون‌ها در هر لایه گام بعدی کامپایل کردن مدل ساخته شده به وسیله متد ()compile است. در اصل در این جا است که کراس در پشت صحنه تنسرفلو را اجرا می‌کند. وقتی یک مدل را کامپایل می‌کنیم باید دو ورودی اصلی را به آن بدهیم. اولین ورودی این است که بگوییم که چطور می‌خواهیم صحت مدل را در طی فرآیند آموزش بسنجیم (تابع زیان مدل چه باشد) که این با پارامتر ورودی loss تعیین می‌شود و ما  برای معمولاً برای مسائل دسته بندی چندکلاسه مثل مساله ما از Categorical crossentropy استفاده می کنیم. دومین چیز این است که می‌خواهیم از چه الگوریتم بهینه سازی استفاده کنیم که این الگوریتم بهینه ساز با پارامتر ورودی optimizer مشخص می‌شود و فرآیند و نرخ یادگیری را کنترل می‌کند. الگوریتم‌های بهینه سازی مختلفی در کراس وجود دارند که الگوریتم Adam یک الگوریتم مناسب است که خودش در حین فرآیند آموزش نرخ یادگیری را تنظیم می‌کند. برای آشنایی با بقیه بهینه سازهای کراس می‌توان به این آدرس مراجعه کرد. علاوه بر این دو ورودی می‌توانیم با استفاده از ورودی metrics مشخص کنیم که در حین فرآیند آموزش چه معیار ارزیابی نمایش داده شود.model.compile(loss = &#039;categorical_crossentropy&#039;,optimizer=&#039;adam&#039;, metrics=[&#039;accuracy&#039;])بعد از کامپایل کردن مدل نوبت به برازش کردن و آموزش دادن آن با متد ()fit می‌رسد که در حقیقت همان فرآیند feed-forward، backpropagation و گرادیان نزولی را بر روی داده‌های آموزش برای به روز رسانی وزن‌ها انجام می دهد. ورودی این متد متغیرهای پیشبینی کننده (پیکسل تصاویر) و متغیر هدف (برچسب متناظر با عدد تصاویر) هستند. چیز دیگری که می‌توانیم در این مرحله مشخص کنیم این است که  چند بار آموزش را بر روی داده‌ها می‌خواهیم اعمال کنیم یعنی چند بار می خواهیم کل داده ها را به الگوریتم بدهیم که این تعداد epoch نامیده می‌شود. تعداد epoch ها در متد ()fit با ورودی epoch مشخص می‌شود. همچنین می‌توانیم در فرآیند آموزش داده‌ها را shuffle کنیم که این کار معمولاً در شبکه‌های عصبی باعث بهبود مدل می‌شود. توجه کنید که اگر تعداد epoch ها خیلی کم باشد ممکن است مدل شبکه عصبی نتواند پیشبینی صحیحی ارائه دهد از سوی دیگر اگر تعداد epoch ها خیلی زیاد باشد زمان آموزش بیشتر می‌شود و ممکن است دچار مسئله بیش برازش شویم. راه حل این است که مدل را تا زمانی که به یک میزان صحت مطلوب رسیدیم ادامه دهیم و سپس آن را متوقف کنیم. در خصوص ورودی batch_size هم در پست های بعدی و زمانی که در خصوص الگوریتم های یادگیری عمیق بحث کردم بیشتر توضیح می دهم.model.fit(X_train,y_train_cat, batch_size = 512, epochs=100,verbose = 1)حالا اگر کد بالا را اجرا کنیم در حین اجر خروجی مرحله کامپایل و برازش بر روی صفحه چاپ می‌شود که روند پیشرفت فرآیند آموزش را به ما نمایش می‌دهد.خروجی چاپ شده در حین آموزش مدل همانطور که دیده می‌شود در هر epoch عملکرد مدل در دسته بندی بهتر می‌شود و زیان نیز کمتر می‌شود به طوری که در انتهای آموزش به صحت 95 درصد می‌رسیم. یعنی توانسته ایم عدد مربوط به رقم  95 درصد تصاویر را به درستی تشخیص دهیم.حالا بعد از کامپایل کردن و آموزش دادن مدل که به نتیجه نسبتاً خوبی بر روی داده‌های آموزش رسیدیم نوبت به تست کردن مدل بر روی داده‌های تست می‌رسد. برای تست کردن مدل از متد ()evaluate استفاده می‌کنیم و داده‌های تست را به عنوان ورودی به آن می‌دهیم model.evaluate(X_test,y_test_cat)15000/15000 [==============================] - 0s 31us/step [0.14266455941200257, 0.9506000000317891]اینجا هم می بنیم که بر روی داده‌های تست هم به عملکرد نسبتاً خوب 95 درصد رسیده‌ایم و این یعنی مدل ما دچار مشکل بیش برازش نشده است. می‌توانیم حالا که مدل را آموزش دادیم در آخرین گام با استفاده از آن برچسب تصاویر جدید را هم پیشبینی کنیم. برای این کار از متد ()predict_classes استفاده می‌کنیم که داده‌های ورودی را می‌گیرد و برچسب متناظر با آن تصاویر را باز می‌گرداند.preds = model.predict_classes(X_test)
predsarray([5, 8, 1, ..., 9, 1, 9], dtype=int64)خب به انتهای این بخش از آموزش رسیدیم و ممنونم که این پست رو خوندید. در پست های بعدی نحوه پیاده سازی شبکه های کانولشنال (مدل معروف LeNet) و بهبود مدل رو برای بازشناسی ارقام رو هم توضیح می دهم.https://www.aparat.com/4f41146f-8bc0-4d73-bc9e-ddc4b26a731c</description>
                <category>میم چ نخعی</category>
                <author>میم چ نخعی</author>
                <pubDate>Thu, 07 Jun 2018 00:07:35 +0430</pubDate>
            </item>
                    <item>
                <title>یادگیری عمیق با کراس - بخش اول (مقدمه)</title>
                <link>https://virgool.io/dataio/kerastutorialpart1-kigszm3gdek6</link>
                <description>به نام خدادر این پست و مجموعه پست های بعدی می خواهم شما را با کراس که یکی از محبوب ترین  پلتفرم های یادگیری عمیق است آشنا کنم و نحوه استفاده از کراس برای حل مسائل مختلفی مثل تشخیص ارقام دست نویس فارسی، پیشبینی بورس و ... را به شما یاد بدهم.کراس یک چهارچوب سطح بالا یادگیری عمیق پایتونی است که توسط آقای François Chollet در سال 2015 تأسیس شده. کراس چهارچوبی است که با آن و تنها با چند خط کد می‌توانیم برای ساختن شبکه‌های عصبی استفاده کنیم. البته کراس همه این کارها را خودش به تنهایی انجام نمی‌دهد، در حقیقت کراس یک فرانت‌اند (front-end) برای فریمورک های یادگیری عمیق تنسرفلو، CNTK و (مرحوم) تیانو است و آن‌ها پشت شبکه‌های عصبی را می‌سازند و آموزش می‌دهند و برای همین به آن یک چهارچوب سطح بالا می گوییم چون کراس پیچیدگی استفاده از این کتابخانه‌ها را تا حد خوبی حذف می‌کند. یک ویژگی خاص دیگر کراس این است که محدود به یک کتابخانه یادگیری عمیق نیست و همانطور که گفتیم می‌توانیم از تنسرفلو، CNTK و یا تیانو برای محاسبات پشت پرده آن استفاده کنیم.توجه: کراس برای اولین بار برای پایتون توسعه داده شده است ولی اگر کاربر R هستید اینترفیس کتابخانه کراس برای زبان R هم چند وقتی است که در دسترس قرار گرفته است. تعداد زیادی فریمورک توسط شرکت‌ها، دانشگاه‌ها و افراد مختلفی توسعه داده شده‌اند ولی اگر از هر متخصص یادگیری عمیق بپرسید که برای شروع چه فریمورک یادگیری عمیق را یاد بگیرم احتمالاً همه آن‌ها به شما جواب می‌دهند که با کراس شروع به کار کنید و بعداً اگر لازم شد (شاید هرگز) سمت فریمورک هایی مثل تنسرفلوبروید. یک دلیل این محبوبیت کراس را در ابتدای پست گفتم و آن این بود که کراس انعطاف پذیری زیادی در استفاده از فریمورک های سطح پائین یادگیری عمیق محبوبی مثل تنسرفلو و CNTK دارد که تجربه کاربری فوق العاده و ساده ای را به کاربر می‌دهد و کاربر لازم نیست که نگران برخی از جزئیات وقت گیر باشد. علاوه بر این، مزیت دیگر کراس این است که به طور وسیعی هم توسط افراد آکادمیک و هم شرکت‌ها استفاده می‌شود و جامعه توسعه دهنده‌های آن هم پویا و بزرگ است. به علاوه چون کراس با پلتفرم‌های مختلفی سازگار است گزینه‌های بیشتری هم در اختیار داریم. به طور مثال، هم می‌توانیم کراس را بر روی سخت افزارهای مختلف مثل CPU، GPU و TPU (سخت افزار مخصوص یادگیری عمیق گوگل) و حتی سیستم‌های عامل تلفن همراه اجرا کنیم.شاید بتوانیم یکی از مهم‌ترین ویژگی‌های کراس را هم این بدانیم که در طراحی مدل‌ها در کراس بهترین رویه‌های (best practices) یادگیری عمیق در نظر گرفته شده‌اند و به صورت پیشفرض تنظیمات مورد استفاده در بسیاری از به صورت پیشفرض مدل‌های کراس دارای بهترین تنطیمات مثل توابع فعال سازی و اندازه دسته که معمولاً در اغلب موارد نتایج خوبی به ما می‌دهند، هستند. به علاوه در کراس مجموعه ای از مدل‌های از قبل آموزش داده شده مثل مدل ResNet50 که بر روی دیتاست ImageNet آموزش داده شده است وجود دارند که کار ما را برای انتقال یادگیری به مراتب ساده تر می‌کنند.با این وجود همیشه استفاده از کراس شاید بهترین گزینه نباشد و باید بدانیم چه زمانی باید و چه زمانی نباید از آن استفاده کنیم. در مواردی مانند کاربردهای آموزشی و تحقیقاتی یا ساخت پروتوتایپ استفاده از کراس گزیته بهتری است ولی به طور مثال، وقتی با موارد زیر رو مواجه هستیم بهتر است به جای کراس از یک فریمورک سطح پائین تر مثل تنسرفلواستفاده کنیم.اگر بخواهیم روی جزئیات مدل خودمان خیلی دقیق کار کنیم یا بخواهیم مدل‌های جدید یادگیری ماشینی را امتحان کنیم.اگر بخواهیم یک سیستم با مقیاس پذیری بالا و برای پشتیبانی از تعداد زیادی کاربر ایجاد کنیم.اگر محدودیت‌هایی که در حافظه و قدرت پردازشی داریم از محدودیتی که صرف زمان کدنویسی می‌کنیم مهم تر باشند.نصب کراستا الان درباره مزیت ها و قابلیت های کراس گفتیم حالا نوبت به نصب کراس می رسد. نصب کراس در پایتون بسیار ساده است و کافی است که با دستور  pipآن را به صورت زیر نصب کنیم.pip install kerasبه علاوه می توانیم به صورت مستقیم از گیت هاب کراس آن را دانلود و نصب کنیم.git clone https://github.com/keras-team/keras.git
 cd keras
python setup.py install با تشکر :)محمد چناریان نخعی</description>
                <category>میم چ نخعی</category>
                <author>میم چ نخعی</author>
                <pubDate>Wed, 02 May 2018 20:20:53 +0430</pubDate>
            </item>
                    <item>
                <title>چطور به صورت خودکار یک دیتاست تصویری برای آموزش مدل های یادگیری عمیق بسازیم؟</title>
                <link>https://virgool.io/dataio/google-images-download-part1-msmv5iyn2m86</link>
                <description> اگر بخواهیم از یادگیری عمیق برای حل از صفر یک مسئله خاص مثل مسائل بینایی ماشین استفاده کنیم معمولاً نیاز به حجم زیادی از داده‌ها داریم (علاوه بر توان پردازشی و GPU خیلی خوب). با این وجود، تقریباً در حال حاضر کسی در حوزه بینایی ماشین یک معماری را از صفر بر روی داده‌هایی که دارد آموزش نمی‌دهد و اغلب از مدل‌های از پیش آموزش داده شده (pre-trained models) برای این کار استفاده می‌شود.در این حالت ما از دانشی که با استفاده از آموزش دادن یک مدل بر روی یک دیتاست بزرگ به دست آمده است برای حل مساله جدید خودمان استفاده می‌کنیم. به طور مثال، فرض کنید می‌خواهیم یک مدل بسازیم که بتواند تصاویر قرمه سبزی و قیمه سیب زمینی را به درستی دسته بندی کند. منتها در این جا تعداد تصاویر قیمه و قرمه ای که داریم زیاد نیست و احتمالاً به خوبی نمی‌توانیم یک مدل را از صفر بر روی داده‌ها آموزش دهیم. در این حالت می‌توانیم از (وزن‌ها) یک مدل از پیش آموزش داده شده مثل مدل ResNet بر روی دیتاست ImageNet که دارای تصاویر زیادی است تا کمی از مشکلات کم بودن داده‌های ما استفاده شود. دلیل این است که این مدل از پیش آموزش داده شده دارای یک سری اطلاعات کلی و عمومی در خصوص تصاویر مثل لبه‌های عمودی و افقی است که معمولاً لازم نیست مدل را برای یادگیری این اطلاعات دوباره آموزش دهیم.با تمام این گفته‌ها کماکان جمع کردن و آماده سازی داده‌های مناسب و برچسب گذاری شده برای مسئله دسته بندی قیمه و قرمه کار چالش برانگیز و زمان بری است. مثلاً در نظر بگیرید که چه قدر زمان باید صرف کنید تا 1000 تصویر مختلف از قیمه سیب زمینی را به صورت دستی از اینترنت دانلود و برچسب گذاری کنید. خوشبختانه راه حل ساده تری هم وجود دارد و آن استفاده از یک کتابخانه پایتون به اسم google-images-download برای دانلود تصاویر به صورت خودکار از سرویس تصویر گوگل است. با نوشتن یک کد ساده می‌توانیم تصاویری که دوست داریم را دانلود کنیم و به صورت خودکار در یک دایرکتوری که شکل رایجی برای ذخیره سازی داده‌های مورد نیاز برای آموزش الگوریتم‌های یادگیری عمیق است ذخیره کنیم. (لازم هست که بگم این کتابخانه توسط یکی از دانش آموزهای کورس یادگیری عمیق سایت fast.ai نوشته شده است)نصب این کتابخانه خیلی ساده است و هیچ پیش نیازی برای نصب آن وجود ندارد مگر این که بخواهیم در هر بار اجرا بیش از 100 تصویر دانلود کنیم که در این حالت باید سلنیوم را نصب کنیم که در پست‌های این مسئله را آموزش می‌دهم. برای نصب کتابخانه هم کافی است که با استفاده از دستور pip به صورت زیر این کتابخانه را نصب کنیم:pip install google_images_downloadحالا که کتابخانه را نصب کردیم می‌توانیم به دو صورت از این کتابخانه استفاده کنیم:طریقه اول: نوشتن یک برنامه در محیط پایتون:روش اول استفاده از این کتابخانه این است که یک محیط پایتون باز کنیم و این کتابخانه را به برنامه اضافه کنیم و با استفاده از آرگومان‌های ورودی بگوییم که می‌خواهیم چه تصاویری و با چه ویژگی‌هایی به دانلود شوند و سپس برنامه را اجرا کنیم. بگذارید با یک مثال این روش را توضیح دهم. فرض کنید که می‌خواهیم فقط 20 تصویر با کلمه‌های کلیدی «قیمه سیب زمینی» و «قرمه سبزی» را دانلود و در یک دایرکتوری خاص ذخیره کنیم. برای این کار اول کتابخانه را با دستور به برنامه اضافه می‌کنیم و پس از این که یک نمونه از کلاس دانلودکننده تصاویر به نام response ساختیم، آرگومان‌های ورودی برای دانلود تصاویر مدنظرمان را از طریق یک دیکشنری مشخص می‌کنیم. در نهایت هم با استفاده از متد download شی ساخته شده تصاویر را دانلود می‌کنیم.به طور مثال، در اینجا می‌خواهیم به وسیله آرگومان keywords به پایتون بگوییم که فقط 20 تصویر (با آرگومان limit) از تصاویر مربوط به کلمه کلیدی قیمه را دانلود کن و با آرگومان output_directory آن‌ها را در یک فولدر به آدرس d://pics ذخیره کن. سپس همین کار را برای کلمه کلیدی قرمه سبزی هم انجام می‌دهیم. from google_images_download import google_images_download   #importing the library

response = google_images_download.googleimagesdownload()   #class instantiation

arguments = {&quot;keywords&quot;:&quot;قیمه سیب زمینی&quot;, &quot;limit&quot;:20,
             &quot;print_urls&quot;:True, &quot;output_directory&quot;:&quot;d://pics&quot;}

response.download(arguments)  


arguments = {&quot;keywords&quot;:&quot;قرمه سبزی&quot;, &quot;limit&quot;:20,
             &quot;print_urls&quot;:True, &quot;output_directory&quot;:&quot;d://pics&quot;}   

response.download(arguments)حالا فرض کنید که می‌خواهیم تنها تصاویر مربوط پیتزا که در سایت سفارش غذای چنگال وجود دارد را در گوگل جستجو و دانلود کنیم. برای این کار از آرگومان ورودی specific_site استفاده می‌کنیم و آن را به همراه متناظرش یعنی changal.com دیگر به دیکشنری آرگومان‌ها اضافه می‌کنیم.arguments = {&quot;keywords&quot;:&quot;پیتزا&quot;, &quot;specific_site&quot; : &quot;http://changal.com/&quot;,
             &quot;limit&quot;:20, &quot;print_urls&quot;:True, &quot;output_directory&quot;:&quot;d://pics&quot;,}
response.download(arguments)حالا می‌توانیم به دایرکتوری که مشخص کردیم برویم و تصاویر دانلود شده را ببینیم.تصاویر دانلود شده پیتزا از سایت چنگالتعداد و تنوع آرگومان‌های ورودی که می‌توانیم برای شخصی سازی دانلود تصاویر از گوگل استفاده کنیم زیاد است و برای همین من همه آن‌ها را اینجا بررسی نمی‌کنم. توصیه می‌کنم برای اطلاع پیدا کردن از بقیه آرگومان‌هایی که می‌توانید استفاده کنید به آدرس سایت اصلی کتابخانه مراجعه کنید.طریقه دوم: استفاده از طریق خط فرمان (Command Line):بلافاصله بعد از نصب کتابخانه می‌توانیم در محیطی که با آن کار می‌کنیم یک ترمینال باز کنیم و از دستور googleimagesdownload به همراه آرگومان‌های ورودی مدنظرمان برای دانلود تصاویر مانند مثال زیر استفاده کنیم.مزیت این روش این است که لازم نیست که یک محیط پایتون باز کنیم و چندین خط کد بنویسیم و به صورت جدا برنامه را اجرا کنیم و همه این کارها را می توانیم با یک خط انجام دهیم.googleimagesdownload  --keywords Mourinho --limit 10در دستور بالا ما با آرگومان limit-- می گوییم که تنها 10 تصویر جستجو شده از مورینیو (Mourinho) را با آرگومان keywords-- را از گوگل دانلود کن. این تصاویر در فولدری به نام کلمه کلید جستجو شده درون یک فولدر ایجاد شده دیگر به نام downloads ذخیره می شوند. برای اطلاع از بقیه آرگومان‌های که این دستور می گیرد مثل راه حل اول می‌توانیم به سایت اصلی این کتابخانه مراجعه کنیم.در پست‌های بعدی توضیح می‌دهم که چطور می‌توانیم بیش از 100 تصویر را دانلود کنیم.با تشکر :)محمد چناریان نخعی</description>
                <category>میم چ نخعی</category>
                <author>میم چ نخعی</author>
                <pubDate>Sun, 22 Apr 2018 20:35:37 +0430</pubDate>
            </item>
            </channel>
</rss>