1669 lines
120 KiB
HTML
1669 lines
120 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
|
||
<html lang="en" data-content_root="./" >
|
||
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
|
||
<title>11. Basic ideas of the Principal Component Analysis (PCA) — Applied Data Analysis and Machine Learning</title>
|
||
|
||
|
||
|
||
<script data-cfasync="false">
|
||
document.documentElement.dataset.mode = localStorage.getItem("mode") || "";
|
||
document.documentElement.dataset.theme = localStorage.getItem("theme") || "";
|
||
</script>
|
||
<!--
|
||
this give us a css class that will be invisible only if js is disabled
|
||
-->
|
||
<noscript>
|
||
<style>
|
||
.pst-js-only { display: none !important; }
|
||
|
||
</style>
|
||
</noscript>
|
||
|
||
<!-- Loaded before other Sphinx assets -->
|
||
<link href="_static/styles/theme.css?digest=26a4bc78f4c0ddb94549" rel="stylesheet" />
|
||
<link href="_static/styles/pydata-sphinx-theme.css?digest=26a4bc78f4c0ddb94549" rel="stylesheet" />
|
||
|
||
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=fa44fd50" />
|
||
<link rel="stylesheet" type="text/css" href="_static/styles/sphinx-book-theme.css?v=a3416100" />
|
||
<link rel="stylesheet" type="text/css" href="_static/togglebutton.css?v=13237357" />
|
||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css?v=76b2166b" />
|
||
<link rel="stylesheet" type="text/css" href="_static/mystnb.4510f1fc1dee50b3e5859aac5469c37c29e427902b24a333a5f9fcb2f0b3ac41.css?v=be8a1c11" />
|
||
<link rel="stylesheet" type="text/css" href="_static/sphinx-thebe.css?v=4fa983c6" />
|
||
<link rel="stylesheet" type="text/css" href="_static/sphinx-design.min.css?v=95c83b7e" />
|
||
|
||
<!-- So that users can add custom icons -->
|
||
<script src="_static/scripts/fontawesome.js?digest=26a4bc78f4c0ddb94549"></script>
|
||
<!-- Pre-loaded scripts that we'll load fully later -->
|
||
<link rel="preload" as="script" href="_static/scripts/bootstrap.js?digest=26a4bc78f4c0ddb94549" />
|
||
<link rel="preload" as="script" href="_static/scripts/pydata-sphinx-theme.js?digest=26a4bc78f4c0ddb94549" />
|
||
|
||
<script src="_static/documentation_options.js?v=9eb32ce0"></script>
|
||
<script src="_static/doctools.js?v=9a2dae69"></script>
|
||
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
|
||
<script src="_static/clipboard.min.js?v=a7894cd8"></script>
|
||
<script src="_static/copybutton.js?v=f281be69"></script>
|
||
<script src="_static/scripts/sphinx-book-theme.js?v=887ef09a"></script>
|
||
<script>let toggleHintShow = 'Click to show';</script>
|
||
<script>let toggleHintHide = 'Click to hide';</script>
|
||
<script>let toggleOpenOnPrint = 'true';</script>
|
||
<script src="_static/togglebutton.js?v=4a39c7ea"></script>
|
||
<script>var togglebuttonSelector = '.toggle, .admonition.dropdown';</script>
|
||
<script src="_static/design-tabs.js?v=f930bc37"></script>
|
||
<script>const THEBE_JS_URL = "https://unpkg.com/thebe@0.8.2/lib/index.js"; const thebe_selector = ".thebe,.cell"; const thebe_selector_input = "pre"; const thebe_selector_output = ".output, .cell_output"</script>
|
||
<script async="async" src="_static/sphinx-thebe.js?v=c100c467"></script>
|
||
<script>var togglebuttonSelector = '.toggle, .admonition.dropdown';</script>
|
||
<script>const THEBE_JS_URL = "https://unpkg.com/thebe@0.8.2/lib/index.js"; const thebe_selector = ".thebe,.cell"; const thebe_selector_input = "pre"; const thebe_selector_output = ".output, .cell_output"</script>
|
||
<script>window.MathJax = {"options": {"processHtmlClass": "tex2jax_process|mathjax_process|math|output_area"}}</script>
|
||
<script defer="defer" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
||
<script>DOCUMENTATION_OPTIONS.pagename = 'chapter8';</script>
|
||
<link rel="index" title="Index" href="genindex.html" />
|
||
<link rel="search" title="Search" href="search.html" />
|
||
<link rel="next" title="12. Clustering and Unsupervised Learning" href="clustering.html" />
|
||
<link rel="prev" title="10. Ensemble Methods: From a Single Tree to Many Trees and Extreme Boosting, Meet the Jungle of Methods" href="chapter7.html" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||
<meta name="docsearch:language" content="en"/>
|
||
<meta name="docsearch:version" content="" />
|
||
</head>
|
||
|
||
|
||
<body data-bs-spy="scroll" data-bs-target=".bd-toc-nav" data-offset="180" data-bs-root-margin="0px 0px -60%" data-default-mode="">
|
||
|
||
|
||
|
||
<div id="pst-skip-link" class="skip-link d-print-none"><a href="#main-content">Skip to main content</a></div>
|
||
|
||
<div id="pst-scroll-pixel-helper"></div>
|
||
|
||
<button type="button" class="btn rounded-pill" id="pst-back-to-top">
|
||
<i class="fa-solid fa-arrow-up"></i>Back to top</button>
|
||
|
||
|
||
<dialog id="pst-search-dialog">
|
||
|
||
<form class="bd-search d-flex align-items-center"
|
||
action="search.html"
|
||
method="get">
|
||
<i class="fa-solid fa-magnifying-glass"></i>
|
||
<input type="search"
|
||
class="form-control"
|
||
name="q"
|
||
placeholder="Search this book..."
|
||
aria-label="Search this book..."
|
||
autocomplete="off"
|
||
autocorrect="off"
|
||
autocapitalize="off"
|
||
spellcheck="false"/>
|
||
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd>K</kbd></span>
|
||
</form>
|
||
</dialog>
|
||
|
||
<div class="pst-async-banner-revealer d-none">
|
||
<aside id="bd-header-version-warning" class="d-none d-print-none" aria-label="Version warning"></aside>
|
||
</div>
|
||
|
||
|
||
<header class="bd-header navbar navbar-expand-lg bd-navbar d-print-none">
|
||
</header>
|
||
|
||
|
||
<div class="bd-container">
|
||
<div class="bd-container__inner bd-page-width">
|
||
|
||
|
||
|
||
<dialog id="pst-primary-sidebar-modal"></dialog>
|
||
<div id="pst-primary-sidebar" class="bd-sidebar-primary bd-sidebar">
|
||
|
||
|
||
|
||
<div class="sidebar-header-items sidebar-primary__section">
|
||
|
||
|
||
|
||
|
||
</div>
|
||
|
||
<div class="sidebar-primary-items__start sidebar-primary__section">
|
||
<div class="sidebar-primary-item">
|
||
|
||
|
||
|
||
|
||
|
||
<a class="navbar-brand logo" href="intro.html">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<img src="_static/logo.png" class="logo__image only-light" alt="Applied Data Analysis and Machine Learning - Home"/>
|
||
<img src="_static/logo.png" class="logo__image only-dark pst-js-only" alt="Applied Data Analysis and Machine Learning - Home"/>
|
||
|
||
|
||
</a></div>
|
||
<div class="sidebar-primary-item">
|
||
|
||
<button class="btn search-button-field search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
|
||
<i class="fa-solid fa-magnifying-glass"></i>
|
||
<span class="search-button__default-text">Search</span>
|
||
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
|
||
</button></div>
|
||
<div class="sidebar-primary-item"><nav class="bd-links bd-docs-nav" aria-label="Main">
|
||
<div class="bd-toc-item navbar-nav active">
|
||
|
||
<ul class="nav bd-sidenav bd-sidenav__home-link">
|
||
<li class="toctree-l1">
|
||
<a class="reference internal" href="intro.html">
|
||
Applied Data Analysis and Machine Learning
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
<p aria-level="2" class="caption" role="heading"><span class="caption-text">About the course</span></p>
|
||
<ul class="nav bd-sidenav">
|
||
<li class="toctree-l1"><a class="reference internal" href="schedule.html">Teaching schedule with links to material</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="teachers.html">Teachers and Grading</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="textbooks.html">Textbooks</a></li>
|
||
|
||
</ul>
|
||
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Review of Statistics with Resampling Techniques and Linear Algebra</span></p>
|
||
<ul class="nav bd-sidenav">
|
||
<li class="toctree-l1"><a class="reference internal" href="statistics.html">1. Elements of Probability Theory and Statistical Data Analysis</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="linalg.html">2. Linear Algebra, Handling of Arrays and more Python Features</a></li>
|
||
</ul>
|
||
<p aria-level="2" class="caption" role="heading"><span class="caption-text">From Regression to Support Vector Machines</span></p>
|
||
<ul class="nav bd-sidenav">
|
||
<li class="toctree-l1"><a class="reference internal" href="chapter1.html">3. Linear Regression</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="chapter2.html">4. Ridge and Lasso Regression</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="chapter3.html">5. Resampling Methods</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="chapter4.html">6. Logistic Regression</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="chapteroptimization.html">7. Optimization, the central part of any Machine Learning algortithm</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="chapter5.html">8. Support Vector Machines, overarching aims</a></li>
|
||
</ul>
|
||
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Decision Trees, Ensemble Methods and Boosting</span></p>
|
||
<ul class="nav bd-sidenav">
|
||
<li class="toctree-l1"><a class="reference internal" href="chapter6.html">9. Decision trees, overarching aims</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="chapter7.html">10. Ensemble Methods: From a Single Tree to Many Trees and Extreme Boosting, Meet the Jungle of Methods</a></li>
|
||
</ul>
|
||
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Dimensionality Reduction</span></p>
|
||
<ul class="current nav bd-sidenav">
|
||
<li class="toctree-l1 current active"><a class="current reference internal" href="#">11. Basic ideas of the Principal Component Analysis (PCA)</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="clustering.html">12. Clustering and Unsupervised Learning</a></li>
|
||
</ul>
|
||
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Deep Learning Methods</span></p>
|
||
<ul class="nav bd-sidenav">
|
||
<li class="toctree-l1"><a class="reference internal" href="chapter9.html">13. Neural networks</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="chapter10.html">14. Building a Feed Forward Neural Network</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="chapter11.html">15. Solving Differential Equations with Deep Learning</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="chapter12.html">16. Convolutional Neural Networks</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="chapter13.html">17. Recurrent neural networks: Overarching view</a></li>
|
||
|
||
</ul>
|
||
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Weekly material, notes and exercises</span></p>
|
||
<ul class="nav bd-sidenav">
|
||
<li class="toctree-l1"><a class="reference internal" href="exercisesweek34.html">Exercises week 34</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="week34.html">Week 34: Introduction to the course, Logistics and Practicalities</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="exercisesweek35.html">Exercises week 35</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="week35.html">Week 35: From Ordinary Linear Regression to Ridge and Lasso Regression</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="exercisesweek36.html">Exercises week 36</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="week36.html">Week 36: Linear Regression and Statistical interpretations</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="exercisesweek37.html">Exercises week 37</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="week37.html">Week 37: Statistical interpretations and Resampling Methods</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="exercisesweek38.html">Exercises week 38</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="week38.html">Week 38: Logistic Regression and Optimization</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="exercisesweek39.html">Exercises week 39</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="week39.html">Week 39: Optimization and Gradient Methods</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="week40.html">Week 40: Gradient descent methods (continued) and start Neural networks</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="exercisesweek41.html">Exercises week 41</a></li>
|
||
|
||
|
||
<li class="toctree-l1"><a class="reference internal" href="week41.html">Week 41 Neural networks and constructing a neural network code</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="exercisesweek42.html">Exercises week 42</a></li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="toctree-l1"><a class="reference internal" href="week42.html">Week 42 Constructing a Neural Network code with examples</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="additionweek42.html">Exercises Week 42: Logistic Regression and Optimization, reminders from week 38 and week 40</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="week43.html">Week 43: Deep Learning: Constructing a Neural Network code and solving differential equations</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="exercisesweek43.html">Exercises week 43</a></li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="toctree-l1"><a class="reference internal" href="week44.html">Week 44, Convolutional Neural Networks (CNN)</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="week45.html">Week 45, Convolutional Neural Networks (CCNs) and Recurrent Neural Networks (RNNs)</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="week46.html">Week 46: Decision Trees, Ensemble methods and Random Forests</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="week47.html">Week 47: From Decision Trees to Ensemble Methods, Random Forests and Boosting Methods</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="exercisesweek47.html">Exercise week 47</a></li>
|
||
|
||
<li class="toctree-l1"><a class="reference internal" href="week48.html">Week 48: Gradient boosting and summary of course</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="exercisesweek48.html">Exercises week 48</a></li>
|
||
|
||
</ul>
|
||
<p aria-level="2" class="caption" role="heading"><span class="caption-text">Projects</span></p>
|
||
<ul class="nav bd-sidenav">
|
||
<li class="toctree-l1"><a class="reference internal" href="project1.html">Project 1 on Machine Learning, deadline October 7 (midnight), 2024</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="project2.html">Project 2 on Machine Learning, deadline November 4 (Midnight)</a></li>
|
||
<li class="toctree-l1"><a class="reference internal" href="project3.html">Project 3 on Machine Learning, deadline December 9 (midnight), 2024</a></li>
|
||
|
||
</ul>
|
||
|
||
</div>
|
||
</nav></div>
|
||
</div>
|
||
|
||
|
||
<div class="sidebar-primary-items__end sidebar-primary__section">
|
||
</div>
|
||
|
||
<div id="rtd-footer-container"></div>
|
||
|
||
|
||
</div>
|
||
|
||
<main id="main-content" class="bd-main" role="main">
|
||
|
||
|
||
|
||
<div class="sbt-scroll-pixel-helper"></div>
|
||
|
||
<div class="bd-content">
|
||
<div class="bd-article-container">
|
||
|
||
<div class="bd-header-article d-print-none">
|
||
<div class="header-article-items header-article__inner">
|
||
|
||
<div class="header-article-items__start">
|
||
|
||
<div class="header-article-item"><button class="sidebar-toggle primary-toggle btn btn-sm" title="Toggle primary sidebar" data-bs-placement="bottom" data-bs-toggle="tooltip">
|
||
<span class="fa-solid fa-bars"></span>
|
||
</button></div>
|
||
|
||
</div>
|
||
|
||
|
||
<div class="header-article-items__end">
|
||
|
||
<div class="header-article-item">
|
||
|
||
<div class="article-header-buttons">
|
||
|
||
|
||
|
||
|
||
|
||
<div class="dropdown dropdown-launch-buttons">
|
||
<button class="btn dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false" aria-label="Launch interactive content">
|
||
<i class="fas fa-rocket"></i>
|
||
</button>
|
||
<ul class="dropdown-menu">
|
||
|
||
|
||
|
||
<li><a href="https://mybinder.org/v2/git/https%3A//compphysics.github.io/MachineLearning/doc/LectureNotes/_build/html/index.html/master?urlpath=tree/chapter8.ipynb" target="_blank"
|
||
class="btn btn-sm dropdown-item"
|
||
title="Launch on Binder"
|
||
data-bs-placement="left" data-bs-toggle="tooltip"
|
||
>
|
||
|
||
|
||
<span class="btn__icon-container">
|
||
|
||
<img alt="Binder logo" src="_static/images/logo_binder.svg">
|
||
</span>
|
||
<span class="btn__text-container">Binder</span>
|
||
</a>
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<div class="dropdown dropdown-download-buttons">
|
||
<button class="btn dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false" aria-label="Download this page">
|
||
<i class="fas fa-download"></i>
|
||
</button>
|
||
<ul class="dropdown-menu">
|
||
|
||
|
||
|
||
<li><a href="_sources/chapter8.ipynb" target="_blank"
|
||
class="btn btn-sm btn-download-source-button dropdown-item"
|
||
title="Download source file"
|
||
data-bs-placement="left" data-bs-toggle="tooltip"
|
||
>
|
||
|
||
|
||
<span class="btn__icon-container">
|
||
<i class="fas fa-file"></i>
|
||
</span>
|
||
<span class="btn__text-container">.ipynb</span>
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
<li>
|
||
<button onclick="window.print()"
|
||
class="btn btn-sm btn-download-pdf-button dropdown-item"
|
||
title="Print to PDF"
|
||
data-bs-placement="left" data-bs-toggle="tooltip"
|
||
>
|
||
|
||
|
||
<span class="btn__icon-container">
|
||
<i class="fas fa-file-pdf"></i>
|
||
</span>
|
||
<span class="btn__text-container">.pdf</span>
|
||
</button>
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
<button onclick="toggleFullScreen()"
|
||
class="btn btn-sm btn-fullscreen-button"
|
||
title="Fullscreen mode"
|
||
data-bs-placement="bottom" data-bs-toggle="tooltip"
|
||
>
|
||
|
||
|
||
<span class="btn__icon-container">
|
||
<i class="fas fa-expand"></i>
|
||
</span>
|
||
|
||
</button>
|
||
|
||
|
||
|
||
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button pst-js-only" aria-label="Color mode" data-bs-title="Color mode" data-bs-placement="bottom" data-bs-toggle="tooltip">
|
||
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light" title="Light"></i>
|
||
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark" title="Dark"></i>
|
||
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto" title="System Settings"></i>
|
||
</button>
|
||
|
||
|
||
<button class="btn btn-sm pst-navbar-icon search-button search-button__button pst-js-only" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
|
||
<i class="fa-solid fa-magnifying-glass fa-lg"></i>
|
||
</button>
|
||
<button class="sidebar-toggle secondary-toggle btn btn-sm" title="Toggle secondary sidebar" data-bs-placement="bottom" data-bs-toggle="tooltip">
|
||
<span class="fa-solid fa-list"></span>
|
||
</button>
|
||
</div></div>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div id="jb-print-docs-body" class="onlyprint">
|
||
<h1>Basic ideas of the Principal Component Analysis (PCA)</h1>
|
||
<!-- Table of contents -->
|
||
<div id="print-main-content">
|
||
<div id="jb-print-toc">
|
||
|
||
<div>
|
||
<h2> Contents </h2>
|
||
</div>
|
||
<nav aria-label="Page">
|
||
<ul class="visible nav section-nav flex-column">
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#introducing-the-covariance-and-correlation-functions">11.1. Introducing the Covariance and Correlation functions</a></li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#correlation-matrix">11.2. Correlation Matrix</a></li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#towards-the-pca-theorem">11.3. Towards the PCA theorem</a><ul class="nav section-nav flex-column">
|
||
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#the-algorithm-before-theorem">11.3.1. The Algorithm before theorem</a></li>
|
||
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#writing-our-own-pca-code">11.3.2. Writing our own PCA code</a></li>
|
||
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#diagonalize-the-sample-covariance-matrix-to-obtain-the-principal-components">11.3.3. Diagonalize the sample covariance matrix to obtain the principal components</a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#classical-pca-theorem">11.4. Classical PCA Theorem</a></li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#geometric-interpretation-and-link-with-singular-value-decomposition">11.5. Geometric Interpretation and link with Singular Value Decomposition</a></li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#pca-and-scikit-learn">11.6. PCA and scikit-learn</a></li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#back-to-the-cancer-data">11.7. Back to the Cancer Data</a><ul class="nav section-nav flex-column">
|
||
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#incremental-pca">11.7.1. Incremental PCA</a></li>
|
||
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#randomized-pca">11.7.2. Randomized PCA</a></li>
|
||
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#kernel-pca">11.7.3. Kernel PCA</a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#other-techniques">11.8. Other techniques</a></li>
|
||
</ul>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div id="searchbox"></div>
|
||
<article class="bd-article">
|
||
|
||
<section class="tex2jax_ignore mathjax_ignore" id="basic-ideas-of-the-principal-component-analysis-pca">
|
||
<h1><span class="section-number">11. </span>Basic ideas of the Principal Component Analysis (PCA)<a class="headerlink" href="#basic-ideas-of-the-principal-component-analysis-pca" title="Link to this heading">#</a></h1>
|
||
<p>The principal component analysis deals with the problem of fitting a
|
||
low-dimensional affine subspace <span class="math notranslate nohighlight">\(S\)</span> of dimension <span class="math notranslate nohighlight">\(d\)</span> much smaller than
|
||
the total dimension <span class="math notranslate nohighlight">\(D\)</span> of the problem at hand (our data
|
||
set). Mathematically it can be formulated as a statistical problem or
|
||
a geometric problem. In our discussion of the theorem for the
|
||
classical PCA, we will stay with a statistical approach.
|
||
Historically, the PCA was first formulated in a statistical setting in order to estimate the principal component of a multivariate random variable.</p>
|
||
<p>We have a data set defined by a design/feature matrix <span class="math notranslate nohighlight">\(\boldsymbol{X}\)</span> (see below for its definition)</p>
|
||
<ul class="simple">
|
||
<li><p>Each data point is determined by <span class="math notranslate nohighlight">\(p\)</span> extrinsic (measurement) variables</p></li>
|
||
<li><p>We may want to ask the following question: Are there fewer intrinsic variables (say <span class="math notranslate nohighlight">\(d << p\)</span>) that still approximately describe the data?</p></li>
|
||
<li><p>If so, these intrinsic variables may tell us something important and finding these intrinsic variables is what dimension reduction methods do.</p></li>
|
||
</ul>
|
||
<p>A good read is for example <a class="reference external" href="https://www.springer.com/gp/book/9780387878102">Vidal, Ma and Sastry</a>.</p>
|
||
<section id="introducing-the-covariance-and-correlation-functions">
|
||
<h2><span class="section-number">11.1. </span>Introducing the Covariance and Correlation functions<a class="headerlink" href="#introducing-the-covariance-and-correlation-functions" title="Link to this heading">#</a></h2>
|
||
<p>Before we discuss the PCA theorem, we need to remind ourselves about
|
||
the definition of the covariance and the correlation function. These are quantities</p>
|
||
<p>Suppose we have defined two vectors
|
||
<span class="math notranslate nohighlight">\(\hat{x}\)</span> and <span class="math notranslate nohighlight">\(\hat{y}\)</span> with <span class="math notranslate nohighlight">\(n\)</span> elements each. The covariance matrix <span class="math notranslate nohighlight">\(\boldsymbol{C}\)</span> is defined as</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[\begin{split}
|
||
\boldsymbol{C}[\boldsymbol{x},\boldsymbol{y}] = \begin{bmatrix} \mathrm{cov}[\boldsymbol{x},\boldsymbol{x}] & \mathrm{cov}[\boldsymbol{x},\boldsymbol{y}] \\
|
||
\mathrm{cov}[\boldsymbol{y},\boldsymbol{x}] & \mathrm{cov}[\boldsymbol{y},\boldsymbol{y}] \\
|
||
\end{bmatrix},
|
||
\end{split}\]</div>
|
||
<p>where for example</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\mathrm{cov}[\boldsymbol{x},\boldsymbol{y}] =\frac{1}{n} \sum_{i=0}^{n-1}(x_i- \overline{x})(y_i- \overline{y}).
|
||
\]</div>
|
||
<p>With this definition and recalling that the variance is defined as</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\mathrm{var}[\boldsymbol{x}]=\frac{1}{n} \sum_{i=0}^{n-1}(x_i- \overline{x})^2,
|
||
\]</div>
|
||
<p>we can rewrite the covariance matrix as</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[\begin{split}
|
||
\boldsymbol{C}[\boldsymbol{x},\boldsymbol{y}] = \begin{bmatrix} \mathrm{var}[\boldsymbol{x}] & \mathrm{cov}[\boldsymbol{x},\boldsymbol{y}] \\
|
||
\mathrm{cov}[\boldsymbol{x},\boldsymbol{y}] & \mathrm{var}[\boldsymbol{y}] \\
|
||
\end{bmatrix}.
|
||
\end{split}\]</div>
|
||
<p>The covariance takes values between zero and infinity and may thus
|
||
lead to problems with loss of numerical precision for particularly
|
||
large values. It is common to scale the covariance matrix by
|
||
introducing instead the correlation matrix defined via the so-called
|
||
correlation function</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\mathrm{corr}[\boldsymbol{x},\boldsymbol{y}]=\frac{\mathrm{cov}[\boldsymbol{x},\boldsymbol{y}]}{\sqrt{\mathrm{var}[\boldsymbol{x}] \mathrm{var}[\boldsymbol{y}]}}.
|
||
\]</div>
|
||
<p>The correlation function is then given by values <span class="math notranslate nohighlight">\(\mathrm{corr}[\boldsymbol{x},\boldsymbol{y}]
|
||
\in [-1,1]\)</span>. This avoids eventual problems with too large values. We
|
||
can then define the correlation matrix for the two vectors <span class="math notranslate nohighlight">\(\boldsymbol{x}\)</span>
|
||
and <span class="math notranslate nohighlight">\(\boldsymbol{y}\)</span> as</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[\begin{split}
|
||
\boldsymbol{K}[\boldsymbol{x},\boldsymbol{y}] = \begin{bmatrix} 1 & \mathrm{corr}[\boldsymbol{x},\boldsymbol{y}] \\
|
||
\mathrm{corr}[\boldsymbol{y},\boldsymbol{x}] & 1 \\
|
||
\end{bmatrix},
|
||
\end{split}\]</div>
|
||
<p>In the above example this is the function we constructed using <strong>pandas</strong>.</p>
|
||
<p>In our derivation of the various regression algorithms like <strong>Ordinary Least Squares</strong> or <strong>Ridge regression</strong>
|
||
we defined the design/feature matrix <span class="math notranslate nohighlight">\(\boldsymbol{X}\)</span> as</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[\begin{split}
|
||
\boldsymbol{X}=\begin{bmatrix}
|
||
x_{0,0} & x_{0,1} & x_{0,2}& \dots & \dots x_{0,p-1}\\
|
||
x_{1,0} & x_{1,1} & x_{1,2}& \dots & \dots x_{1,p-1}\\
|
||
x_{2,0} & x_{2,1} & x_{2,2}& \dots & \dots x_{2,p-1}\\
|
||
\dots & \dots & \dots & \dots \dots & \dots \\
|
||
x_{n-2,0} & x_{n-2,1} & x_{n-2,2}& \dots & \dots x_{n-2,p-1}\\
|
||
x_{n-1,0} & x_{n-1,1} & x_{n-1,2}& \dots & \dots x_{n-1,p-1}\\
|
||
\end{bmatrix},
|
||
\end{split}\]</div>
|
||
<p>with <span class="math notranslate nohighlight">\(\boldsymbol{X}\in {\mathbb{R}}^{n\times p}\)</span>, with the predictors/features <span class="math notranslate nohighlight">\(p\)</span> refering to the column numbers and the
|
||
entries <span class="math notranslate nohighlight">\(n\)</span> being the row elements.
|
||
We can rewrite the design/feature matrix in terms of its column vectors as</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\boldsymbol{X}=\begin{bmatrix} \boldsymbol{x}_0 & \boldsymbol{x}_1 & \boldsymbol{x}_2 & \dots & \dots & \boldsymbol{x}_{p-1}\end{bmatrix},
|
||
\]</div>
|
||
<p>with a given vector</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\boldsymbol{x}_i^T = \begin{bmatrix}x_{0,i} & x_{1,i} & x_{2,i}& \dots & \dots x_{n-1,i}\end{bmatrix}.
|
||
\]</div>
|
||
<p>With these definitions, we can now rewrite our <span class="math notranslate nohighlight">\(2\times 2\)</span>
|
||
correaltion/covariance matrix in terms of a moe general design/feature
|
||
matrix <span class="math notranslate nohighlight">\(\boldsymbol{X}\in {\mathbb{R}}^{n\times p}\)</span>. This leads to a <span class="math notranslate nohighlight">\(p\times p\)</span>
|
||
covariance matrix for the vectors <span class="math notranslate nohighlight">\(\boldsymbol{x}_i\)</span> with <span class="math notranslate nohighlight">\(i=0,1,\dots,p-1\)</span></p>
|
||
<div class="math notranslate nohighlight">
|
||
\[\begin{split}
|
||
\boldsymbol{C}[\boldsymbol{x}] = \begin{bmatrix}
|
||
\mathrm{var}[\boldsymbol{x}_0] & \mathrm{cov}[\boldsymbol{x}_0,\boldsymbol{x}_1] & \mathrm{cov}[\boldsymbol{x}_0,\boldsymbol{x}_2] & \dots & \dots & \mathrm{cov}[\boldsymbol{x}_0,\boldsymbol{x}_{p-1}]\\
|
||
\mathrm{cov}[\boldsymbol{x}_1,\boldsymbol{x}_0] & \mathrm{var}[\boldsymbol{x}_1] & \mathrm{cov}[\boldsymbol{x}_1,\boldsymbol{x}_2] & \dots & \dots & \mathrm{cov}[\boldsymbol{x}_1,\boldsymbol{x}_{p-1}]\\
|
||
\mathrm{cov}[\boldsymbol{x}_2,\boldsymbol{x}_0] & \mathrm{cov}[\boldsymbol{x}_2,\boldsymbol{x}_1] & \mathrm{var}[\boldsymbol{x}_2] & \dots & \dots & \mathrm{cov}[\boldsymbol{x}_2,\boldsymbol{x}_{p-1}]\\
|
||
\dots & \dots & \dots & \dots & \dots & \dots \\
|
||
\dots & \dots & \dots & \dots & \dots & \dots \\
|
||
\mathrm{cov}[\boldsymbol{x}_{p-1},\boldsymbol{x}_0] & \mathrm{cov}[\boldsymbol{x}_{p-1},\boldsymbol{x}_1] & \mathrm{cov}[\boldsymbol{x}_{p-1},\boldsymbol{x}_{2}] & \dots & \dots & \mathrm{var}[\boldsymbol{x}_{p-1}]\\
|
||
\end{bmatrix},
|
||
\end{split}\]</div>
|
||
<p>and the correlation matrix</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[\begin{split}
|
||
\boldsymbol{K}[\boldsymbol{x}] = \begin{bmatrix}
|
||
1 & \mathrm{corr}[\boldsymbol{x}_0,\boldsymbol{x}_1] & \mathrm{corr}[\boldsymbol{x}_0,\boldsymbol{x}_2] & \dots & \dots & \mathrm{corr}[\boldsymbol{x}_0,\boldsymbol{x}_{p-1}]\\
|
||
\mathrm{corr}[\boldsymbol{x}_1,\boldsymbol{x}_0] & 1 & \mathrm{corr}[\boldsymbol{x}_1,\boldsymbol{x}_2] & \dots & \dots & \mathrm{corr}[\boldsymbol{x}_1,\boldsymbol{x}_{p-1}]\\
|
||
\mathrm{corr}[\boldsymbol{x}_2,\boldsymbol{x}_0] & \mathrm{corr}[\boldsymbol{x}_2,\boldsymbol{x}_1] & 1 & \dots & \dots & \mathrm{corr}[\boldsymbol{x}_2,\boldsymbol{x}_{p-1}]\\
|
||
\dots & \dots & \dots & \dots & \dots & \dots \\
|
||
\dots & \dots & \dots & \dots & \dots & \dots \\
|
||
\mathrm{corr}[\boldsymbol{x}_{p-1},\boldsymbol{x}_0] & \mathrm{corr}[\boldsymbol{x}_{p-1},\boldsymbol{x}_1] & \mathrm{corr}[\boldsymbol{x}_{p-1},\boldsymbol{x}_{2}] & \dots & \dots & 1\\
|
||
\end{bmatrix},
|
||
\end{split}\]</div>
|
||
<p>The Numpy function <strong>np.cov</strong> calculates the covariance elements using
|
||
the factor <span class="math notranslate nohighlight">\(1/(n-1)\)</span> instead of <span class="math notranslate nohighlight">\(1/n\)</span> since it assumes we do not have
|
||
the exact mean values. The following simple function uses the
|
||
<strong>np.vstack</strong> function which takes each vector of dimension <span class="math notranslate nohighlight">\(1\times n\)</span>
|
||
and produces a <span class="math notranslate nohighlight">\(2\times n\)</span> matrix <span class="math notranslate nohighlight">\(\boldsymbol{W}\)</span></p>
|
||
<div class="math notranslate nohighlight">
|
||
\[\begin{split}
|
||
\boldsymbol{W} = \begin{bmatrix} x_0 & y_0 \\
|
||
x_1 & y_1 \\
|
||
x_2 & y_2\\
|
||
\dots & \dots \\
|
||
x_{n-2} & y_{n-2}\\
|
||
x_{n-1} & y_{n-1} &
|
||
\end{bmatrix},
|
||
\end{split}\]</div>
|
||
<p>which in turn is converted into into the <span class="math notranslate nohighlight">\(2\times 2\)</span> covariance matrix
|
||
<span class="math notranslate nohighlight">\(\boldsymbol{C}\)</span> via the Numpy function <strong>np.cov()</strong>. We note that we can also calculate
|
||
the mean value of each set of samples <span class="math notranslate nohighlight">\(\boldsymbol{x}\)</span> etc using the Numpy
|
||
function <strong>np.mean(x)</strong>. We can also extract the eigenvalues of the
|
||
covariance matrix through the <strong>np.linalg.eig()</strong> function.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="c1"># Importing various packages</span>
|
||
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
|
||
<span class="n">n</span> <span class="o">=</span> <span class="mi">100</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">normal</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="n">n</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="mi">4</span><span class="o">+</span><span class="mi">3</span><span class="o">*</span><span class="n">x</span><span class="o">+</span><span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">normal</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="n">n</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">y</span><span class="p">))</span>
|
||
<span class="n">W</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">vstack</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">))</span>
|
||
<span class="n">C</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">cov</span><span class="p">(</span><span class="n">W</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">C</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>-0.02745698767039481
|
||
3.9527157086177156
|
||
[[0.80249705 2.35440603]
|
||
[2.35440603 7.83541057]]
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<section id="correlation-matrix">
|
||
<h2><span class="section-number">11.2. </span>Correlation Matrix<a class="headerlink" href="#correlation-matrix" title="Link to this heading">#</a></h2>
|
||
<p>The previous example can be converted into the correlation matrix by
|
||
simply scaling the matrix elements with the variances. We should also
|
||
subtract the mean values for each column. This leads to the following
|
||
code which sets up the correlations matrix for the previous example in
|
||
a more brute force way. Here we scale the mean values for each column of the design matrix, calculate the relevant mean values and variances and then finally set up the <span class="math notranslate nohighlight">\(2\times 2\)</span> correlation matrix (since we have only two vectors).</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
|
||
<span class="n">n</span> <span class="o">=</span> <span class="mi">100</span>
|
||
<span class="c1"># define two vectors </span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="n">n</span><span class="p">)</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="mi">4</span><span class="o">+</span><span class="mi">3</span><span class="o">*</span><span class="n">x</span><span class="o">+</span><span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">normal</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="n">n</span><span class="p">)</span>
|
||
<span class="c1">#scaling the x and y vectors </span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="n">x</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="n">y</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
|
||
<span class="n">variance_x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">x</span><span class="nd">@x</span><span class="p">)</span><span class="o">/</span><span class="n">n</span>
|
||
<span class="n">variance_y</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">y</span><span class="nd">@y</span><span class="p">)</span><span class="o">/</span><span class="n">n</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">variance_x</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">variance_y</span><span class="p">)</span>
|
||
<span class="n">cov_xy</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">x</span><span class="nd">@y</span><span class="p">)</span><span class="o">/</span><span class="n">n</span>
|
||
<span class="n">cov_xx</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">x</span><span class="nd">@x</span><span class="p">)</span><span class="o">/</span><span class="n">n</span>
|
||
<span class="n">cov_yy</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">y</span><span class="nd">@y</span><span class="p">)</span><span class="o">/</span><span class="n">n</span>
|
||
<span class="n">C</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">))</span>
|
||
<span class="n">C</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span><span class="o">=</span> <span class="n">cov_xx</span><span class="o">/</span><span class="n">variance_x</span>
|
||
<span class="n">C</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span> <span class="n">cov_yy</span><span class="o">/</span><span class="n">variance_y</span>
|
||
<span class="n">C</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">]</span><span class="o">=</span> <span class="n">cov_xy</span><span class="o">/</span><span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">variance_y</span><span class="o">*</span><span class="n">variance_x</span><span class="p">)</span>
|
||
<span class="n">C</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span><span class="o">=</span> <span class="n">C</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">]</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">C</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>0.07408022521552643
|
||
1.9519435372439522
|
||
[[1. 0.56323995]
|
||
[0.56323995 1. ]]
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>We see that the matrix elements along the diagonal are one as they
|
||
should be and that the matrix is symmetric. Furthermore, diagonalizing
|
||
this matrix we easily see that it is a positive definite matrix.</p>
|
||
<p>The above procedure with <strong>numpy</strong> can be made more compact if we use <strong>pandas</strong>.</p>
|
||
<p>We whow here how we can set up the correlation matrix using <strong>pandas</strong>, as done in this simple code</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
|
||
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
|
||
<span class="n">n</span> <span class="o">=</span> <span class="mi">10</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">normal</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="n">n</span><span class="p">)</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="n">x</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="mi">4</span><span class="o">+</span><span class="mi">3</span><span class="o">*</span><span class="n">x</span><span class="o">+</span><span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">normal</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="n">n</span><span class="p">)</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="n">y</span> <span class="o">-</span> <span class="n">np</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
|
||
<span class="n">X</span> <span class="o">=</span> <span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">vstack</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)))</span><span class="o">.</span><span class="n">T</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
|
||
<span class="n">Xpd</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">Xpd</span><span class="p">)</span>
|
||
<span class="n">correlation_matrix</span> <span class="o">=</span> <span class="n">Xpd</span><span class="o">.</span><span class="n">corr</span><span class="p">()</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">correlation_matrix</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>[[ 0.53340467 1.72530188]
|
||
[-0.56167889 -3.2544002 ]
|
||
[ 1.85988539 5.87145508]
|
||
[-1.23561281 -4.57354138]
|
||
[ 0.52739566 0.93489572]
|
||
[ 0.89775088 2.87036267]
|
||
[-0.71834014 -0.65667853]
|
||
[ 0.38699758 1.30537358]
|
||
[-1.48772565 -3.9664681 ]
|
||
[-0.20207669 -0.25630072]]
|
||
0 1
|
||
0 0.533405 1.725302
|
||
1 -0.561679 -3.254400
|
||
2 1.859885 5.871455
|
||
3 -1.235613 -4.573541
|
||
4 0.527396 0.934896
|
||
5 0.897751 2.870363
|
||
6 -0.718340 -0.656679
|
||
7 0.386998 1.305374
|
||
8 -1.487726 -3.966468
|
||
9 -0.202077 -0.256301
|
||
0 1
|
||
0 1.000000 0.966262
|
||
1 0.966262 1.000000
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>We expand this model to the Franke function discussed above.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="c1"># Common imports</span>
|
||
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
|
||
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
|
||
|
||
|
||
<span class="k">def</span> <span class="nf">FrankeFunction</span><span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">):</span>
|
||
<span class="n">term1</span> <span class="o">=</span> <span class="mf">0.75</span><span class="o">*</span><span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="p">(</span><span class="mf">0.25</span><span class="o">*</span><span class="p">(</span><span class="mi">9</span><span class="o">*</span><span class="n">x</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span> <span class="o">-</span> <span class="mf">0.25</span><span class="o">*</span><span class="p">((</span><span class="mi">9</span><span class="o">*</span><span class="n">y</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span>
|
||
<span class="n">term2</span> <span class="o">=</span> <span class="mf">0.75</span><span class="o">*</span><span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="p">((</span><span class="mi">9</span><span class="o">*</span><span class="n">x</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span><span class="o">/</span><span class="mf">49.0</span> <span class="o">-</span> <span class="mf">0.1</span><span class="o">*</span><span class="p">(</span><span class="mi">9</span><span class="o">*</span><span class="n">y</span><span class="o">+</span><span class="mi">1</span><span class="p">))</span>
|
||
<span class="n">term3</span> <span class="o">=</span> <span class="mf">0.5</span><span class="o">*</span><span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="p">(</span><span class="mi">9</span><span class="o">*</span><span class="n">x</span><span class="o">-</span><span class="mi">7</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="o">/</span><span class="mf">4.0</span> <span class="o">-</span> <span class="mf">0.25</span><span class="o">*</span><span class="p">((</span><span class="mi">9</span><span class="o">*</span><span class="n">y</span><span class="o">-</span><span class="mi">3</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="p">))</span>
|
||
<span class="n">term4</span> <span class="o">=</span> <span class="o">-</span><span class="mf">0.2</span><span class="o">*</span><span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="o">-</span><span class="p">(</span><span class="mi">9</span><span class="o">*</span><span class="n">x</span><span class="o">-</span><span class="mi">4</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span> <span class="o">-</span> <span class="p">(</span><span class="mi">9</span><span class="o">*</span><span class="n">y</span><span class="o">-</span><span class="mi">7</span><span class="p">)</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">term1</span> <span class="o">+</span> <span class="n">term2</span> <span class="o">+</span> <span class="n">term3</span> <span class="o">+</span> <span class="n">term4</span>
|
||
|
||
|
||
<span class="k">def</span> <span class="nf">create_X</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">n</span> <span class="p">):</span>
|
||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">shape</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">ravel</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">ravel</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
|
||
|
||
<span class="n">N</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
|
||
<span class="n">l</span> <span class="o">=</span> <span class="nb">int</span><span class="p">((</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">n</span><span class="o">+</span><span class="mi">2</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span> <span class="c1"># Number of elements in beta</span>
|
||
<span class="n">X</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">ones</span><span class="p">((</span><span class="n">N</span><span class="p">,</span><span class="n">l</span><span class="p">))</span>
|
||
|
||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="p">):</span>
|
||
<span class="n">q</span> <span class="o">=</span> <span class="nb">int</span><span class="p">((</span><span class="n">i</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span>
|
||
<span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">):</span>
|
||
<span class="n">X</span><span class="p">[:,</span><span class="n">q</span><span class="o">+</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">x</span><span class="o">**</span><span class="p">(</span><span class="n">i</span><span class="o">-</span><span class="n">k</span><span class="p">))</span><span class="o">*</span><span class="p">(</span><span class="n">y</span><span class="o">**</span><span class="n">k</span><span class="p">)</span>
|
||
|
||
<span class="k">return</span> <span class="n">X</span>
|
||
|
||
|
||
<span class="c1"># Making meshgrid of datapoints and compute Franke's function</span>
|
||
<span class="n">n</span> <span class="o">=</span> <span class="mi">4</span>
|
||
<span class="n">N</span> <span class="o">=</span> <span class="mi">100</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="p">))</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="p">))</span>
|
||
<span class="n">z</span> <span class="o">=</span> <span class="n">FrankeFunction</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||
<span class="n">X</span> <span class="o">=</span> <span class="n">create_X</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">n</span><span class="o">=</span><span class="n">n</span><span class="p">)</span>
|
||
|
||
<span class="n">Xpd</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
|
||
<span class="c1"># subtract the mean values and set up the covariance matrix</span>
|
||
<span class="n">Xpd</span> <span class="o">=</span> <span class="n">Xpd</span> <span class="o">-</span> <span class="n">Xpd</span><span class="o">.</span><span class="n">mean</span><span class="p">()</span>
|
||
<span class="n">covariance_matrix</span> <span class="o">=</span> <span class="n">Xpd</span><span class="o">.</span><span class="n">cov</span><span class="p">()</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">covariance_matrix</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span> 0 1 2 3 4 5 6 7 \
|
||
0 0.0 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
|
||
1 0.0 0.073438 0.077471 0.075458 0.076186 0.076594 0.069080 0.068939
|
||
2 0.0 0.077471 0.083242 0.080919 0.082408 0.083412 0.074516 0.074729
|
||
3 0.0 0.075458 0.080919 0.083069 0.084410 0.085279 0.079308 0.079408
|
||
4 0.0 0.076186 0.082408 0.084410 0.086139 0.087327 0.080792 0.081105
|
||
5 0.0 0.076594 0.083412 0.085279 0.087327 0.088786 0.081792 0.082290
|
||
6 0.0 0.069080 0.074516 0.079308 0.080792 0.081792 0.077847 0.078070
|
||
7 0.0 0.068939 0.074729 0.079408 0.081105 0.082290 0.078070 0.078429
|
||
8 0.0 0.068716 0.074791 0.079363 0.081242 0.082589 0.078134 0.078618
|
||
9 0.0 0.068441 0.074753 0.079219 0.081258 0.082750 0.078091 0.078687
|
||
10 0.0 0.061939 0.066921 0.073159 0.074603 0.075599 0.073240 0.073520
|
||
11 0.0 0.061580 0.066741 0.072883 0.074456 0.075571 0.073054 0.073431
|
||
12 0.0 0.061213 0.066524 0.072574 0.074264 0.075487 0.072829 0.073296
|
||
13 0.0 0.060849 0.066290 0.072252 0.074047 0.075371 0.072584 0.073135
|
||
14 0.0 0.060497 0.066053 0.071930 0.073822 0.075239 0.072334 0.072965
|
||
|
||
8 9 10 11 12 13 14
|
||
0 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
|
||
1 0.068716 0.068441 0.061939 0.061580 0.061213 0.060849 0.060497
|
||
2 0.074791 0.074753 0.066921 0.066741 0.066524 0.066290 0.066053
|
||
3 0.079363 0.079219 0.073159 0.072883 0.072574 0.072252 0.071930
|
||
4 0.081242 0.081258 0.074603 0.074456 0.074264 0.074047 0.073822
|
||
5 0.082589 0.082750 0.075599 0.075571 0.075487 0.075371 0.075239
|
||
6 0.078134 0.078091 0.073240 0.073054 0.072829 0.072584 0.072334
|
||
7 0.078618 0.078687 0.073520 0.073431 0.073296 0.073135 0.072965
|
||
8 0.078919 0.079094 0.073650 0.073652 0.073602 0.073523 0.073430
|
||
9 0.079094 0.079368 0.073677 0.073765 0.073796 0.073795 0.073777
|
||
10 0.073650 0.073677 0.069911 0.069801 0.069653 0.069484 0.069308
|
||
11 0.073652 0.073765 0.069801 0.069768 0.069692 0.069593 0.069484
|
||
12 0.073602 0.073796 0.069653 0.069692 0.069686 0.069654 0.069611
|
||
13 0.073523 0.073795 0.069484 0.069593 0.069654 0.069688 0.069709
|
||
14 0.073430 0.073777 0.069308 0.069484 0.069611 0.069709 0.069791
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>We note here that the covariance is zero for the first rows and
|
||
columns since all matrix elements in the design matrix were set to one
|
||
(we are fitting the function in terms of a polynomial of degree <span class="math notranslate nohighlight">\(n\)</span>). We would however not include the intercept
|
||
and wee can simply
|
||
drop these elements and construct a correlation
|
||
matrix without them.</p>
|
||
<p>We can rewrite the covariance matrix in a more compact form in terms of the design/feature matrix <span class="math notranslate nohighlight">\(\boldsymbol{X}\)</span> as</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\boldsymbol{C}[\boldsymbol{x}] = \frac{1}{n}\boldsymbol{X}^T\boldsymbol{X}= \mathbb{E}[\boldsymbol{X}^T\boldsymbol{X}].
|
||
\]</div>
|
||
<p>To see this let us simply look at a design matrix <span class="math notranslate nohighlight">\(\boldsymbol{X}\in {\mathbb{R}}^{2\times 2}\)</span></p>
|
||
<div class="math notranslate nohighlight">
|
||
\[\begin{split}
|
||
\boldsymbol{X}=\begin{bmatrix}
|
||
x_{00} & x_{01}\\
|
||
x_{10} & x_{11}\\
|
||
\end{bmatrix}=\begin{bmatrix}
|
||
\boldsymbol{x}_{0} & \boldsymbol{x}_{1}\\
|
||
\end{bmatrix}.
|
||
\end{split}\]</div>
|
||
<p>If we then compute the expectation value</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[\begin{split}
|
||
\mathbb{E}[\boldsymbol{X}^T\boldsymbol{X}] = \frac{1}{n}\boldsymbol{X}^T\boldsymbol{X}=\begin{bmatrix}
|
||
x_{00}^2+x_{01}^2 & x_{00}x_{10}+x_{01}x_{11}\\
|
||
x_{10}x_{00}+x_{11}x_{01} & x_{10}^2+x_{11}^2\\
|
||
\end{bmatrix},
|
||
\end{split}\]</div>
|
||
<p>which is just</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[\begin{split}
|
||
\boldsymbol{C}[\boldsymbol{x}_0,\boldsymbol{x}_1] = \boldsymbol{C}[\boldsymbol{x}]=\begin{bmatrix} \mathrm{var}[\boldsymbol{x}_0] & \mathrm{cov}[\boldsymbol{x}_0,\boldsymbol{x}_1] \\
|
||
\mathrm{cov}[\boldsymbol{x}_1,\boldsymbol{x}_0] & \mathrm{var}[\boldsymbol{x}_1] \\
|
||
\end{bmatrix},
|
||
\end{split}\]</div>
|
||
<p>where we wrote $<span class="math notranslate nohighlight">\(\boldsymbol{C}[\boldsymbol{x}_0,\boldsymbol{x}_1] = \boldsymbol{C}[\boldsymbol{x}]\)</span><span class="math notranslate nohighlight">\( to indicate that this the covariance of the vectors \)</span>\boldsymbol{x}<span class="math notranslate nohighlight">\( of the design/feature matrix \)</span>\boldsymbol{X}$.</p>
|
||
<p>It is easy to generalize this to a matrix <span class="math notranslate nohighlight">\(\boldsymbol{X}\in {\mathbb{R}}^{n\times p}\)</span>.</p>
|
||
</section>
|
||
<section id="towards-the-pca-theorem">
|
||
<h2><span class="section-number">11.3. </span>Towards the PCA theorem<a class="headerlink" href="#towards-the-pca-theorem" title="Link to this heading">#</a></h2>
|
||
<p>We have that the covariance matrix (the correlation matrix involves a simple rescaling) is given as</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\boldsymbol{C}[\boldsymbol{x}] = \frac{1}{n}\boldsymbol{X}^T\boldsymbol{X}= \mathbb{E}[\boldsymbol{X}^T\boldsymbol{X}].
|
||
\]</div>
|
||
<p>Let us now assume that we can perform a series of orthogonal transformations where we employ some orthogonal matrices <span class="math notranslate nohighlight">\(\boldsymbol{S}\)</span>.
|
||
These matrices are defined as <span class="math notranslate nohighlight">\(\boldsymbol{S}\in {\mathbb{R}}^{p\times p}\)</span> and obey the orthogonality requirements <span class="math notranslate nohighlight">\(\boldsymbol{S}\boldsymbol{S}^T=\boldsymbol{S}^T\boldsymbol{S}=\boldsymbol{I}\)</span>. The matrix can be written out in terms of the column vectors <span class="math notranslate nohighlight">\(\boldsymbol{s}_i\)</span> as <span class="math notranslate nohighlight">\(\boldsymbol{S}=[\boldsymbol{s}_0,\boldsymbol{s}_1,\dots,\boldsymbol{s}_{p-1}]\)</span> and <span class="math notranslate nohighlight">\(\boldsymbol{s}_i \in {\mathbb{R}}^{p}\)</span>.</p>
|
||
<p>Assume also that there is a transformation <span class="math notranslate nohighlight">\(\boldsymbol{S}^T\boldsymbol{C}[\boldsymbol{x}]\boldsymbol{S}=\boldsymbol{C}[\boldsymbol{y}]\)</span> such that the new matrix <span class="math notranslate nohighlight">\(\boldsymbol{C}[\boldsymbol{y}]\)</span> is diagonal with elements <span class="math notranslate nohighlight">\([\lambda_0,\lambda_1,\lambda_2,\dots,\lambda_{p-1}]\)</span>.</p>
|
||
<p>That is we have</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\boldsymbol{C}[\boldsymbol{y}] = \mathbb{E}[\boldsymbol{S}^T\boldsymbol{X}^T\boldsymbol{X}T\boldsymbol{S}]=\boldsymbol{S}^T\boldsymbol{C}[\boldsymbol{x}]\boldsymbol{S},
|
||
\]</div>
|
||
<p>since the matrix <span class="math notranslate nohighlight">\(\boldsymbol{S}\)</span> is not a data dependent matrix. Multiplying with <span class="math notranslate nohighlight">\(\boldsymbol{S}\)</span> from the left we have</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\boldsymbol{S}\boldsymbol{C}[\boldsymbol{y}] = \boldsymbol{C}[\boldsymbol{x}]\boldsymbol{S},
|
||
\]</div>
|
||
<p>and since <span class="math notranslate nohighlight">\(\boldsymbol{C}[\boldsymbol{y}]\)</span> is diagonal we have for a given eigenvalue <span class="math notranslate nohighlight">\(i\)</span> of the covariance matrix that</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\boldsymbol{S}_i\lambda_i = \boldsymbol{C}[\boldsymbol{x}]\boldsymbol{S}_i.
|
||
\]</div>
|
||
<p>In the derivation of the PCA theorem we will assume that the eigenvalues are ordered in descending order, that is
|
||
<span class="math notranslate nohighlight">\(\lambda_0 > \lambda_1 > \dots > \lambda_{p-1}\)</span>.</p>
|
||
<p>The eigenvalues tell us then how much we need to stretch the
|
||
corresponding eigenvectors. Dimensions with large eigenvalues have
|
||
thus large variations (large variance) and define therefore useful
|
||
dimensions. The data points are more spread out in the direction of
|
||
these eigenvectors. Smaller eigenvalues mean on the other hand that
|
||
the corresponding eigenvectors are shrunk accordingly and the data
|
||
points are tightly bunched together and there is not much variation in
|
||
these specific directions. Hopefully then we could leave it out
|
||
dimensions where the eigenvalues are very small. If <span class="math notranslate nohighlight">\(p\)</span> is very large,
|
||
we could then aim at reducing <span class="math notranslate nohighlight">\(p\)</span> to <span class="math notranslate nohighlight">\(l << p\)</span> and handle only <span class="math notranslate nohighlight">\(l\)</span>
|
||
features/predictors.</p>
|
||
<section id="the-algorithm-before-theorem">
|
||
<h3><span class="section-number">11.3.1. </span>The Algorithm before theorem<a class="headerlink" href="#the-algorithm-before-theorem" title="Link to this heading">#</a></h3>
|
||
<p>Here’s how we would proceed in setting up the algorithm for the PCA, see also discussion below here.</p>
|
||
<ul class="simple">
|
||
<li><p>Set up the datapoints for the design/feature matrix <span class="math notranslate nohighlight">\(\boldsymbol{X}\)</span> with <span class="math notranslate nohighlight">\(\boldsymbol{X}\in {\mathbb{R}}^{n\times p}\)</span>, with the predictors/features <span class="math notranslate nohighlight">\(p\)</span> referring to the column numbers and the entries <span class="math notranslate nohighlight">\(n\)</span> being the row elements.</p></li>
|
||
</ul>
|
||
<div class="math notranslate nohighlight">
|
||
\[\begin{split}
|
||
\boldsymbol{X}=\begin{bmatrix}
|
||
x_{0,0} & x_{0,1} & x_{0,2}& \dots & \dots x_{0,p-1}\\
|
||
x_{1,0} & x_{1,1} & x_{1,2}& \dots & \dots x_{1,p-1}\\
|
||
x_{2,0} & x_{2,1} & x_{2,2}& \dots & \dots x_{2,p-1}\\
|
||
\dots & \dots & \dots & \dots \dots & \dots \\
|
||
x_{n-2,0} & x_{n-2,1} & x_{n-2,2}& \dots & \dots x_{n-2,p-1}\\
|
||
x_{n-1,0} & x_{n-1,1} & x_{n-1,2}& \dots & \dots x_{n-1,p-1}\\
|
||
\end{bmatrix},
|
||
\end{split}\]</div>
|
||
<ul class="simple">
|
||
<li><p>Center the data by subtracting the mean value for each column. This leads to a new matrix <span class="math notranslate nohighlight">\(\boldsymbol{X}\rightarrow \overline{\boldsymbol{X}}\)</span>.</p></li>
|
||
<li><p>Compute then the covariance/correlation matrix <span class="math notranslate nohighlight">\(\mathbb{E}[\overline{\boldsymbol{X}}^T\overline{\boldsymbol{X}}]\)</span>.</p></li>
|
||
<li><p>Find the eigenpairs of <span class="math notranslate nohighlight">\(\boldsymbol{C}\)</span> with eigenvalues <span class="math notranslate nohighlight">\([\lambda_0,\lambda_1,\dots,\lambda_{p-1}]\)</span> and eigenvectors <span class="math notranslate nohighlight">\([\boldsymbol{s}_0,\boldsymbol{s}_1,\dots,\boldsymbol{s}_{p-1}]\)</span>.</p></li>
|
||
<li><p>Order the eigenvalue (and the eigenvectors accordingly) in order of decreasing eigenvalues.</p></li>
|
||
<li><p>Keep only those <span class="math notranslate nohighlight">\(l\)</span> eigenvalues larger than a selected threshold value, discarding thus <span class="math notranslate nohighlight">\(p-l\)</span> features since we expect small variations in the data here.</p></li>
|
||
</ul>
|
||
</section>
|
||
<section id="writing-our-own-pca-code">
|
||
<h3><span class="section-number">11.3.2. </span>Writing our own PCA code<a class="headerlink" href="#writing-our-own-pca-code" title="Link to this heading">#</a></h3>
|
||
<p>We will use a simple example first with two-dimensional data
|
||
drawn from a multivariate normal distribution with the following mean and covariance matrix (we have fixed these quantities but will play around with them below):</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[\begin{split}
|
||
\mu = (-1,2) \qquad \Sigma = \begin{bmatrix} 4 & 2 \\
|
||
2 & 2
|
||
\end{bmatrix}
|
||
\end{split}\]</div>
|
||
<p>Note that the mean refers to each column of data.
|
||
We will generate <span class="math notranslate nohighlight">\(n = 10000\)</span> points <span class="math notranslate nohighlight">\(X = \{ x_1, \ldots, x_N \}\)</span> from
|
||
this distribution, and store them in the <span class="math notranslate nohighlight">\(1000 \times 2\)</span> matrix <span class="math notranslate nohighlight">\(\boldsymbol{X}\)</span>. This is our design matrix where we have forced the covariance and mean values to take specific values.</p>
|
||
<p>The following Python code aids in setting up the data and writing out the design matrix.
|
||
Note that the function <strong>multivariate</strong> returns also the covariance discussed above and that it is defined by dividing by <span class="math notranslate nohighlight">\(n-1\)</span> instead of <span class="math notranslate nohighlight">\(n\)</span>.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="o">%</span><span class="k">matplotlib</span> inline
|
||
|
||
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
|
||
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
|
||
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
|
||
<span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">display</span>
|
||
<span class="n">n</span> <span class="o">=</span> <span class="mi">10000</span>
|
||
<span class="n">mean</span> <span class="o">=</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
|
||
<span class="n">cov</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">]]</span>
|
||
<span class="n">X</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">multivariate_normal</span><span class="p">(</span><span class="n">mean</span><span class="p">,</span> <span class="n">cov</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Now we are going to implement the PCA algorithm. We will break it down into various substeps.</p>
|
||
<p>The first step of PCA is to compute the sample mean of the data and use it to center the data. Recall that the sample mean is</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\mu_n = \frac{1}{n} \sum_{i=1}^n x_i
|
||
\]</div>
|
||
<p>and the mean-centered data <span class="math notranslate nohighlight">\(\bar{X} = \{ \bar{x}_1, \ldots, \bar{x}_n \}\)</span> takes the form</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\bar{x}_i = x_i - \mu_n.
|
||
\]</div>
|
||
<p>When you are done with these steps, print out <span class="math notranslate nohighlight">\(\mu_n\)</span> to verify it is
|
||
close to <span class="math notranslate nohighlight">\(\mu\)</span> and plot your mean centered data to verify it is
|
||
centered at the origin!
|
||
The following code elements perform these operations using <strong>pandas</strong> or using our own functionality for doing so. The latter, using <strong>numpy</strong> is rather simple through the <strong>mean()</strong> function.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
|
||
<span class="c1"># Pandas does the centering for us</span>
|
||
<span class="n">df</span> <span class="o">=</span> <span class="n">df</span> <span class="o">-</span><span class="n">df</span><span class="o">.</span><span class="n">mean</span><span class="p">()</span>
|
||
<span class="c1"># we center it ourselves</span>
|
||
<span class="n">X_centered</span> <span class="o">=</span> <span class="n">X</span> <span class="o">-</span> <span class="n">X</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Alternatively, we could use the functions we discussed
|
||
earlier for scaling the data set. That is, we could have used the
|
||
<strong>StandardScaler</strong> function in <strong>Scikit-Learn</strong>, a function which ensures
|
||
that for each feature/predictor we study the mean value is zero and
|
||
the variance is one (every column in the design/feature matrix). You
|
||
would then not get the same results, since we divide by the
|
||
variance. The diagonal covariance matrix elements will then be one,
|
||
while the non-diagonal ones need to be divided by <span class="math notranslate nohighlight">\(2\sqrt{2}\)</span> for our
|
||
specific case.</p>
|
||
<p>Now we are going to use the mean centered data to compute the sample covariance of the data by using the following equation</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\Sigma_n = \frac{1}{n-1} \sum_{i=1}^n \bar{x}_i^T \bar{x}_i = \frac{1}{n-1} \sum_{i=1}^n (x_i - \mu_n)^T (x_i - \mu_n)
|
||
\]</div>
|
||
<p>where the data points <span class="math notranslate nohighlight">\(x_i \in \mathbb{R}^p\)</span> (here in this example <span class="math notranslate nohighlight">\(p = 2\)</span>) are column vectors and <span class="math notranslate nohighlight">\(x^T\)</span> is the transpose of <span class="math notranslate nohighlight">\(x\)</span>.
|
||
We can write our own code or simply use either the functionaly of <strong>numpy</strong> or that of <strong>pandas</strong>, as follows</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="nb">print</span><span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">cov</span><span class="p">())</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">cov</span><span class="p">(</span><span class="n">X_centered</span><span class="o">.</span><span class="n">T</span><span class="p">))</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span> 0 1
|
||
0 4.066103 2.050297
|
||
1 2.050297 2.019626
|
||
[[4.06610301 2.0502966 ]
|
||
[2.0502966 2.01962561]]
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Note that the way we define the covariance matrix here has a factor <span class="math notranslate nohighlight">\(n-1\)</span> instead of <span class="math notranslate nohighlight">\(n\)</span>. This is included in the <strong>cov()</strong> function by <strong>numpy</strong> and <strong>pandas</strong>.
|
||
Our own code here is not very elegant and asks for obvious improvements. It is tailored to this specific <span class="math notranslate nohighlight">\(2\times 2\)</span> covariance matrix.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="c1"># extract the relevant columns from the centered design matrix of dim n x 2</span>
|
||
<span class="n">x</span> <span class="o">=</span> <span class="n">X_centered</span><span class="p">[:,</span><span class="mi">0</span><span class="p">]</span>
|
||
<span class="n">y</span> <span class="o">=</span> <span class="n">X_centered</span><span class="p">[:,</span><span class="mi">1</span><span class="p">]</span>
|
||
<span class="n">Cov</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="mi">2</span><span class="p">,</span><span class="mi">2</span><span class="p">))</span>
|
||
<span class="n">Cov</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">T</span><span class="nd">@y</span><span class="p">)</span><span class="o">/</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mf">1.0</span><span class="p">)</span>
|
||
<span class="n">Cov</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">x</span><span class="o">.</span><span class="n">T</span><span class="nd">@x</span><span class="p">)</span><span class="o">/</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mf">1.0</span><span class="p">)</span>
|
||
<span class="n">Cov</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">sum</span><span class="p">(</span><span class="n">y</span><span class="o">.</span><span class="n">T</span><span class="nd">@y</span><span class="p">)</span><span class="o">/</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mf">1.0</span><span class="p">)</span>
|
||
<span class="n">Cov</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">]</span><span class="o">=</span> <span class="n">Cov</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">]</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Centered covariance using own code"</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">Cov</span><span class="p">)</span>
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="s1">'x'</span><span class="p">)</span>
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">axis</span><span class="p">(</span><span class="s1">'equal'</span><span class="p">)</span>
|
||
<span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>Centered covariance using own code
|
||
[[4.06610301 2.0502966 ]
|
||
[2.0502966 2.01962561]]
|
||
</pre></div>
|
||
</div>
|
||
<img alt="_images/6221ee55bb26dba5cef5540ef9967df02eb119abda11c5c5903f7762c8c9f763.png" src="_images/6221ee55bb26dba5cef5540ef9967df02eb119abda11c5c5903f7762c8c9f763.png" />
|
||
</div>
|
||
</div>
|
||
<p>Depending on the number of points <span class="math notranslate nohighlight">\(n\)</span>, we will get results that are close to the covariance values defined above.
|
||
The plot shows how the data are clustered around a line with slope close to one. Is this expected? Try to change the covariance and the mean values. For example, try to make the variance of the first element much larger than that of the second diagonal element. Try also to shrink the covariance (the non-diagonal elements) and see how the data points are distributed.</p>
|
||
</section>
|
||
<section id="diagonalize-the-sample-covariance-matrix-to-obtain-the-principal-components">
|
||
<h3><span class="section-number">11.3.3. </span>Diagonalize the sample covariance matrix to obtain the principal components<a class="headerlink" href="#diagonalize-the-sample-covariance-matrix-to-obtain-the-principal-components" title="Link to this heading">#</a></h3>
|
||
<p>Now we are ready to solve for the principal components! To do so we
|
||
diagonalize the sample covariance matrix <span class="math notranslate nohighlight">\(\Sigma\)</span>. We can use the
|
||
function <strong>np.linalg.eig</strong> to do so. It will return the eigenvalues and
|
||
eigenvectors of <span class="math notranslate nohighlight">\(\Sigma\)</span>. Once we have these we can perform the
|
||
following tasks:</p>
|
||
<ul class="simple">
|
||
<li><p>We compute the percentage of the total variance captured by the first principal component</p></li>
|
||
<li><p>We plot the mean centered data and lines along the first and second principal components</p></li>
|
||
<li><p>Then we project the mean centered data onto the first and second principal components, and plot the projected data.</p></li>
|
||
<li><p>Finally, we approximate the data as</p></li>
|
||
</ul>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
x_i \approx \tilde{x}_i = \mu_n + \langle x_i, v_0 \rangle v_0
|
||
\]</div>
|
||
<p>where <span class="math notranslate nohighlight">\(v_0\)</span> is the first principal component.</p>
|
||
<p>Collecting all these steps we can write our own PCA function and
|
||
compare this with the functionality included in <strong>Scikit-Learn</strong>.</p>
|
||
<p>The code here outlines some of the elements we could include in the
|
||
analysis. Feel free to extend upon this in order to address the above
|
||
questions.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="c1"># diagonalize and obtain eigenvalues, not necessarily sorted</span>
|
||
<span class="n">EigValues</span><span class="p">,</span> <span class="n">EigVectors</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">eig</span><span class="p">(</span><span class="n">Cov</span><span class="p">)</span>
|
||
<span class="c1"># sort eigenvectors and eigenvalues</span>
|
||
<span class="c1">#permute = EigValues.argsort()</span>
|
||
<span class="c1">#EigValues = EigValues[permute]</span>
|
||
<span class="c1">#EigVectors = EigVectors[:,permute]</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Eigenvalues of Covariance matrix"</span><span class="p">)</span>
|
||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">):</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">EigValues</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
|
||
<span class="n">FirstEigvector</span> <span class="o">=</span> <span class="n">EigVectors</span><span class="p">[:,</span><span class="mi">0</span><span class="p">]</span>
|
||
<span class="n">SecondEigvector</span> <span class="o">=</span> <span class="n">EigVectors</span><span class="p">[:,</span><span class="mi">1</span><span class="p">]</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"First eigenvector"</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">FirstEigvector</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Second eigenvector"</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">SecondEigvector</span><span class="p">)</span>
|
||
<span class="c1">#thereafter we do a PCA with Scikit-learn</span>
|
||
<span class="kn">from</span> <span class="nn">sklearn.decomposition</span> <span class="kn">import</span> <span class="n">PCA</span>
|
||
<span class="n">pca</span> <span class="o">=</span> <span class="n">PCA</span><span class="p">(</span><span class="n">n_components</span> <span class="o">=</span> <span class="mi">2</span><span class="p">)</span>
|
||
<span class="n">X2Dsl</span> <span class="o">=</span> <span class="n">pca</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Eigenvector of largest eigenvalue"</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">pca</span><span class="o">.</span><span class="n">components_</span><span class="o">.</span><span class="n">T</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">])</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>Eigenvalues of Covariance matrix
|
||
5.3343122336302145
|
||
0.7514163800957537
|
||
First eigenvector
|
||
[0.85045481 0.5260481 ]
|
||
Second eigenvector
|
||
[-0.5260481 0.85045481]
|
||
</pre></div>
|
||
</div>
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>Eigenvector of largest eigenvalue
|
||
[0.85045481 0.5260481 ]
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>This code does not contain all the above elements, but it shows how we can use <strong>Scikit-Learn</strong> to extract the eigenvector which corresponds to the largest eigenvalue. Try to address the questions we pose before the above code. Try also to change the values of the covariance matrix by making one of the diagonal elements much larger than the other. What do you observe then?</p>
|
||
</section>
|
||
</section>
|
||
<section id="classical-pca-theorem">
|
||
<h2><span class="section-number">11.4. </span>Classical PCA Theorem<a class="headerlink" href="#classical-pca-theorem" title="Link to this heading">#</a></h2>
|
||
<p>We assume now that we have a design matrix <span class="math notranslate nohighlight">\(\boldsymbol{X}\)</span> which has been
|
||
centered as discussed above. For the sake of simplicity we skip the
|
||
overline symbol. The matrix is defined in terms of the various column
|
||
vectors <span class="math notranslate nohighlight">\([\boldsymbol{x}_0,\boldsymbol{x}_1,\dots, \boldsymbol{x}_{p-1}]\)</span> each with dimension
|
||
<span class="math notranslate nohighlight">\(\boldsymbol{x}\in {\mathbb{R}}^{n}\)</span>.</p>
|
||
<p>The PCA theorem states that minimizing the above reconstruction error
|
||
corresponds to setting <span class="math notranslate nohighlight">\(\boldsymbol{W}=\boldsymbol{S}\)</span>, the orthogonal matrix which
|
||
diagonalizes the empirical covariance(correlation) matrix. The optimal
|
||
low-dimensional encoding of the data is then given by a set of vectors
|
||
<span class="math notranslate nohighlight">\(\boldsymbol{z}_i\)</span> with at most <span class="math notranslate nohighlight">\(l\)</span> vectors, with <span class="math notranslate nohighlight">\(l << p\)</span>, defined by the
|
||
orthogonal projection of the data onto the columns spanned by the
|
||
eigenvectors of the covariance(correlations matrix).</p>
|
||
<p>To show the PCA theorem let us start with the assumption that there is one vector <span class="math notranslate nohighlight">\(\boldsymbol{s}_0\)</span> which corresponds to a solution which minimized the reconstruction error <span class="math notranslate nohighlight">\(J\)</span>. This is an orthogonal vector. It means that we now approximate the reconstruction error in terms of <span class="math notranslate nohighlight">\(\boldsymbol{w}_0\)</span> and <span class="math notranslate nohighlight">\(\boldsymbol{z}_0\)</span> as</p>
|
||
<p>We are almost there, we have obtained a relation between minimizing
|
||
the reconstruction error and the variance and the covariance
|
||
matrix. Minimizing the error is equivalent to maximizing the variance
|
||
of the projected data.</p>
|
||
<p>We could trivially maximize the variance of the projection (and
|
||
thereby minimize the error in the reconstruction function) by letting
|
||
the norm-2 of <span class="math notranslate nohighlight">\(\boldsymbol{w}_0\)</span> go to infinity. However, this norm since we
|
||
want the matrix <span class="math notranslate nohighlight">\(\boldsymbol{W}\)</span> to be an orthogonal matrix, is constrained by
|
||
<span class="math notranslate nohighlight">\(\vert\vert \boldsymbol{w}_0 \vert\vert_2^2=1\)</span>. Imposing this condition via a
|
||
Lagrange multiplier we can then in turn maximize</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
J(\boldsymbol{w}_0)= \boldsymbol{w}_0^T\boldsymbol{C}[\boldsymbol{x}]\boldsymbol{w}_0+\lambda_0(1-\boldsymbol{w}_0^T\boldsymbol{w}_0).
|
||
\]</div>
|
||
<p>Taking the derivative with respect to <span class="math notranslate nohighlight">\(\boldsymbol{w}_0\)</span> we obtain</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\frac{\partial J(\boldsymbol{w}_0)}{\partial \boldsymbol{w}_0}= 2\boldsymbol{C}[\boldsymbol{x}]\boldsymbol{w}_0-2\lambda_0\boldsymbol{w}_0=0,
|
||
\]</div>
|
||
<p>meaning that</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\boldsymbol{C}[\boldsymbol{x}]\boldsymbol{w}_0=\lambda_0\boldsymbol{w}_0.
|
||
\]</div>
|
||
<p><strong>The direction that maximizes the variance (or minimizes the construction error) is an eigenvector of the covariance matrix</strong>! If we left multiply with <span class="math notranslate nohighlight">\(\boldsymbol{w}_0^T\)</span> we have the variance of the projected data is</p>
|
||
<div class="math notranslate nohighlight">
|
||
\[
|
||
\boldsymbol{w}_0^T\boldsymbol{C}[\boldsymbol{x}]\boldsymbol{w}_0=\lambda_0.
|
||
\]</div>
|
||
<p>If we want to maximize the variance (minimize the construction error)
|
||
we simply pick the eigenvector of the covariance matrix with the
|
||
largest eigenvalue. This establishes the link between the minimization
|
||
of the reconstruction function <span class="math notranslate nohighlight">\(J\)</span> in terms of an orthogonal matrix
|
||
and the maximization of the variance and thereby the covariance of our
|
||
observations encoded in the design/feature matrix <span class="math notranslate nohighlight">\(\boldsymbol{X}\)</span>.</p>
|
||
<p>The proof
|
||
for the other eigenvectors <span class="math notranslate nohighlight">\(\boldsymbol{w}_1,\boldsymbol{w}_2,\dots\)</span> can be
|
||
established by applying the above arguments and using the fact that
|
||
our basis of eigenvectors is orthogonal, see <a class="reference external" href="https://mitpress.mit.edu/books/machine-learning-1">Murphy chapter
|
||
12.2</a>. The
|
||
discussion in chapter 12.2 of Murphy’s text has also a nice link with
|
||
the Singular Value Decomposition theorem. For categorical data, see
|
||
chapter 12.4 and discussion therein.</p>
|
||
<p>For more details, see for example <a class="reference external" href="https://www.springer.com/gp/book/9780387878102">Vidal, Ma and Sastry, chapter 2</a>.</p>
|
||
</section>
|
||
<section id="geometric-interpretation-and-link-with-singular-value-decomposition">
|
||
<h2><span class="section-number">11.5. </span>Geometric Interpretation and link with Singular Value Decomposition<a class="headerlink" href="#geometric-interpretation-and-link-with-singular-value-decomposition" title="Link to this heading">#</a></h2>
|
||
<p>For a detailed demonstration of the geometric interpretation, see <a class="reference external" href="https://www.springer.com/gp/book/9780387878102">Vidal, Ma and Sastry, section 2.1.2</a>.</p>
|
||
<p>Principal Component Analysis (PCA) is by far the most popular dimensionality reduction algorithm.
|
||
First it identifies the hyperplane that lies closest to the data, and then it projects the data onto it.</p>
|
||
<p>The following Python code uses NumPy’s <strong>svd()</strong> function to obtain all the principal components of the
|
||
training set, then extracts the first two principal components. First we center the data using either <strong>pandas</strong> or our own code</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
|
||
<span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
|
||
<span class="kn">from</span> <span class="nn">IPython.display</span> <span class="kn">import</span> <span class="n">display</span>
|
||
<span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">seed</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
|
||
<span class="c1"># setting up a 10 x 5 vanilla matrix </span>
|
||
<span class="n">rows</span> <span class="o">=</span> <span class="mi">10</span>
|
||
<span class="n">cols</span> <span class="o">=</span> <span class="mi">5</span>
|
||
<span class="n">X</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randn</span><span class="p">(</span><span class="n">rows</span><span class="p">,</span><span class="n">cols</span><span class="p">)</span>
|
||
<span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
|
||
<span class="c1"># Pandas does the centering for us</span>
|
||
<span class="n">df</span> <span class="o">=</span> <span class="n">df</span> <span class="o">-</span><span class="n">df</span><span class="o">.</span><span class="n">mean</span><span class="p">()</span>
|
||
<span class="n">display</span><span class="p">(</span><span class="n">df</span><span class="p">)</span>
|
||
|
||
<span class="c1"># we center it ourselves</span>
|
||
<span class="n">X_centered</span> <span class="o">=</span> <span class="n">X</span> <span class="o">-</span> <span class="n">X</span><span class="o">.</span><span class="n">mean</span><span class="p">(</span><span class="n">axis</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
|
||
<span class="c1"># Then check the difference between pandas and our own set up</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">X_centered</span><span class="o">-</span><span class="n">df</span><span class="p">)</span>
|
||
<span class="c1">#Now we do an SVD</span>
|
||
<span class="n">U</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">V</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">svd</span><span class="p">(</span><span class="n">X_centered</span><span class="p">)</span>
|
||
<span class="n">c1</span> <span class="o">=</span> <span class="n">V</span><span class="o">.</span><span class="n">T</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">]</span>
|
||
<span class="n">c2</span> <span class="o">=</span> <span class="n">V</span><span class="o">.</span><span class="n">T</span><span class="p">[:,</span> <span class="mi">1</span><span class="p">]</span>
|
||
<span class="n">W2</span> <span class="o">=</span> <span class="n">V</span><span class="o">.</span><span class="n">T</span><span class="p">[:,</span> <span class="p">:</span><span class="mi">2</span><span class="p">]</span>
|
||
<span class="n">X2D</span> <span class="o">=</span> <span class="n">X_centered</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">W2</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">X2D</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_html"><div>
|
||
<style scoped>
|
||
.dataframe tbody tr th:only-of-type {
|
||
vertical-align: middle;
|
||
}
|
||
|
||
.dataframe tbody tr th {
|
||
vertical-align: top;
|
||
}
|
||
|
||
.dataframe thead th {
|
||
text-align: right;
|
||
}
|
||
</style>
|
||
<table border="1" class="dataframe">
|
||
<thead>
|
||
<tr style="text-align: right;">
|
||
<th></th>
|
||
<th>0</th>
|
||
<th>1</th>
|
||
<th>2</th>
|
||
<th>3</th>
|
||
<th>4</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<th>0</th>
|
||
<td>-1.574465</td>
|
||
<td>0.259153</td>
|
||
<td>1.197370</td>
|
||
<td>0.147400</td>
|
||
<td>0.649382</td>
|
||
</tr>
|
||
<tr>
|
||
<th>1</th>
|
||
<td>0.689519</td>
|
||
<td>0.137652</td>
|
||
<td>-1.025709</td>
|
||
<td>0.210340</td>
|
||
<td>-0.076938</td>
|
||
</tr>
|
||
<tr>
|
||
<th>2</th>
|
||
<td>-0.282727</td>
|
||
<td>0.351636</td>
|
||
<td>-0.539261</td>
|
||
<td>1.216683</td>
|
||
<td>0.340782</td>
|
||
</tr>
|
||
<tr>
|
||
<th>3</th>
|
||
<td>0.070889</td>
|
||
<td>-0.614808</td>
|
||
<td>1.074067</td>
|
||
<td>-0.038300</td>
|
||
<td>-1.450257</td>
|
||
</tr>
|
||
<tr>
|
||
<th>4</th>
|
||
<td>1.794282</td>
|
||
<td>1.458078</td>
|
||
<td>-0.207545</td>
|
||
<td>-0.442600</td>
|
||
<td>-0.147420</td>
|
||
</tr>
|
||
<tr>
|
||
<th>5</th>
|
||
<td>1.112383</td>
|
||
<td>0.647473</td>
|
||
<td>1.405890</td>
|
||
<td>0.073598</td>
|
||
<td>-0.276263</td>
|
||
</tr>
|
||
<tr>
|
||
<th>6</th>
|
||
<td>0.397700</td>
|
||
<td>-1.526744</td>
|
||
<td>-0.712018</td>
|
||
<td>1.216290</td>
|
||
<td>0.418506</td>
|
||
</tr>
|
||
<tr>
|
||
<th>7</th>
|
||
<td>-0.280647</td>
|
||
<td>1.106095</td>
|
||
<td>-1.646283</td>
|
||
<td>-0.956563</td>
|
||
<td>-1.564374</td>
|
||
</tr>
|
||
<tr>
|
||
<th>8</th>
|
||
<td>-0.369139</td>
|
||
<td>-0.751699</td>
|
||
<td>0.051649</td>
|
||
<td>-0.213103</td>
|
||
<td>0.967809</td>
|
||
</tr>
|
||
<tr>
|
||
<th>9</th>
|
||
<td>-1.557795</td>
|
||
<td>-1.066837</td>
|
||
<td>0.401842</td>
|
||
<td>-1.213743</td>
|
||
<td>1.138775</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div></div><div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span> 0 1 2 3 4
|
||
0 0.0 0.0 0.0 0.0 0.0
|
||
1 0.0 0.0 0.0 0.0 0.0
|
||
2 0.0 0.0 0.0 0.0 0.0
|
||
3 0.0 0.0 0.0 0.0 0.0
|
||
4 0.0 0.0 0.0 0.0 0.0
|
||
5 0.0 0.0 0.0 0.0 0.0
|
||
6 0.0 0.0 0.0 0.0 0.0
|
||
7 0.0 0.0 0.0 0.0 0.0
|
||
8 0.0 0.0 0.0 0.0 0.0
|
||
9 0.0 0.0 0.0 0.0 0.0
|
||
[[-1.5378811 0.94639099]
|
||
[ 0.86145244 -0.89288636]
|
||
[-0.00445655 -0.81633628]
|
||
[ 0.07145103 1.00433417]
|
||
[ 2.03707133 0.48476997]
|
||
[ 0.72174172 1.4557763 ]
|
||
[-0.55854694 -1.60673226]
|
||
[ 1.6999536 -0.43766686]
|
||
[-1.10405456 -0.31718909]
|
||
[-2.18673098 0.17953942]]
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>PCA assumes that the dataset is centered around the origin. Scikit-Learn’s PCA classes take care of centering
|
||
the data for you. However, if you implement PCA yourself (as in the preceding example), or if you use other libraries, don’t
|
||
forget to center the data first.</p>
|
||
<p>Once you have identified all the principal components, you can reduce the dimensionality of the dataset
|
||
down to <span class="math notranslate nohighlight">\(d\)</span> dimensions by projecting it onto the hyperplane defined by the first <span class="math notranslate nohighlight">\(d\)</span> principal components.
|
||
Selecting this hyperplane ensures that the projection will preserve as much variance as possible.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">W2</span> <span class="o">=</span> <span class="n">V</span><span class="o">.</span><span class="n">T</span><span class="p">[:,</span> <span class="p">:</span><span class="mi">2</span><span class="p">]</span>
|
||
<span class="n">X2D</span> <span class="o">=</span> <span class="n">X_centered</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">W2</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
<section id="pca-and-scikit-learn">
|
||
<h2><span class="section-number">11.6. </span>PCA and scikit-learn<a class="headerlink" href="#pca-and-scikit-learn" title="Link to this heading">#</a></h2>
|
||
<p>Scikit-Learn’s PCA class implements PCA using SVD decomposition just like we did before. The
|
||
following code applies PCA to reduce the dimensionality of the dataset down to two dimensions (note
|
||
that it automatically takes care of centering the data):</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="c1">#thereafter we do a PCA with Scikit-learn</span>
|
||
<span class="kn">from</span> <span class="nn">sklearn.decomposition</span> <span class="kn">import</span> <span class="n">PCA</span>
|
||
<span class="n">pca</span> <span class="o">=</span> <span class="n">PCA</span><span class="p">(</span><span class="n">n_components</span> <span class="o">=</span> <span class="mi">2</span><span class="p">)</span>
|
||
<span class="n">X2D</span> <span class="o">=</span> <span class="n">pca</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">X2D</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>[[ 1.5378811 -0.94639099]
|
||
[-0.86145244 0.89288636]
|
||
[ 0.00445655 0.81633628]
|
||
[-0.07145103 -1.00433417]
|
||
[-2.03707133 -0.48476997]
|
||
[-0.72174172 -1.4557763 ]
|
||
[ 0.55854694 1.60673226]
|
||
[-1.6999536 0.43766686]
|
||
[ 1.10405456 0.31718909]
|
||
[ 2.18673098 -0.17953942]]
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>After fitting the PCA transformer to the dataset, you can access the principal components using the
|
||
components variable (note that it contains the PCs as horizontal vectors, so, for example, the first
|
||
principal component is equal to</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">pca</span><span class="o">.</span><span class="n">components_</span><span class="o">.</span><span class="n">T</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">]</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output text_plain highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>array([-0.62373464, -0.5303329 , 0.317367 , 0.01873344, 0.47815203])
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Another very useful piece of information is the explained variance ratio of each principal component,
|
||
available via the <span class="math notranslate nohighlight">\(explained\_variance\_ratio\)</span> variable. It indicates the proportion of the dataset’s
|
||
variance that lies along the axis of each principal component.</p>
|
||
</section>
|
||
<section id="back-to-the-cancer-data">
|
||
<h2><span class="section-number">11.7. </span>Back to the Cancer Data<a class="headerlink" href="#back-to-the-cancer-data" title="Link to this heading">#</a></h2>
|
||
<p>We can now repeat the above but applied to real data, in this case our breast cancer data.
|
||
Here we compute performance scores on the training data using logistic regression.</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
|
||
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
|
||
<span class="kn">from</span> <span class="nn">sklearn.model_selection</span> <span class="kn">import</span> <span class="n">train_test_split</span>
|
||
<span class="kn">from</span> <span class="nn">sklearn.datasets</span> <span class="kn">import</span> <span class="n">load_breast_cancer</span>
|
||
<span class="kn">from</span> <span class="nn">sklearn.linear_model</span> <span class="kn">import</span> <span class="n">LogisticRegression</span>
|
||
<span class="n">cancer</span> <span class="o">=</span> <span class="n">load_breast_cancer</span><span class="p">()</span>
|
||
|
||
<span class="n">X_train</span><span class="p">,</span> <span class="n">X_test</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">y_test</span> <span class="o">=</span> <span class="n">train_test_split</span><span class="p">(</span><span class="n">cancer</span><span class="o">.</span><span class="n">data</span><span class="p">,</span><span class="n">cancer</span><span class="o">.</span><span class="n">target</span><span class="p">,</span><span class="n">random_state</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
|
||
|
||
<span class="n">logreg</span> <span class="o">=</span> <span class="n">LogisticRegression</span><span class="p">()</span>
|
||
<span class="n">logreg</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Train set accuracy from Logistic Regression: </span><span class="si">{:.2f}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">logreg</span><span class="o">.</span><span class="n">score</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span><span class="n">y_train</span><span class="p">)))</span>
|
||
<span class="c1"># We scale the data</span>
|
||
<span class="kn">from</span> <span class="nn">sklearn.preprocessing</span> <span class="kn">import</span> <span class="n">StandardScaler</span>
|
||
<span class="n">scaler</span> <span class="o">=</span> <span class="n">StandardScaler</span><span class="p">()</span>
|
||
<span class="n">scaler</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train</span><span class="p">)</span>
|
||
<span class="n">X_train_scaled</span> <span class="o">=</span> <span class="n">scaler</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">X_train</span><span class="p">)</span>
|
||
<span class="n">X_test_scaled</span> <span class="o">=</span> <span class="n">scaler</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">X_test</span><span class="p">)</span>
|
||
<span class="c1"># Then perform again a log reg fit</span>
|
||
<span class="n">logreg</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X_train_scaled</span><span class="p">,</span> <span class="n">y_train</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Train set accuracy scaled data: </span><span class="si">{:.2f}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">logreg</span><span class="o">.</span><span class="n">score</span><span class="p">(</span><span class="n">X_train_scaled</span><span class="p">,</span><span class="n">y_train</span><span class="p">)))</span>
|
||
<span class="c1">#thereafter we do a PCA with Scikit-learn</span>
|
||
<span class="kn">from</span> <span class="nn">sklearn.decomposition</span> <span class="kn">import</span> <span class="n">PCA</span>
|
||
<span class="n">pca</span> <span class="o">=</span> <span class="n">PCA</span><span class="p">(</span><span class="n">n_components</span> <span class="o">=</span> <span class="mi">2</span><span class="p">)</span>
|
||
<span class="n">X2D_train</span> <span class="o">=</span> <span class="n">pca</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X_train_scaled</span><span class="p">)</span>
|
||
<span class="c1"># and finally compute the log reg fit and the score on the training data </span>
|
||
<span class="n">logreg</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X2D_train</span><span class="p">,</span><span class="n">y_train</span><span class="p">)</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Train set accuracy scaled and PCA data: </span><span class="si">{:.2f}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">logreg</span><span class="o">.</span><span class="n">score</span><span class="p">(</span><span class="n">X2D_train</span><span class="p">,</span><span class="n">y_train</span><span class="p">)))</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
<div class="cell_output docutils container">
|
||
<div class="output stream highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>Train set accuracy from Logistic Regression: 0.95
|
||
Train set accuracy scaled data: 0.99
|
||
Train set accuracy scaled and PCA data: 0.96
|
||
</pre></div>
|
||
</div>
|
||
<div class="output stderr highlight-myst-ansi notranslate"><div class="highlight"><pre><span></span>/Users/mhjensen/miniforge3/envs/myenv/lib/python3.9/site-packages/sklearn/linear_model/_logistic.py:460: ConvergenceWarning: lbfgs failed to converge (status=1):
|
||
STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.
|
||
|
||
Increase the number of iterations (max_iter) or scale the data as shown in:
|
||
https://scikit-learn.org/stable/modules/preprocessing.html
|
||
Please also refer to the documentation for alternative solver options:
|
||
https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
|
||
n_iter_i = _check_optimize_result(
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>We see that our training data after the PCA decomposition has a performance similar to the non-scaled data.</p>
|
||
<p>Instead of arbitrarily choosing the number of dimensions to reduce down to, it is generally preferable to
|
||
choose the number of dimensions that add up to a sufficiently large portion of the variance (e.g., 95%).
|
||
Unless, of course, you are reducing dimensionality for data visualization — in that case you will
|
||
generally want to reduce the dimensionality down to 2 or 3.
|
||
The following code computes PCA without reducing dimensionality, then computes the minimum number
|
||
of dimensions required to preserve 95% of the training set’s variance:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">pca</span> <span class="o">=</span> <span class="n">PCA</span><span class="p">()</span>
|
||
<span class="n">pca</span><span class="o">.</span><span class="n">fit</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
|
||
<span class="n">cumsum</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">cumsum</span><span class="p">(</span><span class="n">pca</span><span class="o">.</span><span class="n">explained_variance_ratio_</span><span class="p">)</span>
|
||
<span class="n">d</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">argmax</span><span class="p">(</span><span class="n">cumsum</span> <span class="o">>=</span> <span class="mf">0.95</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>You could then set <span class="math notranslate nohighlight">\(n\_components=d\)</span> and run PCA again. However, there is a much better option: instead
|
||
of specifying the number of principal components you want to preserve, you can set <span class="math notranslate nohighlight">\(n\_components\)</span> to be
|
||
a float between 0.0 and 1.0, indicating the ratio of variance you wish to preserve:</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="n">pca</span> <span class="o">=</span> <span class="n">PCA</span><span class="p">(</span><span class="n">n_components</span><span class="o">=</span><span class="mf">0.95</span><span class="p">)</span>
|
||
<span class="n">X_reduced</span> <span class="o">=</span> <span class="n">pca</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<section id="incremental-pca">
|
||
<h3><span class="section-number">11.7.1. </span>Incremental PCA<a class="headerlink" href="#incremental-pca" title="Link to this heading">#</a></h3>
|
||
<p>One problem with the preceding implementation of PCA is that it requires the whole training set to fit in
|
||
memory in order for the SVD algorithm to run. Fortunately, Incremental PCA (IPCA) algorithms have
|
||
been developed: you can split the training set into mini-batches and feed an IPCA algorithm one minibatch
|
||
at a time. This is useful for large training sets, and also to apply PCA online (i.e., on the fly, as new
|
||
instances arrive).</p>
|
||
</section>
|
||
<section id="randomized-pca">
|
||
<h3><span class="section-number">11.7.2. </span>Randomized PCA<a class="headerlink" href="#randomized-pca" title="Link to this heading">#</a></h3>
|
||
<p>Scikit-Learn offers yet another option to perform PCA, called Randomized PCA. This is a stochastic
|
||
algorithm that quickly finds an approximation of the first d principal components. Its computational
|
||
complexity is <span class="math notranslate nohighlight">\(O(m \times d^2)+O(d^3)\)</span>, instead of <span class="math notranslate nohighlight">\(O(m \times n^2) + O(n^3)\)</span>, so it is dramatically faster than the
|
||
previous algorithms when <span class="math notranslate nohighlight">\(d\)</span> is much smaller than <span class="math notranslate nohighlight">\(n\)</span>.</p>
|
||
</section>
|
||
<section id="kernel-pca">
|
||
<h3><span class="section-number">11.7.3. </span>Kernel PCA<a class="headerlink" href="#kernel-pca" title="Link to this heading">#</a></h3>
|
||
<p>The kernel trick is a mathematical technique that implicitly maps instances into a
|
||
very high-dimensional space (called the feature space), enabling nonlinear classification and regression
|
||
with Support Vector Machines. Recall that a linear decision boundary in the high-dimensional feature
|
||
space corresponds to a complex nonlinear decision boundary in the original space.
|
||
It turns out that the same trick can be applied to PCA, making it possible to perform complex nonlinear
|
||
projections for dimensionality reduction. This is called Kernel PCA (kPCA). It is often good at
|
||
preserving clusters of instances after projection, or sometimes even unrolling datasets that lie close to a
|
||
twisted manifold.
|
||
For example, the following code uses Scikit-Learn’s KernelPCA class to perform kPCA with an</p>
|
||
<div class="cell docutils container">
|
||
<div class="cell_input docutils container">
|
||
<div class="highlight-ipython3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">sklearn.decomposition</span> <span class="kn">import</span> <span class="n">KernelPCA</span>
|
||
<span class="n">rbf_pca</span> <span class="o">=</span> <span class="n">KernelPCA</span><span class="p">(</span><span class="n">n_components</span> <span class="o">=</span> <span class="mi">2</span><span class="p">,</span> <span class="n">kernel</span><span class="o">=</span><span class="s2">"rbf"</span><span class="p">,</span> <span class="n">gamma</span><span class="o">=</span><span class="mf">0.04</span><span class="p">)</span>
|
||
<span class="n">X_reduced</span> <span class="o">=</span> <span class="n">rbf_pca</span><span class="o">.</span><span class="n">fit_transform</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</section>
|
||
<section id="other-techniques">
|
||
<h2><span class="section-number">11.8. </span>Other techniques<a class="headerlink" href="#other-techniques" title="Link to this heading">#</a></h2>
|
||
<p>There are many other dimensionality reduction techniques, several of which are available in Scikit-Learn.</p>
|
||
<p>Here are some of the most popular:</p>
|
||
<ul class="simple">
|
||
<li><p><strong>Multidimensional Scaling (MDS)</strong> reduces dimensionality while trying to preserve the distances between the instances.</p></li>
|
||
<li><p><strong>Isomap</strong> creates a graph by connecting each instance to its nearest neighbors, then reduces dimensionality while trying to preserve the geodesic distances between the instances.</p></li>
|
||
<li><p><strong>t-Distributed Stochastic Neighbor Embedding</strong> (t-SNE) reduces dimensionality while trying to keep similar instances close and dissimilar instances apart. It is mostly used for visualization, in particular to visualize clusters of instances in high-dimensional space (e.g., to visualize the MNIST images in 2D).</p></li>
|
||
<li><p>Linear Discriminant Analysis (LDA) is actually a classification algorithm, but during training it learns the most discriminative axes between the classes, and these axes can then be used to define a hyperplane onto which to project the data. The benefit is that the projection will keep classes as far apart as possible, so LDA is a good technique to reduce dimensionality before running another classification algorithm such as a Support Vector Machine (SVM) classifier discussed in the SVM lectures.</p></li>
|
||
</ul>
|
||
</section>
|
||
</section>
|
||
|
||
<script type="text/x-thebe-config">
|
||
{
|
||
requestKernel: true,
|
||
binderOptions: {
|
||
repo: "binder-examples/jupyter-stacks-datascience",
|
||
ref: "master",
|
||
},
|
||
codeMirrorConfig: {
|
||
theme: "abcdef",
|
||
mode: "python"
|
||
},
|
||
kernelOptions: {
|
||
name: "python3",
|
||
path: "./."
|
||
},
|
||
predefinedOutput: true
|
||
}
|
||
</script>
|
||
<script>kernelName = 'python3'</script>
|
||
|
||
</article>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<footer class="prev-next-footer d-print-none">
|
||
|
||
<div class="prev-next-area">
|
||
<a class="left-prev"
|
||
href="chapter7.html"
|
||
title="previous page">
|
||
<i class="fa-solid fa-angle-left"></i>
|
||
<div class="prev-next-info">
|
||
<p class="prev-next-subtitle">previous</p>
|
||
<p class="prev-next-title"><span class="section-number">10. </span>Ensemble Methods: From a Single Tree to Many Trees and Extreme Boosting, Meet the Jungle of Methods</p>
|
||
</div>
|
||
</a>
|
||
<a class="right-next"
|
||
href="clustering.html"
|
||
title="next page">
|
||
<div class="prev-next-info">
|
||
<p class="prev-next-subtitle">next</p>
|
||
<p class="prev-next-title"><span class="section-number">12. </span>Clustering and Unsupervised Learning</p>
|
||
</div>
|
||
<i class="fa-solid fa-angle-right"></i>
|
||
</a>
|
||
</div>
|
||
</footer>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<dialog id="pst-secondary-sidebar-modal"></dialog>
|
||
<div id="pst-secondary-sidebar" class="bd-sidebar-secondary bd-toc"><div class="sidebar-secondary-items sidebar-secondary__inner">
|
||
|
||
|
||
<div class="sidebar-secondary-item">
|
||
<div class="page-toc tocsection onthispage">
|
||
<i class="fa-solid fa-list"></i> Contents
|
||
</div>
|
||
<nav class="bd-toc-nav page-toc">
|
||
<ul class="visible nav section-nav flex-column">
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#introducing-the-covariance-and-correlation-functions">11.1. Introducing the Covariance and Correlation functions</a></li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#correlation-matrix">11.2. Correlation Matrix</a></li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#towards-the-pca-theorem">11.3. Towards the PCA theorem</a><ul class="nav section-nav flex-column">
|
||
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#the-algorithm-before-theorem">11.3.1. The Algorithm before theorem</a></li>
|
||
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#writing-our-own-pca-code">11.3.2. Writing our own PCA code</a></li>
|
||
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#diagonalize-the-sample-covariance-matrix-to-obtain-the-principal-components">11.3.3. Diagonalize the sample covariance matrix to obtain the principal components</a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#classical-pca-theorem">11.4. Classical PCA Theorem</a></li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#geometric-interpretation-and-link-with-singular-value-decomposition">11.5. Geometric Interpretation and link with Singular Value Decomposition</a></li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#pca-and-scikit-learn">11.6. PCA and scikit-learn</a></li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#back-to-the-cancer-data">11.7. Back to the Cancer Data</a><ul class="nav section-nav flex-column">
|
||
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#incremental-pca">11.7.1. Incremental PCA</a></li>
|
||
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#randomized-pca">11.7.2. Randomized PCA</a></li>
|
||
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#kernel-pca">11.7.3. Kernel PCA</a></li>
|
||
</ul>
|
||
</li>
|
||
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#other-techniques">11.8. Other techniques</a></li>
|
||
</ul>
|
||
</nav></div>
|
||
|
||
</div></div>
|
||
|
||
|
||
</div>
|
||
<footer class="bd-footer-content">
|
||
|
||
<div class="bd-footer-content__inner container">
|
||
|
||
<div class="footer-item">
|
||
|
||
<p class="component-author">
|
||
By Morten Hjorth-Jensen
|
||
</p>
|
||
|
||
</div>
|
||
|
||
<div class="footer-item">
|
||
|
||
|
||
<p class="copyright">
|
||
|
||
© Copyright 2023.
|
||
<br/>
|
||
|
||
</p>
|
||
|
||
</div>
|
||
|
||
<div class="footer-item">
|
||
|
||
</div>
|
||
|
||
<div class="footer-item">
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</footer>
|
||
|
||
|
||
</main>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Scripts loaded after <body> so the DOM is not blocked -->
|
||
<script defer src="_static/scripts/bootstrap.js?digest=26a4bc78f4c0ddb94549"></script>
|
||
<script defer src="_static/scripts/pydata-sphinx-theme.js?digest=26a4bc78f4c0ddb94549"></script>
|
||
|
||
<footer class="bd-footer">
|
||
</footer>
|
||
</body>
|
||
</html> |