نمودار پراکندگی شاید سادهترین نمودار دنیا باشد. هر نمونه یک نقطه است و مختصاتش مقدار دو متغیر. اما همین نمودار ساده گاهی مهمترین سؤال پروژه را مطرح میکند. مثلاً چرا قیمت عسل در یک سال خاص ناگهان بالا رفت، در حالی که تولید تغییری نکرده بود؟
در دو قسمت قبل تعداد، نسبت و توزیع را نشان دادیم. حالا سراغ رابطهی بین متغیرها میرویم. در این قسمت با دادهی تولید عسل در ایالتهای آمریکا کار میکنیم. نمودار پراکندگی، نمودار خطی و شبکهی فاست را یاد میگیریم و در پایان همین ابزارها را برای بررسی پیشبینیهای یک مدل به کار میبریم.
داده عسل و سؤالهایی که میپرسیم
این مجموعهداده حدود ۶۰۰ ردیف دارد و تولید عسل در ایالتهای مختلف آمریکا را از ۱۹۹۸ تا ۲۰۱۲ نشان میدهد. هر ردیف یک ایالت در یک سال است. ستونهایی مثل تعداد کلنی زنبور، بازده هر کلنی، تولید کل، ذخیره، قیمت هر پوند و ارزش تولید دارد.
سؤالهای جالبی از این داده میشود پرسید. آیا قیمت در طول سالها بالا رفته است؟ آیا تولید کم شده است؟ آیا ایالتهایی که کلنی بیشتری دارند، بازده بیشتری هم دارند؟ هر سؤال نمودار مناسب خودش را دارد.
seaborn و تابع relplot
seaborn کتابخانهای روی Matplotlib است که نمودارهای آماری را با کد کمتر و ظاهر بهتر میسازد. تابع relplot برای نمودارهای رابطه طراحی شده است. با پارامتر kind بین پراکندگی و خطی جابهجا میشوید.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
honey = pd.read_csv("honey.csv")
print(honey[["state", "year", "numcol", "yieldpercol", "totalprod", "priceperlb"]].head())نمودار پراکندگی؛ قیمت عسل در هر ایالت
با یک نمودار پراکندگی ساده شروع میکنیم. محور افقی قیمت هر پوند و محور عمودی ایالت است. هر نقطه قیمت یک ایالت در یک سال را نشان میدهد. پس برای هر ایالت یک ردیف نقطه داریم.
افزودن بعد سوم با رنگ
این نمودار پراکندگی بازهی قیمت هر ایالت را نشان میدهد، اما زمان در آن دیده نمیشود. با پارامتر hue میتوانیم سال را به رنگ نقطهها تبدیل کنیم. یک طیف رنگی عسلی، از زرد روشن تا قهوهای، هم به موضوع میخورد و هم ترتیب زمانی را حسپذیر میکند:
sns.relplot(data=honey, x="priceperlb", y="state", hue="year",
palette="YlOrBr", height=12, aspect=0.5)
plt.show()حالا الگوی روشنی دیده میشود. در تقریباً همهی ایالتها، نقطههای قهوهای که سالهای اخیرند، سمت راستاند. یعنی قیمت عسل در طول سالها بهطور پیوسته بالا رفته است.
اندازه به جای رنگ؛ دسترسپذیری
حدود هشت درصد مردان نوعی کوررنگی دارند. برای آنها تفاوت بعضی رنگها دیده نمیشود. راه دیگر نشان دادن بعد سوم، اندازهی نقطه است. با size="year" نقطههای سالهای اخیر بزرگتر میشوند.
اندازه برای مقایسهی دقیق به خوبی رنگ نیست، اما به رنگ وابسته نیست. در گزارشهای مهم، ترکیب هر دو مطمئنترین انتخاب است. در هر صورت، پالت رنگی را طوری انتخاب کنید که در حالت سیاهوسفید هم ترتیبش قابل خواندن باشد.
بیشتر بخوانید: برای دیدن شکل توزیع هر متغیر پیش از بررسی رابطهها، هیستوگرام چیست؟ را بخوانید.
نمودار خطی؛ روند در طول زمان
وقتی محور افقی زمان است، نمودار خطی بهترین انتخاب است. خط بین نقطهها ترتیب و پیوستگی زمان را نشان میدهد. حالا سؤال اول را دقیقتر میپرسیم: آیا قیمت در طول سالها افزایش واضحی داشته است؟
تجمیع و بازهی اطمینان
با kind="line" و محور افقی سال، seaborn برای هر سال همهی ایالتها را تجمیع میکند. خط میانگین را نشان میدهد و ناحیهی سایهدار دور آن بازهی اطمینان ۹۵ درصد است:
sns.relplot(data=honey, x="year", y="priceperlb", kind="line")
sns.relplot(data=honey, x="year", y="totalprod", kind="line")
plt.show()پاسخ روشن است. قیمت بهطور پیوسته بالا رفته، با یک جهش مشخص حدود سال ۲۰۰۳. ناحیهی سایهدار هم یادآوری میکند که هر نقطهی خط میانگین چند ایالت است، نه یک عدد قطعی.
سؤال تازه از دل نمودار
حالا سؤال دوم؛ آیا در ۲۰۰۳ عرضهی عسل کم شد که قیمت بالا رفت؟ نمودار تولید کل نشان میدهد تولید در طول سالها کاهش یافته است. اما در همان سال ۲۰۰۳، تولید حتی کمی افزایش داشته است. پس کمبود عرضه در آن سال توضیح جهش قیمت نیست.
این همان لحظهای است که نمودار سؤال درست را مطرح میکند. چه چیز دیگری در حدود ۲۰۰۳ تغییر کرد؟ شاید تعداد کلنیها یا بازده هر کلنی. برای بررسی، به ابزاری نیاز داریم که الگو را سال به سال کنار هم نشان دهد.
شبکه فاست و نمودار دومحوره
شبکهی فاست یک نمودار را برای هر مقدار یک متغیر دستهای جداگانه رسم میکند و همه را در یک شبکه میچیند. در مثال ما، برای هر سال یک نمودار از بازده هر کلنی در برابر تعداد کلنی. نمودار زیر مسیر بررسی رابطهها را که تا اینجا دیدیم خلاصه میکند.

شبکه فاست؛ مقایسهی سال به سال
با پارامترهای col و col_wrap، همان relplot به شبکهی فاست تبدیل میشود:
sns.relplot(data=honey, x="yieldpercol", y="numcol",
col="year", col_wrap=3, kind="line")
plt.show()در این شبکه، شکل رابطهی بازده و تعداد کلنی در سالهای مختلف تقریباً یکسان است. یعنی الگوی ایالتها سال به سال تغییر چشمگیری نکرده است. ایالتهایی که کلنی بیشتری دارند، تقریباً همیشه همانها هستند.
نمودار دومحوره؛ با احتیاط
برای مقایسهی مستقیم تعداد کلنی و بازده در طول زمان، میشود دو خط را با دو محور عمودی مختلف روی یک نمودار کشید. نتیجه نشان میدهد تعداد کلنی نسبتاً ثابت مانده، اما بازده هر کلنی کاهش یافته است. شاید پدیدهی فروپاشی کلنی زنبورها بخشی از ماجرا باشد.
اما نمودار دومحوره خطرناک است. با تغییر مقیاس هر محور، میشود هر دو خط را طوری نشان داد که همزمان بالا و پایین بروند. نتیجه رابطهای ساختگی است. اگر از آن استفاده میکنید، مقیاسها را صریح برچسب بزنید. راه امنتر دو نمودار جدا با محور افقی مشترک است.
کاربرد در هوش مصنوعی؛ پیشبینی در برابر مقدار واقعی
نمودار پراکندگی یکی از بهترین ابزارهای بررسی مدل رگرسیون است. محور افقی مقدار واقعی و محور عمودی پیشبینی مدل است. اگر مدل کامل بود، همهی نقطهها روی خط قطری قرار میگرفتند.
خواندن نمودار پیشبینی
فاصلهی هر نقطه از خط قطری خطای آن پیشبینی است. الگوی این فاصلهها از یک عدد خطای کلی آموزندهتر است. مثلاً اگر نقطهها برای مقادیر بزرگ همیشه زیر خطاند، مدل مقادیر بزرگ را کم تخمین میزند.
این الگوی سیستماتیک در عدد میانگین خطا دیده نمیشود. اما در نمودار پراکندگی فوراً به چشم میآید. با رنگ کردن نقطهها بر اساس یک گروه، مثلاً ایالت، میشود دید مدل برای کدام گروه بدتر است.
نمودار باقیمانده
نسخهی دقیقتر، نمودار باقیمانده است. محور افقی پیشبینی و محور عمودی خطا یعنی واقعی منهای پیشبینی. در مدل خوب، نقطهها بینظم حول صفر پخشاند. هر الگویی، مثل قیف یا منحنی، یعنی مدل چیزی را یاد نگرفته است.
from sklearn.linear_model import LinearRegression
X, y = honey[["year", "numcol"]], honey["priceperlb"]
pred = LinearRegression().fit(X, y).predict(X)
sns.scatterplot(x=pred, y=y - pred, alpha=0.5)
plt.axhline(0, color="gray")
plt.show()تمرین عملی؛ یک سؤال، سه نمودار
از دادهی پروژهی خودتان یک سؤال دربارهی رابطهی دو متغیر بپرسید و این کارها را انجام دهید:
- نمودار پراکندگی: دو متغیر را رسم کنید و یک متغیر سوم را با رنگ و اندازه اضافه کنید.
- نمودار خطی: اگر داده زمان دارد، روند را با بازهی اطمینان رسم کنید.
- شبکهی فاست: رابطه را برای هر گروه جداگانه نشان دهید.
- سؤال تازه: یک سؤال بنویسید که پیش از رسم نمودارها به ذهنتان نرسیده بود.
آخرین مورد مهمترین است. اگر نمودارها سؤال تازهای نساختند، احتمالاً فقط چیزی را نشان دادند که از قبل میدانستید.
سخن پایانی
نمودار پراکندگی رابطهی دو متغیر را نشان میدهد و با رنگ و اندازه میشود بعد سوم را هم به آن اضافه کرد. نمودار خطی برای روند زمانی است و seaborn بازهی اطمینان را هم کنارش میکشد. شبکهی فاست الگو را بین گروهها مقایسه میکند و نمودار دومحوره فقط با احتیاط کاربرد دارد.
دادهی عسل نشان داد نمودار خوب فقط جواب نمیدهد، سؤال هم میسازد. جهش قیمت در ۲۰۰۳ با کمبود تولید توضیح داده نمیشد و ما را به سمت بازده کلنیها برد. همین نگاه را در بررسی مدلها هم به کار ببرید؛ الگوی خطا گویاتر از عدد خطاست.
این آموزش بر پایهی درس Visualizing Relationships از مجموعهی آزاد Data Science for Beginners مایکروسافت (مجوز MIT) به فارسی بازنویسی و تکمیل شده است.
پرسشهای پرتکرار
نمودار پراکندگی چیست؟
نمودار پراکندگی یا Scatter Plot هر نمونه را به شکل یک نقطه روی صفحه نشان میدهد که مختصاتش مقدار دو متغیر است. از روی الگوی نقطهها میشود فهمید دو متغیر با هم رابطه دارند یا نه، این رابطه مثبت است یا منفی، و دادهی پرت کجاست.
کی نمودار خطی و کی نمودار پراکندگی؟
نمودار خطی برای وقتی است که محور افقی ترتیب معنادار دارد، مثل زمان، و میخواهید روند را ببینید. نمودار پراکندگی برای رابطهی دو متغیر عددی بدون ترتیب طبیعی است؛ مثل قیمت و تولید.
شبکه فاست یا Facet Grid چیست؟
شبکهی فاست یک نمودار را برای هر مقدار از یک متغیر دستهای، مثلاً هر سال، جداگانه رسم میکند و همه را در یک شبکه کنار هم میگذارد. این کار مقایسهی الگو بین گروهها را بدون شلوغ کردن یک نمودار ممکن میکند.
چرا نمودار دومحوره خطرناک است؟
چون با تغییر مقیاس هر محور میشود هر دو خط را طوری نشان داد که همزمان بالا و پایین بروند و رابطهای ساختگی القا کنند. اگر از آن استفاده میکنید، مقیاسها را صریح برچسب بزنید یا دو نمودار جدا با محور افقی مشترک بکشید.







دیدگاهها
هنوز دیدگاهی ثبت نشده است. شروعکننده باشید — پرسش و اصلاح را با آغوش باز میپذیریم.