فاز 1 · درس 10

کاهش ابعاد: راهنمای عملی PCA، t-SNE و UMAP

نوع
ساختنی
زمان
حدود 90 دقیقه
زبان‌ها
Python
یک شیء سه‌بعدی پیچیده و درخشان که نوری از زاویه‌ای دقیق به آن تابیده شده و سایه‌ای دوبعدی، ساده و تفکیک‌شده روی سطح ایجاد کرده است.
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. مفاهیم پایه
  4. نفرین ابعاد
  5. تحلیل مؤلفه‌های اصلی (PCA): یافتن جهت‌های مهم
  6. نسبت واریانس توجیه‌شده
  7. انتخاب تعداد مؤلفه‌ها
  8. الگوریتم t-SNE: حفظ همسایگی‌ها
  9. الگوریتم UMAP: سریع‌تر و با ساختار سراسری بهتر
  10. چه زمانی از کدام روش استفاده کنیم؟
  11. روش Kernel PCA
  12. خطای بازسازی (Reconstruction Error)
  13. پیاده‌سازی از صفر
  14. گام 1: پیاده‌سازی PCA از صفر
  15. گام 2: آزمون روی داده‌های ساختگی
  16. گام 3: ارقام MNIST در فضای 2بعدی
  17. گام 4: مقایسه با sklearn
  18. گام 5: مقایسه با UMAP
  19. استفاده از ابزارهای واقعی
  20. خروجی این درس
  21. تمرین‌ها
  22. راهنمایی‌ها
  23. اصطلاحات کلیدی
  24. برای مطالعه‌ی بیشتر

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

کاهش ابعاد به شما کمک می‌کند حجم عظیم نویز و همبستگی‌های تکراری را حذف کنید و اطلاعات کلیدی را در فضایی بسیار فشرده‌تر نگه دارید. این کار هم سرعت آموزش مدل‌ها را به‌شدت بالا می‌برد و هم مصورسازی الگوهای پنهان در نمودارهای 2بعدی را ممکن می‌سازد.

در این درس، الگوریتم PCA را از صفر پیاده‌سازی می‌کنید، روش‌های مدرن بصری‌سازی مثل t-SNE و UMAP را مقایسه خواهید کرد و یاد می‌گیرید که چه زمانی برای داده‌های غیرخطی سراغ Kernel PCA بروید.

داده‌های با ابعاد بالا ساختار دارند. برای پیدا کردنش کافی است از زاویه‌ی درستی به آن‌ها نگاه کنید.

اهداف یادگیری

  • پیاده‌سازی PCA از صفر: میانگین‌زدایی از داده‌ها، محاسبه‌ی ماتریس کوواریانس، تجزیه‌ی ویژه‌مقدار و تصویر کردن داده‌ها
  • استفاده از نسبت واریانس توجیه‌شده (Explained variance ratio) و روش زانویی (Elbow method) برای انتخاب تعداد مؤلفه‌های اصلی
  • مقایسه‌ی PCA، t-SNE و UMAP برای مصورسازی ارقام MNIST در فضای 2بعدی و بررسی نقاط قوت و ضعف هرکدام
  • به‌کارگیری PCA با کرنل (Kernel PCA) به کمک کرنل RBF برای جداسازی ساختارهای غیرخطیِ داده که PCA استاندارد از پسِ آن‌ها برنمی‌آید

صورت مسئله

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

اما بیشتر این 784 ویژگی زاید هستند. اطلاعات واقعی روی رویه‌ای بسیار کوچک‌تر قرار دارد. برای توصیف یک عدد «7» دست‌نویس به 784 عدد مستقل نیازی ندارید؛ چند متغیر کافی است: زاویه‌ی خط، طول خط افقی، یا میزان انحراف آن. بقیه‌ی اطلاعات صرفاً نویز است.

کاهش ابعاد (Dimensionality reduction) همین رویه‌ی کوچک‌تر را پیدا می‌کند. این روش داده‌های 784بعدی شما را می‌گیرد و بدون از دست دادن ساختارهای مهم، آن‌ها را به 2، 10 یا 50 بعد فشرده می‌کند.

مفاهیم پایه

نفرین ابعاد

فضاهای با ابعاد بالا با شهود ما سازگار نیستند. با افزایش ابعاد، سه چیز به‌هم می‌ریزد.

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

Dimension    Avg distance ratio (max/min between random points)
2            ~5.0
10           ~1.8
100          ~1.2
1000         ~1.02

حجم در گوشه‌ها جمع می‌شود. یک ابرمکعب واحد در فضای ddبعدی دارای 2d2^d گوشه است. در 100 بعد، تقریباً تمام حجم در گوشه‌ها متمرکز شده و از مرکز فاصله دارد. نقاط داده به سمت لبه‌ها پراکنده می‌شوند و مدل‌های شما در بخش‌های میانی با کمبود شدید داده مواجه می‌مانند.

به داده‌های بسیار بیشتری با نرخ نمایی نیاز دارید. برای حفظ همان چگالی نمونه‌ها در فضا، رفتن از فضای 2بعدی به 20بعدی به این معناست که به 101810^{18} برابر داده‌ی بیشتر احتیاج دارید. هیچ‌وقت داده‌ی کافی نخواهید داشت؛ کاهش ابعاد، چگالی داده‌ها را دوباره به وضعیتی منطقی و کاربردی برمی‌گرداند.

تحلیل مؤلفه‌های اصلی (PCA): یافتن جهت‌های مهم

تحلیل مؤلفه‌های اصلی (Principal Component Analysis یا PCA) محورهایی را پیدا می‌کند که داده‌های شما در امتداد آن‌ها بیشترین تغییرات را دارند. این روش دستگاه مختصات شما را می‌چرخاند؛ به‌طوری‌که محور اول بیشترین واریانس را ثبت می‌کند، محور دوم بیشترین واریانسِ بعدی را، و به همین ترتیب ادامه می‌یابد.

مراحل الگوریتم:

1. Center the data        (subtract the mean from each feature)
2. Compute covariance     (how features move together)
3. Eigendecomposition     (find the principal directions)
4. Sort by eigenvalue     (biggest variance first)
5. Project               (keep top k eigenvectors, drop the rest)

چرا تجزیه‌ی ویژه‌مقدار (Eigendecomposition)؟ ماتریس کوواریانس متقارن و نیمه‌معین مثبت است. بردارهای ویژه‌ی آن جهت‌های عمود بر هم (متعامد) در فضای ویژگی‌ها هستند. مقادیر ویژه نشان می‌دهند که هر جهت چقدر از واریانس را در بر می‌گیرد؛ بنابراین بردار ویژه‌ای که بزرگ‌ترین مقدار ویژه را دارد، هم‌راستا با جهت بیشترین واریانس است.

چرخش PCAداده‌های اصلی (2D)پراکندگی داده در هر دوجهت x و yپس از PCAPC1 کشیدگی اصلی را پوشش می‌دهدPC2 پراکندگی کم را پوشش می‌دهدحذف PC2 اطلاعات کمی را از بین می‌برد
  • پیش از PCA: ابرِ داده‌ها به‌صورت مورب در امتداد هر دو محور x و y پراکنده است.
  • پس از PCA: دستگاه مختصات می‌چرخد تا PC1 با جهت بیشترین واریانس (پراکندگی کشیده) و PC2 با جهت کمترین واریانس (پراکندگی باریک) هم‌راستا شود.
  • کاهش ابعاد: با حذف PC2، داده‌ها روی PC1 تصویر می‌شوند و اطلاعات بسیار کمی از دست می‌رود.

نسبت واریانس توجیه‌شده

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

Component    Eigenvalue    Explained ratio    Cumulative
PC1          4.73          0.473              0.473
PC2          2.51          0.251              0.724
PC3          1.12          0.112              0.836
PC4          0.89          0.089              0.925
...

وقتی مجموع تجمعیِ واریانس توجیه‌شده به 0.95 برسد، می‌فهمید که این تعداد مؤلفه 95% اطلاعات را حفظ کرده‌اند. از اینجا به بعد، داده‌ها عمدتاً نویز هستند.

انتخاب تعداد مؤلفه‌ها

سه راهبرد وجود دارد:

  1. آستانه‌ی ثابت (Threshold): نگه‌داشتن مؤلفه‌های کافی برای پوشش 90 تا 95 درصد از واریانس.
  2. روش زانویی (Elbow method): رسم نمودار واریانس توجیه‌شده بر حسب هر مؤلفه و پیدا کردن نقطه‌ای که شیب نمودار ناگهان افت می‌کند.
  3. عملکرد مدل نهایی (Downstream performance): استفاده از PCA به‌عنوان پیش‌پردازش. مقادیر مختلف kk را تست کنید و دقت مدل را بسنجید؛ بهترین kk جایی است که نمودار دقت مسطح می‌شود.

الگوریتم t-SNE: حفظ همسایگی‌ها

امبدینگ همسایگی تصادفی با توزیع تی (t-Distributed Stochastic Neighbor Embedding یا t-SNE) ویژه‌ی مصورسازی طراحی شده است. این الگوریتم داده‌های چندبعدی را به 2 بعد (یا 3 بعد) می‌برد، طوری‌که نزدیک بودن نقاط به یکدیگر در فضای مبدا حفظ شود.

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

ویژگی‌های کلیدی t-SNE:

  • غیرخطی است؛ ساختارهای خمیده‌ی پیچیده‌ای (Manifolds) را باز می‌کند که PCA از عهده‌ی آن‌ها برنمی‌آید.
  • تصادفی (Stochastic) است؛ اجراهای متفاوت چینش‌های بصری متفاوتی تولید می‌کنند.
  • پارامتر Perplexity تعیین می‌کند چند همسایه در نظر گرفته شوند (بازه معمول: 5 تا 50).
  • فاصله‌ی میان خوشه‌ها در خروجی معنای خاصی ندارد؛ تنها خود خوشه‌ها معتبرند.
  • روی مجموعه‌داده‌های بزرگ کند اجرا می‌شود؛ پیچیدگی پیش‌فرض آن O(n2)O(n^2) است.

الگوریتم UMAP: سریع‌تر و با ساختار سراسری بهتر

تقریب و تصویر چندوجهی یکنواخت (Uniform Manifold Approximation and Projection یا UMAP) عملکردی شبیه به t-SNE دارد اما با دو مزیت مهم:

  • سریع‌تر است؛ به‌جای محاسبه‌ی فاصله‌ی همه‌ی جفت‌ها، از گراف تقریبی نزدیک‌ترین همسایه‌ها استفاده می‌کند.
  • ساختار سراسری (Global structure) را بهتر نگه می‌دارد؛ موقعیت نسبی خوشه‌ها نسبت به یکدیگر در خروجی معمولاً معنادارتر از t-SNE است.

الگوریتم UMAP گرافی وزن‌دار در فضای ابعاد بالا می‌سازد («نمایش توپولوژیک فازی») و سپس ساختاری در ابعاد پایین پیدا می‌کند که این گراف را تا جای ممکن دقیق بازتولید کند.

پارامترهای کلیدی:

  • n_neighbors: تعداد همسایگانی که ساختار محلی را تعریف می‌کنند (مشابه Perplexity). مقادیر بالاتر ساختار سراسری بیشتری را حفظ می‌کنند.
  • min_dist: میزان فشردگی نقاط در خروجی. مقادیر کمتر خوشه‌های چگال‌تری می‌سازند.

چه زمانی از کدام روش استفاده کنیم؟

روش کاربرد ویژگیِ حفظ‌شده سرعت
PCA پیش‌پردازش قبل از آموزش مدل واریانس سراسری سریع (دقیق)، مناسب برای میلیون‌ها نمونه
PCA مصورسازی اکتشافی سریع ساختار خطی سریع
t-SNE نمودارهای 2بعدی با کیفیت مناسب مقالات همسایگی‌های محلی کند (بهترین حالت کمتر از 10هزار نمونه)
UMAP مصورسازی 2بعدی در مقیاس بزرگ محلی به‌همراه بخشی از ساختار سراسری متوسط (مناسب برای میلیون‌ها نمونه)
PCA کاهش ابعاد ویژگی‌ها برای مدل‌ها ویژگی‌ها بر اساس رتبه‌ی واریانس سریع
t-SNE / UMAP درک ساختار خوشه‌بندی تفکیک خوشه‌ها متوسط تا کند

یک قاعده‌ی تجربی: برای پیش‌پردازش و فشرده‌سازی داده‌ها سراغ PCA بروید؛ وقتی هدف نمایش بصری ساختار در 2 بعد است، از t-SNE یا UMAP استفاده کنید.

روش Kernel PCA

روش PCA استاندارد زیرفضاهای خطی را پیدا می‌کند؛ یعنی دستگاه مختصات را می‌چرخاند و بعضی محورها را کنار می‌گذارد. اما اگر داده‌ها روی یک خمینه (Manifold) غیرخطی باشند چه؟ نقاط یک دایره در فضای 2بعدی با هیچ خطی جدا نمی‌شوند و PCA استاندارد کمکی نخواهد کرد.

روش Kernel PCA همان PCA را در یک فضای ویژگی با ابعاد بالا که توسط یک تابع کرنل تعریف شده اجرا می‌کند، بدون اینکه نیاز باشد مختصات نقاط در آن فضا مستقیماً محاسبه شوند. این همان ترفند کرنل (Kernel trick) است؛ ایده‌ای که در SVM هم استفاده می‌شود.

مراحل الگوریتم:

  1. محاسبه‌ی ماتریس کرنل KK که در آن Kij=k(xi,xj)K_{ij} = k(x_i, x_j)
  2. میانگین‌زدایی از ماتریس کرنل در فضای ویژگی
  3. تجزیه‌ی ویژه‌مقدار روی ماتریس کرنل میانگین‌زدایی‌شده
  4. برترین بردارهای ویژه (به‌مقیاس‌درآمده با ضریب 1/eigenvalue1/\sqrt{\text{eigenvalue}}) همان داده‌های تصویرشده هستند

توابع کرنل رایج:

کرنل فرمول مناسب برای
RBF (گوسی) exp⁡(−γ∥x−y∥2)\exp(-\gamma \lVert x - y \rVert^2) بیشتر داده‌های غیرخطی، خمینه‌های هموار
چندجمله‌ای (x⋅y+c)d(x \cdot y + c)^d روابط چندجمله‌ای
سیگموئید tanh⁡(αx⋅y+c)\tanh(\alpha x \cdot y + c) نگاشت‌های شبیه به شبکه عصبی

مقایسه‌ی Kernel PCA با PCA استاندارد:

معیار PCA استاندارد Kernel PCA
ساختار داده زیرفضای خطی خمینه‌ی غیرخطی
سرعت O(min⁡(n2d,d2n))O(\min(n^2 d, d^2 n)) O(n2d+n3)O(n^2 d + n^3)
تفسیرپذیری مؤلفه‌ها ترکیب‌های خطی از ویژگی‌ها هستند مؤلفه‌ها تفسیر مستقیم مبتنی بر ویژگی ندارند
مقیاس‌پذیری روی میلیون‌ها نمونه کار می‌کند ابعاد ماتریس کرنل n×nn \times n است، محدود به حافظه
بازسازی داده تبدیل معکوس مستقیم نیاز به تقریب تصویر پیشین (Pre-image) دارد

مثال کلاسیک: دو دایره‌ی هم‌مرکز در فضای 2بعدی؛ دو حلقه از نقاط که یکی درون دیگری قرار دارد. تحلیل PCA استاندارد هر دو حلقه را روی یک خط تصویر می‌کند که برای دسته‌بندی کاملاً بی‌فایده است. اما Kernel PCA با کرنل RBF دایره‌ی داخلی و خارجی را به نواحی مجزایی می‌برد و آن‌ها را تفکیک‌پذیر خطی می‌کند.

خطای بازسازی (Reconstruction Error)

کاهش ابعاد چقدر خوب عمل کرده است؟ شما 784 بعد را به 50 بعد فشرده کردید؛ چه مقدار اطلاعات از دست رفت؟

سنجش خطای بازسازی:

  1. تصویر داده‌ها روی kk بعد: Xreduced=XWkX_{\text{reduced}} = X W_k
  2. بازسازی داده‌ها: X^=XreducedWkT\hat{X} = X_{\text{reduced}} W_k^T
  3. محاسبه‌ی میانگین مربعات خطا (MSE): mean((X−X^)2)\text{mean}((X - \hat{X})^2)

در PCA، خطای بازسازی رابطه‌ی شفاف و مستقیمی با واریانس توجیه‌شده دارد:

Reconstruction error=sum of eigenvalues NOT includedTotal variance=sum of ALL eigenvaluesFraction lost=sum of dropped eigenvaluessum of all eigenvalues\begin{aligned} \text{Reconstruction error} &= \text{sum of eigenvalues NOT included} \\ \text{Total variance} &= \text{sum of ALL eigenvalues} \\ \text{Fraction lost} &= \frac{\text{sum of dropped eigenvalues}}{\text{sum of all eigenvalues}} \end{aligned}

نسبت واریانس توجیه‌شده برای هر مؤلفه برابر است با:

explained_ratiok=eigenvaluek∑all eigenvalues\text{explained\_ratio}_k = \frac{\text{eigenvalue}_k}{\sum \text{all eigenvalues}}

رسم واریانس توجیه‌شده‌ی تجمعی در برابر تعداد مؤلفه‌ها، نمودار «زانویی» را به شما می‌دهد. تعداد مناسب مؤلفه‌ها نقطه‌ای است که:

  • شیب منحنی ملایم و مسطح شود (بازده نزولی)
  • واریانس تجمعی از آستانه‌ی مد نظر شما (معمولاً 0.90 یا 0.95) بگذرد
  • عملکرد مدل در وظیفه‌ی نهایی ثابت بماند

کاربرد خطای بازسازی فقط به انتخاب kk محدود نمی‌شود؛ از آن در تشخیص ناهنجاری (Anomaly detection) هم استفاده می‌کنند: نمونه‌هایی با خطای بازسازی بالا همان داده‌های پرت هستند که در زیرفضای آموخته‌شده نمی‌گنجند. این اصل پایه‌ی تشخیص ناهنجاری بر مبنای PCA در سیستم‌های عملیاتی است.

محورهای PCAهمبستگی را بکشید
PCA AXESPCA finds the eigenvectors of the covariance matrix. The blue axis (PC1) points along the direction of greatest spread; the orange axis (PC2) is perpendicular and captures what is left. The eigenvalues are the variances along each axis, so the variance-explained on PC1 climbs as the cloud becomes more elongated and correlated.
روش PCA بردارهای ویژه ماتریس کوواریانس را پیدا می‌کند. محور آبی (PC1) در جهت بیشترین پراکندگی قرار دارد؛ محور نارنجی (PC2) بر آن عمود است و باقی‌مانده را پوشش می‌دهد. مقادیر ویژه همان واریانس‌های در راستای هر محور هستند، بنابراین با کشیده‌تر و همبسته‌تر شدن ابر نقاط، واریانس توجیه‌شده در PC1 افزایش می‌یابد.

پیاده‌سازی از صفر

گام 1: پیاده‌سازی PCA از صفر

import numpy as np

class PCA:
    def __init__(self, n_components):
        self.n_components = n_components
        self.components = None
        self.mean = None
        self.eigenvalues = None
        self.explained_variance_ratio_ = None

    def fit(self, X):
        self.mean = np.mean(X, axis=0)
        X_centered = X - self.mean

        cov_matrix = np.cov(X_centered, rowvar=False)

        eigenvalues, eigenvectors = np.linalg.eigh(cov_matrix)

        sorted_idx = np.argsort(eigenvalues)[::-1]
        eigenvalues = eigenvalues[sorted_idx]
        eigenvectors = eigenvectors[:, sorted_idx]

        self.components = eigenvectors[:, :self.n_components].T
        self.eigenvalues = eigenvalues[:self.n_components]
        total_var = np.sum(eigenvalues)
        self.explained_variance_ratio_ = self.eigenvalues / total_var

        return self

    def transform(self, X):
        X_centered = X - self.mean
        return X_centered @ self.components.T

    def fit_transform(self, X):
        self.fit(X)
        return self.transform(X)

گام 2: آزمون روی داده‌های ساختگی

np.random.seed(42)
n_samples = 500

t = np.random.uniform(0, 2 * np.pi, n_samples)
x1 = 3 * np.cos(t) + np.random.normal(0, 0.2, n_samples)
x2 = 3 * np.sin(t) + np.random.normal(0, 0.2, n_samples)
x3 = 0.5 * x1 + 0.3 * x2 + np.random.normal(0, 0.1, n_samples)

X_synthetic = np.column_stack([x1, x2, x3])

pca = PCA(n_components=2)
X_reduced = pca.fit_transform(X_synthetic)

print(f"Original shape: {X_synthetic.shape}")
print(f"Reduced shape:  {X_reduced.shape}")
print(f"Explained variance ratios: {pca.explained_variance_ratio_}")
print(f"Total variance captured: {sum(pca.explained_variance_ratio_):.4f}")

گام 3: ارقام MNIST در فضای 2بعدی

from sklearn.datasets import fetch_openml

mnist = fetch_openml("mnist_784", version=1, as_frame=False, parser="auto")
X_mnist = mnist.data[:5000].astype(float)
y_mnist = mnist.target[:5000].astype(int)

pca_mnist = PCA(n_components=50)
X_pca50 = pca_mnist.fit_transform(X_mnist)
print(f"50 components capture {sum(pca_mnist.explained_variance_ratio_):.2%} of variance")

pca_2d = PCA(n_components=2)
X_pca2d = pca_2d.fit_transform(X_mnist)
print(f"2 components capture {sum(pca_2d.explained_variance_ratio_):.2%} of variance")

گام 4: مقایسه با sklearn

from sklearn.decomposition import PCA as SklearnPCA
from sklearn.manifold import TSNE

sklearn_pca = SklearnPCA(n_components=2)
X_sklearn_pca = sklearn_pca.fit_transform(X_mnist)

print(f"\nOur PCA explained variance:     {pca_2d.explained_variance_ratio_}")
print(f"Sklearn PCA explained variance: {sklearn_pca.explained_variance_ratio_}")

diff = np.abs(np.abs(X_pca2d) - np.abs(X_sklearn_pca))
print(f"Max absolute difference: {diff.max():.10f}")

tsne = TSNE(n_components=2, perplexity=30, random_state=42)
X_tsne = tsne.fit_transform(X_mnist)
print(f"\nt-SNE output shape: {X_tsne.shape}")

گام 5: مقایسه با UMAP

try:
    from umap import UMAP

    reducer = UMAP(n_components=2, n_neighbors=15, min_dist=0.1, random_state=42)
    X_umap = reducer.fit_transform(X_mnist)
    print(f"UMAP output shape: {X_umap.shape}")
except ImportError:
    print("Install umap-learn: pip install umap-learn")

استفاده از ابزارهای واقعی

استفاده از PCA به‌عنوان پیش‌پردازش قبل از دسته‌بند:

from sklearn.decomposition import PCA as SklearnPCA
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

X_train, X_test, y_train, y_test = train_test_split(
    X_mnist, y_mnist, test_size=0.2, random_state=42
)

results = {}
for k in [10, 30, 50, 100, 200]:
    pca_k = SklearnPCA(n_components=k)
    X_tr = pca_k.fit_transform(X_train)
    X_te = pca_k.transform(X_test)

    clf = LogisticRegression(max_iter=1000, random_state=42)
    clf.fit(X_tr, y_train)
    acc = accuracy_score(y_test, clf.predict(X_te))
    var_captured = sum(pca_k.explained_variance_ratio_)
    results[k] = (acc, var_captured)
    print(f"k={k:>3d}  accuracy={acc:.4f}  variance={var_captured:.4f}")

عملکرد مدل خیلی قبل از رسیدن به 784 بعد ثابت می‌ماند. نقطه‌ی ورود به این فلات، همان نقطه‌ی کاری ایدئال شماست.

خروجی این درس

این درس یک خروجی دارد:

  • outputs/skill-dimensionality-reduction.md - راهنمای مهارتی برای انتخاب تکنیک مناسب کاهش ابعاد متناسب با هر مسئله

تمرین‌ها

  1. کلاس PCA را طوری تغییر دهید که از inverse_transform پشتیبانی کند. ارقام MNIST را با 10، 50 و 200 مؤلفه بازسازی کرده و خطای بازسازی (میانگین مربعات اختلاف با داده‌ی اصلی) را برای هر کدام چاپ کنید.

  2. الگوریتم t-SNE را روی همان زیرمجموعه‌ی MNIST با مقادیر Perplexity برابر 5، 30 و 100 اجرا کنید. توضیح دهید که خروجی چگونه تغییر می‌کند. چرا Perplexity بر میزان فشردگی خوشه‌ها اثر می‌گذارد؟

  3. مجموعه‌داده‌ای با 50 ویژگی بسازید که تنها 5 ویژگی آن اطلاعات‌بخش باشند (می‌توانید از sklearn.datasets.make_classification کمک بگیرید). روش PCA را روی آن اعمال کرده و بررسی کنید که آیا نمودار واریانس توجیه‌شده، 5بعدی بودنِ مؤثرِ داده‌ها را به‌درستی تشخیص می‌دهد یا خیر.

راهنمایی‌ها

تمرین 1. متد inverse_transform را در کلاس PCA پیاده‌سازی کنید و برای هر تعداد مؤلفه یک مدل برازش دهید. مقدار reconstruction_error را برای 10، 50 و 200 مؤلفه حساب کنید؛ این خطا با افزایش تعداد مؤلفه‌ها حتماً کاهش می‌یابد.

تمرین 2. تابع sklearn.manifold.TSNE را سه بار روی همان زیرمجموعه اجرا کنید؛ فقط perplexity را تغییر دهید و random_state یکسانی بگذارید. پارامتر Perplexity پایین همسایه‌های کمتری را بررسی می‌کند و خوشه‌های کوچک و فشرده می‌سازد؛ مقادیر بالا همسایه‌های بیشتری می‌بینند و در نتیجه خوشه‌های بزرگ‌تر و یکدست‌تری تولید می‌کنند.

تمرین 3. تابع make_classification(n_features=50, n_informative=5, n_redundant=45) را فراخوانی کنید، مدل PCA را برازش دهید و مقدار واریانس تجمعی را چاپ کنید. ویژگی‌های زاید در واقع ترکیب‌های خطی از ویژگی‌های اصلی هستند؛ بنابراین نمودار در 5 مؤلفه تقریباً به 1.0 می‌رسد. سپس حالت n_redundant=0 را آزمایش کنید: در این حالت 45 ویژگیِ دیگر نویز مستقل هستند و نمودار به این راحتی‌ها مسطح نخواهد شد.

اصطلاحات کلیدی

اصطلاح در گفت‌وگوها معنای دقیق فنی
نفرین ابعاد (Curse of dimensionality) «ویژگی‌ها خیلی زیاده» رفتار غیرشهودی فاصله‌ها، حجم‌ها و چگالی داده با افزایش ابعاد. مدل‌ها برای جبران به داده‌های بسیار بیشتری با نرخ نمایی نیاز پیدا می‌کنند.
PCA «کم کردن ابعاد» چرخاندن دستگاه مختصات برای هم‌راستا شدن محورها با بیشترین واریانس و سپس حذف محورهای با واریانس پایین.
مؤلفه‌ی اصلی (Principal component) «یک جهت مهم» بردار ویژه‌ی ماتریس کوواریانس؛ جهتی در فضای ویژگی‌ها که داده‌ها در راستای آن بیشترین تغییر را دارند.
نسبت واریانس توجیه‌شده (Explained variance ratio) «میزان اطلاعات این مؤلفه» سهمی از کل واریانس که توسط یک مؤلفه‌ی اصلی پوشش داده می‌شود. با جمع زدن kk نسبت برتر مشخص می‌شود که kk مؤلفه چه مقدار اطلاعات را حفظ کرده‌اند.
ماتریس کوواریانس (Covariance matrix) «همبستگی بین ویژگی‌ها» ماتریسی متقارن که درایه‌ی (i,j)(i,j) آن نشان می‌دهد ویژگی ii و ویژگی jj چقدر با هم تغییر می‌کنند. درایه‌های روی قطر اصلی، واریانس‌های هر ویژگی هستند.
t-SNE «همون نمودار خوشه‌بندی» روشی غیرخطی که داده‌های چندبعدی را با حفظ احتمالات همسایگی به 2 بعد می‌برد؛ مناسب مصورسازی، نامناسب برای پیش‌پردازش مدل‌ها.
UMAP «نسخه‌ی سریع‌تر t-SNE» روشی غیرخطی مبتنی بر تحلیل داده‌های توپولوژیک؛ ساختارهای محلی و بخشی از ساختار سراسری را حفظ می‌کند و مقیاس‌پذیری بالاتری نسبت به t-SNE دارد.
Perplexity «پیچ تنظیم t-SNE» تعداد مؤثر همسایگانی که هر نقطه مد نظر قرار می‌دهد را کنترل می‌کند. مقدار پایین روی ساختارهای خیلی محلی تمرکز دارد و مقدار بالا الگوهای وسیع‌تر را در بر می‌گیرد.
خمینه (Manifold) «سطحی که داده روی اون قرار داره» رویه‌ای با ابعاد پایین‌تر که درون فضایی با ابعاد بالاتر قرار گرفته است؛ یک برگه‌ی کاغذ مچاله‌شده در فضای 3بعدی، خمینه‌ای 2بعدی است.

برای مطالعه‌ی بیشتر

  • A Tutorial on Principal Component Analysis (Shlens) - استخراج و اثبات گام‌به‌گام و شفاف PCA از پایه‌ای‌ترین اصول
  • How to Use t-SNE Effectively (Wattenberg et al.) - راهنمای تعاملی درباره‌ی چالش‌ها و انتخاب درست پارامترهای t-SNE
  • مستندات UMAP - مبانی نظری و راهنمای عملی از زبان توسعه‌دهندگان UMAP

خودآزمایی

به سؤال‌ها جواب بدهید تا ببینید چقدر از درس در ذهنتان مانده است.

  1. پیش از درس«نفرین ابعاد» (curse of dimensionality) چیست؟
  2. پیش از درسروش PCA چه چیزی را پیدا می‌کند؟
  3. پس از درسپس از اجرای PCA روی داده‌های 784-بعدی MNIST با k=50 مؤلفه، متوجه می‌شوید که 95% از واریانس پوشش داده شده است. این موضوع چه چیزی را نشان می‌دهد؟
  4. پس از درسچرا نباید از t-SNE به عنوان پیش‌پردازش پیش از آموزش طبقه‌بند استفاده کرد؟
  5. پس از درسچه زمانی کرنل PCA را به PCA استاندارد ترجیح می‌دهید؟

سؤالات متداول

تفاوت اصلی کاربرد PCA با t-SNE و UMAP چیست؟

روش PCA خطی، قطعی و سریع است و برای پیش‌پردازش، فشرده‌سازی و حذف نویز پیش از آموزش مدل‌ها استفاده می‌شود؛ اما t-SNE و UMAP غیرخطی هستند و مشخصاً برای مصورسازی خوشه‌ها و روابط همسایگی در فضاهای 2 یا 3بعدی کاربرد دارند.

چگونه تعداد مؤلفه‌های مناسب در PCA را انتخاب کنیم؟

از طریق تعیین آستانه واریانس تجمعی (معمولاً حفظ 90 تا 95 درصد واریانس کل)، بررسی نقطه زانویی (Elbow) در نمودار افت واریانس، یا اندازه‌گیری پایداری دقت مدل نهایی بر حسب تعداد مؤلفه‌ها.

Kernel PCA چه مشکلی را در PCA استاندارد حل می‌کند؟

روش PCA استاندارد فقط زیرفضاهای خطی را می‌شناسد. اگر داده‌ها روی خمینه‌های غیرخطی (مانند دو دایره هم‌مرکز) قرار داشته باشند، Kernel PCA با استفاده از ترفند کرنل داده‌ها را به فضایی با ابعاد بالاتر می‌برد تا تفکیک‌پذیر خطی شوند.

ما رو توی گوگل بیشتر ببین

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