527 lines
36 KiB
HTML
527 lines
36 KiB
HTML
<!--
|
|
Automatically generated HTML file from DocOnce source
|
|
(https://github.com/hplgit/doconce/)
|
|
-->
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<meta name="generator" content="DocOnce: https://github.com/hplgit/doconce/" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<meta name="description" content="Data Analysis and Machine Learning: Preprocessing and Dimensionality Reduction">
|
|
|
|
<title>Data Analysis and Machine Learning: Preprocessing and Dimensionality Reduction</title>
|
|
|
|
|
|
<style type="text/css">
|
|
/* bloodish style */
|
|
|
|
body {
|
|
font-family: Helvetica, Verdana, Arial, Sans-serif;
|
|
color: #404040;
|
|
background: #ffffff;
|
|
}
|
|
h1 { font-size: 1.8em; color: #8A0808; }
|
|
h2 { font-size: 1.6em; color: #8A0808; }
|
|
h3 { font-size: 1.4em; color: #8A0808; }
|
|
h4 { color: #8A0808; }
|
|
a { color: #8A0808; text-decoration:none; }
|
|
tt { font-family: "Courier New", Courier; }
|
|
/* pre style removed because it will interfer with pygments */
|
|
p { text-indent: 0px; }
|
|
hr { border: 0; width: 80%; border-bottom: 1px solid #aaa}
|
|
p.caption { width: 80%; font-style: normal; text-align: left; }
|
|
hr.figure { border: 0; width: 80%; border-bottom: 1px solid #aaa}
|
|
.alert-text-small { font-size: 80%; }
|
|
.alert-text-large { font-size: 130%; }
|
|
.alert-text-normal { font-size: 90%; }
|
|
.alert {
|
|
padding:8px 35px 8px 14px; margin-bottom:18px;
|
|
text-shadow:0 1px 0 rgba(255,255,255,0.5);
|
|
border:1px solid #bababa;
|
|
border-radius: 4px;
|
|
-webkit-border-radius: 4px;
|
|
-moz-border-radius: 4px;
|
|
color: #555;
|
|
background-color: #f8f8f8;
|
|
background-position: 10px 5px;
|
|
background-repeat: no-repeat;
|
|
background-size: 38px;
|
|
padding-left: 55px;
|
|
width: 75%;
|
|
}
|
|
.alert-block {padding-top:14px; padding-bottom:14px}
|
|
.alert-block > p, .alert-block > ul {margin-bottom:1em}
|
|
.alert li {margin-top: 1em}
|
|
.alert-block p+p {margin-top:5px}
|
|
.alert-notice { background-image: url(https://cdn.rawgit.com/hplgit/doconce/master/bundled/html_images/small_gray_notice.png); }
|
|
.alert-summary { background-image:url(https://cdn.rawgit.com/hplgit/doconce/master/bundled/html_images/small_gray_summary.png); }
|
|
.alert-warning { background-image: url(https://cdn.rawgit.com/hplgit/doconce/master/bundled/html_images/small_gray_warning.png); }
|
|
.alert-question {background-image:url(https://cdn.rawgit.com/hplgit/doconce/master/bundled/html_images/small_gray_question.png); }
|
|
|
|
div { text-align: justify; text-justify: inter-word; }
|
|
</style>
|
|
|
|
|
|
</head>
|
|
|
|
<!-- tocinfo
|
|
{'highest level': 2,
|
|
'sections': [('Reducing the number of degrees of freedom, overarching view',
|
|
2,
|
|
None,
|
|
'___sec0'),
|
|
('Preprocessing our data', 2, None, '___sec1'),
|
|
('Simple preprocessing examples, Franke function and regression',
|
|
2,
|
|
None,
|
|
'___sec2'),
|
|
('Simple preprocessing examples, breast cancer data and '
|
|
'classification',
|
|
2,
|
|
None,
|
|
'___sec3'),
|
|
('Principal Component Analysis', 2, None, '___sec4'),
|
|
('PCA and scikit-learn', 2, None, '___sec5'),
|
|
('More on the PCA', 2, None, '___sec6'),
|
|
('Incremental PCA', 2, None, '___sec7'),
|
|
('Randomized PCA', 2, None, '___sec8'),
|
|
('Kernel PCA', 2, None, '___sec9'),
|
|
('LLE', 2, None, '___sec10'),
|
|
('Other techniques', 2, None, '___sec11')]}
|
|
end of tocinfo -->
|
|
|
|
<body>
|
|
|
|
|
|
|
|
<script type="text/x-mathjax-config">
|
|
MathJax.Hub.Config({
|
|
TeX: {
|
|
equationNumbers: { autoNumber: "AMS" },
|
|
extensions: ["AMSmath.js", "AMSsymbols.js", "autobold.js", "color.js"]
|
|
}
|
|
});
|
|
</script>
|
|
<script type="text/javascript" async
|
|
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<!-- ------------------- main content ---------------------- -->
|
|
|
|
|
|
|
|
<center><h1>Data Analysis and Machine Learning: Preprocessing and Dimensionality Reduction</h1></center> <!-- document title -->
|
|
|
|
<p>
|
|
<!-- author(s): Morten Hjorth-Jensen -->
|
|
|
|
<center>
|
|
<b>Morten Hjorth-Jensen</b> [1, 2]
|
|
</center>
|
|
|
|
<p>
|
|
<!-- institution(s) -->
|
|
|
|
<center>[1] <b>Department of Physics, University of Oslo</b></center>
|
|
<center>[2] <b>Department of Physics and Astronomy and National Superconducting Cyclotron Laboratory, Michigan State University</b></center>
|
|
<br>
|
|
<p>
|
|
<center><h4>Oct 14, 2019</h4></center> <!-- date -->
|
|
<br>
|
|
<p>
|
|
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
|
|
|
|
<h2 id="___sec0">Reducing the number of degrees of freedom, overarching view </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<p>
|
|
|
|
<p>
|
|
Many Machine Learning problems involve thousands or even millions of features for each training
|
|
instance. Not only does this make training extremely slow, it can also make it much harder to find a good
|
|
solution, as we will see. This problem is often referred to as the curse of dimensionality.
|
|
Fortunately, in real-world problems, it is often possible to reduce the number of features considerably,
|
|
turning an intractable problem into a tractable one.
|
|
|
|
<p>
|
|
Here we will discuss some of the most popular dimensionality
|
|
reduction techniques: the principal component analysis PCA, Kernel PCA, and Locally Linear Embedding (LLE).
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
|
|
|
|
<h2 id="___sec1">Preprocessing our data </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<p>
|
|
|
|
<p>
|
|
Before we proceed however, we will discuss how to preprocess our
|
|
data. Till now and in connection with our previous examples we have not met so many cases
|
|
where we are too sensitive to the scaling of our data. Normally the
|
|
data may need a rescaling and/or may be sensitive to extreme
|
|
values. Scaling the data renders our inputs much more suitable for the
|
|
algorithms we want to employ.
|
|
|
|
<p>
|
|
<b>Scikit-Learn</b> has several functions which allow us to rescale the data, normally resulting in much better results in terms of various accuracy scores. The <b>StandardScaler</b> function in <b>Scikit-Learn</b> ensures that for each feature/predictor we study the mean value is zero and the variance is zero (every column in the design/feature matrix).
|
|
This scaling has the drawback that it does not ensure that we have a particular maximum or minumum in our data set. Another function included in <b>Scikit-Learn</b> is the <b>MinMaxScaler</b> which ensures that all features are exactly between \( 0 \) and \( 1 \). The <b>Normalizer</b> function scales each column of the design matrix by its Euclidean norm.
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
|
|
|
|
<h2 id="___sec2">Simple preprocessing examples, Franke function and regression </h2>
|
|
|
|
<p>
|
|
|
|
<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span><span style="color: #408080; font-style: italic"># Common imports</span>
|
|
<span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">os</span>
|
|
<span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">numpy</span> <span style="color: #008000; font-weight: bold">as</span> <span style="color: #0000FF; font-weight: bold">np</span>
|
|
<span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">pandas</span> <span style="color: #008000; font-weight: bold">as</span> <span style="color: #0000FF; font-weight: bold">pd</span>
|
|
<span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">matplotlib.pyplot</span> <span style="color: #008000; font-weight: bold">as</span> <span style="color: #0000FF; font-weight: bold">plt</span>
|
|
<span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">sklearn.linear_model</span> <span style="color: #008000; font-weight: bold">as</span> <span style="color: #0000FF; font-weight: bold">skl</span>
|
|
<span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">sklearn.metrics</span> <span style="color: #008000; font-weight: bold">import</span> mean_squared_error
|
|
<span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">sklearn.model_selection</span> <span style="color: #008000; font-weight: bold">import</span> train_test_split
|
|
<span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">sklearn.preprocessing</span> <span style="color: #008000; font-weight: bold">import</span> MinMaxScaler, StandardScaler, Normalizer
|
|
<span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">sklearn.svm</span> <span style="color: #008000; font-weight: bold">import</span> SVR
|
|
|
|
<span style="color: #408080; font-style: italic"># Where to save the figures and data files</span>
|
|
PROJECT_ROOT_DIR <span style="color: #666666">=</span> <span style="color: #BA2121">"Results"</span>
|
|
FIGURE_ID <span style="color: #666666">=</span> <span style="color: #BA2121">"Results/FigureFiles"</span>
|
|
DATA_ID <span style="color: #666666">=</span> <span style="color: #BA2121">"DataFiles/"</span>
|
|
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #AA22FF; font-weight: bold">not</span> os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>exists(PROJECT_ROOT_DIR):
|
|
os<span style="color: #666666">.</span>mkdir(PROJECT_ROOT_DIR)
|
|
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #AA22FF; font-weight: bold">not</span> os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>exists(FIGURE_ID):
|
|
os<span style="color: #666666">.</span>makedirs(FIGURE_ID)
|
|
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #AA22FF; font-weight: bold">not</span> os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>exists(DATA_ID):
|
|
os<span style="color: #666666">.</span>makedirs(DATA_ID)
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">image_path</span>(fig_id):
|
|
<span style="color: #008000; font-weight: bold">return</span> os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>join(FIGURE_ID, fig_id)
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">data_path</span>(dat_id):
|
|
<span style="color: #008000; font-weight: bold">return</span> os<span style="color: #666666">.</span>path<span style="color: #666666">.</span>join(DATA_ID, dat_id)
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">save_fig</span>(fig_id):
|
|
plt<span style="color: #666666">.</span>savefig(image_path(fig_id) <span style="color: #666666">+</span> <span style="color: #BA2121">".png"</span>, format<span style="color: #666666">=</span><span style="color: #BA2121">'png'</span>)
|
|
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">FrankeFunction</span>(x,y):
|
|
term1 <span style="color: #666666">=</span> <span style="color: #666666">0.75*</span>np<span style="color: #666666">.</span>exp(<span style="color: #666666">-</span>(<span style="color: #666666">0.25*</span>(<span style="color: #666666">9*</span>x<span style="color: #666666">-2</span>)<span style="color: #666666">**2</span>) <span style="color: #666666">-</span> <span style="color: #666666">0.25*</span>((<span style="color: #666666">9*</span>y<span style="color: #666666">-2</span>)<span style="color: #666666">**2</span>))
|
|
term2 <span style="color: #666666">=</span> <span style="color: #666666">0.75*</span>np<span style="color: #666666">.</span>exp(<span style="color: #666666">-</span>((<span style="color: #666666">9*</span>x<span style="color: #666666">+1</span>)<span style="color: #666666">**2</span>)<span style="color: #666666">/49.0</span> <span style="color: #666666">-</span> <span style="color: #666666">0.1*</span>(<span style="color: #666666">9*</span>y<span style="color: #666666">+1</span>))
|
|
term3 <span style="color: #666666">=</span> <span style="color: #666666">0.5*</span>np<span style="color: #666666">.</span>exp(<span style="color: #666666">-</span>(<span style="color: #666666">9*</span>x<span style="color: #666666">-7</span>)<span style="color: #666666">**2/4.0</span> <span style="color: #666666">-</span> <span style="color: #666666">0.25*</span>((<span style="color: #666666">9*</span>y<span style="color: #666666">-3</span>)<span style="color: #666666">**2</span>))
|
|
term4 <span style="color: #666666">=</span> <span style="color: #666666">-0.2*</span>np<span style="color: #666666">.</span>exp(<span style="color: #666666">-</span>(<span style="color: #666666">9*</span>x<span style="color: #666666">-4</span>)<span style="color: #666666">**2</span> <span style="color: #666666">-</span> (<span style="color: #666666">9*</span>y<span style="color: #666666">-7</span>)<span style="color: #666666">**2</span>)
|
|
<span style="color: #008000; font-weight: bold">return</span> term1 <span style="color: #666666">+</span> term2 <span style="color: #666666">+</span> term3 <span style="color: #666666">+</span> term4
|
|
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">create_X</span>(x, y, n ):
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #008000">len</span>(x<span style="color: #666666">.</span>shape) <span style="color: #666666">></span> <span style="color: #666666">1</span>:
|
|
x <span style="color: #666666">=</span> np<span style="color: #666666">.</span>ravel(x)
|
|
y <span style="color: #666666">=</span> np<span style="color: #666666">.</span>ravel(y)
|
|
|
|
N <span style="color: #666666">=</span> <span style="color: #008000">len</span>(x)
|
|
l <span style="color: #666666">=</span> <span style="color: #008000">int</span>((n<span style="color: #666666">+1</span>)<span style="color: #666666">*</span>(n<span style="color: #666666">+2</span>)<span style="color: #666666">/2</span>) <span style="color: #408080; font-style: italic"># Number of elements in beta</span>
|
|
X <span style="color: #666666">=</span> np<span style="color: #666666">.</span>ones((N,l))
|
|
|
|
<span style="color: #008000; font-weight: bold">for</span> i <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #008000">range</span>(<span style="color: #666666">1</span>,n<span style="color: #666666">+1</span>):
|
|
q <span style="color: #666666">=</span> <span style="color: #008000">int</span>((i)<span style="color: #666666">*</span>(i<span style="color: #666666">+1</span>)<span style="color: #666666">/2</span>)
|
|
<span style="color: #008000; font-weight: bold">for</span> k <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #008000">range</span>(i<span style="color: #666666">+1</span>):
|
|
X[:,q<span style="color: #666666">+</span>k] <span style="color: #666666">=</span> (x<span style="color: #666666">**</span>(i<span style="color: #666666">-</span>k))<span style="color: #666666">*</span>(y<span style="color: #666666">**</span>k)
|
|
|
|
<span style="color: #008000; font-weight: bold">return</span> X
|
|
|
|
|
|
<span style="color: #408080; font-style: italic"># Making meshgrid of datapoints and compute Franke's function</span>
|
|
n <span style="color: #666666">=</span> <span style="color: #666666">5</span>
|
|
N <span style="color: #666666">=</span> <span style="color: #666666">1000</span>
|
|
x <span style="color: #666666">=</span> np<span style="color: #666666">.</span>sort(np<span style="color: #666666">.</span>random<span style="color: #666666">.</span>uniform(<span style="color: #666666">0</span>, <span style="color: #666666">1</span>, N))
|
|
y <span style="color: #666666">=</span> np<span style="color: #666666">.</span>sort(np<span style="color: #666666">.</span>random<span style="color: #666666">.</span>uniform(<span style="color: #666666">0</span>, <span style="color: #666666">1</span>, N))
|
|
z <span style="color: #666666">=</span> FrankeFunction(x, y)
|
|
X <span style="color: #666666">=</span> create_X(x, y, n<span style="color: #666666">=</span>n)
|
|
<span style="color: #408080; font-style: italic"># split in training and test data</span>
|
|
X_train, X_test, y_train, y_test <span style="color: #666666">=</span> train_test_split(X,z,test_size<span style="color: #666666">=0.2</span>)
|
|
|
|
|
|
svm <span style="color: #666666">=</span> SVR(gamma<span style="color: #666666">=</span><span style="color: #BA2121">'auto'</span>,C<span style="color: #666666">=10.0</span>)
|
|
svm<span style="color: #666666">.</span>fit(X_train, y_train)
|
|
|
|
<span style="color: #408080; font-style: italic"># The mean squared error and R2 score</span>
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"MSE before scaling: {:.2f}"</span><span style="color: #666666">.</span>format(mean_squared_error(svm<span style="color: #666666">.</span>predict(X_test), y_test)))
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"R2 score before scaling {:.2f}"</span><span style="color: #666666">.</span>format(svm<span style="color: #666666">.</span>score(X_test,y_test)))
|
|
|
|
scaler <span style="color: #666666">=</span> StandardScaler()
|
|
scaler<span style="color: #666666">.</span>fit(X_train)
|
|
X_train_scaled <span style="color: #666666">=</span> scaler<span style="color: #666666">.</span>transform(X_train)
|
|
X_test_scaled <span style="color: #666666">=</span> scaler<span style="color: #666666">.</span>transform(X_test)
|
|
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"Feature min values before scaling:</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121"> {}"</span><span style="color: #666666">.</span>format(X_train<span style="color: #666666">.</span>min(axis<span style="color: #666666">=0</span>)))
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"Feature max values before scaling:</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121"> {}"</span><span style="color: #666666">.</span>format(X_train<span style="color: #666666">.</span>max(axis<span style="color: #666666">=0</span>)))
|
|
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"Feature min values after scaling:</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121"> {}"</span><span style="color: #666666">.</span>format(X_train_scaled<span style="color: #666666">.</span>min(axis<span style="color: #666666">=0</span>)))
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"Feature max values after scaling:</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121"> {}"</span><span style="color: #666666">.</span>format(X_train_scaled<span style="color: #666666">.</span>max(axis<span style="color: #666666">=0</span>)))
|
|
|
|
svm <span style="color: #666666">=</span> SVR(gamma<span style="color: #666666">=</span><span style="color: #BA2121">'auto'</span>,C<span style="color: #666666">=10.0</span>)
|
|
svm<span style="color: #666666">.</span>fit(X_train_scaled, y_train)
|
|
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"MSE after scaling: {:.2f}"</span><span style="color: #666666">.</span>format(mean_squared_error(svm<span style="color: #666666">.</span>predict(X_test_scaled), y_test)))
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"R2 score for scaled data: {:.2f}"</span><span style="color: #666666">.</span>format(svm<span style="color: #666666">.</span>score(X_test_scaled,y_test)))
|
|
</pre></div>
|
|
<p>
|
|
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
|
|
|
|
<h2 id="___sec3">Simple preprocessing examples, breast cancer data and classification </h2>
|
|
|
|
<p>
|
|
We show here how we can use a simple regression case on the breast cancer data using support vector machine as algorithm for classification
|
|
|
|
<p>
|
|
|
|
<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span><span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">matplotlib.pyplot</span> <span style="color: #008000; font-weight: bold">as</span> <span style="color: #0000FF; font-weight: bold">plt</span>
|
|
<span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">numpy</span> <span style="color: #008000; font-weight: bold">as</span> <span style="color: #0000FF; font-weight: bold">np</span>
|
|
<span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">sklearn.model_selection</span> <span style="color: #008000; font-weight: bold">import</span> train_test_split
|
|
<span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">sklearn.datasets</span> <span style="color: #008000; font-weight: bold">import</span> load_breast_cancer
|
|
<span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">sklearn.svm</span> <span style="color: #008000; font-weight: bold">import</span> SVC
|
|
cancer <span style="color: #666666">=</span> load_breast_cancer()
|
|
|
|
X_train, X_test, y_train, y_test <span style="color: #666666">=</span> train_test_split(cancer<span style="color: #666666">.</span>data,cancer<span style="color: #666666">.</span>target,random_state<span style="color: #666666">=0</span>)
|
|
<span style="color: #008000; font-weight: bold">print</span>(X_train<span style="color: #666666">.</span>shape)
|
|
<span style="color: #008000; font-weight: bold">print</span>(X_test<span style="color: #666666">.</span>shape)
|
|
|
|
svm <span style="color: #666666">=</span> SVC(C<span style="color: #666666">=100</span>)
|
|
svm<span style="color: #666666">.</span>fit(X_train, y_train)
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"Test set accuracy: {:.2f}"</span><span style="color: #666666">.</span>format(svm<span style="color: #666666">.</span>score(X_test,y_test)))
|
|
|
|
<span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">sklearn.preprocessing</span> <span style="color: #008000; font-weight: bold">import</span> MinMaxScaler, StandardScaler
|
|
|
|
scaler <span style="color: #666666">=</span> MinMaxScaler()
|
|
scaler<span style="color: #666666">.</span>fit(X_train)
|
|
X_train_scaled <span style="color: #666666">=</span> scaler<span style="color: #666666">.</span>transform(X_train)
|
|
X_test_scaled <span style="color: #666666">=</span> scaler<span style="color: #666666">.</span>transform(X_test)
|
|
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"Feature min values before scaling:</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121"> {}"</span><span style="color: #666666">.</span>format(X_train<span style="color: #666666">.</span>min(axis<span style="color: #666666">=0</span>)))
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"Feature max values before scaling:</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121"> {}"</span><span style="color: #666666">.</span>format(X_train<span style="color: #666666">.</span>max(axis<span style="color: #666666">=0</span>)))
|
|
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"Feature min values before scaling:</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121"> {}"</span><span style="color: #666666">.</span>format(X_train_scaled<span style="color: #666666">.</span>min(axis<span style="color: #666666">=0</span>)))
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"Feature max values before scaling:</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121"> {}"</span><span style="color: #666666">.</span>format(X_train_scaled<span style="color: #666666">.</span>max(axis<span style="color: #666666">=0</span>)))
|
|
|
|
|
|
svm<span style="color: #666666">.</span>fit(X_train_scaled, y_train)
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"Test set accuracy scaled data: {:.2f}"</span><span style="color: #666666">.</span>format(svm<span style="color: #666666">.</span>score(X_test_scaled,y_test)))
|
|
|
|
scaler <span style="color: #666666">=</span> StandardScaler()
|
|
scaler<span style="color: #666666">.</span>fit(X_train)
|
|
X_train_scaled <span style="color: #666666">=</span> scaler<span style="color: #666666">.</span>transform(X_train)
|
|
X_test_scaled <span style="color: #666666">=</span> scaler<span style="color: #666666">.</span>transform(X_test)
|
|
|
|
svm<span style="color: #666666">.</span>fit(X_train_scaled, y_train)
|
|
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">"Test set accuracy scaled data: {:.2f}"</span><span style="color: #666666">.</span>format(svm<span style="color: #666666">.</span>score(X_test_scaled,y_test)))
|
|
</pre></div>
|
|
<p>
|
|
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
|
|
|
|
<h2 id="___sec4">Principal Component Analysis </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<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>
|
|
The following Python code uses NumPy’s <b>svd()</b> function to obtain all the principal components of the
|
|
training set, then extracts the first two principal components
|
|
<p>
|
|
|
|
<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>X_centered <span style="color: #666666">=</span> X <span style="color: #666666">-</span> X<span style="color: #666666">.</span>mean(axis<span style="color: #666666">=0</span>)
|
|
U, s, V <span style="color: #666666">=</span> np<span style="color: #666666">.</span>linalg<span style="color: #666666">.</span>svd(X_centered)
|
|
c1 <span style="color: #666666">=</span> V<span style="color: #666666">.</span>T[:, <span style="color: #666666">0</span>]
|
|
c2 <span style="color: #666666">=</span> V<span style="color: #666666">.</span>T[:, <span style="color: #666666">1</span>]
|
|
</pre></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>
|
|
Once you have identified all the principal components, you can reduce the dimensionality of the dataset
|
|
down to \( d \) dimensions by projecting it onto the hyperplane defined by the first \( d \) principal components.
|
|
Selecting this hyperplane ensures that the projection will preserve as much variance as possible.
|
|
<p>
|
|
|
|
<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>W2 <span style="color: #666666">=</span> V<span style="color: #666666">.</span>T[:, :<span style="color: #666666">2</span>]
|
|
X2D <span style="color: #666666">=</span> X_centered<span style="color: #666666">.</span>dot(W2)
|
|
</pre></div>
|
|
<p>
|
|
<!-- !split -->
|
|
|
|
<h2 id="___sec5">PCA and scikit-learn </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>
|
|
|
|
<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span><span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">sklearn.decomposition</span> <span style="color: #008000; font-weight: bold">import</span> PCA
|
|
pca <span style="color: #666666">=</span> PCA(n_components <span style="color: #666666">=</span> <span style="color: #666666">2</span>)
|
|
X2D <span style="color: #666666">=</span> pca<span style="color: #666666">.</span>fit_transform(X)
|
|
</pre></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>
|
|
|
|
<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>pca<span style="color: #666666">.</span>components_<span style="color: #666666">.</span>T[:, <span style="color: #666666">0</span>])<span style="color: #666666">.</span>
|
|
</pre></div>
|
|
<p>
|
|
Another very useful piece of information is the explained variance ratio of each principal component,
|
|
available via the \( explained\_variance\_ratio \) variable. It indicates the proportion of the dataset’s
|
|
variance that lies along the axis of each principal component.
|
|
More material to come here.
|
|
|
|
<p>
|
|
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
|
|
|
|
<h2 id="___sec6">More on the PCA </h2>
|
|
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>
|
|
|
|
<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>pca <span style="color: #666666">=</span> PCA()
|
|
pca<span style="color: #666666">.</span>fit(X)
|
|
cumsum <span style="color: #666666">=</span> np<span style="color: #666666">.</span>cumsum(pca<span style="color: #666666">.</span>explained_variance_ratio_)
|
|
d <span style="color: #666666">=</span> np<span style="color: #666666">.</span>argmax(cumsum <span style="color: #666666">>=</span> <span style="color: #666666">0.95</span>) <span style="color: #666666">+</span> <span style="color: #666666">1</span>
|
|
</pre></div>
|
|
<p>
|
|
You could then set \( n\_components=d \) 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 \( n\_components \) to be
|
|
a float between 0.0 and 1.0, indicating the ratio of variance you wish to preserve:
|
|
<p>
|
|
|
|
<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span>pca <span style="color: #666666">=</span> PCA(n_components<span style="color: #666666">=0.95</span>)
|
|
X_reduced <span style="color: #666666">=</span> pca<span style="color: #666666">.</span>fit_transform(X)
|
|
</pre></div>
|
|
<p>
|
|
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
|
|
|
|
<h2 id="___sec7">Incremental PCA </h2>
|
|
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>
|
|
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
|
|
|
|
<h2 id="___sec8">Randomized PCA </h2>
|
|
|
|
<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 \( O(m \times d^2)+O(d^3) \), instead of \( O(m \times n^2) + O(n^3) \), so it is dramatically faster than the
|
|
previous algorithms when \( d \) is much smaller than \( n \).
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
|
|
|
|
<h2 id="___sec9">Kernel PCA </h2>
|
|
<div class="alert alert-block alert-block alert-text-normal">
|
|
<b></b>
|
|
<p>
|
|
|
|
<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>
|
|
|
|
<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
<div class="highlight" style="background: #f8f8f8"><pre style="line-height: 125%"><span></span><span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">sklearn.decomposition</span> <span style="color: #008000; font-weight: bold">import</span> KernelPCA
|
|
rbf_pca <span style="color: #666666">=</span> KernelPCA(n_components <span style="color: #666666">=</span> <span style="color: #666666">2</span>, kernel<span style="color: #666666">=</span><span style="color: #BA2121">"rbf"</span>, gamma<span style="color: #666666">=0.04</span>)
|
|
X_reduced <span style="color: #666666">=</span> rbf_pca<span style="color: #666666">.</span>fit_transform(X)
|
|
</pre></div>
|
|
|
|
</div>
|
|
|
|
|
|
<p>
|
|
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
|
|
|
|
<h2 id="___sec10">LLE </h2>
|
|
|
|
<p>
|
|
Locally Linear Embedding (LLE) is another very powerful nonlinear dimensionality reduction
|
|
(NLDR) technique. It is a Manifold Learning technique that does not rely on projections like the previous
|
|
algorithms. In a nutshell, LLE works by first measuring how each training instance linearly relates to its
|
|
closest neighbors (c.n.), and then looking for a low-dimensional representation of the training set where
|
|
these local relationships are best preserved (more details shortly).
|
|
|
|
<p>
|
|
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
|
|
|
|
<h2 id="___sec11">Other techniques </h2>
|
|
|
|
<p>
|
|
There are many other dimensionality reduction techniques, several of which are available in Scikit-Learn.
|
|
|
|
<p>
|
|
Here are some of the most popular:
|
|
|
|
<ul>
|
|
<li> <b>Multidimensional Scaling (MDS)</b> reduces dimensionality while trying to preserve the distances between the instances.</li>
|
|
<li> <b>Isomap</b> creates a graph by connecting each instance to its nearest neighbors, then reduces dimensionality while trying to preserve the geodesic distances between the instances.</li>
|
|
<li> <b>t-Distributed Stochastic Neighbor Embedding</b> (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).</li>
|
|
<li> 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.</li>
|
|
</ul>
|
|
|
|
|
|
<!-- ------------------- end of main content --------------- -->
|
|
|
|
|
|
<center style="font-size:80%">
|
|
<!-- copyright --> © 1999-2019, Morten Hjorth-Jensen. Released under CC Attribution-NonCommercial 4.0 license
|
|
</center>
|
|
|
|
|
|
</body>
|
|
</html>
|
|
|
|
|