کتابخانه seaborn پایتون: مصورسازی داده با یک مثال واقعی

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


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

دراین مطلب چند تا از نمودارهایی ص که با استفاده از کتابخونه seaborn می‌تونیم رسم کنیم رو معرفی می‌کنم. برای این کار از دیتاست بیمه استفاده می‌کنیم.

طبق معمول اول با ایمپورت کردن کتابخونه‌هایی که لازم داریم شروع می‌کنیم:

import numpy as np 
import pandas as pd
import seaborn as sns 
import matplotlib.pyplot as plt

و با این کد، بک‌گروند نمودارهاتون گریدبندی می‌شن و دید بهتری از نظر عددی می‌دن:

sns.set(style='darkgrid')

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


داده‌های بیمه شامل ویژگی‌های درمورد مشتری‌های یک شرکت بیمه هستند و میزان استفاده‌ای که از خدمات بیمه داشتند:

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

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

https://virgool.io/p/ltemjlecdwws/sns.displot(insurance,x='bmi',kind='hist',aspect=1.2)

همونطور که مشاهده می‌کنید متغیر bmi توزیع نرمال داره، به جز چند داده‌ پرت که شاخص bmi بالای ۵۰ دارند.

تابع displot به ما اجازه می‌ده نمودار KDE رو هم روی هیستوگرام اضافه کنیم. تابع KDE (Kernel Density Estimation) یک روش غیرپارامتری هست که تابع توزیع احتمال برای یک متغیر رندم رو تخمین بزنه. با تغییر کد به این صورت می‌تونیم این نمودار رو هم به هیستوگرام قبلی اضافه کنیم:

این امکان وجود داره که فقط نمودار KDE رو رسم کنیم. برای این کار پارامتر kind رو برابر “kde” قرار می‌دیم و دیگه نیازی نیست به استفاده از پارامتر kde نیست.

sns.displot(insurance, x='bmi', kind='kde', aspect=1.2)

کار دیگه‌ای که می‌تونه دید خوبی از داده‌ها بهمون بده اینه که نمودارها رو بر اساس یک متغیر دیگه رسم کنیم. یک روش استفاده از پارامتر hue هست. نمودار زیر هیستوگرام bmi رو برای افراد سیگاری و غیرسیگاری به صورت جداگانه نشون می‌ده:

sns.displot(insurance, x='bmi', kind='hist', hue='smoker', aspect=1.2)

همچنین می‌تونیم نمودار میله‌ای رو براساس دو تا متغیر مختلف کنار همدیگه رسم کنیم:

sns.displot (insurance, x='bmi', kind='hist', hue='smoker', multiple='dodge', aspect=1.2)

حالا می‌تونیم یه پارامتر دیگه رو هم وارد کنیم و ببینیم زن یا مرد بودن چه تاثیری روی میزان هزینه می‌گذاره:

sns.displot(insurance, x='charges', kind='hist', hue='smoker', col='sex', height=6, aspect=1)

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

یکی دیگه از نمودارهایی که می‌تونیم داشته باشیم یک هیستوگرام دوبعدی هست که دیدی از دو متغیر به ما می‌ده. کافیه علاوه بر x، برای بعد y هم یه متغیر تعریف کنیم:

sns.displot(insurance, x='charges', y='bmi', kind='hist', height=6, aspect=1.2)

یکی دیگر از ویژگی‌هایی که می‌توانیم برای دیدن توزیع داده‌ها از آن استفاده کنیم، rug plot هست. این نمودار، تمام نقاط داده‌ای رو روی محورها نشون می‌ده:

sns.displot(insurance, x='charges', y='bmi', kind='hist', rug=True, height=6, aspect=1.2)

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

حالا متغیر سیگاری بودن یا نبودن را هم با رنگ‌های مختلف به نمودار اضافه می‌کنیم:

sns.displot(insurance, x='charges', y='bmi', kind='hist',rug=True, hue='smoker',height=6, aspect=1.2)

همچنین می‌تونیم یک نمودار kde با دو متغیر رسم کنیم. به عنوان مثال، نمودار زیر، همون نمودار bmi و هزینه رو با رنگ‌های مختلف برای افراد سیگاری و غیرسیگاری نشون می‌ده:‌

sns.displot(insurance, x='charges', y='bmi', kind='kde',rug=True, hue='smoker',height=6, aspect=1.2)

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

می‌تونیم از پارامتر fill استفاده کنیم تا بیشتر شبیه هیستوگرام بشه:


sns.displot(insurance, x='charges', y='bmi', kind='kde',rug=True, hue='smoker',fill=True, height=6, aspect=1.2)

یکی دیگه از نمودارهای متداول برای بررسی همبستگی بین دو متغیر عددی نمودار پراکندگی یا scatter plot هست. هرچند این نمودار درمورد توزیع هم می‌تونه یه دید کلی بهمون بده.

کتابخونه seaborn درمورد ترکیب کردن نمودارهای مختلف خیلی انعطاف‌پذیره. به عنوان مثال joinplot هیستوگرام و پراکندگی رو باهم ترکیب می‌کنه:

sns.jointplot(data=insurance, x='charges', y='bmi', hue='smoker', height=7, ratio=4)

حالا بیاید همه نمودارهای پراکندگی رو در یک نما ببینیم:

sns.pairplot(insurance, hue = 'smoker')

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

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

plt.figure(figsize=(8,6))
sns.scatterplot(data=insurance, x='age', y='charges', hue='sex',palette= ['red','green'] ,alpha=0.6)
plt.show()

اما برای دیدن همبستگی بین متغیرها می‌تونیم کار جالب‌تری هم انجام بدیم: ماتریس همبستگی رو روی یه hitmap‌ نمایش بدیم:

sns.heatmap(insurance.corr(), annot = True)

توی این نمودار می‌تونیم ببینیم که میزان هزینه‌ها بیشترین ارتباط رو با شاخص bmi و سن افراد داره. بین باقی متغیرها هم ارتباط چندانی دیده نمی‌شه.

اشکالی که این نمودار داره اینه که فقط متغیرهای عددی رو بررسی کرده. برای اینکه بتونیم همبستگی داده‌های غیرعددی مثل شاخص مهم سیگاری بودن یا نبودن و جنسیت رو هم ببینیم، لازمه که تغییراتی توی داده‌ها اعمال کنیم. به این صورت که متغیرهای سیگاری بودن و جنسیت رو به وسیله ۰ و ۱ کدگذاری می‌کنیم:

smoker01 = pd.get_dummies(insurance['smoker'], drop_first = True)
gender = pd.get_dummies(insurance['sex'], drop_first = True)
insurance.drop(['sex'], axis = 1, inplace = True)
insurance = pd.concat([insurance, smoker01], axis = 1)
insurance.drop(['smoker'], axis = 1, inplace = True)
insurance = pd.concat([insurance, gender], axis = 1)

حالا دادهامون به این شکل دراومدن:

حالا برای اینکه اسم و جای ستون‌ها رو مرتب کنیم، از کدهای زیر استفاده می‌کنیم:

insurance = insurance[['age', 'male', 'bmi', 'region','yes', 'charges']]
insurance = insurance.rename(columns = {'male': 'sex', 'yes': 'smoker'})

و یک بار دیگه نمودار hitmap رو برای همبستگی بین متغیرها رسم می‌کنیم:

همونطور که می‌بینید ارتباط مستقیمی بین هزینه‌های بیمه و سیگاری بودن افراد وجود داره و بین شاخص bmi و سن افراد هم ارتباط خطی هست که منطقی به نظر می‌رسه.

بریم ببینیم بین منطقه جغرافیایی افراد با هزینه‌های بیمه ارتباطی وجود داره یا نه:

https://virgool.io/p/ltemjlecdwws/sns.barplot(y=insurance['charges'],x=insurance['region'])

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