ادامهٔ کار با Google Colab
شکل ۲-۳. فهرست Notebookها در Google Colab
شکل ۲-۴. Notebook شما در Google Colab
اکنون با انتخاب مسیر Insert → Code cell از منو یک سلول کد جدید بسازید. راه دیگر این است که روی دکمهٔ + Code در نوار ابزار کلیک کنید، یا نشانگر ماوس را پایین یک سلول نگه دارید تا گزینههای + Code و + Text ظاهر شوند و سپس + Code را انتخاب کنید.
در سلول کد جدید، کمی کد Python مانند قطعهٔ زیر تایپ کنید و سپس Shift-Enter را بزنید؛ یا دکمهٔ اجرای مثلثی سمت چپ سلول را انتخاب کنید:
print("Hello World")
اگر هنوز به حساب Google وارد نشده باشید، در این مرحله از شما خواسته میشود وارد شوید؛ و اگر حساب Google ندارید باید یکی بسازید. پس از ورود، هنگامی که برای نخستین بار کد را اجرا میکنید هشدار امنیتیای میبینید که میگوید این Notebook توسط Google نوشته نشده است. فردی مخرب میتواند Notebookی بسازد که شما را فریب دهد تا اطلاعات ورود Google خود را وارد کنید و به این ترتیب به دادههای شخصیتان دسترسی پیدا کند. بنابراین پیش از اجرای هر Notebook همیشه مطمئن شوید نویسندهٔ آن قابل اعتماد است، یا دستکم بررسی کنید هر سلول کد چه کاری انجام میدهد. اگر به نویسنده اعتماد دارید - یا قصد دارید همهٔ سلولهای کد را بررسی کنید - میتوانید گزینهٔ Run anyway را انتخاب کنید.
Colab سپس یک Runtime جدید در اختیار شما قرار میدهد: ماشین مجازی رایگانی روی سرورهای Google که مجموعهای از ابزارها و کتابخانههای Python، از جمله تقریباً همهٔ چیزهایی را که برای بیشتر فصلها نیاز دارید، در خود دارد. در برخی فصلها لازم است فرمانی برای نصب کتابخانههای اضافی اجرا کنید. آمادهشدن Runtime چند ثانیه طول میکشد. سپس Colab بهطور خودکار به آن متصل میشود و سلول کد تازه را در همان Runtime اجرا میکند. نکتهٔ مهم این است که کد روی Runtime اجرا میشود، نه روی رایانهٔ شما؛ خروجی نیز زیر سلول نمایش داده میشود. به این ترتیب نخستین کد Python خود را در Colab اجرا کردهاید.
ذخیرهٔ تغییرات کد و دادهها
میتوانید Notebook Colab را تغییر دهید و تا زمانی که زبانهٔ مرورگر باز است، تغییرات باقی میمانند. اما بعد از بستن زبانه، تغییرات از دست میروند. برای جلوگیری از این موضوع، با انتخاب File → Save a copy in Drive یک نسخه از Notebook را در Google Drive ذخیره کنید. همچنین میتوانید با انتخاب File → Download → Download .ipynb آن را روی رایانه دانلود کنید. بعداً با مراجعه به https://colab.research.google.com میتوانید Notebook را دوباره از Google Drive باز کنید یا فایل ذخیرهشده روی رایانه را بارگذاری نمایید.
اگر Notebook دادهای تولید میکند که برایتان مهم است، پیش از خاموششدن Runtime آن را دانلود کنید. برای این کار روی نماد Files کلیک کنید، فایل مورد نظر را بیابید، سهنقطهٔ عمودی کنار آن را انتخاب کنید و سپس Download را بزنید. راه دیگر این است که Google Drive را روی Runtime سوار کنید تا Notebook بتواند فایلها را مانند یک پوشهٔ محلی مستقیماً از Drive بخواند یا در آن بنویسد. برای این کار نماد Files و سپس نماد Google Drive را انتخاب و دستورهای روی صفحه را دنبال کنید.
شکل ۲-۵. دانلود فایل از Runtime در Google Colab، مراحل ۱ تا ۳، یا سوارکردن Google Drive با نماد مشخصشده
بهطور پیشفرض Google Drive در مسیر /content/drive/MyDrive سوار میشود. اگر میخواهید از یک فایل داده نسخهٔ پشتیبان بگیرید، کافی است با فرمان زیر آن را به این پوشه کپی کنید:
!cp /content/my_great_model /content/drive/MyDrive
هر فرمانی که با علامت تعجب ! آغاز شود بهعنوان فرمان Shell در نظر گرفته میشود، نه کد Python. فرمان cp فرمان Shell در Linux برای کپیکردن یک فایل از یک مسیر به مسیر دیگر است. Runtimeهای Colab روی Linux، مشخصاً Ubuntu، اجرا میشوند.
قدرت و خطر تعاملپذیری
Notebookهای Jupyter تعاملیاند و این ویژگی بسیار ارزشمند است: میتوانید سلولها را یکییکی اجرا کنید، هرجا خواستید متوقف شوید، سلول تازهای اضافه کنید، با کد بازی کنید، به عقب برگردید و همان سلول را دوباره اجرا کنید و مانند آن. نویسنده شدیداً توصیه میکند واقعاً با کد آزمایش کنید؛ اگر فقط سلولها را بهترتیب اجرا کنید و هیچ تغییری ندهید، سرعت یادگیریتان کمتر خواهد بود.
اما این انعطاف هزینهای هم دارد: بسیار آسان است سلولها را با ترتیب نادرست اجرا کنید یا اجرای یک سلول را فراموش کنید. در این صورت سلولهای کد بعدی احتمالاً با خطا روبهرو میشوند. برای نمونه، نخستین سلول کد هر Notebook شامل کدهای آمادهسازی، مانند importها، است؛ بنابراین حتماً آن را ابتدا اجرا کنید، وگرنه هیچچیز درست کار نخواهد کرد.
کد کتاب در برابر کد Notebook
گاهی ممکن است تفاوتهای کوچکی میان کد چاپشده در کتاب و کد Notebookها ببینید. چند دلیل دارد:
- ممکن است یک کتابخانه تا زمانی که شما کتاب را میخوانید کمی تغییر کرده باشد، یا باوجود تلاش نویسنده خطایی در کتاب باقی مانده باشد. نویسنده نمیتواند نسخهٔ چاپی کتاب شما را جادویی اصلاح کند - مگر اینکه نسخهٔ الکترونیکی باشد و نسخهٔ تازه را دانلود کنید - اما میتواند Notebookها را اصلاح کند. پس اگر کدی که از کتاب کپی کردهاید خطا داد، نسخهٔ اصلاحشده را در Notebook بررسی کنید؛ نویسنده تلاش میکند Notebookها را بدون خطا و هماهنگ با نسخههای تازهٔ کتابخانهها نگه دارد.
- Notebookها مقداری کد اضافی برای زیباترکردن شکلها - افزودن برچسب، تنظیم اندازهٔ قلم و مانند آن - و ذخیرهٔ تصاویر با وضوح بالا برای کتاب دارند. اگر هدفتان اجرای مثال اصلی است میتوانید این کدهای اضافی را نادیده بگیرید.
کدهای کتاب برای خوانایی و سادگی بهینه شدهاند: تا حد ممکن خطی و مسطح نوشته شدهاند و توابع یا کلاسهای کمی تعریف شده است. هدف این است که کدی که اجرا میکنید معمولاً جلوی چشمتان باشد و در چند لایهٔ انتزاعی پنهان نشده باشد که مجبور شوید دنبالش بگردید. این ساختار بازیکردن با کد را نیز آسانتر میکند. برای سادگی، مدیریت خطا محدود است و بعضی importهای کمکاربرد درست در محل نیاز قرار گرفتهاند، نه در ابتدای فایل که راهنمای سبک Python با نام PEP 8 پیشنهاد میکند. بااینحال کد عملیاتی شما تفاوت بنیادی نخواهد داشت؛ فقط کمی پیمانهایتر و همراه با آزمونها و مدیریت خطای بیشتر خواهد بود.
وقتی با Colab راحت شدید، آمادهاید دادهها را دانلود کنید.
دانلود دادهها
در محیطهای معمول، دادهها احتمالاً در یک پایگاه دادهٔ رابطهای یا مخزن دادهٔ رایج دیگری قرار دارند و میان چند جدول، سند یا فایل پخش شدهاند. برای دسترسی به آنها ابتدا باید اطلاعات هویتی و مجوزهای دسترسی لازم را دریافت کنید۴ و با شِمای داده آشنا شوید. در این پروژه شرایط بسیار سادهتر است: تنها یک فایل فشرده به نام housing.tgz را دانلود میکنید که یک فایل مقادیر جداشده با ویرگول، housing.csv، را با تمام دادهها در خود دارد.
بهجای دانلود و بازکردن دستی فایل، معمولاً بهتر است تابعی بنویسید که این کار را انجام دهد. این روش بهویژه وقتی داده مرتب تغییر میکند مفید است: میتوانید اسکریپت کوچکی بنویسید که با این تابع تازهترین داده را دریافت کند یا یک کار زمانبندیشده برای انجام خودکار آن در فواصل منظم بسازید. خودکارسازی دریافت داده همچنین هنگامی مفید است که لازم باشد مجموعهداده را روی چند ماشین نصب کنید.
تابع زیر داده را دریافت و بارگذاری میکند:
from pathlib import Path
import pandas as pd
import tarfile
import urllib.request
def load_housing_data():
tarball_path = Path("datasets/housing.tgz")
if not tarball_path.is_file():
Path("datasets").mkdir(parents=True, exist_ok=True)
url = "https://github.com/ageron/data/raw/main/housing.tgz"
urllib.request.urlretrieve(url, tarball_path)
with tarfile.open(tarball_path) as housing_tarball:
housing_tarball.extractall(path="datasets")
return pd.read_csv(Path("datasets/housing/housing.csv"))
housing = load_housing_data()
وقتی load_housing_data() فراخوانی میشود، ابتدا بهدنبال فایل datasets/housing.tgz میگردد. اگر فایل را پیدا نکند، پوشهٔ datasets را در پوشهٔ جاری - که در Colab بهطور پیشفرض /content است - میسازد، فایل housing.tgz را از مخزن ageron/data در GitHub دانلود و محتوا را در همان پوشه استخراج میکند. در نتیجه پوشهٔ datasets/housing و فایل housing.csv ایجاد میشوند. در پایان، فایل CSV در یک شیء Pandas DataFrame شامل همهٔ دادهها بارگذاری و بازگردانده میشود.
نگاهی سریع به ساختار داده
کار را با مشاهدهٔ پنج سطر نخست داده با متد head() در DataFrame آغاز کنید.
شکل ۲-۶. پنج سطر نخست مجموعهداده
هر سطر یک ناحیه را نمایش میدهد. ده ویژگی وجود دارد، هرچند همه در تصویر دیده نمیشوند: longitude، latitude، housing_median_age، total_rooms، total_bedrooms، population، households، median_income، median_house_value و ocean_proximity.
متد info() برای بهدستآوردن توصیفی سریع از داده سودمند است؛ بهویژه تعداد کل سطرها، نوع هر ویژگی و تعداد مقادیر غیرتهی را نشان میدهد:
>>> housing.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20640 entries, 0 to 20639
Data columns (total 10 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 longitude 20640 non-null float64
1 latitude 20640 non-null float64
2 housing_median_age 20640 non-null float64
3 total_rooms 20640 non-null float64
4 total_bedrooms 20433 non-null float64
5 population 20640 non-null float64
6 households 20640 non-null float64
7 median_income 20640 non-null float64
8 median_house_value 20640 non-null float64
9 ocean_proximity 20640 non-null object
dtypes: float64(9), object(1)
memory usage: 1.6+ MB
این مجموعهداده ۲۰٬۶۴۰ نمونه دارد؛ در مقیاس یادگیری ماشین مجموعهای نسبتاً کوچک است، اما برای شروع بسیار مناسب است. ویژگی total_bedrooms فقط ۲۰٬۴۳۳ مقدار غیرتهی دارد؛ یعنی مقدار این ویژگی برای ۲۰۷ ناحیه گم شده است و بعداً باید برای آن راهحلی در نظر بگیرید.
همهٔ ویژگیها عددیاند، بهجز ocean_proximity. نوع آن object است و در Python میتواند هر نوع شیئی را نگه دارد، اما چون داده از CSV بارگذاری شده میدانیم این ویژگی باید متنی باشد. با نگاه به پنج سطر نخست، احتمالاً متوجه شدهاید مقادیر این ستون تکراریاند؛ پس احتمالاً با یک ویژگی دستهای روبهرو هستیم. برای دیدن دستهها و تعداد ناحیههای هر دسته از value_counts() استفاده کنید:
>>> housing["ocean_proximity"].value_counts()
<1H OCEAN 9136
INLAND 6551
NEAR OCEAN 2658
NEAR BAY 2290
ISLAND 5
Name: ocean_proximity, dtype: int64
اکنون به سایر فیلدها نگاه کنید. متد describe() خلاصهای از ویژگیهای عددی را نمایش میدهد.
شکل ۲-۷. خلاصهٔ هر ویژگی عددی
سطرهای count، mean، min و max روشناند. توجه کنید مقادیر تهی نادیده گرفته میشوند؛ برای نمونه تعداد total_bedrooms برابر ۲۰٬۴۳۳ است، نه ۲۰٬۶۴۰. سطر std انحراف معیار را نشان میدهد که میزان پراکندگی مقادیر را اندازه میگیرد.۵ سطرهای ۲۵٪، ۵۰٪ و ۷۵٪ نیز صدکهای متناظر را نشان میدهند.
صدک مقداری است که درصد مشخصی از مشاهدات گروه پایینتر از آن قرار میگیرند. برای مثال، در ۲۵ درصد ناحیهها housing_median_age کمتر از ۱۸ است؛ در ۵۰ درصد کمتر از ۲۹ و در ۷۵ درصد کمتر از ۳۷. این مقادیر اغلب بهترتیب صدک ۲۵ یا چارک اول، میانه و صدک ۷۵ یا چارک سوم نامیده میشوند.
راه سریع دیگر برای درک نوع داده، رسم هیستوگرام برای هر ویژگی عددی است. هیستوگرام تعداد نمونههایی را روی محور عمودی نشان میدهد که مقدارشان در بازهای مشخص روی محور افقی قرار میگیرد. میتوانید هر ویژگی را جداگانه رسم کنید یا متد hist() را روی کل مجموعهداده فراخوانی کنید تا برای هر ویژگی عددی یک هیستوگرام بسازد:
import matplotlib.pyplot as plt
housing.hist(bins=50, figsize=(12, 8))
plt.show()
شکل ۲-۸. یک هیستوگرام برای هر ویژگی عددی
نکتههایی که از هیستوگرامها آشکار میشوند
- نخست، ویژگی درآمد میانه شبیه مقدار دلار آمریکا نیست. پس از پرسش از تیم گردآوری داده مشخص میشود داده مقیاسبندی شده و برای درآمدهای بالاتر در ۱۵، دقیقتر ۱۵٫۰۰۰۱، و برای درآمدهای پایینتر در ۰٫۵، دقیقتر ۰٫۴۹۹۹، سقف و کفگذاری شده است. اعداد تقریباً دهها هزار دلار را نمایش میدهند؛ مثلاً مقدار ۳ تقریباً به ۳۰ هزار دلار اشاره میکند. کار با ویژگیهای پیشپردازششده در یادگیری ماشین رایج است و لزوماً مشکل محسوب نمیشود، اما باید بفهمید داده چگونه محاسبه شده است.
- سن میانهٔ مسکن و قیمت میانهٔ خانه نیز سقفگذاری شدهاند. سقف قیمت میانهٔ خانه میتواند مشکل جدی باشد، زیرا این ویژگی هدف یا برچسب شماست. الگوریتم ممکن است یاد بگیرد که قیمت هرگز از سقف تعیینشده بالاتر نمیرود. باید از تیم مشتری بپرسید آیا به پیشبینی دقیق برای قیمتهای بالاتر از ۵۰۰ هزار دلار نیاز دارند یا نه. اگر پاسخ مثبت باشد دو راه دارید: برچسب درست ناحیههایی را که قیمتشان سقفگذاری شده گردآوری کنید؛ یا این ناحیهها را از مجموعهٔ آموزشی و همچنین مجموعهٔ آزمون حذف کنید تا سامانه بهدلیل پیشبینی قیمتهای بالاتر از ۵۰۰ هزار دلار ناعادلانه ضعیف ارزیابی نشود.
- ویژگیها مقیاسهای بسیار متفاوتی دارند. این موضوع بعداً در همین فصل هنگام بررسی مقیاسبندی ویژگیها مطرح میشود.
- بسیاری از هیستوگرامها به راست چولهاند؛ یعنی نسبت به سمت چپ، بسیار دورتر از میانه به سمت راست کشیده میشوند. این وضعیت میتواند یافتن الگو را برای بعضی الگوریتمهای یادگیری ماشین دشوارتر کند. بعداً تلاش میکنید با تبدیل این ویژگیها توزیعهایی متقارنتر و نزدیکتر به زنگوله بسازید.
اکنون باید درک بهتری از نوع دادهای که با آن کار میکنید داشته باشید. اما پیش از اینکه بیشتر به داده نگاه کنید، باید یک مجموعهٔ آزمون بسازید، آن را کنار بگذارید و دیگر به آن نگاه نکنید.