آموزش

آموزش تحلیل اکتشافی داده با پایتون

اینجا با مبانی تحلیل اکتشافی داده‌ها (EDA) در پایتون آشنا می‌شیم و یاد می‌گیریم چطور با استفاده از Pandas، Matplotlib و NumPy کارهایی مثل نمونه‌گیری، مهندسی ویژگی، بررسی همبستگی و سایر مراحل اولیه تحلیل داده رو انجام بدیم.

تاریخ انتشار:
7 شهریور 1405
پایتون
15 دقیقه
علم داده
تحلیل داده
کاربرهای فینکا در چه شرکت‌هایی مشغول به کار هستند؟

همون‌طور که می‌دونی، از کتابخونه pandas در پایتون برای دستکاری داده‌ها استفاده می‌شه. خیلی از کسانی که تازه کار رو شروع کردن، فکر می‌کنن این پکیج فقط برای پیش‌پردازش داده‌هاست، اما اصلاً این‌طور نیست! pandas برای بررسی و کاوش داده‌ها و ذخیره کردنشون بعد از پیش‌پردازش هم فوق‌العاده‌ست.

ضمناً، اگر آموزش‌های پایتون فینکا رو دنبال کرده باشی یا قبلاً با اصول scipy، numpy، matplotlib و pandas آشنا شده باشی، بد نیست یه مروری روی اطلاعاتت داشته باشی.

آموزش امروز دقیقاً روش‌هایی رو برای بررسی و کاوش کارآمد داده‌ها با استفاده از همین پکیج‌ها بهت یاد می‌ده تا بتونی مدل‌سازی داده‌هات رو شروع کنی:

وارد کردن داده‌ها

برای شروع بررسی داده‌ها، اول از همه باید اون‌ها رو بارگذاری کنی. احتمالاً این رو خودت می‌دونی، اما به لطف کتابخونه pandas این کار خیلی راحت شده. طبق معمول، پکیج رو با اسم pd وارد می‌کنی و از تابع read_csv() استفاده می‌کنی. کافیه آدرس (URL) داده‌ها و آرگومان header رو بهش بدی. این آرگومان آخری برای اینه که مطمئن بشی داده‌هات درست خونده می‌شن و ردیف اول داده‌های تو به عنوان اسم ستون‌های دیتافریم در نظر گرفته نمی‌شه.

البته آرگومان‌های دیگه‌ای هم هستن که می‌تونی برای اطمینان از درست خونده شدن داده‌ها مشخصشون کنی: مثلاً می‌تونی با آرگومان‌های sep یا delimiter جداکننده رو مشخص کنی، با names اسم ستون‌ها رو تعیین کنی و با index_col بگی کدوم ستون به عنوان برچسب ردیف‌ها برای دیتافریم نهایی در نظر گرفته بشه.

این‌ها فقط چندتا از آرگومان‌هایی هستن که می‌تونی به تابع read_csv() بدی. برای آشنایی بیشتر با این تابع و آرگومان‌هاش می‌تونی به مستنداتش سر بزنی.

دقت کن که اینجا از تابع read_csv() استفاده کردیم، چون فرمت داده‌ها با کاما از هم جدا شده (CSV) بود. اگر فایل‌هایی داری که جداکننده‌های متفاوتی دارن، می‌تونی از توابع دیگه‌ای مثل read_table()، read_excel()، read_fwf() و read_clipboard() استفاده کنی تا فایل‌های محدودشده عمومی، فایل‌های اکسل، داده‌های با عرض ثابت (Fixed-width) و داده‌هایی که در کلیپ‌بورد کپی شدن رو بخونی.

علاوه بر این‌ها، read_sql() هم گزینه خوبیه که باهاش می‌تونی نتیجه یک کوئری SQL یا یه جدول از دیتابیس رو مستقیم وارد دیتافریم کنی.

تحلیل اکتشافی داده چیه؟

تحلیل اکتشافی داده (EDA) از یه طرف برای جواب دادن به سوالات، تست کردن فرضیه‌های کسب‌وکار و ایجاد فرضیه‌های جدید برای تحلیل‌های بعدی استفاده می‌شه. از طرف دیگه، می‌تونی ازش برای آماده‌سازی داده‌ها جهت مدل‌سازی هم استفاده کنی. نقطه اشتراکِ هر دوی این‌ها اینه که باید شناخت خیلی خوبی از داده‌ها داشته باشی تا بتونی به جواب‌های مورد نظرت برسی یا درک درستی برای تفسیر نتایج مدل‌سازی در آینده پیدا کنی.

برای رسیدن به این اهداف راه‌های زیادی وجود داره: می‌تونی یک توصیف پایه از داده‌ها به دست بیاری، اون‌ها رو مصورسازی کنی، الگوهاشون رو پیدا کنی و چالش‌هایی که ممکنه تو استفاده از این داده‌ها باهاشون روبه‌رو بشی رو مشخص کنی.

یکی از مفاهیمی که موقع مطالعه درباره EDA زیاد به چشمت می‌خوره، پروفایل‌سازی داده‌ها (Data Profiling) هست. پروفایل‌سازی یعنی خلاصه کردن دیتاست‌ها به کمک آمارهای توصیفی. تو باید از معیارهای مختلفی استفاده کنی تا دیتاست‌هات رو بهتر بشناسی. هدف اصلی از این کار، رسیدن به یک درک دقیق از داده‌هاست تا بتونی بعدش با خیال راحت روی اون‌ها کوئری بزنی و به شکل‌های مختلف مصورسازیشون کنی. البته این به این معنی نیست که دیگه نیازی به تکرار مراحل نداری: دقیقاً به همین دلیل که پروفایل‌سازی برای خلاصه کردن داده‌هاست، خیلی وقت‌ها برای ارزیابی کیفیت داده‌ها هم استفاده می‌شه. بسته به نتیجه پروفایل‌سازی، ممکنه تصمیم بگیری یه سری از داده‌ها رو اصلاح یا حذف کنی، یا به روش دیگه‌ای پردازششون کنی.

 

تفاوت EDA و داده‌کاوی

با اینکه EDA و داده‌کاوی خیلی به هم نزدیکن و خیلی از تکنیک‌های EDA در داده‌کاوی هم کاربرد دارن، اما این دو تفاوت‌هایی با هم دارن. اهدافشون واقعاً شبیه به همه: EDA خیالت رو راحت می‌کنه که داده‌ها رو طوری بررسی کنی که ویژگی‌های جالب و روابط بینشون کاملاً مشخص بشه. در EDA، معمولاً متغیرهای مختلف رو با تکنیک‌های گوناگون بررسی و مقایسه می‌کنی تا الگوهای سیستماتیک رو پیدا کنی. اما از اون طرف، داده‌کاوی بیشتر روی استخراج الگوها از دل داده‌ها تمرکز داره. این الگوها بهت دید خوبی درباره روابط بین متغیرها می‌دن که می‌تونی ازشون برای تصمیم‌گیری‌های بهتر در کسب‌وکار استفاده کنی. در هر دو مورد، از قبل انتظار خاصی از روابط بین متغیرها نداری یا اگر هم داری، کامل و قطعی نیست.

به طور کلی می‌شه گفت داده‌کاوی بیشتر مبتنی بر کاربرده، در حالی که EDA بیشتر روی ماهیت اصلی پدیده‌های زیربنایی تمرکز می‌کنه. به زبون ساده‌تر، داده‌کاوی خیلی درگیر پیدا کردن دلایل و روابط خاص بین متغیرها نمی‌شه. به همین خاطر، از رویکرد «جعبه سیاه» برای کاوش داده‌ها استقبال می‌کنه و فقط به تکنیک‌های EDA محدود نمی‌مونه؛ بلکه از روش‌هایی مثل شبکه‌های عصبی هم کمک می‌گیره تا پیش‌بینی‌های معتبری بسازه، حتی اگه نتونه ماهیت دقیقِ روابطی که این پیش‌بینی‌ها بر اساسشون انجام شدن رو توضیح بده.

 

توصیف اولیه داده‌ها

همون‌طور که بالاتر خوندی، هدف اصلی EDA اینه که با داده‌ها آشنا بشی. یکی از اولین قدم‌ها برای این کار، گرفتنِ یک توصیف پایه از داده‌هاست. توصیف پایه یه عبارت خیلی کلیه: می‌تونی بهش به چشم یه روش سریع برای گرفتن اطلاعات اولیه، فهمیدن نکات ساده از داده‌ها یا رسیدن به یک شهود اولیه نسبت به اون‌ها نگاه کنی.

در این بخش نمی‌خوایم خیلی بین این تفسیرها فرق بذاریم؛ فقط قراره با روش‌هایی آشنا بشی که بهت کمک می‌کنن خیلی سریع یه سری اطلاعات مفید و قابل فهم درباره دیتافریمت به دست بیاری.

توصیف کردن داده‌ها

مثلاً می‌تونی از تابع describe() استفاده کنی تا آمارهای خلاصه مختلفی رو به دست بیاری (البته یادت باشه که این تابع مقادیر NaN رو نادیده می‌گیره). به این مثال توجه کن؛ در این مثال داریم دیتاست معروف گل زنبق یا Iris رو توصیف می‌کنیم. این داده‌ها از قبل در ادیتور برات بارگذاری شدن:

می‌بینی که این تابع اطلاعاتی مثل تعداد، میانگین، انحراف معیار، حداقل، حداکثر و چندک‌های داده‌ها رو برمی‌گردونه. البته پکیج‌های زیادی در پایتون هستن که این آمارها رو بهت می‌دن (از جمله خود pandas). استفاده از این تابع فقط یکی از راه‌های به دست آوردن این اطلاعاته.

ضمناً حواست باشه که اگه تا الان عمیقاً روی آمارهای توصیفی وقت نذاشتی، حتماً الان این کار رو بکن. کلاً می‌تونی از همین آمارهای توصیفی برای شروع ارزیابی کیفیت داده‌هات استفاده کنی. بعدش می‌تونی تصمیم بگیری که آیا نیازی هست داده‌ها رو اصلاح یا حذف کنی و کلاً برنامه‌ت براشون چیه. به این مرحله عموماً «پروفایل‌سازی داده‌ها» می‌گن. این بخش از EDA برای اینه که عناصر و ناهنجاری‌های داده‌هات رو بهتر درک کنی و ببینی داده‌ها چقدر با مستندات همخونی دارن و نیازهای کسب‌وکار رو برآورده می‌کنن یا نه.

توجه: در طول فرآیند تحلیل اکتشافی، بارها پیش میاد که دوباره به همین مرحله پروفایل‌سازی برگردی؛ چون کیفیت داده‌ها ممکنه تحت تأثیر کارهایی قرار بگیره که در مراحل بعدی انجام می‌دی.

ردیف‌های اول و آخر دیتافریم

حالا که یه دید کلی نسبت به دیتاست پیدا کردی، بهتره نگاه دقیق‌تری هم به خود داده‌ها بندازی. به کمک توابع head() و tail() در کتابخونه pandas می‌تونی به راحتی سطرهای اول و آخر دیتافریمت رو ببینی.

در ویرایشگر زیر، پنج سطر اول و آخرِ داده‌های مربوط به ارقام دست‌نویس رو با استفاده از همین دو تا تابع بررسی کن (داده‌ها از قبل برات بارگذاری شدن):

احتمالاً متوجه این موضوع می‌شی که اگه با این نوع داده‌ها آشنا نباشی، خروجی توابع head() و tail() خیلی برات با معنی به نظر نمی‌رسه!

شاید فقط چند تا سطر و ستون پر از اعداد ببینی. پیشنهاد می‌کنم اگه تا الان این کار رو نکردی، یه نگاهی به توضیحات دیتاست بندازی. این توضیحات بهت می‌گن که داده‌ها چطور جمع‌آوری شدن و تعداد ویژگی‌ها و سطرها چقدره. خوندن این اطلاعات کمکت می‌کنه بررسی کنی که اصلاً داده‌ها درست بارگذاری شدن یا نه.

علاوه بر این، به همون نتیجه‌گیری اولیه‌مون برگرد: این که ردیف‌ها پر از مقادیر عددی هستن. در نگاه اول ممکنه فکر کنی هیچ مشکلی نیست، چون اعداد صحیح، طبیعی به نظر می‌رسن و هشدار خاصی هم بهت نمی‌دن.

اما فرض کن همین کار رو روی یه دیتاست دیگه انجام می‌دادی که مثلاً حاوی اطلاعات زمانی و تاریخ بود؛ در این شرایط یه نگاه سریع به خروجی این کدها ممکنه این سوالات رو برات پیش بیاره: «آیا داده‌های من به عنوان دیتافریم خونده شدن؟»، «چطور می‌تونم این موضوع رو بررسی کنم؟» و «چطور می‌تونم نوع داده رو تغییر بدم؟»

این‌ها سوالات عمیق‌تری هستن که معمولاً در همون مرحله پروفایل‌سازی داده‌ها بهشون پرداخته می‌شه و در بخش بعدی درباره‌شون بیشتر می‌خونی.

نمونه‌گیری از داده‌ها

اگه با یه دیتاست بزرگ سروکار داری، شاید دلت بخواد یه نمونه تصادفی از داده‌ها بگیری تا بتونی خیلی سریع با فضای داده‌ها آشنا بشی. برای یه روش ساده و دم‌دستی، می‌تونی از تابع sample() در pandas استفاده کنی. دقیقاً مثل کد زیر:

روش دیگه‌ای که شاید یه کم پیچیده‌تر باشه، اینه که یک ایندکس تصادفی بسازی و بعد ردیف‌های تصادفی رو از روی اون ایندکس از دیتافریم بگیری. در کد زیر می‌بینی که از پکیج random استفاده شده. این پکیج یه ماژول به اسم sample داره که ترکیبش با توابع range() و len() بهت اجازه می‌ده از داده‌هات نمونه بگیری. یادت باشه که برای انتخاب ردیف‌های مد نظرت از دیتافریم، باید از ویژگی iloc استفاده کنی.

اگه دقیقاً نمی‌دونی چرا اینجا از iloc استفاده می‌کنیم، می‌تونی به آموزش‌های تخصصی‌ترِ فینکا سر بزنی! این آموزش‌ها موضوعات کلی رو با جزئیات بیشتری پوشش می‌دن. (برای دسترسی می‌تونی روی لینک‌هایی که بالاتر گذاشتیم کلیک کنی).

خب، حالا بیا یه کم مهارت‌های پایتونی‌مون رو تمرین کنیم! تمرین زیر رو شروع کن:

نگاه دقیق‌تر به داده‌ها: کوئری‌ها

حالا که یه نگاه سریع به داده‌ها انداختی و دستت اومده جریان از چه قراره، وقتشه که یه کم عمیق‌تر بشی! باید با کوئری‌زدن روی داده‌ها، اون‌ها رو بیشتر بررسی کنی.

این کار با تابع query() خیلی راحت انجام می‌شه. این تابع بهت اجازه می‌ده فرضیه‌های خیلی ساده‌ای که درباره داده‌هات داری رو تست کنی. مثلاً این که: «آیا طول گلبرگ عموماً از طول کاسبرگ بیشتره؟» یا «آیا طول گلبرگ گاهی با طول کاسبرگ برابر می‌شه؟»

همون‌طور که می‌بینی، این فرضیه درست نیست و در جواب، یک دیتافریم خالی تحویل می‌گیری.

نکته: حواست باشه که این کوئری رو می‌تونی به شکل iris[iris.Petal_length > iris.Sepal_length] هم بنویسی.

چالش‌هایی مربوط به داده‌ها

حالا که یه سری اطلاعات اولیه درباره داده‌هات به دست آوردی، خوبه که بریم سراغ چالش‌هایی که ممکنه این داده‌ها برات ایجاد کنن و دقیق‌تر بررسیشون کنیم. اگه قبلاً با مرحله پروفایل‌سازی داده‌ها آشنا شده باشی، حتماً اسم «مقادیر گمشده» به گوشِت خورده و احتمالاً می‌تونی حدس بزنی چه مقادیری ممکنه «داده‌های پرت» باشن و الی آخر.

در این بخش یه سری راه‌حل‌های پایه معرفی می‌شه تا هم این مسائل رو بهتر درک کنی و هم یاد بگیری که اگه بی‌نظمی و مشکلی در داده‌هات پیدا کردی، چطور باهاش برخورد کنی. بازم یادآوری می‌کنم که در مرحله پروفایل‌سازی خیلی عمیق‌تر به شناسایی این مشکلات پرداخته می‌شه و کاملاً هم طبیعیه که بعد از حل یه سری از چالش‌ها، دوباره به همون مرحله برگردی.

مقادیر گمشده

یکی دیگه از چیزهایی که موقع کاوش داده‌ها باید چک کنی، اینه که آیا دیتاستت مقادیر گمشده‌ای داره یا نه.

بررسی این موضوع به شدت مهمه؛ چون وقتی بخشی از داده‌ها در دسترس نباشه، دیتاست ممکنه ارزش و گویایی خودش رو از دست بده و همین مسئله باعث بشه تحلیل‌هات ضعیف یا دارای سوگیری (Bias) بشن. در عمل اگه بخوایم بگیم، یعنی وقتی یک‌سری مقادیر رو برای ویژگی‌های خاصی از دست می‌دی، احتمال اینکه مدل تو در پیش‌بینی یا دسته‌بندی اون داده‌ها اشتباه کنه، خیلی بالاتر می‌ره.

البته گمشده بودن داده‌ها می‌تونه دلایل مختلفی داشته باشه؛ ممکنه موقع استخراج یا وارد کردن اطلاعات خطایی پیش اومده باشه، یا اصلاً مشکل مربوط به خود فرآیند جمع‌آوری داده‌ها باشه. مثلاً سیستمی که داده‌ها رو در اختیارت می‌ذاره درست کار نکرده باشه یا کسانی که فرم نظرسنجی رو پر کردن، بعضی از فیلدها رو خالی گذاشته باشن. خیلی مهمه که بگردی و ببینی آیا الگوی خاصی در این داده‌های گمشده وجود داره یا نه. اینجاست که مرحله پروفایل‌سازی به کارت میاد! یادت نره که می‌تونی از پروفایل‌سازی برای درکِ بهتر کیفیت داده‌هات استفاده کنی.

خلاصه که دلیل از دست رفتن داده‌ها متفاوته و تا حد زیادی به متن (Context) داده‌ها و همچنین خودت بستگی داره. دقیقاً به همین خاطره که در یکی از مراحل قبلی (همون موقع وارد کردن داده‌ها)، اون‌ها رو بررسی کردی!

برای پیدا کردن سطرهایی که مقادیر گمشده دارن، می‌تونی از تابع isnull() استفاده کنی. در خروجی، به جای هر سلول کلمه True یا False رو می‌بینی: True یعنی مقدار اون سلول گمشده است و False یعنی اون سلول یه مقدار قطعی و عادی داره.

در این مثال می‌بینی که داده‌ها روی‌هم‌رفته کاملن؛ یعنی هیچ مقدار گمشده‌ای نداریم.

جالب اینجاست که می‌تونستی همین نکته رو در توضیحات دیتاستت هم بخونی؛ چون همونجا نوشته شده بود که تا حالا هیچ مقدار گمشده‌ای برای این داده‌ها ثبت نشده.

با این وجود، قرار نیست هر دیتاستی که باهاش سروکله می‌زنی همین‌قدر تر و تمیز باشه! به همین خاطر باید بدونی که وقتی باید برای یک‌سری مقادیرِ گمشده تصمیم بگیری، چه راه‌هایی پیش روت داری:

  • می‌تونی کلاً داده‌های گمشده رو پاک کنی: یعنی یا کل یک رکورد رو دور می‌ندازی، یا فقط رکوردهایی رو نگه می‌داری که دقیقاً ویژگی‌های مد نظرت رو دارن. البته باید در این روش خیلی محتاط باشی، چون پاک کردن داده‌ها ممکنه باعث بشه تحلیلت دچار سوگیری بشه. واسه همین باید از خودت بپرسی: «آیا احتمال گم شدن داده در بقیه رکوردها هم به همین اندازه‌ست؟» اگه این احتمال برای همه رکوردها تقریباً یکی باشه، اون‌وقت حذف کردنشون کار منطقیه.
  • علاوه بر حذف، می‌تونی از روش‌های جایگذاری (Imputation) هم برای پر کردن اون سلول‌ها استفاده کنی. اگه در کار با آمار تجربه داشته باشی، می‌دونی که جایگذاری یعنی مقادیر گمشده رو با یه سری مقادیرِ جایگزین پر کنیم. مثلاً می‌تونی از میانگین، مُد یا میانه استفاده کنی. اینجا باید تصمیم بگیری که آیا می‌خوای میانگینِ کل رو به جای مقادیر گمشده یک متغیر بذاری، یا می‌خوای بر اساس یک متغیر دیگه اون‌ها رو پر کنی. مثلاً درباره متغیرهای دسته‌بندی‌شده مثل «مرد» یا «زن»، شاید بهتر باشه این موضوع رو لحاظ کنی، چون معمولاً مشاهدات درباره زن‌ها و مردها متفاوته. در این حالت، می‌تونی میانگینِ مشاهدات رو فقط برای خانم‌ها حساب کنی و بعد، مقادیر گمشده مربوط به بقیه رکوردهایِ «زنان» رو با همون میانگین پر کنی.
  • تخمین مقدار با کمک رگرسیون، تحلیل واریانس (ANOVA)، رگرسیون لجستیک یا بقیه تکنیک‌های مدل‌سازی. شک نکن که این روش پیچیده‌ترین راه برای پر کردن مقادیر گمشده‌ست.
  • می‌تونی سلول‌ها رو با مقادیری پر کنی که رکوردهاشون بیشترین شباهت رو به رکوردی که مقدار گمشده داره، داشته باشن. در این مواقع می‌تونی از الگوریتم KNN استفاده کنی.

حواست باشه که هر کدوم از این روش‌ها، مزایا و معایب خاص خودشون رو دارن! پس قبل از گرفتن تصمیم نهایی، حتماً فاکتورهایی مثل زمان، هزینه، ماهیت داده‌ها و غیره رو در نظر بگیر.

وقتی تصمیم گرفتی که می‌خوای با داده‌های گمشده چه‌کار کنی، ادامه مطلب رو بخون تا ببینی چطور می‌تونی این تغییراتِ دلخواه رو روی داده‌هات اعمال کنی.

پر کردن مقادیر گمشده

اگه تصمیم گرفتی که مقادیر رو با روش‌های جایگذاری پر کنی، باز هم دستت بازه که انتخاب کنی چطور می‌خوای این کار رو انجام بدی!

می‌تونی از ترکیبِ تابع fillna() در pandas و توابع کتابخونه numpy استفاده کنی. به قطعه کد زیر دقت کن؛ فرض کن یه دیتافریم از نتایج یه نظرسنجی داری که در اون درباره حقوق افراد (Salary) سوال شده. اگه فرض رو بر این بگیریم که مخاطب‌های تو همه از یه طبقه اجتماعی هستن و احتمال پاسخ دادن به این سوال برای همه‌شون برابره، می‌تونی میانگینِ حقوقِ کسانی که به این سوال جواب دادن رو حساب کنی و همون رو جایگزینِ حقوق کسانی کنی که پاسخی ندادن.

البته مجبور نیستی که حتماً یک مقدار ثابت رو به صورت دستی به fillna() پاس بدی. با اضافه کردن آرگومان method به این تابع می‌تونی مقادیر غیرخالی رو به سمت جلو یا عقب بسط بدی. کافیه مقدار ffill یا bfill رو به این آرگومان بدی تا مشخص بشه می‌خوای مقادیر به سمت جلو (Forward) پر بشن یا به سمت عقب (Backward).

حذف برچسب‌های دارای مقادیر گمشده

برای پاک کردنِ ردیف‌ها یا ستون‌هایی که مقادیر گمشده دارن، می‌تونی از تابع dropna() در pandas استفاده کنی:

درون‌یابی

علاوه بر این‌ها، می‌تونی از روش درون‌یابی (Interpolation) هم برای پر کردن مقادیرِ گمشده استفاده کنی: تابع interpolate() یه درون‌یابی خطی بین نقاطِ داده‌ای انجام می‌ده تا مقداری که بیشترین احتمال رو داره حدس بزنه و اونجا قرار بده.

می‌تونی آرگومان method رو هم بهش اضافه کنی تا بتونی از روش‌های پیشرفته‌تری مثل درون‌یابی چندجمله‌ای یا مکعبی استفاده کنی؛ فقط یادت باشه که برای این روش‌ها، نصب بودن کتابخونه scipy الزامیه.

البته درون‌یابی محدودیت‌های خاص خودش رو هم داره؛ مخصوصاً زمانی که مقادیر NaN فاصله خیلی زیادی از آخرین مشاهدهٔ معتبرت داشته باشن. در همچین شرایطی باید آرگومان limit رو هم به کد اضافه کنی. با پاس دادن یه عدد صحیحِ مثبت به این آرگومان، تعیین می‌کنی که دقیقاً چند تا خونه بعد از آخرین مقدارِ غیر NaN پر بشن. مسیر پیش‌فرضِ این محدودیت به سمتِ جلوئه، اما با اضافه کردن limit_direction می‌تونی جهت رو هم عوض کنی.

داده‌های پرت

درست مثل مقادیر گمشده، در دیتاستت ممکنه مقادیری پیدا بشن که تفاوت خیلی فاحشی با بقیه داده‌ها دارن. به این نقاط «داده‌های پرت» (Outliers) می‌گن. برای شناسایی‌شون، می‌تونی با یه نمودار جعبه‌ای (Boxplot)، توزیع هر متغیر رو چک کنی، و یا با رسم کردن یک نمودار پراکندگی (Scatter plot)، نقاطی که خارج از محدوده «مورد انتظار» هستن رو پیدا کنی.

این داده‌های پرت می‌تونن دلایل مختلفی داشته باشن؛ از خطاهای سیستمی گرفته تا اشتباهاتِ انسانی موقع وارد کردن یا پردازش داده‌ها. اما نکته مهم اینه که حواست باشه این پرتی‌ها می‌تونن چه اثراتِ مخربی روی تحلیلت بذارن: اون‌ها می‌تونن نتایجِ آزمون‌های آماری (مثل انحراف معیار، میانگین یا میانه) رو تغییر بدن، باعث کاهش نرمال‌بودن توزیعِ داده‌ها بشن و در نهایت روی خروجیِ مدل‌های آماری مثل رگرسیون یا تحلیل واریانس تأثیر منفی بذارن.

برای دست‌و‌پنجه نرم کردن با داده‌های پرت، می‌تونی حذفشون کنی، تغییرشون بدی یا با مقادیر دیگه‌ای جایگزینشون کنی. تصمیم‌گیری در این مورد، کاملاً به ماهیت و زمینه داده‌هات بستگی داره. دقیقاً به همین دلیله که درک داده‌ها و فهمیدنِ دلیل حضور داده‌های پرت، اهمیت خیلی زیادی داره:

اگه دلیل پرت بودن یه داده خطای پردازش یا ورود داده باشه، شاید بهترین کار این باشه که کلاً پاکش کنی.

می‌تونی با تخصیص وزن به مشاهدات، داده‌های پرت رو تغییر بدی یا از لگاریتم طبیعی استفاده کنی تا شدت تغییری که این داده‌ها در دیتاست ایجاد می‌کنن، کم بشه.

دقیقاً مثل داستان مقادیر گمشده، می‌تونی اینجا هم از روش‌های جایگذاری کمک بگیری و این مقادیر شدید رو با میانه، میانگین یا مد جایگزین کنی.

در نهایت هم می‌تونی از توابعی که در بخش‌های قبلی توضیح دادیم برای مهار داده‌های پرت استفاده کنی.

ویژگی‌های داده‌

دقت کن که این مرحله‌ایه که باید اون رو به صورت تکراری و همزمان با بقیه کارهای علوم داده انجام بدی: یعنی مدل‌هات رو می‌سازی، اعتبارسنجی می‌کنی، بعد ممکنه حس کنی باید ویژگی‌ها رو دستکاری و متناسب‌سازی کنی و دوباره مدل رو از نو بسازی... و این چرخه همین‌طور ادامه داره.

مهندسی ویژگی

می‌تونی از مهندسی ویژگی (Feature Engineering) به عنوان یه ترفند برای بالا بردن قدرتِ پیش‌بینی الگوریتم‌های یادگیری ماشین استفاده کنی. روندش به این صورته که سعی می‌کنی ویژگی‌های جدید و مفیدی رو از دلِ همون متغیرهای خامِ دیتاستت استخراج کنی تا فرآیند یادگیری مدل بهتر بشه. این کار با ترکیب کردن یا تغییر دادنِ ویژگی‌های اولیه‌ای که در دسترس هستن، انجام می‌شه.

مهندسی ویژگی چیزیه که مهارت پیدا کردن در اون زمان می‌بره؛ چون همیشه واضح نیست که چطور می‌تونی با کمک داده‌های خام، قدرت پیش‌بینی مدلت رو تقویت کنی. اما لیستی که در ادامه می‌بینی، شاید بتونه برای ایده‌گرفتن موقع انجام مهندسی ویژگی بهت کمک کنه:

فاکتورسازی یه ویژگی: می‌تونی با استفاده از تابع factorize()، متغیرهای دسته‌بندی‌شده رو به متغیرهای عددی تبدیل کنی. دقیقاً مثل این مثال:

دسته‌بندی متغیرهای پیوسته در گروه‌های مختلف: برای تقسیم مقادیر یک ستون به بازه‌ها مختلف، می‌تونی از تابع cut() استفاده کنی.

مقیاس‌بندی (Scaling) ویژگی‌ها: داده‌هات رو حولِ محورِ عددِ صفر متمرکز کن. برای این کار می‌تونی از ماژول پیش‌پردازشِ کتابخونه Scikit-Learn کمک بگیری:

نکته: اگه با دقت بیشتری ماژول پیش‌پردازش در Scikit-Learn رو بگردی، می‌بینی که توابع خیلی جالبی اونجا هست که برای ساختِ ویژگی‌های جدید حسابی به دردت می‌خورن!

یادت باشه که این‌ها فقط چندتا از روش‌های مختلفِ مهندسی ویژگی برای بهتر کردن قدرت پیش‌بینی مدل هستن. نکته اصلی اینجاست که باید حسابی ایده‌پردازی کنی، ویژگی‌های قبلی رو روی هم بریزی و ترکیب کنی، و بعد سعی کنی اثربخشی اون‌ها رو با استفاده از Scikit-Learn محک بزنی.

انتخاب ویژگی

وقتی حرف از انتخاب ویژگی در میون میاد، یعنی قراره از بین کل ویژگی‌های اولیه، یه زیرمجموعه حیاتی رو سوا کنی تا در زمان آموزش دادن، ابعادِ مسئله کمتر بشه. ممکنه فکر کنی این کار به شدت شبیه سایر تکنیک‌های کاهش ابعاد، مثل PCA هست (احتمالاً قبلاً باهاش آشنا شدی). اما این دو یه فرق اساسی دارن: الگوریتم PCA ویژگی‌های شبیه به هم (هم‌بسته) رو با هم قاطی می‌کنه و ویژگی‌های کاملاً جدیدی می‌سازه که برتریِ خاصی نسبت به ویژگی‌های خام دیتاست دارن. اما «انتخاب ویژگی»، چیزی رو با هم ترکیب نمی‌کنه؛ بلکه کیفیت و قدرت‌ پیش‌بینی تک‌تک ویژگی‌ها رو ارزیابی می‌کنه و در نهایت بهترین مجموعه رو برمی‌گردونه.

برای پیدا کردن ویژگی‌های مهم، می‌تونی روی الگوریتمِ جنگل تصادفی (Random Forest) حساب کنی: این الگوریتم هزاران درختِ تصمیم رو به صورت کاملاً تصادفی به وجود میاره و به نوبت، هر بار یکی از متغیرها رو از مدل‌سازی حذف می‌کنه. با این متد، الگوریتم می‌تونه حساب کنه وقتی که یک متغیر مشخص رو کنار می‌ذاریم، عملکرد مدل چقدر بهتر یا بدتر می‌شه. برای پیاده‌سازی این الگوریتم می‌تونی خیلی راحت از کتابخونه Scikit-Learn استفاده کنی:

 

همون‌طور که می‌بینی، بهترین و تأثیرگذارترین مجموعه از متغیرها، مجموعه‌ایه که شاملِ طول و عرض گلبرگ باشه.

نکته: حواست باشه که با استفاده از matplotlib می‌تونی نتایجِ انتخاب ویژگی رو به صورت بصری هم رسم کنی و نشون بدی:

الگوهای موجود در داده‌هات

یکی از قدم‌های بعدی که می‌تونی در فرایند کاوشِ داده‌ها برداری، شناساییِ الگوهاست. این الگوها شامل مواردی مثل همبستگی بینِ ویژگی‌ها، یا حتی همبستگی بین داده‌های گمشده می‌شه. مصورسازی داده‌ها یکی از بهترین ابزارها برای پیدا کردن این الگوهاست؛ خیالت راحت باشه، نمودارهای تو لزوماً نباید ثابت (استاتیک) باشن: می‌تونی با کمکِ گرفتن از کتابخونه‌های پایتونی مثل Bokeh یا Plotly مصورسازی‌های فوق‌العاده جذابی به صورت تعاملی (Interactive) بسازی.

شناسایی همبستگی با Matplotlib

حالا که اعداد رو زیرورو کردی و داده‌ها رو به شکل کمی ارزیابی کردی، بد نیست که به صورت بصری هم بهشون یه نگاهی بندازی. وقتشه که داده‌ها رو تبدیل به تصویر کنیم!

برای اینکه این کار رو سریع و راحت انجام بدی، می‌تونی از کتابخونه مصورسازیِ matplotlib در پایتون استفاده کنی. فقط نکته بامزش اینجاست که تنها مانعی که الان سرِ راهت قرار داره، خود داده‌هاست! همون‌طور که احتمالاً فهمیدی، داده‌های تو 64 تا ستون یا ویژگی دارن. در علم داده به دیتاست‌هایی که این‌قدر ویژگی دارن، «داده‌های با ابعاد بالا» (High-dimensional) می‌گن.

در دوره‌های آموزشِ یادگیری ماشین دقیقاً یاد می‌گیری که داده‌های ابعادی چه ویژگی‌هایی دارن و چی هستن؛ اما فعلاً همین‌قدر بدون که برای رسمِ یک نمودار دو‌بعدی (2D) یا سه‌بعدی (3D)، داده‌های تو هم باید نهایتاً دو یا سه بُعد داشته باشن. این یعنی باید یه جوری از شرِّ ابعادِ اضافه خلاص بشی!

پس، اول از همه باید سراغِ تکنیک‌های کاهش ابعاد مثل «تحلیل مؤلفه‌های اصلی» (PCA) بری:

وقتی به خروجیِ داده‌های کاهش‌یافته نگاه می‌کنی، متوجه می‌شی که الان ستون‌ها یا ویژگی‌ها فقط به دو تا کاهش پیدا کردن. تعداد ردیف‌ها یا همون مشاهدات، دقیقاً همون مقدار قبلیه (یعنی 3823 ردیف). حالا که داده‌هات دقیقاً در فرمتِ درست و ایده‌آل قرار دارن، وقتشه که بریم سراغ رسم نمودار!

خودِ انتخاب نمودار مناسب مرحله مهمیه. حالا تو چه نموداری رو انتخاب می‌کنی؟

از اونجایی که ما اینجا در فاز کاوش داده‌ها هستیم، احتمالاً هدفت اینه که همبستگی‌های احتمالی رو بین ویژگی‌ها پیدا کنی. پس یه نمودارِ پراکندگی (Scatter plot) می‌تونه یه انتخاب محشر باشه: این نمودار بهت اجازه می‌ده رابطه بین همون دو ویژگی که با کمک تکنیک کاهش ابعاد به دست آوردی رو به راحتی به تصویر بکشی.

شناسایی همبستگی با Bokeh

برای کشف همبستگی بین ویژگی‌ها، یه راه دوم هم وجود داره؛ می‌تونی از کتابخونه Bokeh استفاده کنی و یه نمودار تعاملی (Interactive) بسازی. Bokeh کتابخونه مصورسازیِ تعاملی در پایتونه که خروجی‌هاش در مرورگرهای وبِ مدرن خیلی زیبا رندر می‌شن. اگه با داده‌های حجیم یا جریانی (Streaming) کار می‌کنی، این کتابخونه یه انتخاب ایده‌آله؛ اما همون‌طور که در کد زیر می‌بینی، می‌تونی برای داده‌های «معمولی» هم روی اون حساب کنی.

کدش واقعاً ساده‌ست: فقط ماژول‌های مورد نیاز رو وارد می‌کنی، نمودار پراکندگیت رو می‌کشی، و خروجی رو طوری تنظیم می‌کنی که وقتی تابع show() صدا زده می‌شه، نمودارت در یه فایلِ جدا ذخیره بشه. دست آخرِ تابع show() رو صدا می‌زنی تا بتونی همون نمودار پراکندگی که ساختی رو نگاه کنی!

حواست باشه که این عکسی که الان داری می‌بینی، فقط یه تصویرِ ثابت و ذخیره‌شده از اون نموداره؛ اما نمودار اصلی که در محیطِ نوت‌بوک یا ترمینال رندر می‌شه، کاملاً تعاملیه! البته این فقط یه مثالِ خیلی ساده از این بود که چطور می‌تونی با کمک Bokeh نمودارهای تعاملی بسازی. برای اینکه ایده‌‌های بیشتری بگیری، پیشنهاد می‌کنم حتماً یه سر به گالری کتابخونه Bokeh بزنی یا برای یادگیری عمیق‌تر، در دوره مصورسازی تعاملی داده‌ها با Bokeh فینکا شرکت کنی.

شناسایی همبستگی با Pandas

نمودارهایی که در بخش‌های قبلی دیدی، یه شیوه عالی و بصری برای کاوش همبستگی بین ویژگی‌های مختلف داده‌هات هستن. اما این اصلاً به این معنی نیست که نمی‌تونی این ارتباطات رو به شیوهِ کمی (Quantitative) هم اندازه‌گیری کنی! اگه ترجیح می‌دی با اعداد کار کنی، می‌تونی خیلی راحت از تابع corr() در کتابخونه pandas استفاده کنی. فقط یادت نره که مقادیر گمشده یا NaN به کل در این محاسبات نادیده گرفته می‌شن!

دقت کن که برای محاسبه ضرایب در اون دو تا معیارِ آخری (کندال و اسپیرمن)، اول باید داده‌ها رو رتبه‌بندی کنی. این کار با کمک تابع rank() خیلی راحت انجام می‌شه: در واقع در تمرین بالا، داده‌های iris با اجرای قطعه کد iris.rank()، از قبل برات رتبه‌بندی شدن.

علاوه بر این، برای استفاده از این ضریب‌های همبستگی، پای یه سری فرضیات هم در میونه: مثلاً «همبستگی پیرسون» فرض رو بر این می‌گیره که متغیرهای تو کلاً توزیع نرمال دارن، رابطه مستقیمی بینشون هست و داده‌ها حولِ خطِ رگرسیون، توزیعِ یکدستی دارن. از اون طرف، «همبستگی اسپیرمن» فرضش اینه که تو دو تا متغیرِ ترتیبی (Ordinal) داری یا کلاً دو متغیر داری که یه‌جورایی با هم در ارتباطن، ولی لزوماً این رابطه خطی نیست.

«همبستگی کندال تاو» ضریبیه که میزان هماهنگی بین دو ستون از داده‌های رتبه‌بندی‌شده رو نشون می‌ده. در حالی که از همبستگی اسپیرمن می‌تونی برای اندازه‌گیریِ میزان ارتباط بین دو متغیر استفاده کنی. این دو تا خیلی شبیه هم به نظر می‌رسن، مگه نه؟

با وجودِ اینکه کندال و اسپیرمن خیلی شبیه همن، اما تفاوت‌هایی هم با هم دارن که مهم‌ترینشون در نحوه محاسباتشونه. ضریب کندال تاو از این طریق به دست میاد: تفاضلِ بین تعداد جفت‌های هماهنگ و ناهماهنگ که تقسیم بر کل تعداد جفت‌ها می‌شه. در مقابل، ضریب اسپیرمن برابر با مجموعِ مجذور انحرافات تقسیم بر (n-1)*n هست.

در اکثر مواقع ضریب اسپیرمن عددِ بزرگ‌تری نسبت به کندال تاو بهت می‌ده، اما این یه قانون همیشگی نیست: وقتی که انحرافات و تفاوت‌ها بین مشاهدات خیلی زیاد باشه، ضریب اسپیرمنی که به دست میاد کوچیک‌تر می‌شه. در واقع، همبستگیِ اسپیرمن به این موضوع خیلی حساسه و دقیقاً همین جاست که این ویژگی می‌تونه خیلی به دردت بخوره!

پس سوال اینه که بالاخره، کِی باید از کدوم ضریب استفاده کنیم؟ از اونجا که این دو تا همبستگی واقعاً چیزهای متفاوتی رو می‌سنجن، باید با دقت انتخاب کنی. کندال تاو نسبت جفت‌های هماهنگ به ناهماهنگ رو نشون می‌ده، کاری که اسپیرمن انجام نمی‌ده. بعضی‌ها معتقدن کندال تاو تفسیر خیلی بهتری داره، محاسبه‌اش راحت‌تره، تخمین دقیق‌تری از پارامترِ جامعه می‌ده و موقع کار با نمونه‌های سایز کوچیک، p-value در اون خیلی دقیق‌تره.

نکته: از تابع print() استفاده کن تا بتونی نتیجه محاسباتِ همبستگی رو به صورت جفت‌جفت و مشخص بین ستون‌ها ببینی.

پیش به سوی آینده!

تبریک می‌گم! با موفقیت به انتهای آموزش pandas ما رسیدی! الان دیگه یه سری مهارت اولیه و مهم داری که باهاشون می‌تونی داده‌هات رو در پایتون کاوش کنی.

اگه دلت می‌خواد عمیق‌تر وارد این موضوع بشی، سری دوره‌های pandas فینکا فوق‌العاده‌ست: حتماً به دوره‌هایی مثل کار با داده‌ها با pandas، تغییر شکل داده‌ها با pandas و یا ترکیب داده‌ها با pandas یه نگاهی بنداز.

اما، اگه احساس می‌کنی وقتشه که یه کم از pandas فراتر بری و پکیج matplotlib رو بیشتر بررسی کنی، شدیداً پیشنهاد می‌کنم به آموزش مصورسازی داده‌ها در پایتون در فینکا سر بزنی و یا مدل‌سازی روی داده‌هات رو شروع کنی! برای اینکه ببینی چطور می‌شه یه مدل یادگیری ماشین رو برای تشخیص اتوماتیک اعداد دست‌نویس توسعه داد، یه سر به آموزش یادگیری ماشین ما بزن!

اشتراک‌گذاری
فهرست مطالب
  • وارد کردن داده‌ها
  • تحلیل اکتشافی داده چیه؟
  • توصیف اولیه داده‌ها
  • نگاه دقیق‌تر به داده‌ها: کوئری‌ها
  • چالش‌هایی مربوط به داده‌ها
  • ویژگی‌های داده‌
  • الگوهای موجود در داده‌هات
  • پیش به سوی آینده!

دریافت اپلیکیشن فینکا

با اپلیکیشن فینکا، به بیشتر دوره‌ها و مسیرها روی موبایل دسترسی دارید، تمرین می‌کنید و یادگیری رو هم‌زمان روی موبایل و دسکتاپ ادامه می‌دید.