Files
FYS-STK4155/doc/LectureNotes/_build/html/chapter8.html
T
Morten Hjorth-Jensen 24b52866e2 update
2025-08-31 21:54:16 +02:00

1325 lines
73 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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) &#8212; 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>
<!-- Loaded before other Sphinx assets -->
<link href="_static/styles/theme.css?digest=dfe6caa3a7d634c4db9b" rel="stylesheet" />
<link href="_static/styles/bootstrap.css?digest=dfe6caa3a7d634c4db9b" rel="stylesheet" />
<link href="_static/styles/pydata-sphinx-theme.css?digest=dfe6caa3a7d634c4db9b" rel="stylesheet" />
<link href="_static/vendor/fontawesome/6.5.2/css/all.min.css?digest=dfe6caa3a7d634c4db9b" rel="stylesheet" />
<link rel="preload" as="font" type="font/woff2" crossorigin href="_static/vendor/fontawesome/6.5.2/webfonts/fa-solid-900.woff2" />
<link rel="preload" as="font" type="font/woff2" crossorigin href="_static/vendor/fontawesome/6.5.2/webfonts/fa-brands-400.woff2" />
<link rel="preload" as="font" type="font/woff2" crossorigin href="_static/vendor/fontawesome/6.5.2/webfonts/fa-regular-400.woff2" />
<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=eba8b062" />
<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.8ecb98da25f57f5357bf6f572d296f466b2cfe2517ffebfabe82451661e28f02.css?v=6644e6bb" />
<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" />
<!-- Pre-loaded scripts that we'll load fully later -->
<link rel="preload" as="script" href="_static/scripts/bootstrap.js?digest=dfe6caa3a7d634c4db9b" />
<link rel="preload" as="script" href="_static/scripts/pydata-sphinx-theme.js?digest=dfe6caa3a7d634c4db9b" />
<script src="_static/vendor/fontawesome/6.5.2/js/all.min.js?digest=dfe6caa3a7d634c4db9b"></script>
<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"/>
</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>
<input type="checkbox"
class="sidebar-toggle"
id="pst-primary-sidebar-checkbox"/>
<label class="overlay overlay-primary" for="pst-primary-sidebar-checkbox"></label>
<input type="checkbox"
class="sidebar-toggle"
id="pst-secondary-sidebar-checkbox"/>
<label class="overlay overlay-secondary" for="pst-secondary-sidebar-checkbox"></label>
<div class="search-button__wrapper">
<div class="search-button__overlay"></div>
<div class="search-button__search-container">
<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"
id="search-input"
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></div>
</div>
<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">
<div 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"/>
<script>document.write(`<img src="_static/logo.png" class="logo__image only-dark" alt="Applied Data Analysis and Machine Learning - Home"/>`);</script>
</a></div>
<div class="sidebar-primary-item">
<script>
document.write(`
<button class="btn search-button-field search-button__button" 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>
`);
</script></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">Course setting</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 Gradient descent</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-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>
<script>
document.write(`
<button class="btn btn-sm nav-link pst-navbar-icon theme-switch-button" title="light/dark" aria-label="light/dark" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="theme-switch fa-solid fa-sun fa-lg" data-mode="light"></i>
<i class="theme-switch fa-solid fa-moon fa-lg" data-mode="dark"></i>
<i class="theme-switch fa-solid fa-circle-half-stroke fa-lg" data-mode="auto"></i>
</button>
`);
</script>
<script>
document.write(`
<button class="btn btn-sm pst-navbar-icon search-button search-button__button" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass fa-lg"></i>
</button>
`);
</script>
<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 &lt;&lt; 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}] &amp; \mathrm{cov}[\boldsymbol{x},\boldsymbol{y}] \\
\mathrm{cov}[\boldsymbol{y},\boldsymbol{x}] &amp; \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}] &amp; \mathrm{cov}[\boldsymbol{x},\boldsymbol{y}] \\
\mathrm{cov}[\boldsymbol{x},\boldsymbol{y}] &amp; \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 &amp; \mathrm{corr}[\boldsymbol{x},\boldsymbol{y}] \\
\mathrm{corr}[\boldsymbol{y},\boldsymbol{x}] &amp; 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} &amp; x_{0,1} &amp; x_{0,2}&amp; \dots &amp; \dots x_{0,p-1}\\
x_{1,0} &amp; x_{1,1} &amp; x_{1,2}&amp; \dots &amp; \dots x_{1,p-1}\\
x_{2,0} &amp; x_{2,1} &amp; x_{2,2}&amp; \dots &amp; \dots x_{2,p-1}\\
\dots &amp; \dots &amp; \dots &amp; \dots \dots &amp; \dots \\
x_{n-2,0} &amp; x_{n-2,1} &amp; x_{n-2,2}&amp; \dots &amp; \dots x_{n-2,p-1}\\
x_{n-1,0} &amp; x_{n-1,1} &amp; x_{n-1,2}&amp; \dots &amp; \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 &amp; \boldsymbol{x}_1 &amp; \boldsymbol{x}_2 &amp; \dots &amp; \dots &amp; \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} &amp; x_{1,i} &amp; x_{2,i}&amp; \dots &amp; \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] &amp; \mathrm{cov}[\boldsymbol{x}_0,\boldsymbol{x}_1] &amp; \mathrm{cov}[\boldsymbol{x}_0,\boldsymbol{x}_2] &amp; \dots &amp; \dots &amp; \mathrm{cov}[\boldsymbol{x}_0,\boldsymbol{x}_{p-1}]\\
\mathrm{cov}[\boldsymbol{x}_1,\boldsymbol{x}_0] &amp; \mathrm{var}[\boldsymbol{x}_1] &amp; \mathrm{cov}[\boldsymbol{x}_1,\boldsymbol{x}_2] &amp; \dots &amp; \dots &amp; \mathrm{cov}[\boldsymbol{x}_1,\boldsymbol{x}_{p-1}]\\
\mathrm{cov}[\boldsymbol{x}_2,\boldsymbol{x}_0] &amp; \mathrm{cov}[\boldsymbol{x}_2,\boldsymbol{x}_1] &amp; \mathrm{var}[\boldsymbol{x}_2] &amp; \dots &amp; \dots &amp; \mathrm{cov}[\boldsymbol{x}_2,\boldsymbol{x}_{p-1}]\\
\dots &amp; \dots &amp; \dots &amp; \dots &amp; \dots &amp; \dots \\
\dots &amp; \dots &amp; \dots &amp; \dots &amp; \dots &amp; \dots \\
\mathrm{cov}[\boldsymbol{x}_{p-1},\boldsymbol{x}_0] &amp; \mathrm{cov}[\boldsymbol{x}_{p-1},\boldsymbol{x}_1] &amp; \mathrm{cov}[\boldsymbol{x}_{p-1},\boldsymbol{x}_{2}] &amp; \dots &amp; \dots &amp; \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 &amp; \mathrm{corr}[\boldsymbol{x}_0,\boldsymbol{x}_1] &amp; \mathrm{corr}[\boldsymbol{x}_0,\boldsymbol{x}_2] &amp; \dots &amp; \dots &amp; \mathrm{corr}[\boldsymbol{x}_0,\boldsymbol{x}_{p-1}]\\
\mathrm{corr}[\boldsymbol{x}_1,\boldsymbol{x}_0] &amp; 1 &amp; \mathrm{corr}[\boldsymbol{x}_1,\boldsymbol{x}_2] &amp; \dots &amp; \dots &amp; \mathrm{corr}[\boldsymbol{x}_1,\boldsymbol{x}_{p-1}]\\
\mathrm{corr}[\boldsymbol{x}_2,\boldsymbol{x}_0] &amp; \mathrm{corr}[\boldsymbol{x}_2,\boldsymbol{x}_1] &amp; 1 &amp; \dots &amp; \dots &amp; \mathrm{corr}[\boldsymbol{x}_2,\boldsymbol{x}_{p-1}]\\
\dots &amp; \dots &amp; \dots &amp; \dots &amp; \dots &amp; \dots \\
\dots &amp; \dots &amp; \dots &amp; \dots &amp; \dots &amp; \dots \\
\mathrm{corr}[\boldsymbol{x}_{p-1},\boldsymbol{x}_0] &amp; \mathrm{corr}[\boldsymbol{x}_{p-1},\boldsymbol{x}_1] &amp; \mathrm{corr}[\boldsymbol{x}_{p-1},\boldsymbol{x}_{2}] &amp; \dots &amp; \dots &amp; 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 &amp; y_0 \\
x_1 &amp; y_1 \\
x_2 &amp; y_2\\
\dots &amp; \dots \\
x_{n-2} &amp; y_{n-2}\\
x_{n-1} &amp; y_{n-1} &amp;
\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-none notranslate"><div class="highlight"><pre><span></span># Importing various packages
import numpy as np
n = 100
x = np.random.normal(size=n)
print(np.mean(x))
y = 4+3*x+np.random.normal(size=n)
print(np.mean(y))
W = np.vstack((x, y))
C = np.cov(W)
print(C)
</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-none notranslate"><div class="highlight"><pre><span></span>import numpy as np
n = 100
# define two vectors
x = np.random.random(size=n)
y = 4+3*x+np.random.normal(size=n)
#scaling the x and y vectors
x = x - np.mean(x)
y = y - np.mean(y)
variance_x = np.sum(x@x)/n
variance_y = np.sum(y@y)/n
print(variance_x)
print(variance_y)
cov_xy = np.sum(x@y)/n
cov_xx = np.sum(x@x)/n
cov_yy = np.sum(y@y)/n
C = np.zeros((2,2))
C[0,0]= cov_xx/variance_x
C[1,1]= cov_yy/variance_y
C[0,1]= cov_xy/np.sqrt(variance_y*variance_x)
C[1,0]= C[0,1]
print(C)
</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-none notranslate"><div class="highlight"><pre><span></span>import numpy as np
import pandas as pd
n = 10
x = np.random.normal(size=n)
x = x - np.mean(x)
y = 4+3*x+np.random.normal(size=n)
y = y - np.mean(y)
X = (np.vstack((x, y))).T
print(X)
Xpd = pd.DataFrame(X)
print(Xpd)
correlation_matrix = Xpd.corr()
print(correlation_matrix)
</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-none notranslate"><div class="highlight"><pre><span></span># Common imports
import numpy as np
import pandas as pd
def FrankeFunction(x,y):
term1 = 0.75*np.exp(-(0.25*(9*x-2)**2) - 0.25*((9*y-2)**2))
term2 = 0.75*np.exp(-((9*x+1)**2)/49.0 - 0.1*(9*y+1))
term3 = 0.5*np.exp(-(9*x-7)**2/4.0 - 0.25*((9*y-3)**2))
term4 = -0.2*np.exp(-(9*x-4)**2 - (9*y-7)**2)
return term1 + term2 + term3 + term4
def create_X(x, y, n ):
if len(x.shape) &gt; 1:
x = np.ravel(x)
y = np.ravel(y)
N = len(x)
l = int((n+1)*(n+2)/2) # Number of elements in beta
X = np.ones((N,l))
for i in range(1,n+1):
q = int((i)*(i+1)/2)
for k in range(i+1):
X[:,q+k] = (x**(i-k))*(y**k)
return X
# Making meshgrid of datapoints and compute Franke&#39;s function
n = 4
N = 100
x = np.sort(np.random.uniform(0, 1, N))
y = np.sort(np.random.uniform(0, 1, N))
z = FrankeFunction(x, y)
X = create_X(x, y, n=n)
Xpd = pd.DataFrame(X)
# subtract the mean values and set up the covariance matrix
Xpd = Xpd - Xpd.mean()
covariance_matrix = Xpd.cov()
print(covariance_matrix)
</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} &amp; x_{01}\\
x_{10} &amp; x_{11}\\
\end{bmatrix}=\begin{bmatrix}
\boldsymbol{x}_{0} &amp; \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 &amp; x_{00}x_{10}+x_{01}x_{11}\\
x_{10}x_{00}+x_{11}x_{01} &amp; 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] &amp; \mathrm{cov}[\boldsymbol{x}_0,\boldsymbol{x}_1] \\
\mathrm{cov}[\boldsymbol{x}_1,\boldsymbol{x}_0] &amp; \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 &gt; \lambda_1 &gt; \dots &gt; \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 &lt;&lt; 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>Heres 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} &amp; x_{0,1} &amp; x_{0,2}&amp; \dots &amp; \dots x_{0,p-1}\\
x_{1,0} &amp; x_{1,1} &amp; x_{1,2}&amp; \dots &amp; \dots x_{1,p-1}\\
x_{2,0} &amp; x_{2,1} &amp; x_{2,2}&amp; \dots &amp; \dots x_{2,p-1}\\
\dots &amp; \dots &amp; \dots &amp; \dots \dots &amp; \dots \\
x_{n-2,0} &amp; x_{n-2,1} &amp; x_{n-2,2}&amp; \dots &amp; \dots x_{n-2,p-1}\\
x_{n-1,0} &amp; x_{n-1,1} &amp; x_{n-1,2}&amp; \dots &amp; \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 &amp; 2 \\
2 &amp; 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-none notranslate"><div class="highlight"><pre><span></span>%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import display
n = 10000
mean = (-1, 2)
cov = [[4, 2], [2, 2]]
X = np.random.multivariate_normal(mean, cov, n)
</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-none notranslate"><div class="highlight"><pre><span></span>df = pd.DataFrame(X)
# Pandas does the centering for us
df = df -df.mean()
# we center it ourselves
X_centered = X - X.mean(axis=0)
</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-none notranslate"><div class="highlight"><pre><span></span>print(df.cov())
print(np.cov(X_centered.T))
</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-none notranslate"><div class="highlight"><pre><span></span># extract the relevant columns from the centered design matrix of dim n x 2
x = X_centered[:,0]
y = X_centered[:,1]
Cov = np.zeros((2,2))
Cov[0,1] = np.sum(x.T@y)/(n-1.0)
Cov[0,0] = np.sum(x.T@x)/(n-1.0)
Cov[1,1] = np.sum(y.T@y)/(n-1.0)
Cov[1,0]= Cov[0,1]
print(&quot;Centered covariance using own code&quot;)
print(Cov)
plt.plot(x, y, &#39;x&#39;)
plt.axis(&#39;equal&#39;)
plt.show()
</pre></div>
</div>
</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-none notranslate"><div class="highlight"><pre><span></span># diagonalize and obtain eigenvalues, not necessarily sorted
EigValues, EigVectors = np.linalg.eig(Cov)
# sort eigenvectors and eigenvalues
#permute = EigValues.argsort()
#EigValues = EigValues[permute]
#EigVectors = EigVectors[:,permute]
print(&quot;Eigenvalues of Covariance matrix&quot;)
for i in range(2):
print(EigValues[i])
FirstEigvector = EigVectors[:,0]
SecondEigvector = EigVectors[:,1]
print(&quot;First eigenvector&quot;)
print(FirstEigvector)
print(&quot;Second eigenvector&quot;)
print(SecondEigvector)
#thereafter we do a PCA with Scikit-learn
from sklearn.decomposition import PCA
pca = PCA(n_components = 2)
X2Dsl = pca.fit_transform(X)
print(&quot;Eigenvector of largest eigenvalue&quot;)
print(pca.components_.T[:, 0])
</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 &lt;&lt; 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 Murphys 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 NumPys <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-none notranslate"><div class="highlight"><pre><span></span>import numpy as np
import pandas as pd
from IPython.display import display
np.random.seed(100)
# setting up a 10 x 5 vanilla matrix
rows = 10
cols = 5
X = np.random.randn(rows,cols)
df = pd.DataFrame(X)
# Pandas does the centering for us
df = df -df.mean()
display(df)
# we center it ourselves
X_centered = X - X.mean(axis=0)
# Then check the difference between pandas and our own set up
print(X_centered-df)
#Now we do an SVD
U, s, V = np.linalg.svd(X_centered)
c1 = V.T[:, 0]
c2 = V.T[:, 1]
W2 = V.T[:, :2]
X2D = X_centered.dot(W2)
print(X2D)
</pre></div>
</div>
</div>
</div>
<p>PCA assumes that the dataset is centered around the origin. Scikit-Learns 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, dont
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-none notranslate"><div class="highlight"><pre><span></span>W2 = V.T[:, :2]
X2D = X_centered.dot(W2)
</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-Learns 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-none notranslate"><div class="highlight"><pre><span></span>#thereafter we do a PCA with Scikit-learn
from sklearn.decomposition import PCA
pca = PCA(n_components = 2)
X2D = pca.fit_transform(X)
print(X2D)
</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-none notranslate"><div class="highlight"><pre><span></span>pca.components_.T[:, 0]
</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 datasets
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-none notranslate"><div class="highlight"><pre><span></span>import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data,cancer.target,random_state=0)
logreg = LogisticRegression()
logreg.fit(X_train, y_train)
print(&quot;Train set accuracy from Logistic Regression: {:.2f}&quot;.format(logreg.score(X_train,y_train)))
# We scale the data
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train_scaled = scaler.transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Then perform again a log reg fit
logreg.fit(X_train_scaled, y_train)
print(&quot;Train set accuracy scaled data: {:.2f}&quot;.format(logreg.score(X_train_scaled,y_train)))
#thereafter we do a PCA with Scikit-learn
from sklearn.decomposition import PCA
pca = PCA(n_components = 2)
X2D_train = pca.fit_transform(X_train_scaled)
# and finally compute the log reg fit and the score on the training data
logreg.fit(X2D_train,y_train)
print(&quot;Train set accuracy scaled and PCA data: {:.2f}&quot;.format(logreg.score(X2D_train,y_train)))
</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 sets variance:</p>
<div class="cell docutils container">
<div class="cell_input docutils container">
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>pca = PCA()
pca.fit(X)
cumsum = np.cumsum(pca.explained_variance_ratio_)
d = np.argmax(cumsum &gt;= 0.95) + 1
</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-none notranslate"><div class="highlight"><pre><span></span>pca = PCA(n_components=0.95)
X_reduced = pca.fit_transform(X)
</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-Learns KernelPCA class to perform kPCA with an</p>
<div class="cell docutils container">
<div class="cell_input docutils container">
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>from sklearn.decomposition import KernelPCA
rbf_pca = KernelPCA(n_components = 2, kernel=&quot;rbf&quot;, gamma=0.04)
X_reduced = rbf_pca.fit_transform(X)
</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>
<div 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 src="_static/scripts/bootstrap.js?digest=dfe6caa3a7d634c4db9b"></script>
<script src="_static/scripts/pydata-sphinx-theme.js?digest=dfe6caa3a7d634c4db9b"></script>
<footer class="bd-footer">
</footer>
</body>
</html>