در این فصل چه یاد میگیری#
ابزارها را داری: خلاصه، گروهبندی، نمودار. این فصل آنها را در یک فرآیند میچیند. تحلیلِ اکتشافی یعنی قبل از هر مدل و هر نتیجهگیری، چند سؤالِ ثابت از داده بپرسی. در این فصل آن سؤالها را یاد میگیری، مقدارهای پرت را پیدا میکنی و میفهمی چرا حذفشان معمولاً اشتباه است، و مهمتر از همه: میبینی یک همبستگیِ ۰٫۶۳۵ چطور میتواند تصویرِ کاملاً غلطی بدهد — و با یک فیلترِ ساده به ۰٫۸۹۵ برسد.

آخر این فصل میتوانی:
- پنج سؤالِ ثابتِ تحلیلِ اکتشافی را روی هر دیتاستِ تازهای بپرسی
- مقدارهای پرت را با قاعدهٔ
IQRپیدا کنی و آگاهانه دربارهٔ آنها تصمیم بگیری - همبستگی را بخوانی و بگویی دقیقاً چه چیزی را نمیگوید
- یک متغیرِ پنهان را پیدا کنی که رابطهٔ دو ستونِ دیگر را تحریف میکند
قبل از شروع#
از فصل ۶: groupby و agg.
از فصل ۷: هیستوگرام، نمودارِ پراکندگی و corr().
از فصل ۳: describe() و چارکها.
📓 نوتبوک: نوتبوک این فصل را در Colab باز کن — همهٔ کدهای این فصل آماده و بهترتیب داخلش هست.
۱. پنج سؤالِ ثابت#
تحلیلِ اکتشافی الهام نمیخواهد؛ یک فهرست است. هر بار که دیتاستِ تازهای میگیری، همین پنج سؤال را بپرس:
- چقدر است و چه شکلی است؟ —
shape،dtypes،head - چقدرش گم است؟ —
isna().sum() - هر ستون چه توزیعی دارد؟ —
describe،value_counts، هیستوگرام - چه چیزی عجیب است؟ — مقدارِ غیرممکن، مقدارِ پرت، دستهٔ تکعضوی
- ستونها با هم چه رابطهای دارند؟ —
corr،groupby، پراکندگی
سؤالِ اول تا سوم را در فصلهای ۳ تا ۷ انجام دادی. این فصل چهار و پنج است — سختترینشان، چون جوابشان عدد نیست، قضاوت است.
۲. مقدارِ پرت: قاعدهٔ IQR#
import pandas as pd
df = pd.read_csv("laptops_clean.csv")
q1 = df["price"].quantile(0.25)
q3 = df["price"].quantile(0.75)
iqr = q3 - q1
low = q1 - 1.5 * iqr
high = q3 + 1.5 * iqr
print("چارک اول:", round(q1))
print("چارک سوم:", round(q3))
print("مرز پایین:", round(low))
print("مرز بالا:", round(high))
چارک اول: 19000000
چارک سوم: 31700000
مرز پایین: -50000
مرز بالا: 50750000
متدِ quantile(0.25) همان عددی را میدهد که در خروجیِ describe() فصلِ ۳ زیرِ برچسبِ 25% دیدی: عددی که یکچهارمِ داده زیرِ آن است. اینجا جداگانه میگیریمش، چون میخواهیم رویش حساب کنیم نه فقط نگاهش کنیم.
IQR فاصلهٔ چارکِ اول تا سوم است — بازهای که نیمهٔ میانیِ داده در آن است. قاعدهٔ متعارف میگوید هر چیزی که بیش از یکونیم برابرِ IQR بیرونِ این بازه باشد، «پرت» است.
توجه کن مرزِ پایین منفی درآمد، یعنی از این طرف هیچ پرتی نداریم — که منطقی است، قیمت منفی نمیشود.
outliers = df[(df["price"] < low) | (df["price"] > high)]
print("تعداد پرت:", len(outliers))
print(outliers["brand"].value_counts())
تعداد پرت: 9
brand
اپل 9
Name: count, dtype: int64
و اینجا مهمترین درسِ فصل است. هر نُه مقدارِ پرت مالِ یک برند است.
اگر کورکورانه قاعده را اجرا میکردی — «مقدارِ پرت را حذف کن» — نُه لپتاپِ گرانقیمت را دور میریختی، در حالی که هیچکدامشان خطا نیستند. آنها یک زیرگروهِ واقعیاند.
📏 اندازه بگیر: قاعدهٔ کار با مقدارِ پرت، در یک جمله: اول بپرس این چیست، بعد تصمیم بگیر. سه حالتِ کاملاً متفاوت وجود دارد و کدشان یکی است ولی جوابشان نه — (۱) خطای ثبت مثلِ سالِ ۲۲۰۵؛ حذف یا تصحیح. (۲) زیرگروهِ واقعی مثلِ همین اپل؛ هرگز حذف نکن، بهجایش یک ستونِ دستهبندی بساز. (۳) رویدادِ نادرِ واقعی؛ نگهدار و در گزارش صریح بگو.
value_countsروی ردیفهای پرت، ارزانترین راهِ فهمیدنِ اینکه با کدام حالت طرفی.
۳. همبستگی، و آنچه نمیگوید#
print(df[["year", "ram_gb", "price"]].corr().round(3))
year ram_gb price
year 1.000 0.041 0.635
ram_gb 0.041 1.000 0.290
price 0.635 0.290 1.000
همبستگی میگوید دو متغیر چقدر همجهت حرکت میکنند: نزدیک به ۱+ یعنی با هم بالا میروند، نزدیک به ۱- یعنی یکی بالا و دیگری پایین، نزدیک به صفر یعنی رابطهٔ خطیای دیده نمیشود.
سه چیزی که این جدول نمیگوید و همه فرض میکنند میگوید:
- علیت. ۰٫۶۳۵ بینِ سال و قیمت نمیگوید سالِ ساخت باعثِ قیمت است. میتواند برعکس باشد، یا هر دو از عاملِ سومی بیایند.
- رابطهٔ غیرخطی. همبستگیِ نزدیکِ صفر فقط یعنی رابطهٔ خطی ضعیف است. دو متغیر میتوانند رابطهٔ کاملاً محکمِ منحنی داشته باشند و همبستگیشان صفر باشد. همیشه نمودار را هم ببین.
- اهمیت. ۰٫۲۹ بینِ حافظه و قیمت «کم» است، ولی روی ۲۳۸ ردیف میتواند کاملاً واقعی باشد. کوچکیِ عدد یعنی رابطه ضعیف است، نه اینکه وجود ندارد.
🌱 ریشهاش کجاست: جملهٔ «همبستگی علیت نیست» را همه شنیدهاند و کمتر کسی میداند دقیقاً چرا. ریشه، ترم ۶ فصل ۸ — نمونهگیری، و چطور با آمار دروغ میگویند با مثالهای واقعی نشان میدهد چطور دو چیزِ کاملاً بیربط میتوانند همبستگیِ بالا داشته باشند.
۴. متغیرِ پنهان: وقتی یک زیرگروه رابطه را پنهان میکند#
بیایید فرضیهای را بسنجیم. شاید آن همبستگیِ ۰٫۶۳۵ بهخاطرِ اپل باشد — اگر سهمِ اپل در سالهای اخیر بیشتر شده باشد، بخشی از «گرانشدن» فقط تغییرِ ترکیبِ برندهاست.
df["is_apple"] = df["brand"] == "اپل"
print(df.groupby("year")["is_apple"].mean().round(3))
year
2016 0.133
2017 0.091
2018 0.160
2019 0.130
2020 0.057
2021 0.194
2022 0.050
2023 0.107
2024 0.125
Name: is_apple, dtype: float64
فرضیه رد شد: سهمِ اپل بالا و پایین میرود ولی روندِ صعودی ندارد. پس گرانشدن از تغییرِ ترکیبِ برندها نمیآید.
ولی حالا یک کارِ دیگر بکنیم — اپل را کاملاً کنار بگذاریم و همان همبستگی را دوباره حساب کنیم:
no_apple = df[df["brand"] != "اپل"]
print("همبستگی با اپل:", df[["year", "price"]].corr().round(3).iloc[0, 1])
print("همبستگی بدون اپل:", no_apple[["year", "price"]].corr().round(3).iloc[0, 1])
print(no_apple.groupby("year")["price"].mean().round(0))
همبستگی با اپل: 0.635
همبستگی بدون اپل: 0.895
year
2016 14338462.0
2017 15820000.0
2018 18380952.0
2019 20455000.0
2020 23909091.0
2021 26308000.0
2022 28952632.0
2023 32752000.0
2024 33742857.0
Name: price, dtype: float64
همبستگی از ۰٫۶۳۵ به ۰٫۸۹۵ رفت. و روندِ سالانه حالا کاملاً یکنواخت است — بدونِ آن افتِ ۲۰۲۲ که در فصلِ ۷ دیدیم.
چه اتفاقی افتاد؟ اپل قیمتهایی دارد که در همهٔ سالها بالاست، پس در هر سال یک پراکندگیِ بزرگ اضافه میکند که رابطهٔ زیرین را میپوشاند. اپل خطا نبود، پرتِ حذفکردنی هم نبود — یک جمعیتِ متفاوت بود که با بقیه قاطی شده بود.
قبل از ادامه، جواب بده: پس کدام عدد درست است، ۰٫۶۳۵ یا ۰٫۸۹۵؟ جواب: هر دو، برای دو سؤالِ متفاوت. اگر میپرسی «در کلِ بازار قیمت با سال چه رابطهای دارد» جواب ۰٫۶۳۵ است. اگر میپرسی «برای یک لپتاپِ معمولی» جواب ۰٫۸۹۵ است. عدد بدونِ سؤال معنا ندارد — و این دقیقاً همان چیزی است که کلِ این دوره روی آن بنا شده.
✅ چک کن: هر دو عدد را خودت اجرا کن. اگر عددِ دومی از اولی کمتر شد، احتمالاً
!=را==نوشتهای و داری فقط روی اپل حساب میکنی.
۵. یک خطای واقعی: همبستگی روی ستونِ غیرعددی#
df[["brand", "price"]].corr()
ValueError: could not convert string to float: 'اپل'
corr() فقط با عدد کار میکند. برای رابطهٔ یک ستونِ دستهای با یک ستونِ عددی، ابزارِ درست groupby است، نه همبستگی — دقیقاً همان کاری که در فصلِ ۶ کردیم.
🔧 اگر کار نکرد: اگر
corr()روی کلِ جدول جواب داد ولی ستونهایی که انتظار داشتی در نتیجه نبودند،pandasبیسروصدا ستونهای غیرعددی را کنار گذاشته. همیشه چک کن نتیجهٔcorr()چند ستون دارد — اگر کمتر از انتظارت بود، یک ستونِ «عددی» در واقع متن است.
🤖 از دستیارت بپرس: «یک مثالِ واقعی از دو متغیر بزن که همبستگیِ بالا دارند ولی هیچ رابطهٔ علّیای ندارند، و توضیح بده متغیرِ پنهانشان چیست.» جوابش را با کاری که در بخشِ ۴ کردیم مقایسه کن. اگر مثالی زد که متغیرِ پنهانش را نگفت، دوباره بپرس — نیمهٔ دوم جواب مهمتر است.
واژههای تازهٔ این فصل#
| کلمه | تلفظ به حروف فارسی | یعنی چه |
|---|---|---|
| EDA | ایدیاِی | تحلیلِ اکتشافی: پرسیدنِ سؤالهای ثابت از دادهٔ تازه |
| IQR | آیکیوآر | فاصلهٔ چارکِ اول تا سوم؛ بازهٔ نیمهٔ میانیِ داده |
| outlier | اوتلایِر | مقداری که خیلی از بقیه دور است — خطا، زیرگروه، یا رویدادِ نادر |
| confounder | کانفاوندِر | متغیرِ پنهانی که رابطهٔ دو متغیرِ دیگر را تحریف میکند |
تمرینها
اول خودت فکر کن یا امتحان کن — بعد اینجا را باز کن.
در فصل بعد#
تا اینجا با ستونهای عددی و دستهای کار کردی. ولی بخشِ بزرگی از دادهٔ واقعی متن است — نظرِ کاربر، عنوانِ آگهی، توضیحِ محصول. و متنِ فارسی مسائلِ خودش را دارد که هیچ آموزشِ انگلیسیای به آن نمیپردازد: نیمفاصله، اعراب، ارقامِ چندشکلی، و کلمههایی که در ظاهر یکیاند و در یونیکد نه. فصلِ بعد ابزارِ حرفهایِ این کار را میآورد.
به آخر این فصل رسیدی!
اگر ساختی و جواب داد، این دکمه مال توست.