small typo in log reg

This commit is contained in:
mhjensen
2019-09-19 15:42:54 +02:00
parent b6da39ee82
commit f6049d88b2
152 changed files with 50 additions and 26250 deletions
-189
View File
@@ -1,189 +0,0 @@
<!--
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: Logistic Regression">
<title>Data Analysis and Machine Learning: Logistic Regression</title>
<!-- Bootstrap style: bootstrap -->
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
<!-- not necessary
<link href="https://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
-->
<style type="text/css">
/* Add scrollbar to dropdown menus in bootstrap navigation bar */
.dropdown-menu {
height: auto;
max-height: 400px;
overflow-x: hidden;
}
/* Adds an invisible element before each target to offset for the navigation
bar */
.anchor::before {
content:"";
display:block;
height:50px; /* fixed header height for style bootstrap */
margin:-50px 0 0; /* negative fixed header height */
}
</style>
</head>
<!-- tocinfo
{'highest level': 2,
'sections': [('Logistic Regression', 2, None, '___sec0'),
('Optimization and Deep learning', 2, None, '___sec1'),
('Basics', 2, None, '___sec2'),
('Linear classifier', 2, None, '___sec3'),
('Some selected properties', 2, None, '___sec4'),
('The logistic function', 2, None, '___sec5'),
('Two parameters', 2, None, '___sec6'),
('Maximum likelihood', 2, None, '___sec7'),
('The cost function rewritten', 2, None, '___sec8'),
('Minimizing the cross entropy', 2, None, '___sec9'),
('A more compact expression', 2, None, '___sec10'),
('Extending to more predictors', 2, None, '___sec11'),
('Including more classes', 2, None, '___sec12'),
('The Softmax function', 2, None, '___sec13'),
('A simple classification problem', 2, None, '___sec14'),
('The Credit Card example', 2, None, '___sec15')]}
end of tocinfo -->
<body>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
TeX: {
equationNumbers: { autoNumber: "none" },
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>
<!-- Bootstrap navigation bar -->
<div class="navbar navbar-default navbar-fixed-top">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="LogReg-bs.html">Data Analysis and Machine Learning: Logistic Regression</a>
</div>
<div class="navbar-collapse collapse navbar-responsive-collapse">
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Contents <b class="caret"></b></a>
<ul class="dropdown-menu">
<!-- navigation toc: --> <li><a href="._LogReg-bs001.html#___sec0" style="font-size: 80%;">Logistic Regression</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs002.html#___sec1" style="font-size: 80%;">Optimization and Deep learning</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs003.html#___sec2" style="font-size: 80%;">Basics</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs004.html#___sec3" style="font-size: 80%;">Linear classifier</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs005.html#___sec4" style="font-size: 80%;">Some selected properties</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs006.html#___sec5" style="font-size: 80%;">The logistic function</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs007.html#___sec6" style="font-size: 80%;">Two parameters</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs008.html#___sec7" style="font-size: 80%;">Maximum likelihood</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs009.html#___sec8" style="font-size: 80%;">The cost function rewritten</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs010.html#___sec9" style="font-size: 80%;">Minimizing the cross entropy</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs011.html#___sec10" style="font-size: 80%;">A more compact expression</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs012.html#___sec11" style="font-size: 80%;">Extending to more predictors</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs013.html#___sec12" style="font-size: 80%;">Including more classes</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs014.html#___sec13" style="font-size: 80%;">The Softmax function</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs015.html#___sec14" style="font-size: 80%;">A simple classification problem</a></li>
<!-- navigation toc: --> <li><a href="._LogReg-bs016.html#___sec15" style="font-size: 80%;">The Credit Card example</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div> <!-- end of navigation bar -->
<div class="container">
<p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p> <!-- add vertical space -->
<a name="part0000"></a>
<!-- ------------------- main content ---------------------- -->
<div class="jumbotron">
<center><h1>Data Analysis and Machine Learning: Logistic Regression</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>Sep 19, 2019</h4></center> <!-- date -->
<br>
<p>
<p>
<!-- navigation buttons at the bottom of the page -->
<ul class="pagination">
<li class="active"><a href="._LogReg-bs000.html">1</a></li>
<li><a href="._LogReg-bs001.html">2</a></li>
<li><a href="._LogReg-bs002.html">3</a></li>
<li><a href="._LogReg-bs003.html">4</a></li>
<li><a href="._LogReg-bs004.html">5</a></li>
<li><a href="._LogReg-bs005.html">6</a></li>
<li><a href="._LogReg-bs006.html">7</a></li>
<li><a href="._LogReg-bs007.html">8</a></li>
<li><a href="._LogReg-bs008.html">9</a></li>
<li><a href="._LogReg-bs009.html">10</a></li>
<li><a href="">...</a></li>
<li><a href="._LogReg-bs016.html">17</a></li>
<li><a href="._LogReg-bs001.html">&raquo;</a></li>
</ul>
<!-- ------------------- end of main content --------------- -->
</div> <!-- end container -->
<!-- include javascript, jQuery *first* -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<!-- Bootstrap footer
<footer>
<a href="http://..."><img width="250" align=right src="http://..."></a>
</footer>
-->
<center style="font-size:80%">
<!-- copyright --> &copy; 1999-2019, Morten Hjorth-Jensen. Released under CC Attribution-NonCommercial 4.0 license
</center>
</body>
</html>
Binary file not shown.
@@ -1,738 +0,0 @@
%%
%% Automatically generated file from DocOnce source
%% (https://github.com/hplgit/doconce/)
%%
%%
%-------------------- begin preamble ----------------------
\documentclass[%
oneside, % oneside: electronic viewing, twoside: printing
final, % draft: marks overfull hboxes, figures with paths
10pt]{article}
\listfiles % print all files needed to compile this document
\usepackage{relsize,makeidx,color,setspace,amsmath,amsfonts,amssymb}
\usepackage[table]{xcolor}
\usepackage{bm,ltablex,microtype}
\usepackage[pdftex]{graphicx}
\usepackage{fancyvrb} % packages needed for verbatim environments
\usepackage{minted}
\usemintedstyle{default}
\usepackage[T1]{fontenc}
%\usepackage[latin1]{inputenc}
\usepackage{ucs}
\usepackage[utf8x]{inputenc}
\usepackage{lmodern} % Latin Modern fonts derived from Computer Modern
% Hyperlinks in PDF:
\definecolor{linkcolor}{rgb}{0,0,0.4}
\usepackage{hyperref}
\hypersetup{
breaklinks=true,
colorlinks=true,
linkcolor=linkcolor,
urlcolor=linkcolor,
citecolor=black,
filecolor=black,
%filecolor=blue,
pdfmenubar=true,
pdftoolbar=true,
bookmarksdepth=3 % Uncomment (and tweak) for PDF bookmarks with more levels than the TOC
}
%\hyperbaseurl{} % hyperlinks are relative to this root
\setcounter{tocdepth}{2} % levels in table of contents
% --- fancyhdr package for fancy headers ---
\usepackage{fancyhdr}
\fancyhf{} % sets both header and footer to nothing
\renewcommand{\headrulewidth}{0pt}
\fancyfoot[LE,RO]{\thepage}
% Ensure copyright on titlepage (article style) and chapter pages (book style)
\fancypagestyle{plain}{
\fancyhf{}
\fancyfoot[C]{{\footnotesize \copyright\ 1999-2019, Morten Hjorth-Jensen. Released under CC Attribution-NonCommercial 4.0 license}}
% \renewcommand{\footrulewidth}{0mm}
\renewcommand{\headrulewidth}{0mm}
}
% Ensure copyright on titlepages with \thispagestyle{empty}
\fancypagestyle{empty}{
\fancyhf{}
\fancyfoot[C]{{\footnotesize \copyright\ 1999-2019, Morten Hjorth-Jensen. Released under CC Attribution-NonCommercial 4.0 license}}
\renewcommand{\footrulewidth}{0mm}
\renewcommand{\headrulewidth}{0mm}
}
\pagestyle{fancy}
% prevent orhpans and widows
\clubpenalty = 10000
\widowpenalty = 10000
% --- end of standard preamble for documents ---
% insert custom LaTeX commands...
\raggedbottom
\makeindex
\usepackage[totoc]{idxlayout} % for index in the toc
\usepackage[nottoc]{tocbibind} % for references/bibliography in the toc
%-------------------- end preamble ----------------------
\begin{document}
% matching end for #ifdef PREAMBLE
\newcommand{\exercisesection}[1]{\subsection*{#1}}
% ------------------- main content ----------------------
% ----------------- title -------------------------
\thispagestyle{empty}
\begin{center}
{\LARGE\bf
\begin{spacing}{1.25}
Data Analysis and Machine Learning: Logistic Regression
\end{spacing}
}
\end{center}
% ----------------- author(s) -------------------------
\begin{center}
{\bf Morten Hjorth-Jensen${}^{1, 2}$} \\ [0mm]
\end{center}
\begin{center}
% List of all institutions:
\centerline{{\small ${}^1$Department of Physics, University of Oslo}}
\centerline{{\small ${}^2$Department of Physics and Astronomy and National Superconducting Cyclotron Laboratory, Michigan State University}}
\end{center}
% ----------------- end author(s) -------------------------
% --- begin date ---
\begin{center}
Sep 19, 2019
\end{center}
% --- end date ---
\vspace{1cm}
% !split
\subsection*{Logistic Regression}
In linear regression our main interest was centered on learning the
coefficients of a functional fit (say a polynomial) in order to be
able to predict the response of a continuous variable on some unseen
data. The fit to the continuous variable $y_i$ is based on some
independent variables $\hat{x}_i$. Linear regression resulted in
analytical expressions for standard ordinary Least Squares or Ridge
regression (in terms of matrices to invert) for several quantities,
ranging from the variance and thereby the confidence intervals of the
parameters $\hat{\beta}$ to the mean squared error. If we can invert
the product of the design matrices, linear regression gives then a
simple recipe for fitting our data.
Classification problems, however, are concerned with outcomes taking
the form of discrete variables (i.e.~categories). We may for example,
on the basis of DNA sequencing for a number of patients, like to find
out which mutations are important for a certain disease; or based on
scans of various patients' brains, figure out if there is a tumor or
not; or given a specific physical system, we'd like to identify its
state, say whether it is an ordered or disordered system (typical
situation in solid state physics); or classify the status of a
patient, whether she/he has a stroke or not and many other similar
situations.
The most common situation we encounter when we apply logistic
regression is that of two possible outcomes, normally denoted as a
binary outcome, true or false, positive or negative, success or
failure etc.
% !split
\subsection*{Optimization and Deep learning}
Logistic regression will also serve as our stepping stone towards neural
network algorithms and supervised deep learning. For logistic
learning, the minimization of the cost function leads to a non-linear
equation in the parameters $\hat{\beta}$. The optimization of the problem calls therefore for minimization algorithms. This forms the bottle neck of all machine learning algorithms, namely how to find reliable minima of a multi-variable function. This leads us to the family of gradient descent methods. The latter are the working horses of basically all modern machine learning algorithms.
We note also that many of the topics discussed here
regression are also commonly used in modern supervised Deep Learning
models, as we will see later.
% !split
\subsection*{Basics}
We consider the case where the dependent variables, also called the
responses or the outcomes, $y_i$ are discrete and only take values
from $k=0,\dots,K-1$ (i.e.~$K$ classes).
The goal is to predict the
output classes from the design matrix $\hat{X}\in\mathbb{R}^{n\times p}$
made of $n$ samples, each of which carries $p$ features or predictors. The
primary goal is to identify the classes to which new unseen samples
belong.
Let us specialize to the case of two classes only, with outputs
$y_i=0$ and $y_i=1$. Our outcomes could represent the status of a
credit card user that could default or not on her/his credit card
debt. That is
\[
y_i = \begin{bmatrix} 0 & \mathrm{no}\\ 1 & \mathrm{yes} \end{bmatrix}.
\]
% !split
\subsection*{Linear classifier}
Before moving to the logistic model, let us try to use our linear regression model to classify these two outcomes. We could for example fit a linear model to the default case if $y_i > 0.5$ and the no default case $y_i \leq 0.5$.
We would then have our
weighted linear combination, namely
\begin{equation}
\hat{y} = \hat{X}^T\hat{\beta} + \hat{\epsilon},
\end{equation}
where $\hat{y}$ is a vector representing the possible outcomes, $\hat{X}$ is our
$n\times p$ design matrix and $\hat{\beta}$ represents our estimators/predictors.
% !split
\subsection*{Some selected properties}
The main problem with our function is that it
takes values on the entire real axis. In the case of
logistic regression, however, the labels $y_i$ are discrete
variables. A typical example is the credit card data discussed below here, where we can set the state of defaulting the debt to $y_i=1$ and not to $y_i=0$ for one the persons in the data set (see the full example below).
One simple way to get a discrete output is to have sign
functions that map the output of a linear regressor to values $\{0,1\}$,
$f(s_i)=sign(s_i)=1$ if $s_i\ge 0$ and 0 if otherwise.
We will encounter this model in our first demonstration of neural networks. Historically it is called the ``perceptron" model in the machine learning
literature. This model is extremely simple. However, in many cases it is more
favorable to use a ``soft" classifier that outputs
the probability of a given category. This leads us to the logistic function.
% !split
\subsection*{The logistic function}
The perceptron is an example of a ``hard classification'' model. We
will encounter this model when we discuss neural networks as
well. Each datapoint is deterministically assigned to a category (i.e
$y_i=0$ or $y_i=1$). In many cases, it is favorable to have a ``soft''
classifier that outputs the probability of a given category rather
than a single value. For example, given $x_i$, the classifier
outputs the probability of being in a category $k$. Logistic regression
is the most common example of a so-called soft classifier. In logistic
regression, the probability that a data point $x_i$
belongs to a category $y_i=\{0,1\}$ is given by the so-called logit function (or Sigmoid) which is meant to represent the likelihood for a given event,
\[
p(t) = \frac{1}{1+\mathrm \exp{-t}}=\frac{\exp{t}}{1+\mathrm \exp{t}}.
\]
Note that $1-p(t)= p(-t)$.
The following code plots the logistic function, the step function and other functions we will encounter from here and on.
\begin{minted}[fontsize=\fontsize{9pt}{9pt},linenos=false,mathescape,baselinestretch=1.0,fontfamily=tt,xleftmargin=7mm]{python}
"""The sigmoid function (or the logistic curve) is a
function that takes any real number, z, and outputs a number (0,1).
It is useful in neural networks for assigning weights on a relative scale.
The value z is the weighted sum of parameters involved in the learning algorithm."""
import numpy
import matplotlib.pyplot as plt
import math as mt
z = numpy.arange(-5, 5, .1)
sigma_fn = numpy.vectorize(lambda z: 1/(1+numpy.exp(-z)))
sigma = sigma_fn(z)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(z, sigma)
ax.set_ylim([-0.1, 1.1])
ax.set_xlim([-5,5])
ax.grid(True)
ax.set_xlabel('z')
ax.set_title('sigmoid function')
plt.show()
"""Step Function"""
z = numpy.arange(-5, 5, .02)
step_fn = numpy.vectorize(lambda z: 1.0 if z >= 0.0 else 0.0)
step = step_fn(z)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(z, step)
ax.set_ylim([-0.5, 1.5])
ax.set_xlim([-5,5])
ax.grid(True)
ax.set_xlabel('z')
ax.set_title('step function')
plt.show()
"""tanh Function"""
z = numpy.arange(-2*mt.pi, 2*mt.pi, 0.1)
t = numpy.tanh(z)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(z, t)
ax.set_ylim([-1.0, 1.0])
ax.set_xlim([-2*mt.pi,2*mt.pi])
ax.grid(True)
ax.set_xlabel('z')
ax.set_title('tanh function')
plt.show()
\end{minted}
% !split
\subsection*{Two parameters}
We assume now that we have two classes with $y_i$ either $0$ or $1$. Furthermore we assume also that we have only two parameters $\beta$ in our fitting of the Sigmoid function, that is we define probabilities
\begin{align*}
p(y_i=1|x_i,\hat{\beta}) &= \frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}},\nonumber\\
p(y_i=0|x_i,\hat{\beta}) &= 1 - p(y_i=1|x_i,\hat{\beta}),
\end{align*}
where $\hat{\beta}$ are the weights we wish to extract from data, in our case $\beta_0$ and $\beta_1$.
Note that we used
\[
p(y_i=0\vert x_i, \hat{\beta}) = 1-p(y_i=1\vert x_i, \hat{\beta}).
\]
% !split
\subsection*{Maximum likelihood}
In order to define the total likelihood for all possible outcomes from a
dataset $\mathcal{D}=\{(y_i,x_i)\}$, with the binary labels
$y_i\in\{0,1\}$ and where the data points are drawn independently, we use the so-called \href{{https://en.wikipedia.org/wiki/Maximum_likelihood_estimation}}{Maximum Likelihood Estimation} (MLE) principle.
We aim thus at maximizing
the probability of seeing the observed data. We can then approximate the
likelihood in terms of the product of the individual probabilities of a specific outcome $y_i$, that is
\begin{align*}
P(\mathcal{D}|\hat{\beta})& = \prod_{i=1}^n \left[p(y_i=1|x_i,\hat{\beta})\right]^{y_i}\left[1-p(y_i=1|x_i,\hat{\beta}))\right]^{1-y_i}\nonumber \\
\end{align*}
from which we obtain the log-likelihood and our \textbf{cost/loss} function
\[
\mathcal{C}(\hat{\beta}) = \sum_{i=1}^n \left( y_i\log{p(y_i=1|x_i,\hat{\beta})} + (1-y_i)\log\left[1-p(y_i=1|x_i,\hat{\beta}))\right]\right).
\]
% !split
\subsection*{The cost function rewritten}
Reordering the logarithms, we can rewrite the \textbf{cost/loss} function as
\[
\mathcal{C}(\hat{\beta}) = \sum_{i=1}^n \left(y_i(\beta_0+\beta_1x_i) -\log{(1+\exp{(\beta_0+\beta_1x_i)})}\right).
\]
The maximum likelihood estimator is defined as the set of parameters that maximize the log-likelihood where we maximize with respect to $\beta$.
Since the cost (error) function is just the negative log-likelihood, for logistic regression we have that
\[
\mathcal{C}(\hat{\beta})=-\sum_{i=1}^n \left(y_i(\beta_0+\beta_1x_i) -\log{(1+\exp{(\beta_0+\beta_1x_i)})}\right).
\]
This equation is known in statistics as the \textbf{cross entropy}. Finally, we note that just as in linear regression,
in practice we often supplement the cross-entropy with additional regularization terms, usually $L_1$ and $L_2$ regularization as we did for Ridge and Lasso regression.
% !split
\subsection*{Minimizing the cross entropy}
The cross entropy is a convex function of the weights $\hat{\beta}$ and,
therefore, any local minimizer is a global minimizer.
Minimizing this
cost function with respect to the two parameters $\beta_0$ and $\beta_1$ we obtain
\[
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \beta_0} = -\sum_{i=1}^n \left(y_i -\frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}}\right),
\]
and
\[
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \beta_1} = -\sum_{i=1}^n \left(y_ix_i -x_i\frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}}\right).
\]
% !split
\subsection*{A more compact expression}
Let us now define a vector $\hat{y}$ with $n$ elements $y_i$, an
$n\times p$ matrix $\hat{X}$ which contains the $x_i$ values and a
vector $\hat{p}$ of fitted probabilities $p(y_i\vert x_i,\hat{\beta})$. We can rewrite in a more compact form the first
derivative of cost function as
\[
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \hat{\beta}} = -\hat{X}^T\left(\hat{y}-\hat{p}\right).
\]
If we in addition define a diagonal matrix $\hat{W}$ with elements
$p(y_i\vert x_i,\hat{\beta})(1-p(y_i\vert x_i,\hat{\beta})$, we can obtain a compact expression of the second derivative as
\[
\frac{\partial^2 \mathcal{C}(\hat{\beta})}{\partial \hat{\beta}\partial \hat{\beta}^T} = \hat{X}^T\hat{W}\hat{X}.
\]
% !split
\subsection*{Extending to more predictors}
Within a binary classification problem, we can easily expand our model to include multiple predictors. Our ratio between likelihoods is then with $p$ predictors
\[
\log{ \frac{p(\hat{\beta}\hat{x})}{1-p(\hat{\beta}\hat{x})}} = \beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p.
\]
Here we defined $\hat{x}=[1,x_1,x_2,\dots,x_p]$ and $\hat{\beta}=[\beta_0, \beta_1, \dots, \beta_p]$ leading to
\[
p(\hat{\beta}\hat{x})=\frac{ \exp{(\beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p)}}{1+\exp{(\beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p)}}.
\]
% !split
\subsection*{Including more classes}
Till now we have mainly focused on two classes, the so-called binary
system. Suppose we wish to extend to $K$ classes. Let us for the sake
of simplicity assume we have only two predictors. We have then
following model
\[
\log{\frac{p(C=1\vert x)}{p(K\vert x)}} = \beta_{10}+\beta_{11}x_1,
\]
\[
\log{\frac{p(C=2\vert x)}{p(K\vert x)}} = \beta_{20}+\beta_{21}x_1,
\]
and so on till the class $C=K-1$ class
\[
\log{\frac{p(C=K-1\vert x)}{p(K\vert x)}} = \beta_{(K-1)0}+\beta_{(K-1)1}x_1,
\]
and the model is specified in term of $K-1$ so-called log-odds or
\textbf{logit} transformations.
% !split
\subsection*{The Softmax function}
In our discussion of neural networks we will encounter the above again
in terms of the so-called \textbf{Softmax} function.
The softmax function is used in various multiclass classification
methods, such as multinomial logistic regression (also known as
softmax regression), multiclass linear discriminant analysis, naive
Bayes classifiers, and artificial neural networks. Specifically, in
multinomial logistic regression and linear discriminant analysis, the
input to the function is the result of $K$ distinct linear functions,
and the predicted probability for the $k$-th class given a sample
vector $\hat{x}$ and a weighting vector $\hat{\beta}$ is (with two
predictors):
\[
p(C=k\vert \mathbf {x} )=\frac{\exp{(\beta_{k0}+\beta_{k1}x_1)}}{1+\sum_{l=1}^{K-1}\exp{(\beta_{l0}+\beta_{l1}x_1)}}.
\]
It is easy to extend to more predictors. The final class is
\[
p(C=K\vert \mathbf {x} )=\frac{1}{1+\sum_{l=1}^{K-1}\exp{(\beta_{l0}+\beta_{l1}x_1)}},
\]
and they sum to one. Our earlier discussions were all specialized to
the case with two classes only. It is easy to see from the above that
what we derived earlier is compatible with these equations.
To find the optimal parameters we would typically use a gradient
descent method. Newton's method and gradient descent methods are
discussed in the material on \href{{https://compphysics.github.io/MachineLearning/doc/pub/Splines/html/Splines-bs.html}}{optimization
methods}.
% !split
\subsection*{A simple classification problem}
\begin{minted}[fontsize=\fontsize{9pt}{9pt},linenos=false,mathescape,baselinestretch=1.0,fontfamily=tt,xleftmargin=7mm]{python}
import numpy as np
from sklearn import datasets, linear_model
import matplotlib.pyplot as plt
def generate_data():
np.random.seed(0)
X, y = datasets.make_moons(200, noise=0.20)
return X, y
def visualize(X, y, clf):
plot_decision_boundary(lambda x: clf.predict(x), X, y)
def plot_decision_boundary(pred_func, X, y):
# Set min and max values and give it some padding
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
h = 0.01
# Generate a grid of points with distance h between them
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
# Predict the function value for the whole gid
Z = pred_func(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# Plot the contour and training examples
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)
plt.show()
def classify(X, y):
clf = linear_model.LogisticRegressionCV()
clf.fit(X, y)
return clf
def main():
X, y = generate_data()
# visualize(X, y)
clf = classify(X, y)
visualize(X, y, clf)
if __name__ == "__main__":
main()
\end{minted}
% !split
\subsection*{The Credit Card example}
Here we use the the \href{{https://archive.ics.uci.edu/ml/datasets/default+of+credit+card+clients}}{credit card data}. More text to come.
\begin{minted}[fontsize=\fontsize{9pt}{9pt},linenos=false,mathescape,baselinestretch=1.0,fontfamily=tt,xleftmargin=7mm]{python}
import pandas as pd
import os
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.metrics import confusion_matrix, accuracy_score, roc_auc_score
# Trying to set the seed
np.random.seed(0)
import random
random.seed(0)
# Reading file into data frame
cwd = os.getcwd()
filename = cwd + '/default of credit card clients.xls'
nanDict = {}
df = pd.read_excel(filename, header=1, skiprows=0, index_col=0, na_values=nanDict)
df.rename(index=str, columns={"default payment next month": "defaultPaymentNextMonth"}, inplace=True)
# Features and targets
X = df.loc[:, df.columns != 'defaultPaymentNextMonth'].values
y = df.loc[:, df.columns == 'defaultPaymentNextMonth'].values
# Categorical variables to one-hot's
onehotencoder = OneHotEncoder(categories="auto")
X = ColumnTransformer(
[("", onehotencoder, [3]),],
remainder="passthrough"
).fit_transform(X)
y.shape
# Train-test split
trainingShare = 0.5
seed = 1
XTrain, XTest, yTrain, yTest=train_test_split(X, y, train_size=trainingShare, \
test_size = 1-trainingShare,
random_state=seed)
# Input Scaling
sc = StandardScaler()
XTrain = sc.fit_transform(XTrain)
XTest = sc.transform(XTest)
# One-hot's of the target vector
Y_train_onehot, Y_test_onehot = onehotencoder.fit_transform(yTrain), onehotencoder.fit_transform(yTest)
# Remove instances with zeros only for past bill statements or paid amounts
'''
df = df.drop(df[(df.BILL_AMT1 == 0) &
(df.BILL_AMT2 == 0) &
(df.BILL_AMT3 == 0) &
(df.BILL_AMT4 == 0) &
(df.BILL_AMT5 == 0) &
(df.BILL_AMT6 == 0) &
(df.PAY_AMT1 == 0) &
(df.PAY_AMT2 == 0) &
(df.PAY_AMT3 == 0) &
(df.PAY_AMT4 == 0) &
(df.PAY_AMT5 == 0) &
(df.PAY_AMT6 == 0)].index)
'''
df = df.drop(df[(df.BILL_AMT1 == 0) &
(df.BILL_AMT2 == 0) &
(df.BILL_AMT3 == 0) &
(df.BILL_AMT4 == 0) &
(df.BILL_AMT5 == 0) &
(df.BILL_AMT6 == 0)].index)
df = df.drop(df[(df.PAY_AMT1 == 0) &
(df.PAY_AMT2 == 0) &
(df.PAY_AMT3 == 0) &
(df.PAY_AMT4 == 0) &
(df.PAY_AMT5 == 0) &
(df.PAY_AMT6 == 0)].index)
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
lambdas=np.logspace(-5,7,13)
parameters = [{'C': 1./lambdas, "solver":["lbfgs"]}]#*len(parameters)}]
scoring = ['accuracy', 'roc_auc']
logReg = LogisticRegression()
gridSearch = GridSearchCV(logReg, parameters, cv=5, scoring=scoring, refit='roc_auc')
\end{minted}
\begin{minted}[fontsize=\fontsize{9pt}{9pt},linenos=false,mathescape,baselinestretch=1.0,fontfamily=tt,xleftmargin=7mm]{python}
# "refit" gives the metric used deciding best model.
# See more http://scikit-learn.org/stable/auto_examples/model_selection/plot_multi_metric_evaluation.html
gridSearch.fit(XTrain, yTrain.ravel())
def gridSearchSummary(method, scoring):
"""Prints best parameters from Grid search
and AUC with standard deviation for all
parameter combos """
method = eval(method)
if scoring == 'accuracy':
mean = 'mean_test_score'
sd = 'std_test_score'
elif scoring == 'auc':
mean = 'mean_test_roc_auc'
sd = 'std_test_roc_auc'
print("Best: %f using %s" % (method.best_score_, method.best_params_))
means = method.cv_results_[mean]
stds = method.cv_results_[sd]
params = method.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
print("%f (%f) with: %r" % (mean, stdev, param))
def createConfusionMatrix(method, printOut=True):
"""
Computes and prints confusion matrices, accuracy scores,
and AUC for test and training sets
"""
confusionArray = np.zeros(6, dtype=object)
method = eval(method)
# Train
yPredTrain = method.predict(XTrain)
yPredTrain = (yPredTrain > 0.5)
cm = confusion_matrix(
yTrain, yPredTrain)
cm = np.around(cm/cm.sum(axis=1)[:,None], 2)
confusionArray[0] = cm
accScore = accuracy_score(yTrain, yPredTrain)
confusionArray[1] = accScore
AUC = roc_auc_score(yTrain, yPredTrain)
confusionArray[2] = AUC
if printOut:
print('\n################### Training ###############')
print('\nTraining Confusion matrix: \n', cm)
print('\nTraining Accuracy score: \n', accScore)
print('\nTrain AUC: \n', AUC)
# Test
yPred = method.predict(XTest)
yPred = (yPred > 0.5)
cm = confusion_matrix(
yTest, yPred)
cm = np.around(cm/cm.sum(axis=1)[:,None], 2)
confusionArray[3] = cm
accScore = accuracy_score(yTest, yPred)
confusionArray[4] = accScore
AUC = roc_auc_score(yTest, yPred)
confusionArray[5] = AUC
if printOut:
print('\n################### Testing ###############')
print('\nTest Confusion matrix: \n', cm)
print('\nTest Accuracy score: \n', accScore)
print('\nTestAUC: \n', AUC)
return confusionArray
import matplotlib.pyplot as plt
import seaborn
import scikitplot as skplt
seaborn.set(style="white", context="notebook", font_scale=1.5,
rc={"axes.grid": True, "legend.frameon": False,
"lines.markeredgewidth": 1.4, "lines.markersize": 10})
seaborn.set_context("notebook", font_scale=1.5, rc={"lines.linewidth": 4.5})
yPred = gridSearch.predict_proba(XTest)
print(yTest.ravel().shape, yPred.shape)
#skplt.metrics.plot_cumulative_gain(yTest.ravel(), yPred_onehot)
skplt.metrics.plot_cumulative_gain(yTest.ravel(), yPred)
defaults = sum(yTest == 1)
total = len(yTest)
defaultRate = defaults/total
def bestCurve(defaults, total, defaultRate):
x = np.linspace(0, 1, total)
y1 = np.linspace(0, 1, defaults)
y2 = np.ones(total-defaults)
y3 = np.concatenate([y1,y2])
return x, y3
x, best = bestCurve(defaults=defaults, total=total, defaultRate=defaultRate)
plt.plot(x, best)
plt.show()
\end{minted}
% ------------------- end of main content ---------------
\end{document}
File diff suppressed because it is too large Load Diff
@@ -1,767 +0,0 @@
<!--
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: Logistic Regression">
<title>Data Analysis and Machine Learning: Logistic Regression</title>
<link href="https://cdn.rawgit.com/hplgit/doconce/master/bundled/html_styles/style_solarized_box/css/solarized_light_code.css" rel="stylesheet" type="text/css" title="light"/>
<script src="https://cdn.rawgit.com/hplgit/doconce/master/bundled/html_styles/style_solarized_box/js/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<link href="https://thomasf.github.io/solarized-css/solarized-light.min.css" rel="stylesheet">
<style type="text/css">
h1 {color: #b58900;} /* yellow */
/* h1 {color: #cb4b16;} orange */
/* h1 {color: #d33682;} magenta, the original choice of thomasf */
code { padding: 0px; background-color: inherit; }
pre {
border: 0pt solid #93a1a1;
box-shadow: none;
}
div { text-align: justify; text-justify: inter-word; }
</style>
</head>
<!-- tocinfo
{'highest level': 2,
'sections': [('Logistic Regression', 2, None, '___sec0'),
('Optimization and Deep learning', 2, None, '___sec1'),
('Basics', 2, None, '___sec2'),
('Linear classifier', 2, None, '___sec3'),
('Some selected properties', 2, None, '___sec4'),
('The logistic function', 2, None, '___sec5'),
('Two parameters', 2, None, '___sec6'),
('Maximum likelihood', 2, None, '___sec7'),
('The cost function rewritten', 2, None, '___sec8'),
('Minimizing the cross entropy', 2, None, '___sec9'),
('A more compact expression', 2, None, '___sec10'),
('Extending to more predictors', 2, None, '___sec11'),
('Including more classes', 2, None, '___sec12'),
('The Softmax function', 2, None, '___sec13'),
('A simple classification problem', 2, None, '___sec14'),
('The Credit Card example', 2, None, '___sec15')]}
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: Logistic Regression</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>Sep 19, 2019</h4></center> <!-- date -->
<br>
<p>
<!-- !split -->
<h2 id="___sec0">Logistic Regression </h2>
<p>
In linear regression our main interest was centered on learning the
coefficients of a functional fit (say a polynomial) in order to be
able to predict the response of a continuous variable on some unseen
data. The fit to the continuous variable \( y_i \) is based on some
independent variables \( \hat{x}_i \). Linear regression resulted in
analytical expressions for standard ordinary Least Squares or Ridge
regression (in terms of matrices to invert) for several quantities,
ranging from the variance and thereby the confidence intervals of the
parameters \( \hat{\beta} \) to the mean squared error. If we can invert
the product of the design matrices, linear regression gives then a
simple recipe for fitting our data.
<p>
Classification problems, however, are concerned with outcomes taking
the form of discrete variables (i.e. categories). We may for example,
on the basis of DNA sequencing for a number of patients, like to find
out which mutations are important for a certain disease; or based on
scans of various patients' brains, figure out if there is a tumor or
not; or given a specific physical system, we'd like to identify its
state, say whether it is an ordered or disordered system (typical
situation in solid state physics); or classify the status of a
patient, whether she/he has a stroke or not and many other similar
situations.
<p>
The most common situation we encounter when we apply logistic
regression is that of two possible outcomes, normally denoted as a
binary outcome, true or false, positive or negative, success or
failure etc.
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec1">Optimization and Deep learning </h2>
<p>
Logistic regression will also serve as our stepping stone towards neural
network algorithms and supervised deep learning. For logistic
learning, the minimization of the cost function leads to a non-linear
equation in the parameters \( \hat{\beta} \). The optimization of the problem calls therefore for minimization algorithms. This forms the bottle neck of all machine learning algorithms, namely how to find reliable minima of a multi-variable function. This leads us to the family of gradient descent methods. The latter are the working horses of basically all modern machine learning algorithms.
<p>
We note also that many of the topics discussed here
regression are also commonly used in modern supervised Deep Learning
models, as we will see later.
<p>
<!-- !split -->
<h2 id="___sec2">Basics </h2>
<p>
We consider the case where the dependent variables, also called the
responses or the outcomes, \( y_i \) are discrete and only take values
from \( k=0,\dots,K-1 \) (i.e. \( K \) classes).
<p>
The goal is to predict the
output classes from the design matrix \( \hat{X}\in\mathbb{R}^{n\times p} \)
made of \( n \) samples, each of which carries \( p \) features or predictors. The
primary goal is to identify the classes to which new unseen samples
belong.
<p>
Let us specialize to the case of two classes only, with outputs
\( y_i=0 \) and \( y_i=1 \). Our outcomes could represent the status of a
credit card user that could default or not on her/his credit card
debt. That is
$$
y_i = \begin{bmatrix} 0 & \mathrm{no}\\ 1 & \mathrm{yes} \end{bmatrix}.
$$
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec3">Linear classifier </h2>
<p>
Before moving to the logistic model, let us try to use our linear regression model to classify these two outcomes. We could for example fit a linear model to the default case if \( y_i > 0.5 \) and the no default case \( y_i \leq 0.5 \).
<p>
We would then have our
weighted linear combination, namely
$$
\begin{equation}
\hat{y} = \hat{X}^T\hat{\beta} + \hat{\epsilon},
\label{_auto1}
\end{equation}
$$
where \( \hat{y} \) is a vector representing the possible outcomes, \( \hat{X} \) is our
\( n\times p \) design matrix and \( \hat{\beta} \) represents our estimators/predictors.
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec4">Some selected properties </h2>
<p>
The main problem with our function is that it
takes values on the entire real axis. In the case of
logistic regression, however, the labels \( y_i \) are discrete
variables. A typical example is the credit card data discussed below here, where we can set the state of defaulting the debt to \( y_i=1 \) and not to \( y_i=0 \) for one the persons in the data set (see the full example below).
<p>
One simple way to get a discrete output is to have sign
functions that map the output of a linear regressor to values \( \{0,1\} \),
\( f(s_i)=sign(s_i)=1 \) if \( s_i\ge 0 \) and 0 if otherwise.
We will encounter this model in our first demonstration of neural networks. Historically it is called the &quot;perceptron" model in the machine learning
literature. This model is extremely simple. However, in many cases it is more
favorable to use a ``soft" classifier that outputs
the probability of a given category. This leads us to the logistic function.
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec5">The logistic function </h2>
<p>
The perceptron is an example of a ``hard classification&quot; model. We
will encounter this model when we discuss neural networks as
well. Each datapoint is deterministically assigned to a category (i.e
\( y_i=0 \) or \( y_i=1 \)). In many cases, it is favorable to have a &quot;soft&quot;
classifier that outputs the probability of a given category rather
than a single value. For example, given \( x_i \), the classifier
outputs the probability of being in a category \( k \). Logistic regression
is the most common example of a so-called soft classifier. In logistic
regression, the probability that a data point \( x_i \)
belongs to a category \( y_i=\{0,1\} \) is given by the so-called logit function (or Sigmoid) which is meant to represent the likelihood for a given event,
$$
p(t) = \frac{1}{1+\mathrm \exp{-t}}=\frac{\exp{t}}{1+\mathrm \exp{t}}.
$$
Note that \( 1-p(t)= p(-t) \).
The following code plots the logistic function, the step function and other functions we will encounter from here and on.
<p>
<!-- code=python (!bc pycod) typeset with pygments style "perldoc" -->
<div class="highlight" style="background: #eeeedd"><pre style="line-height: 125%"><span></span><span style="color: #CD5555">&quot;&quot;&quot;The sigmoid function (or the logistic curve) is a</span>
<span style="color: #CD5555">function that takes any real number, z, and outputs a number (0,1).</span>
<span style="color: #CD5555">It is useful in neural networks for assigning weights on a relative scale.</span>
<span style="color: #CD5555">The value z is the weighted sum of parameters involved in the learning algorithm.&quot;&quot;&quot;</span>
<span style="color: #8B008B; font-weight: bold">import</span> <span style="color: #008b45; text-decoration: underline">numpy</span>
<span style="color: #8B008B; font-weight: bold">import</span> <span style="color: #008b45; text-decoration: underline">matplotlib.pyplot</span> <span style="color: #8B008B; font-weight: bold">as</span> <span style="color: #008b45; text-decoration: underline">plt</span>
<span style="color: #8B008B; font-weight: bold">import</span> <span style="color: #008b45; text-decoration: underline">math</span> <span style="color: #8B008B; font-weight: bold">as</span> <span style="color: #008b45; text-decoration: underline">mt</span>
z = numpy.arange(-<span style="color: #B452CD">5</span>, <span style="color: #B452CD">5</span>, .<span style="color: #B452CD">1</span>)
sigma_fn = numpy.vectorize(<span style="color: #8B008B; font-weight: bold">lambda</span> z: <span style="color: #B452CD">1</span>/(<span style="color: #B452CD">1</span>+numpy.exp(-z)))
sigma = sigma_fn(z)
fig = plt.figure()
ax = fig.add_subplot(<span style="color: #B452CD">111</span>)
ax.plot(z, sigma)
ax.set_ylim([-<span style="color: #B452CD">0.1</span>, <span style="color: #B452CD">1.1</span>])
ax.set_xlim([-<span style="color: #B452CD">5</span>,<span style="color: #B452CD">5</span>])
ax.grid(<span style="color: #658b00">True</span>)
ax.set_xlabel(<span style="color: #CD5555">&#39;z&#39;</span>)
ax.set_title(<span style="color: #CD5555">&#39;sigmoid function&#39;</span>)
plt.show()
<span style="color: #CD5555">&quot;&quot;&quot;Step Function&quot;&quot;&quot;</span>
z = numpy.arange(-<span style="color: #B452CD">5</span>, <span style="color: #B452CD">5</span>, .<span style="color: #B452CD">02</span>)
step_fn = numpy.vectorize(<span style="color: #8B008B; font-weight: bold">lambda</span> z: <span style="color: #B452CD">1.0</span> <span style="color: #8B008B; font-weight: bold">if</span> z &gt;= <span style="color: #B452CD">0.0</span> <span style="color: #8B008B; font-weight: bold">else</span> <span style="color: #B452CD">0.0</span>)
step = step_fn(z)
fig = plt.figure()
ax = fig.add_subplot(<span style="color: #B452CD">111</span>)
ax.plot(z, step)
ax.set_ylim([-<span style="color: #B452CD">0.5</span>, <span style="color: #B452CD">1.5</span>])
ax.set_xlim([-<span style="color: #B452CD">5</span>,<span style="color: #B452CD">5</span>])
ax.grid(<span style="color: #658b00">True</span>)
ax.set_xlabel(<span style="color: #CD5555">&#39;z&#39;</span>)
ax.set_title(<span style="color: #CD5555">&#39;step function&#39;</span>)
plt.show()
<span style="color: #CD5555">&quot;&quot;&quot;tanh Function&quot;&quot;&quot;</span>
z = numpy.arange(-<span style="color: #B452CD">2</span>*mt.pi, <span style="color: #B452CD">2</span>*mt.pi, <span style="color: #B452CD">0.1</span>)
t = numpy.tanh(z)
fig = plt.figure()
ax = fig.add_subplot(<span style="color: #B452CD">111</span>)
ax.plot(z, t)
ax.set_ylim([-<span style="color: #B452CD">1.0</span>, <span style="color: #B452CD">1.0</span>])
ax.set_xlim([-<span style="color: #B452CD">2</span>*mt.pi,<span style="color: #B452CD">2</span>*mt.pi])
ax.grid(<span style="color: #658b00">True</span>)
ax.set_xlabel(<span style="color: #CD5555">&#39;z&#39;</span>)
ax.set_title(<span style="color: #CD5555">&#39;tanh function&#39;</span>)
plt.show()
</pre></div>
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec6">Two parameters </h2>
<p>
We assume now that we have two classes with \( y_i \) either \( 0 \) or \( 1 \). Furthermore we assume also that we have only two parameters \( \beta \) in our fitting of the Sigmoid function, that is we define probabilities
$$
\begin{align*}
p(y_i=1|x_i,\hat{\beta}) &= \frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}},\nonumber\\
p(y_i=0|x_i,\hat{\beta}) &= 1 - p(y_i=1|x_i,\hat{\beta}),
\end{align*}
$$
where \( \hat{\beta} \) are the weights we wish to extract from data, in our case \( \beta_0 \) and \( \beta_1 \).
<p>
Note that we used
$$
p(y_i=0\vert x_i, \hat{\beta}) = 1-p(y_i=1\vert x_i, \hat{\beta}).
$$
<p>
<!-- !split -->
<h2 id="___sec7">Maximum likelihood </h2>
<p>
In order to define the total likelihood for all possible outcomes from a
dataset \( \mathcal{D}=\{(y_i,x_i)\} \), with the binary labels
\( y_i\in\{0,1\} \) and where the data points are drawn independently, we use the so-called <a href="https://en.wikipedia.org/wiki/Maximum_likelihood_estimation" target="_blank">Maximum Likelihood Estimation</a> (MLE) principle.
We aim thus at maximizing
the probability of seeing the observed data. We can then approximate the
likelihood in terms of the product of the individual probabilities of a specific outcome \( y_i \), that is
$$
\begin{align*}
P(\mathcal{D}|\hat{\beta})& = \prod_{i=1}^n \left[p(y_i=1|x_i,\hat{\beta})\right]^{y_i}\left[1-p(y_i=1|x_i,\hat{\beta}))\right]^{1-y_i}\nonumber \\
\end{align*}
$$
from which we obtain the log-likelihood and our <b>cost/loss</b> function
$$
\mathcal{C}(\hat{\beta}) = \sum_{i=1}^n \left( y_i\log{p(y_i=1|x_i,\hat{\beta})} + (1-y_i)\log\left[1-p(y_i=1|x_i,\hat{\beta}))\right]\right).
$$
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec8">The cost function rewritten </h2>
<p>
Reordering the logarithms, we can rewrite the <b>cost/loss</b> function as
$$
\mathcal{C}(\hat{\beta}) = \sum_{i=1}^n \left(y_i(\beta_0+\beta_1x_i) -\log{(1+\exp{(\beta_0+\beta_1x_i)})}\right).
$$
<p>
The maximum likelihood estimator is defined as the set of parameters that maximize the log-likelihood where we maximize with respect to \( \beta \).
Since the cost (error) function is just the negative log-likelihood, for logistic regression we have that
$$
\mathcal{C}(\hat{\beta})=-\sum_{i=1}^n \left(y_i(\beta_0+\beta_1x_i) -\log{(1+\exp{(\beta_0+\beta_1x_i)})}\right).
$$
This equation is known in statistics as the <b>cross entropy</b>. Finally, we note that just as in linear regression,
in practice we often supplement the cross-entropy with additional regularization terms, usually \( L_1 \) and \( L_2 \) regularization as we did for Ridge and Lasso regression.
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec9">Minimizing the cross entropy </h2>
<p>
The cross entropy is a convex function of the weights \( \hat{\beta} \) and,
therefore, any local minimizer is a global minimizer.
<p>
Minimizing this
cost function with respect to the two parameters \( \beta_0 \) and \( \beta_1 \) we obtain
$$
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \beta_0} = -\sum_{i=1}^n \left(y_i -\frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}}\right),
$$
and
$$
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \beta_1} = -\sum_{i=1}^n \left(y_ix_i -x_i\frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}}\right).
$$
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec10">A more compact expression </h2>
<p>
Let us now define a vector \( \hat{y} \) with \( n \) elements \( y_i \), an
\( n\times p \) matrix \( \hat{X} \) which contains the \( x_i \) values and a
vector \( \hat{p} \) of fitted probabilities \( p(y_i\vert x_i,\hat{\beta}) \). We can rewrite in a more compact form the first
derivative of cost function as
$$
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \hat{\beta}} = -\hat{X}^T\left(\hat{y}-\hat{p}\right).
$$
<p>
If we in addition define a diagonal matrix \( \hat{W} \) with elements
\( p(y_i\vert x_i,\hat{\beta})(1-p(y_i\vert x_i,\hat{\beta}) \), we can obtain a compact expression of the second derivative as
$$
\frac{\partial^2 \mathcal{C}(\hat{\beta})}{\partial \hat{\beta}\partial \hat{\beta}^T} = \hat{X}^T\hat{W}\hat{X}.
$$
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec11">Extending to more predictors </h2>
<p>
Within a binary classification problem, we can easily expand our model to include multiple predictors. Our ratio between likelihoods is then with \( p \) predictors
$$
\log{ \frac{p(\hat{\beta}\hat{x})}{1-p(\hat{\beta}\hat{x})}} = \beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p.
$$
Here we defined \( \hat{x}=[1,x_1,x_2,\dots,x_p] \) and \( \hat{\beta}=[\beta_0, \beta_1, \dots, \beta_p] \) leading to
$$
p(\hat{\beta}\hat{x})=\frac{ \exp{(\beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p)}}{1+\exp{(\beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p)}}.
$$
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec12">Including more classes </h2>
<p>
Till now we have mainly focused on two classes, the so-called binary
system. Suppose we wish to extend to \( K \) classes. Let us for the sake
of simplicity assume we have only two predictors. We have then
following model
$$
\log{\frac{p(C=1\vert x)}{p(K\vert x)}} = \beta_{10}+\beta_{11}x_1,
$$
$$
\log{\frac{p(C=2\vert x)}{p(K\vert x)}} = \beta_{20}+\beta_{21}x_1,
$$
and so on till the class \( C=K-1 \) class
$$
\log{\frac{p(C=K-1\vert x)}{p(K\vert x)}} = \beta_{(K-1)0}+\beta_{(K-1)1}x_1,
$$
<p>
and the model is specified in term of \( K-1 \) so-called log-odds or
<b>logit</b> transformations.
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec13">The Softmax function </h2>
<p>
In our discussion of neural networks we will encounter the above again
in terms of the so-called <b>Softmax</b> function.
<p>
The softmax function is used in various multiclass classification
methods, such as multinomial logistic regression (also known as
softmax regression), multiclass linear discriminant analysis, naive
Bayes classifiers, and artificial neural networks. Specifically, in
multinomial logistic regression and linear discriminant analysis, the
input to the function is the result of \( K \) distinct linear functions,
and the predicted probability for the \( k \)-th class given a sample
vector \( \hat{x} \) and a weighting vector \( \hat{\beta} \) is (with two
predictors):
$$
p(C=k\vert \mathbf {x} )=\frac{\exp{(\beta_{k0}+\beta_{k1}x_1)}}{1+\sum_{l=1}^{K-1}\exp{(\beta_{l0}+\beta_{l1}x_1)}}.
$$
It is easy to extend to more predictors. The final class is
$$
p(C=K\vert \mathbf {x} )=\frac{1}{1+\sum_{l=1}^{K-1}\exp{(\beta_{l0}+\beta_{l1}x_1)}},
$$
<p>
and they sum to one. Our earlier discussions were all specialized to
the case with two classes only. It is easy to see from the above that
what we derived earlier is compatible with these equations.
<p>
To find the optimal parameters we would typically use a gradient
descent method. Newton's method and gradient descent methods are
discussed in the material on <a href="https://compphysics.github.io/MachineLearning/doc/pub/Splines/html/Splines-bs.html" target="_blank">optimization
methods</a>.
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec14">A simple classification problem </h2>
<p>
<!-- code=python (!bc pycod) typeset with pygments style "perldoc" -->
<div class="highlight" style="background: #eeeedd"><pre style="line-height: 125%"><span></span><span style="color: #8B008B; font-weight: bold">import</span> <span style="color: #008b45; text-decoration: underline">numpy</span> <span style="color: #8B008B; font-weight: bold">as</span> <span style="color: #008b45; text-decoration: underline">np</span>
<span style="color: #8B008B; font-weight: bold">from</span> <span style="color: #008b45; text-decoration: underline">sklearn</span> <span style="color: #8B008B; font-weight: bold">import</span> datasets, linear_model
<span style="color: #8B008B; font-weight: bold">import</span> <span style="color: #008b45; text-decoration: underline">matplotlib.pyplot</span> <span style="color: #8B008B; font-weight: bold">as</span> <span style="color: #008b45; text-decoration: underline">plt</span>
<span style="color: #8B008B; font-weight: bold">def</span> <span style="color: #008b45">generate_data</span>():
np.random.seed(<span style="color: #B452CD">0</span>)
X, y = datasets.make_moons(<span style="color: #B452CD">200</span>, noise=<span style="color: #B452CD">0.20</span>)
<span style="color: #8B008B; font-weight: bold">return</span> X, y
<span style="color: #8B008B; font-weight: bold">def</span> <span style="color: #008b45">visualize</span>(X, y, clf):
plot_decision_boundary(<span style="color: #8B008B; font-weight: bold">lambda</span> x: clf.predict(x), X, y)
<span style="color: #8B008B; font-weight: bold">def</span> <span style="color: #008b45">plot_decision_boundary</span>(pred_func, X, y):
<span style="color: #228B22"># Set min and max values and give it some padding</span>
x_min, x_max = X[:, <span style="color: #B452CD">0</span>].min() - .<span style="color: #B452CD">5</span>, X[:, <span style="color: #B452CD">0</span>].max() + .<span style="color: #B452CD">5</span>
y_min, y_max = X[:, <span style="color: #B452CD">1</span>].min() - .<span style="color: #B452CD">5</span>, X[:, <span style="color: #B452CD">1</span>].max() + .<span style="color: #B452CD">5</span>
h = <span style="color: #B452CD">0.01</span>
<span style="color: #228B22"># Generate a grid of points with distance h between them</span>
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
<span style="color: #228B22"># Predict the function value for the whole gid</span>
Z = pred_func(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
<span style="color: #228B22"># Plot the contour and training examples</span>
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
plt.scatter(X[:, <span style="color: #B452CD">0</span>], X[:, <span style="color: #B452CD">1</span>], c=y, cmap=plt.cm.Spectral)
plt.show()
<span style="color: #8B008B; font-weight: bold">def</span> <span style="color: #008b45">classify</span>(X, y):
clf = linear_model.LogisticRegressionCV()
clf.fit(X, y)
<span style="color: #8B008B; font-weight: bold">return</span> clf
<span style="color: #8B008B; font-weight: bold">def</span> <span style="color: #008b45">main</span>():
X, y = generate_data()
<span style="color: #228B22"># visualize(X, y)</span>
clf = classify(X, y)
visualize(X, y, clf)
<span style="color: #8B008B; font-weight: bold">if</span> <span style="color: #00688B">__name__</span> == <span style="color: #CD5555">&quot;__main__&quot;</span>:
main()
</pre></div>
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec15">The Credit Card example </h2>
Here we use the the <a href="https://archive.ics.uci.edu/ml/datasets/default+of+credit+card+clients" target="_blank">credit card data</a>. More text to come.
<p>
<!-- code=python (!bc pycod) typeset with pygments style "perldoc" -->
<div class="highlight" style="background: #eeeedd"><pre style="line-height: 125%"><span></span><span style="color: #8B008B; font-weight: bold">import</span> <span style="color: #008b45; text-decoration: underline">pandas</span> <span style="color: #8B008B; font-weight: bold">as</span> <span style="color: #008b45; text-decoration: underline">pd</span>
<span style="color: #8B008B; font-weight: bold">import</span> <span style="color: #008b45; text-decoration: underline">os</span>
<span style="color: #8B008B; font-weight: bold">import</span> <span style="color: #008b45; text-decoration: underline">numpy</span> <span style="color: #8B008B; font-weight: bold">as</span> <span style="color: #008b45; text-decoration: underline">np</span>
<span style="color: #8B008B; font-weight: bold">from</span> <span style="color: #008b45; text-decoration: underline">sklearn.model_selection</span> <span style="color: #8B008B; font-weight: bold">import</span> train_test_split
<span style="color: #8B008B; font-weight: bold">from</span> <span style="color: #008b45; text-decoration: underline">sklearn.preprocessing</span> <span style="color: #8B008B; font-weight: bold">import</span> OneHotEncoder
<span style="color: #8B008B; font-weight: bold">from</span> <span style="color: #008b45; text-decoration: underline">sklearn.compose</span> <span style="color: #8B008B; font-weight: bold">import</span> ColumnTransformer
<span style="color: #8B008B; font-weight: bold">from</span> <span style="color: #008b45; text-decoration: underline">sklearn.preprocessing</span> <span style="color: #8B008B; font-weight: bold">import</span> StandardScaler, OneHotEncoder
<span style="color: #8B008B; font-weight: bold">from</span> <span style="color: #008b45; text-decoration: underline">sklearn.metrics</span> <span style="color: #8B008B; font-weight: bold">import</span> confusion_matrix, accuracy_score, roc_auc_score
<span style="color: #228B22"># Trying to set the seed</span>
np.random.seed(<span style="color: #B452CD">0</span>)
<span style="color: #8B008B; font-weight: bold">import</span> <span style="color: #008b45; text-decoration: underline">random</span>
random.seed(<span style="color: #B452CD">0</span>)
<span style="color: #228B22"># Reading file into data frame</span>
cwd = os.getcwd()
filename = cwd + <span style="color: #CD5555">&#39;/default of credit card clients.xls&#39;</span>
nanDict = {}
df = pd.read_excel(filename, header=<span style="color: #B452CD">1</span>, skiprows=<span style="color: #B452CD">0</span>, index_col=<span style="color: #B452CD">0</span>, na_values=nanDict)
df.rename(index=<span style="color: #658b00">str</span>, columns={<span style="color: #CD5555">&quot;default payment next month&quot;</span>: <span style="color: #CD5555">&quot;defaultPaymentNextMonth&quot;</span>}, inplace=<span style="color: #658b00">True</span>)
<span style="color: #228B22"># Features and targets </span>
X = df.loc[:, df.columns != <span style="color: #CD5555">&#39;defaultPaymentNextMonth&#39;</span>].values
y = df.loc[:, df.columns == <span style="color: #CD5555">&#39;defaultPaymentNextMonth&#39;</span>].values
<span style="color: #228B22"># Categorical variables to one-hot&#39;s</span>
onehotencoder = OneHotEncoder(categories=<span style="color: #CD5555">&quot;auto&quot;</span>)
X = ColumnTransformer(
[(<span style="color: #CD5555">&quot;&quot;</span>, onehotencoder, [<span style="color: #B452CD">3</span>]),],
remainder=<span style="color: #CD5555">&quot;passthrough&quot;</span>
).fit_transform(X)
y.shape
<span style="color: #228B22"># Train-test split</span>
trainingShare = <span style="color: #B452CD">0.5</span>
seed = <span style="color: #B452CD">1</span>
XTrain, XTest, yTrain, yTest=train_test_split(X, y, train_size=trainingShare, \
test_size = <span style="color: #B452CD">1</span>-trainingShare,
random_state=seed)
<span style="color: #228B22"># Input Scaling</span>
sc = StandardScaler()
XTrain = sc.fit_transform(XTrain)
XTest = sc.transform(XTest)
<span style="color: #228B22"># One-hot&#39;s of the target vector</span>
Y_train_onehot, Y_test_onehot = onehotencoder.fit_transform(yTrain), onehotencoder.fit_transform(yTest)
<span style="color: #228B22"># Remove instances with zeros only for past bill statements or paid amounts</span>
<span style="color: #CD5555">&#39;&#39;&#39;</span>
<span style="color: #CD5555">df = df.drop(df[(df.BILL_AMT1 == 0) &amp;</span>
<span style="color: #CD5555"> (df.BILL_AMT2 == 0) &amp;</span>
<span style="color: #CD5555"> (df.BILL_AMT3 == 0) &amp;</span>
<span style="color: #CD5555"> (df.BILL_AMT4 == 0) &amp;</span>
<span style="color: #CD5555"> (df.BILL_AMT5 == 0) &amp;</span>
<span style="color: #CD5555"> (df.BILL_AMT6 == 0) &amp;</span>
<span style="color: #CD5555"> (df.PAY_AMT1 == 0) &amp;</span>
<span style="color: #CD5555"> (df.PAY_AMT2 == 0) &amp;</span>
<span style="color: #CD5555"> (df.PAY_AMT3 == 0) &amp;</span>
<span style="color: #CD5555"> (df.PAY_AMT4 == 0) &amp;</span>
<span style="color: #CD5555"> (df.PAY_AMT5 == 0) &amp;</span>
<span style="color: #CD5555"> (df.PAY_AMT6 == 0)].index)</span>
<span style="color: #CD5555">&#39;&#39;&#39;</span>
df = df.drop(df[(df.BILL_AMT1 == <span style="color: #B452CD">0</span>) &amp;
(df.BILL_AMT2 == <span style="color: #B452CD">0</span>) &amp;
(df.BILL_AMT3 == <span style="color: #B452CD">0</span>) &amp;
(df.BILL_AMT4 == <span style="color: #B452CD">0</span>) &amp;
(df.BILL_AMT5 == <span style="color: #B452CD">0</span>) &amp;
(df.BILL_AMT6 == <span style="color: #B452CD">0</span>)].index)
df = df.drop(df[(df.PAY_AMT1 == <span style="color: #B452CD">0</span>) &amp;
(df.PAY_AMT2 == <span style="color: #B452CD">0</span>) &amp;
(df.PAY_AMT3 == <span style="color: #B452CD">0</span>) &amp;
(df.PAY_AMT4 == <span style="color: #B452CD">0</span>) &amp;
(df.PAY_AMT5 == <span style="color: #B452CD">0</span>) &amp;
(df.PAY_AMT6 == <span style="color: #B452CD">0</span>)].index)
<span style="color: #8B008B; font-weight: bold">from</span> <span style="color: #008b45; text-decoration: underline">sklearn.linear_model</span> <span style="color: #8B008B; font-weight: bold">import</span> LogisticRegression
<span style="color: #8B008B; font-weight: bold">from</span> <span style="color: #008b45; text-decoration: underline">sklearn.model_selection</span> <span style="color: #8B008B; font-weight: bold">import</span> GridSearchCV
lambdas=np.logspace(-<span style="color: #B452CD">5</span>,<span style="color: #B452CD">7</span>,<span style="color: #B452CD">13</span>)
parameters = [{<span style="color: #CD5555">&#39;C&#39;</span>: <span style="color: #B452CD">1.</span>/lambdas, <span style="color: #CD5555">&quot;solver&quot;</span>:[<span style="color: #CD5555">&quot;lbfgs&quot;</span>]}]<span style="color: #228B22">#*len(parameters)}]</span>
scoring = [<span style="color: #CD5555">&#39;accuracy&#39;</span>, <span style="color: #CD5555">&#39;roc_auc&#39;</span>]
logReg = LogisticRegression()
gridSearch = GridSearchCV(logReg, parameters, cv=<span style="color: #B452CD">5</span>, scoring=scoring, refit=<span style="color: #CD5555">&#39;roc_auc&#39;</span>)
</pre></div>
<p>
<!-- code=python (!bc pycod) typeset with pygments style "perldoc" -->
<div class="highlight" style="background: #eeeedd"><pre style="line-height: 125%"><span></span><span style="color: #228B22"># &quot;refit&quot; gives the metric used deciding best model. </span>
<span style="color: #228B22"># See more http://scikit-learn.org/stable/auto_examples/model_selection/plot_multi_metric_evaluation.html</span>
gridSearch.fit(XTrain, yTrain.ravel())
<span style="color: #8B008B; font-weight: bold">def</span> <span style="color: #008b45">gridSearchSummary</span>(method, scoring):
<span style="color: #CD5555">&quot;&quot;&quot;Prints best parameters from Grid search</span>
<span style="color: #CD5555"> and AUC with standard deviation for all </span>
<span style="color: #CD5555"> parameter combos &quot;&quot;&quot;</span>
method = <span style="color: #658b00">eval</span>(method)
<span style="color: #8B008B; font-weight: bold">if</span> scoring == <span style="color: #CD5555">&#39;accuracy&#39;</span>:
mean = <span style="color: #CD5555">&#39;mean_test_score&#39;</span>
sd = <span style="color: #CD5555">&#39;std_test_score&#39;</span>
<span style="color: #8B008B; font-weight: bold">elif</span> scoring == <span style="color: #CD5555">&#39;auc&#39;</span>:
mean = <span style="color: #CD5555">&#39;mean_test_roc_auc&#39;</span>
sd = <span style="color: #CD5555">&#39;std_test_roc_auc&#39;</span>
<span style="color: #8B008B; font-weight: bold">print</span>(<span style="color: #CD5555">&quot;Best: %f using %s&quot;</span> % (method.best_score_, method.best_params_))
means = method.cv_results_[mean]
stds = method.cv_results_[sd]
params = method.cv_results_[<span style="color: #CD5555">&#39;params&#39;</span>]
<span style="color: #8B008B; font-weight: bold">for</span> mean, stdev, param <span style="color: #8B008B">in</span> <span style="color: #658b00">zip</span>(means, stds, params):
<span style="color: #8B008B; font-weight: bold">print</span>(<span style="color: #CD5555">&quot;%f (%f) with: %r&quot;</span> % (mean, stdev, param))
<span style="color: #8B008B; font-weight: bold">def</span> <span style="color: #008b45">createConfusionMatrix</span>(method, printOut=<span style="color: #658b00">True</span>):
<span style="color: #CD5555">&quot;&quot;&quot;</span>
<span style="color: #CD5555"> Computes and prints confusion matrices, accuracy scores,</span>
<span style="color: #CD5555"> and AUC for test and training sets </span>
<span style="color: #CD5555"> &quot;&quot;&quot;</span>
confusionArray = np.zeros(<span style="color: #B452CD">6</span>, dtype=<span style="color: #658b00">object</span>)
method = <span style="color: #658b00">eval</span>(method)
<span style="color: #228B22"># Train</span>
yPredTrain = method.predict(XTrain)
yPredTrain = (yPredTrain &gt; <span style="color: #B452CD">0.5</span>)
cm = confusion_matrix(
yTrain, yPredTrain)
cm = np.around(cm/cm.sum(axis=<span style="color: #B452CD">1</span>)[:,<span style="color: #658b00">None</span>], <span style="color: #B452CD">2</span>)
confusionArray[<span style="color: #B452CD">0</span>] = cm
accScore = accuracy_score(yTrain, yPredTrain)
confusionArray[<span style="color: #B452CD">1</span>] = accScore
AUC = roc_auc_score(yTrain, yPredTrain)
confusionArray[<span style="color: #B452CD">2</span>] = AUC
<span style="color: #8B008B; font-weight: bold">if</span> printOut:
<span style="color: #8B008B; font-weight: bold">print</span>(<span style="color: #CD5555">&#39;\n################### Training ###############&#39;</span>)
<span style="color: #8B008B; font-weight: bold">print</span>(<span style="color: #CD5555">&#39;\nTraining Confusion matrix: \n&#39;</span>, cm)
<span style="color: #8B008B; font-weight: bold">print</span>(<span style="color: #CD5555">&#39;\nTraining Accuracy score: \n&#39;</span>, accScore)
<span style="color: #8B008B; font-weight: bold">print</span>(<span style="color: #CD5555">&#39;\nTrain AUC: \n&#39;</span>, AUC)
<span style="color: #228B22"># Test</span>
yPred = method.predict(XTest)
yPred = (yPred &gt; <span style="color: #B452CD">0.5</span>)
cm = confusion_matrix(
yTest, yPred)
cm = np.around(cm/cm.sum(axis=<span style="color: #B452CD">1</span>)[:,<span style="color: #658b00">None</span>], <span style="color: #B452CD">2</span>)
confusionArray[<span style="color: #B452CD">3</span>] = cm
accScore = accuracy_score(yTest, yPred)
confusionArray[<span style="color: #B452CD">4</span>] = accScore
AUC = roc_auc_score(yTest, yPred)
confusionArray[<span style="color: #B452CD">5</span>] = AUC
<span style="color: #8B008B; font-weight: bold">if</span> printOut:
<span style="color: #8B008B; font-weight: bold">print</span>(<span style="color: #CD5555">&#39;\n################### Testing ###############&#39;</span>)
<span style="color: #8B008B; font-weight: bold">print</span>(<span style="color: #CD5555">&#39;\nTest Confusion matrix: \n&#39;</span>, cm)
<span style="color: #8B008B; font-weight: bold">print</span>(<span style="color: #CD5555">&#39;\nTest Accuracy score: \n&#39;</span>, accScore)
<span style="color: #8B008B; font-weight: bold">print</span>(<span style="color: #CD5555">&#39;\nTestAUC: \n&#39;</span>, AUC)
<span style="color: #8B008B; font-weight: bold">return</span> confusionArray
<span style="color: #8B008B; font-weight: bold">import</span> <span style="color: #008b45; text-decoration: underline">matplotlib.pyplot</span> <span style="color: #8B008B; font-weight: bold">as</span> <span style="color: #008b45; text-decoration: underline">plt</span>
<span style="color: #8B008B; font-weight: bold">import</span> <span style="color: #008b45; text-decoration: underline">seaborn</span>
<span style="color: #8B008B; font-weight: bold">import</span> <span style="color: #008b45; text-decoration: underline">scikitplot</span> <span style="color: #8B008B; font-weight: bold">as</span> <span style="color: #008b45; text-decoration: underline">skplt</span>
seaborn.set(style=<span style="color: #CD5555">&quot;white&quot;</span>, context=<span style="color: #CD5555">&quot;notebook&quot;</span>, font_scale=<span style="color: #B452CD">1.5</span>,
rc={<span style="color: #CD5555">&quot;axes.grid&quot;</span>: <span style="color: #658b00">True</span>, <span style="color: #CD5555">&quot;legend.frameon&quot;</span>: <span style="color: #658b00">False</span>,
<span style="color: #CD5555">&quot;lines.markeredgewidth&quot;</span>: <span style="color: #B452CD">1.4</span>, <span style="color: #CD5555">&quot;lines.markersize&quot;</span>: <span style="color: #B452CD">10</span>})
seaborn.set_context(<span style="color: #CD5555">&quot;notebook&quot;</span>, font_scale=<span style="color: #B452CD">1.5</span>, rc={<span style="color: #CD5555">&quot;lines.linewidth&quot;</span>: <span style="color: #B452CD">4.5</span>})
yPred = gridSearch.predict_proba(XTest)
<span style="color: #8B008B; font-weight: bold">print</span>(yTest.ravel().shape, yPred.shape)
<span style="color: #228B22">#skplt.metrics.plot_cumulative_gain(yTest.ravel(), yPred_onehot)</span>
skplt.metrics.plot_cumulative_gain(yTest.ravel(), yPred)
defaults = <span style="color: #658b00">sum</span>(yTest == <span style="color: #B452CD">1</span>)
total = <span style="color: #658b00">len</span>(yTest)
defaultRate = defaults/total
<span style="color: #8B008B; font-weight: bold">def</span> <span style="color: #008b45">bestCurve</span>(defaults, total, defaultRate):
x = np.linspace(<span style="color: #B452CD">0</span>, <span style="color: #B452CD">1</span>, total)
y1 = np.linspace(<span style="color: #B452CD">0</span>, <span style="color: #B452CD">1</span>, defaults)
y2 = np.ones(total-defaults)
y3 = np.concatenate([y1,y2])
<span style="color: #8B008B; font-weight: bold">return</span> x, y3
x, best = bestCurve(defaults=defaults, total=total, defaultRate=defaultRate)
plt.plot(x, best)
plt.show()
</pre></div>
<p>
<!-- ------------------- end of main content --------------- -->
<center style="font-size:80%">
<!-- copyright --> &copy; 1999-2019, Morten Hjorth-Jensen. Released under CC Attribution-NonCommercial 4.0 license
</center>
</body>
</html>
+2 -2
View File
@@ -343,10 +343,10 @@ _logit_ transformations.
!split
===== The Softmax function =====
===== More classes =====
In our discussion of neural networks we will encounter the above again
in terms of the so-called _Softmax_ function.
in terms of a slightly modified function, the so-called _Softmax_ function.
The softmax function is used in various multiclass classification
methods, such as multinomial logistic regression (also known as
-772
View File
@@ -1,772 +0,0 @@
<!--
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: Logistic Regression">
<title>Data Analysis and Machine Learning: Logistic Regression</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}
div { text-align: justify; text-justify: inter-word; }
</style>
</head>
<!-- tocinfo
{'highest level': 2,
'sections': [('Logistic Regression', 2, None, '___sec0'),
('Optimization and Deep learning', 2, None, '___sec1'),
('Basics', 2, None, '___sec2'),
('Linear classifier', 2, None, '___sec3'),
('Some selected properties', 2, None, '___sec4'),
('The logistic function', 2, None, '___sec5'),
('Two parameters', 2, None, '___sec6'),
('Maximum likelihood', 2, None, '___sec7'),
('The cost function rewritten', 2, None, '___sec8'),
('Minimizing the cross entropy', 2, None, '___sec9'),
('A more compact expression', 2, None, '___sec10'),
('Extending to more predictors', 2, None, '___sec11'),
('Including more classes', 2, None, '___sec12'),
('The Softmax function', 2, None, '___sec13'),
('A simple classification problem', 2, None, '___sec14'),
('The Credit Card example', 2, None, '___sec15')]}
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: Logistic Regression</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>Sep 19, 2019</h4></center> <!-- date -->
<br>
<p>
<!-- !split -->
<h2 id="___sec0">Logistic Regression </h2>
<p>
In linear regression our main interest was centered on learning the
coefficients of a functional fit (say a polynomial) in order to be
able to predict the response of a continuous variable on some unseen
data. The fit to the continuous variable \( y_i \) is based on some
independent variables \( \hat{x}_i \). Linear regression resulted in
analytical expressions for standard ordinary Least Squares or Ridge
regression (in terms of matrices to invert) for several quantities,
ranging from the variance and thereby the confidence intervals of the
parameters \( \hat{\beta} \) to the mean squared error. If we can invert
the product of the design matrices, linear regression gives then a
simple recipe for fitting our data.
<p>
Classification problems, however, are concerned with outcomes taking
the form of discrete variables (i.e. categories). We may for example,
on the basis of DNA sequencing for a number of patients, like to find
out which mutations are important for a certain disease; or based on
scans of various patients' brains, figure out if there is a tumor or
not; or given a specific physical system, we'd like to identify its
state, say whether it is an ordered or disordered system (typical
situation in solid state physics); or classify the status of a
patient, whether she/he has a stroke or not and many other similar
situations.
<p>
The most common situation we encounter when we apply logistic
regression is that of two possible outcomes, normally denoted as a
binary outcome, true or false, positive or negative, success or
failure etc.
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec1">Optimization and Deep learning </h2>
<p>
Logistic regression will also serve as our stepping stone towards neural
network algorithms and supervised deep learning. For logistic
learning, the minimization of the cost function leads to a non-linear
equation in the parameters \( \hat{\beta} \). The optimization of the problem calls therefore for minimization algorithms. This forms the bottle neck of all machine learning algorithms, namely how to find reliable minima of a multi-variable function. This leads us to the family of gradient descent methods. The latter are the working horses of basically all modern machine learning algorithms.
<p>
We note also that many of the topics discussed here
regression are also commonly used in modern supervised Deep Learning
models, as we will see later.
<p>
<!-- !split -->
<h2 id="___sec2">Basics </h2>
<p>
We consider the case where the dependent variables, also called the
responses or the outcomes, \( y_i \) are discrete and only take values
from \( k=0,\dots,K-1 \) (i.e. \( K \) classes).
<p>
The goal is to predict the
output classes from the design matrix \( \hat{X}\in\mathbb{R}^{n\times p} \)
made of \( n \) samples, each of which carries \( p \) features or predictors. The
primary goal is to identify the classes to which new unseen samples
belong.
<p>
Let us specialize to the case of two classes only, with outputs
\( y_i=0 \) and \( y_i=1 \). Our outcomes could represent the status of a
credit card user that could default or not on her/his credit card
debt. That is
$$
y_i = \begin{bmatrix} 0 & \mathrm{no}\\ 1 & \mathrm{yes} \end{bmatrix}.
$$
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec3">Linear classifier </h2>
<p>
Before moving to the logistic model, let us try to use our linear regression model to classify these two outcomes. We could for example fit a linear model to the default case if \( y_i > 0.5 \) and the no default case \( y_i \leq 0.5 \).
<p>
We would then have our
weighted linear combination, namely
$$
\begin{equation}
\hat{y} = \hat{X}^T\hat{\beta} + \hat{\epsilon},
\label{_auto1}
\end{equation}
$$
where \( \hat{y} \) is a vector representing the possible outcomes, \( \hat{X} \) is our
\( n\times p \) design matrix and \( \hat{\beta} \) represents our estimators/predictors.
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec4">Some selected properties </h2>
<p>
The main problem with our function is that it
takes values on the entire real axis. In the case of
logistic regression, however, the labels \( y_i \) are discrete
variables. A typical example is the credit card data discussed below here, where we can set the state of defaulting the debt to \( y_i=1 \) and not to \( y_i=0 \) for one the persons in the data set (see the full example below).
<p>
One simple way to get a discrete output is to have sign
functions that map the output of a linear regressor to values \( \{0,1\} \),
\( f(s_i)=sign(s_i)=1 \) if \( s_i\ge 0 \) and 0 if otherwise.
We will encounter this model in our first demonstration of neural networks. Historically it is called the &quot;perceptron" model in the machine learning
literature. This model is extremely simple. However, in many cases it is more
favorable to use a ``soft" classifier that outputs
the probability of a given category. This leads us to the logistic function.
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec5">The logistic function </h2>
<p>
The perceptron is an example of a ``hard classification&quot; model. We
will encounter this model when we discuss neural networks as
well. Each datapoint is deterministically assigned to a category (i.e
\( y_i=0 \) or \( y_i=1 \)). In many cases, it is favorable to have a &quot;soft&quot;
classifier that outputs the probability of a given category rather
than a single value. For example, given \( x_i \), the classifier
outputs the probability of being in a category \( k \). Logistic regression
is the most common example of a so-called soft classifier. In logistic
regression, the probability that a data point \( x_i \)
belongs to a category \( y_i=\{0,1\} \) is given by the so-called logit function (or Sigmoid) which is meant to represent the likelihood for a given event,
$$
p(t) = \frac{1}{1+\mathrm \exp{-t}}=\frac{\exp{t}}{1+\mathrm \exp{t}}.
$$
Note that \( 1-p(t)= p(-t) \).
The following code plots the logistic function, the step function and other functions we will encounter from here and on.
<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: #BA2121; font-style: italic">&quot;&quot;&quot;The sigmoid function (or the logistic curve) is a</span>
<span style="color: #BA2121; font-style: italic">function that takes any real number, z, and outputs a number (0,1).</span>
<span style="color: #BA2121; font-style: italic">It is useful in neural networks for assigning weights on a relative scale.</span>
<span style="color: #BA2121; font-style: italic">The value z is the weighted sum of parameters involved in the learning algorithm.&quot;&quot;&quot;</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">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">math</span> <span style="color: #008000; font-weight: bold">as</span> <span style="color: #0000FF; font-weight: bold">mt</span>
z <span style="color: #666666">=</span> numpy<span style="color: #666666">.</span>arange(<span style="color: #666666">-5</span>, <span style="color: #666666">5</span>, <span style="color: #666666">.1</span>)
sigma_fn <span style="color: #666666">=</span> numpy<span style="color: #666666">.</span>vectorize(<span style="color: #008000; font-weight: bold">lambda</span> z: <span style="color: #666666">1/</span>(<span style="color: #666666">1+</span>numpy<span style="color: #666666">.</span>exp(<span style="color: #666666">-</span>z)))
sigma <span style="color: #666666">=</span> sigma_fn(z)
fig <span style="color: #666666">=</span> plt<span style="color: #666666">.</span>figure()
ax <span style="color: #666666">=</span> fig<span style="color: #666666">.</span>add_subplot(<span style="color: #666666">111</span>)
ax<span style="color: #666666">.</span>plot(z, sigma)
ax<span style="color: #666666">.</span>set_ylim([<span style="color: #666666">-0.1</span>, <span style="color: #666666">1.1</span>])
ax<span style="color: #666666">.</span>set_xlim([<span style="color: #666666">-5</span>,<span style="color: #666666">5</span>])
ax<span style="color: #666666">.</span>grid(<span style="color: #008000">True</span>)
ax<span style="color: #666666">.</span>set_xlabel(<span style="color: #BA2121">&#39;z&#39;</span>)
ax<span style="color: #666666">.</span>set_title(<span style="color: #BA2121">&#39;sigmoid function&#39;</span>)
plt<span style="color: #666666">.</span>show()
<span style="color: #BA2121; font-style: italic">&quot;&quot;&quot;Step Function&quot;&quot;&quot;</span>
z <span style="color: #666666">=</span> numpy<span style="color: #666666">.</span>arange(<span style="color: #666666">-5</span>, <span style="color: #666666">5</span>, <span style="color: #666666">.02</span>)
step_fn <span style="color: #666666">=</span> numpy<span style="color: #666666">.</span>vectorize(<span style="color: #008000; font-weight: bold">lambda</span> z: <span style="color: #666666">1.0</span> <span style="color: #008000; font-weight: bold">if</span> z <span style="color: #666666">&gt;=</span> <span style="color: #666666">0.0</span> <span style="color: #008000; font-weight: bold">else</span> <span style="color: #666666">0.0</span>)
step <span style="color: #666666">=</span> step_fn(z)
fig <span style="color: #666666">=</span> plt<span style="color: #666666">.</span>figure()
ax <span style="color: #666666">=</span> fig<span style="color: #666666">.</span>add_subplot(<span style="color: #666666">111</span>)
ax<span style="color: #666666">.</span>plot(z, step)
ax<span style="color: #666666">.</span>set_ylim([<span style="color: #666666">-0.5</span>, <span style="color: #666666">1.5</span>])
ax<span style="color: #666666">.</span>set_xlim([<span style="color: #666666">-5</span>,<span style="color: #666666">5</span>])
ax<span style="color: #666666">.</span>grid(<span style="color: #008000">True</span>)
ax<span style="color: #666666">.</span>set_xlabel(<span style="color: #BA2121">&#39;z&#39;</span>)
ax<span style="color: #666666">.</span>set_title(<span style="color: #BA2121">&#39;step function&#39;</span>)
plt<span style="color: #666666">.</span>show()
<span style="color: #BA2121; font-style: italic">&quot;&quot;&quot;tanh Function&quot;&quot;&quot;</span>
z <span style="color: #666666">=</span> numpy<span style="color: #666666">.</span>arange(<span style="color: #666666">-2*</span>mt<span style="color: #666666">.</span>pi, <span style="color: #666666">2*</span>mt<span style="color: #666666">.</span>pi, <span style="color: #666666">0.1</span>)
t <span style="color: #666666">=</span> numpy<span style="color: #666666">.</span>tanh(z)
fig <span style="color: #666666">=</span> plt<span style="color: #666666">.</span>figure()
ax <span style="color: #666666">=</span> fig<span style="color: #666666">.</span>add_subplot(<span style="color: #666666">111</span>)
ax<span style="color: #666666">.</span>plot(z, t)
ax<span style="color: #666666">.</span>set_ylim([<span style="color: #666666">-1.0</span>, <span style="color: #666666">1.0</span>])
ax<span style="color: #666666">.</span>set_xlim([<span style="color: #666666">-2*</span>mt<span style="color: #666666">.</span>pi,<span style="color: #666666">2*</span>mt<span style="color: #666666">.</span>pi])
ax<span style="color: #666666">.</span>grid(<span style="color: #008000">True</span>)
ax<span style="color: #666666">.</span>set_xlabel(<span style="color: #BA2121">&#39;z&#39;</span>)
ax<span style="color: #666666">.</span>set_title(<span style="color: #BA2121">&#39;tanh function&#39;</span>)
plt<span style="color: #666666">.</span>show()
</pre></div>
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec6">Two parameters </h2>
<p>
We assume now that we have two classes with \( y_i \) either \( 0 \) or \( 1 \). Furthermore we assume also that we have only two parameters \( \beta \) in our fitting of the Sigmoid function, that is we define probabilities
$$
\begin{align*}
p(y_i=1|x_i,\hat{\beta}) &= \frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}},\nonumber\\
p(y_i=0|x_i,\hat{\beta}) &= 1 - p(y_i=1|x_i,\hat{\beta}),
\end{align*}
$$
where \( \hat{\beta} \) are the weights we wish to extract from data, in our case \( \beta_0 \) and \( \beta_1 \).
<p>
Note that we used
$$
p(y_i=0\vert x_i, \hat{\beta}) = 1-p(y_i=1\vert x_i, \hat{\beta}).
$$
<p>
<!-- !split -->
<h2 id="___sec7">Maximum likelihood </h2>
<p>
In order to define the total likelihood for all possible outcomes from a
dataset \( \mathcal{D}=\{(y_i,x_i)\} \), with the binary labels
\( y_i\in\{0,1\} \) and where the data points are drawn independently, we use the so-called <a href="https://en.wikipedia.org/wiki/Maximum_likelihood_estimation" target="_blank">Maximum Likelihood Estimation</a> (MLE) principle.
We aim thus at maximizing
the probability of seeing the observed data. We can then approximate the
likelihood in terms of the product of the individual probabilities of a specific outcome \( y_i \), that is
$$
\begin{align*}
P(\mathcal{D}|\hat{\beta})& = \prod_{i=1}^n \left[p(y_i=1|x_i,\hat{\beta})\right]^{y_i}\left[1-p(y_i=1|x_i,\hat{\beta}))\right]^{1-y_i}\nonumber \\
\end{align*}
$$
from which we obtain the log-likelihood and our <b>cost/loss</b> function
$$
\mathcal{C}(\hat{\beta}) = \sum_{i=1}^n \left( y_i\log{p(y_i=1|x_i,\hat{\beta})} + (1-y_i)\log\left[1-p(y_i=1|x_i,\hat{\beta}))\right]\right).
$$
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec8">The cost function rewritten </h2>
<p>
Reordering the logarithms, we can rewrite the <b>cost/loss</b> function as
$$
\mathcal{C}(\hat{\beta}) = \sum_{i=1}^n \left(y_i(\beta_0+\beta_1x_i) -\log{(1+\exp{(\beta_0+\beta_1x_i)})}\right).
$$
<p>
The maximum likelihood estimator is defined as the set of parameters that maximize the log-likelihood where we maximize with respect to \( \beta \).
Since the cost (error) function is just the negative log-likelihood, for logistic regression we have that
$$
\mathcal{C}(\hat{\beta})=-\sum_{i=1}^n \left(y_i(\beta_0+\beta_1x_i) -\log{(1+\exp{(\beta_0+\beta_1x_i)})}\right).
$$
This equation is known in statistics as the <b>cross entropy</b>. Finally, we note that just as in linear regression,
in practice we often supplement the cross-entropy with additional regularization terms, usually \( L_1 \) and \( L_2 \) regularization as we did for Ridge and Lasso regression.
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec9">Minimizing the cross entropy </h2>
<p>
The cross entropy is a convex function of the weights \( \hat{\beta} \) and,
therefore, any local minimizer is a global minimizer.
<p>
Minimizing this
cost function with respect to the two parameters \( \beta_0 \) and \( \beta_1 \) we obtain
$$
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \beta_0} = -\sum_{i=1}^n \left(y_i -\frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}}\right),
$$
and
$$
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \beta_1} = -\sum_{i=1}^n \left(y_ix_i -x_i\frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}}\right).
$$
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec10">A more compact expression </h2>
<p>
Let us now define a vector \( \hat{y} \) with \( n \) elements \( y_i \), an
\( n\times p \) matrix \( \hat{X} \) which contains the \( x_i \) values and a
vector \( \hat{p} \) of fitted probabilities \( p(y_i\vert x_i,\hat{\beta}) \). We can rewrite in a more compact form the first
derivative of cost function as
$$
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \hat{\beta}} = -\hat{X}^T\left(\hat{y}-\hat{p}\right).
$$
<p>
If we in addition define a diagonal matrix \( \hat{W} \) with elements
\( p(y_i\vert x_i,\hat{\beta})(1-p(y_i\vert x_i,\hat{\beta}) \), we can obtain a compact expression of the second derivative as
$$
\frac{\partial^2 \mathcal{C}(\hat{\beta})}{\partial \hat{\beta}\partial \hat{\beta}^T} = \hat{X}^T\hat{W}\hat{X}.
$$
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec11">Extending to more predictors </h2>
<p>
Within a binary classification problem, we can easily expand our model to include multiple predictors. Our ratio between likelihoods is then with \( p \) predictors
$$
\log{ \frac{p(\hat{\beta}\hat{x})}{1-p(\hat{\beta}\hat{x})}} = \beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p.
$$
Here we defined \( \hat{x}=[1,x_1,x_2,\dots,x_p] \) and \( \hat{\beta}=[\beta_0, \beta_1, \dots, \beta_p] \) leading to
$$
p(\hat{\beta}\hat{x})=\frac{ \exp{(\beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p)}}{1+\exp{(\beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p)}}.
$$
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec12">Including more classes </h2>
<p>
Till now we have mainly focused on two classes, the so-called binary
system. Suppose we wish to extend to \( K \) classes. Let us for the sake
of simplicity assume we have only two predictors. We have then
following model
$$
\log{\frac{p(C=1\vert x)}{p(K\vert x)}} = \beta_{10}+\beta_{11}x_1,
$$
$$
\log{\frac{p(C=2\vert x)}{p(K\vert x)}} = \beta_{20}+\beta_{21}x_1,
$$
and so on till the class \( C=K-1 \) class
$$
\log{\frac{p(C=K-1\vert x)}{p(K\vert x)}} = \beta_{(K-1)0}+\beta_{(K-1)1}x_1,
$$
<p>
and the model is specified in term of \( K-1 \) so-called log-odds or
<b>logit</b> transformations.
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec13">The Softmax function </h2>
<p>
In our discussion of neural networks we will encounter the above again
in terms of the so-called <b>Softmax</b> function.
<p>
The softmax function is used in various multiclass classification
methods, such as multinomial logistic regression (also known as
softmax regression), multiclass linear discriminant analysis, naive
Bayes classifiers, and artificial neural networks. Specifically, in
multinomial logistic regression and linear discriminant analysis, the
input to the function is the result of \( K \) distinct linear functions,
and the predicted probability for the \( k \)-th class given a sample
vector \( \hat{x} \) and a weighting vector \( \hat{\beta} \) is (with two
predictors):
$$
p(C=k\vert \mathbf {x} )=\frac{\exp{(\beta_{k0}+\beta_{k1}x_1)}}{1+\sum_{l=1}^{K-1}\exp{(\beta_{l0}+\beta_{l1}x_1)}}.
$$
It is easy to extend to more predictors. The final class is
$$
p(C=K\vert \mathbf {x} )=\frac{1}{1+\sum_{l=1}^{K-1}\exp{(\beta_{l0}+\beta_{l1}x_1)}},
$$
<p>
and they sum to one. Our earlier discussions were all specialized to
the case with two classes only. It is easy to see from the above that
what we derived earlier is compatible with these equations.
<p>
To find the optimal parameters we would typically use a gradient
descent method. Newton's method and gradient descent methods are
discussed in the material on <a href="https://compphysics.github.io/MachineLearning/doc/pub/Splines/html/Splines-bs.html" target="_blank">optimization
methods</a>.
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec14">A simple classification problem </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: #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</span> <span style="color: #008000; font-weight: bold">import</span> datasets, linear_model
<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">def</span> <span style="color: #0000FF">generate_data</span>():
np<span style="color: #666666">.</span>random<span style="color: #666666">.</span>seed(<span style="color: #666666">0</span>)
X, y <span style="color: #666666">=</span> datasets<span style="color: #666666">.</span>make_moons(<span style="color: #666666">200</span>, noise<span style="color: #666666">=0.20</span>)
<span style="color: #008000; font-weight: bold">return</span> X, y
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">visualize</span>(X, y, clf):
plot_decision_boundary(<span style="color: #008000; font-weight: bold">lambda</span> x: clf<span style="color: #666666">.</span>predict(x), X, y)
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">plot_decision_boundary</span>(pred_func, X, y):
<span style="color: #408080; font-style: italic"># Set min and max values and give it some padding</span>
x_min, x_max <span style="color: #666666">=</span> X[:, <span style="color: #666666">0</span>]<span style="color: #666666">.</span>min() <span style="color: #666666">-</span> <span style="color: #666666">.5</span>, X[:, <span style="color: #666666">0</span>]<span style="color: #666666">.</span>max() <span style="color: #666666">+</span> <span style="color: #666666">.5</span>
y_min, y_max <span style="color: #666666">=</span> X[:, <span style="color: #666666">1</span>]<span style="color: #666666">.</span>min() <span style="color: #666666">-</span> <span style="color: #666666">.5</span>, X[:, <span style="color: #666666">1</span>]<span style="color: #666666">.</span>max() <span style="color: #666666">+</span> <span style="color: #666666">.5</span>
h <span style="color: #666666">=</span> <span style="color: #666666">0.01</span>
<span style="color: #408080; font-style: italic"># Generate a grid of points with distance h between them</span>
xx, yy <span style="color: #666666">=</span> np<span style="color: #666666">.</span>meshgrid(np<span style="color: #666666">.</span>arange(x_min, x_max, h), np<span style="color: #666666">.</span>arange(y_min, y_max, h))
<span style="color: #408080; font-style: italic"># Predict the function value for the whole gid</span>
Z <span style="color: #666666">=</span> pred_func(np<span style="color: #666666">.</span>c_[xx<span style="color: #666666">.</span>ravel(), yy<span style="color: #666666">.</span>ravel()])
Z <span style="color: #666666">=</span> Z<span style="color: #666666">.</span>reshape(xx<span style="color: #666666">.</span>shape)
<span style="color: #408080; font-style: italic"># Plot the contour and training examples</span>
plt<span style="color: #666666">.</span>contourf(xx, yy, Z, cmap<span style="color: #666666">=</span>plt<span style="color: #666666">.</span>cm<span style="color: #666666">.</span>Spectral)
plt<span style="color: #666666">.</span>scatter(X[:, <span style="color: #666666">0</span>], X[:, <span style="color: #666666">1</span>], c<span style="color: #666666">=</span>y, cmap<span style="color: #666666">=</span>plt<span style="color: #666666">.</span>cm<span style="color: #666666">.</span>Spectral)
plt<span style="color: #666666">.</span>show()
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">classify</span>(X, y):
clf <span style="color: #666666">=</span> linear_model<span style="color: #666666">.</span>LogisticRegressionCV()
clf<span style="color: #666666">.</span>fit(X, y)
<span style="color: #008000; font-weight: bold">return</span> clf
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">main</span>():
X, y <span style="color: #666666">=</span> generate_data()
<span style="color: #408080; font-style: italic"># visualize(X, y)</span>
clf <span style="color: #666666">=</span> classify(X, y)
visualize(X, y, clf)
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #19177C">__name__</span> <span style="color: #666666">==</span> <span style="color: #BA2121">&quot;__main__&quot;</span>:
main()
</pre></div>
<p>
<!-- !split --><br><br><br><br><br><br><br><br><br><br>
<h2 id="___sec15">The Credit Card example </h2>
Here we use the the <a href="https://archive.ics.uci.edu/ml/datasets/default+of+credit+card+clients" target="_blank">credit card data</a>. More text to come.
<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">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">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">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> OneHotEncoder
<span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">sklearn.compose</span> <span style="color: #008000; font-weight: bold">import</span> ColumnTransformer
<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> StandardScaler, OneHotEncoder
<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> confusion_matrix, accuracy_score, roc_auc_score
<span style="color: #408080; font-style: italic"># Trying to set the seed</span>
np<span style="color: #666666">.</span>random<span style="color: #666666">.</span>seed(<span style="color: #666666">0</span>)
<span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">random</span>
random<span style="color: #666666">.</span>seed(<span style="color: #666666">0</span>)
<span style="color: #408080; font-style: italic"># Reading file into data frame</span>
cwd <span style="color: #666666">=</span> os<span style="color: #666666">.</span>getcwd()
filename <span style="color: #666666">=</span> cwd <span style="color: #666666">+</span> <span style="color: #BA2121">&#39;/default of credit card clients.xls&#39;</span>
nanDict <span style="color: #666666">=</span> {}
df <span style="color: #666666">=</span> pd<span style="color: #666666">.</span>read_excel(filename, header<span style="color: #666666">=1</span>, skiprows<span style="color: #666666">=0</span>, index_col<span style="color: #666666">=0</span>, na_values<span style="color: #666666">=</span>nanDict)
df<span style="color: #666666">.</span>rename(index<span style="color: #666666">=</span><span style="color: #008000">str</span>, columns<span style="color: #666666">=</span>{<span style="color: #BA2121">&quot;default payment next month&quot;</span>: <span style="color: #BA2121">&quot;defaultPaymentNextMonth&quot;</span>}, inplace<span style="color: #666666">=</span><span style="color: #008000">True</span>)
<span style="color: #408080; font-style: italic"># Features and targets </span>
X <span style="color: #666666">=</span> df<span style="color: #666666">.</span>loc[:, df<span style="color: #666666">.</span>columns <span style="color: #666666">!=</span> <span style="color: #BA2121">&#39;defaultPaymentNextMonth&#39;</span>]<span style="color: #666666">.</span>values
y <span style="color: #666666">=</span> df<span style="color: #666666">.</span>loc[:, df<span style="color: #666666">.</span>columns <span style="color: #666666">==</span> <span style="color: #BA2121">&#39;defaultPaymentNextMonth&#39;</span>]<span style="color: #666666">.</span>values
<span style="color: #408080; font-style: italic"># Categorical variables to one-hot&#39;s</span>
onehotencoder <span style="color: #666666">=</span> OneHotEncoder(categories<span style="color: #666666">=</span><span style="color: #BA2121">&quot;auto&quot;</span>)
X <span style="color: #666666">=</span> ColumnTransformer(
[(<span style="color: #BA2121">&quot;&quot;</span>, onehotencoder, [<span style="color: #666666">3</span>]),],
remainder<span style="color: #666666">=</span><span style="color: #BA2121">&quot;passthrough&quot;</span>
)<span style="color: #666666">.</span>fit_transform(X)
y<span style="color: #666666">.</span>shape
<span style="color: #408080; font-style: italic"># Train-test split</span>
trainingShare <span style="color: #666666">=</span> <span style="color: #666666">0.5</span>
seed <span style="color: #666666">=</span> <span style="color: #666666">1</span>
XTrain, XTest, yTrain, yTest<span style="color: #666666">=</span>train_test_split(X, y, train_size<span style="color: #666666">=</span>trainingShare, \
test_size <span style="color: #666666">=</span> <span style="color: #666666">1-</span>trainingShare,
random_state<span style="color: #666666">=</span>seed)
<span style="color: #408080; font-style: italic"># Input Scaling</span>
sc <span style="color: #666666">=</span> StandardScaler()
XTrain <span style="color: #666666">=</span> sc<span style="color: #666666">.</span>fit_transform(XTrain)
XTest <span style="color: #666666">=</span> sc<span style="color: #666666">.</span>transform(XTest)
<span style="color: #408080; font-style: italic"># One-hot&#39;s of the target vector</span>
Y_train_onehot, Y_test_onehot <span style="color: #666666">=</span> onehotencoder<span style="color: #666666">.</span>fit_transform(yTrain), onehotencoder<span style="color: #666666">.</span>fit_transform(yTest)
<span style="color: #408080; font-style: italic"># Remove instances with zeros only for past bill statements or paid amounts</span>
<span style="color: #BA2121; font-style: italic">&#39;&#39;&#39;</span>
<span style="color: #BA2121; font-style: italic">df = df.drop(df[(df.BILL_AMT1 == 0) &amp;</span>
<span style="color: #BA2121; font-style: italic"> (df.BILL_AMT2 == 0) &amp;</span>
<span style="color: #BA2121; font-style: italic"> (df.BILL_AMT3 == 0) &amp;</span>
<span style="color: #BA2121; font-style: italic"> (df.BILL_AMT4 == 0) &amp;</span>
<span style="color: #BA2121; font-style: italic"> (df.BILL_AMT5 == 0) &amp;</span>
<span style="color: #BA2121; font-style: italic"> (df.BILL_AMT6 == 0) &amp;</span>
<span style="color: #BA2121; font-style: italic"> (df.PAY_AMT1 == 0) &amp;</span>
<span style="color: #BA2121; font-style: italic"> (df.PAY_AMT2 == 0) &amp;</span>
<span style="color: #BA2121; font-style: italic"> (df.PAY_AMT3 == 0) &amp;</span>
<span style="color: #BA2121; font-style: italic"> (df.PAY_AMT4 == 0) &amp;</span>
<span style="color: #BA2121; font-style: italic"> (df.PAY_AMT5 == 0) &amp;</span>
<span style="color: #BA2121; font-style: italic"> (df.PAY_AMT6 == 0)].index)</span>
<span style="color: #BA2121; font-style: italic">&#39;&#39;&#39;</span>
df <span style="color: #666666">=</span> df<span style="color: #666666">.</span>drop(df[(df<span style="color: #666666">.</span>BILL_AMT1 <span style="color: #666666">==</span> <span style="color: #666666">0</span>) <span style="color: #666666">&amp;</span>
(df<span style="color: #666666">.</span>BILL_AMT2 <span style="color: #666666">==</span> <span style="color: #666666">0</span>) <span style="color: #666666">&amp;</span>
(df<span style="color: #666666">.</span>BILL_AMT3 <span style="color: #666666">==</span> <span style="color: #666666">0</span>) <span style="color: #666666">&amp;</span>
(df<span style="color: #666666">.</span>BILL_AMT4 <span style="color: #666666">==</span> <span style="color: #666666">0</span>) <span style="color: #666666">&amp;</span>
(df<span style="color: #666666">.</span>BILL_AMT5 <span style="color: #666666">==</span> <span style="color: #666666">0</span>) <span style="color: #666666">&amp;</span>
(df<span style="color: #666666">.</span>BILL_AMT6 <span style="color: #666666">==</span> <span style="color: #666666">0</span>)]<span style="color: #666666">.</span>index)
df <span style="color: #666666">=</span> df<span style="color: #666666">.</span>drop(df[(df<span style="color: #666666">.</span>PAY_AMT1 <span style="color: #666666">==</span> <span style="color: #666666">0</span>) <span style="color: #666666">&amp;</span>
(df<span style="color: #666666">.</span>PAY_AMT2 <span style="color: #666666">==</span> <span style="color: #666666">0</span>) <span style="color: #666666">&amp;</span>
(df<span style="color: #666666">.</span>PAY_AMT3 <span style="color: #666666">==</span> <span style="color: #666666">0</span>) <span style="color: #666666">&amp;</span>
(df<span style="color: #666666">.</span>PAY_AMT4 <span style="color: #666666">==</span> <span style="color: #666666">0</span>) <span style="color: #666666">&amp;</span>
(df<span style="color: #666666">.</span>PAY_AMT5 <span style="color: #666666">==</span> <span style="color: #666666">0</span>) <span style="color: #666666">&amp;</span>
(df<span style="color: #666666">.</span>PAY_AMT6 <span style="color: #666666">==</span> <span style="color: #666666">0</span>)]<span style="color: #666666">.</span>index)
<span style="color: #008000; font-weight: bold">from</span> <span style="color: #0000FF; font-weight: bold">sklearn.linear_model</span> <span style="color: #008000; font-weight: bold">import</span> LogisticRegression
<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> GridSearchCV
lambdas<span style="color: #666666">=</span>np<span style="color: #666666">.</span>logspace(<span style="color: #666666">-5</span>,<span style="color: #666666">7</span>,<span style="color: #666666">13</span>)
parameters <span style="color: #666666">=</span> [{<span style="color: #BA2121">&#39;C&#39;</span>: <span style="color: #666666">1./</span>lambdas, <span style="color: #BA2121">&quot;solver&quot;</span>:[<span style="color: #BA2121">&quot;lbfgs&quot;</span>]}]<span style="color: #408080; font-style: italic">#*len(parameters)}]</span>
scoring <span style="color: #666666">=</span> [<span style="color: #BA2121">&#39;accuracy&#39;</span>, <span style="color: #BA2121">&#39;roc_auc&#39;</span>]
logReg <span style="color: #666666">=</span> LogisticRegression()
gridSearch <span style="color: #666666">=</span> GridSearchCV(logReg, parameters, cv<span style="color: #666666">=5</span>, scoring<span style="color: #666666">=</span>scoring, refit<span style="color: #666666">=</span><span style="color: #BA2121">&#39;roc_auc&#39;</span>)
</pre></div>
<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"># &quot;refit&quot; gives the metric used deciding best model. </span>
<span style="color: #408080; font-style: italic"># See more http://scikit-learn.org/stable/auto_examples/model_selection/plot_multi_metric_evaluation.html</span>
gridSearch<span style="color: #666666">.</span>fit(XTrain, yTrain<span style="color: #666666">.</span>ravel())
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">gridSearchSummary</span>(method, scoring):
<span style="color: #BA2121; font-style: italic">&quot;&quot;&quot;Prints best parameters from Grid search</span>
<span style="color: #BA2121; font-style: italic"> and AUC with standard deviation for all </span>
<span style="color: #BA2121; font-style: italic"> parameter combos &quot;&quot;&quot;</span>
method <span style="color: #666666">=</span> <span style="color: #008000">eval</span>(method)
<span style="color: #008000; font-weight: bold">if</span> scoring <span style="color: #666666">==</span> <span style="color: #BA2121">&#39;accuracy&#39;</span>:
mean <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;mean_test_score&#39;</span>
sd <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;std_test_score&#39;</span>
<span style="color: #008000; font-weight: bold">elif</span> scoring <span style="color: #666666">==</span> <span style="color: #BA2121">&#39;auc&#39;</span>:
mean <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;mean_test_roc_auc&#39;</span>
sd <span style="color: #666666">=</span> <span style="color: #BA2121">&#39;std_test_roc_auc&#39;</span>
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">&quot;Best: </span><span style="color: #BB6688; font-weight: bold">%f</span><span style="color: #BA2121"> using </span><span style="color: #BB6688; font-weight: bold">%s</span><span style="color: #BA2121">&quot;</span> <span style="color: #666666">%</span> (method<span style="color: #666666">.</span>best_score_, method<span style="color: #666666">.</span>best_params_))
means <span style="color: #666666">=</span> method<span style="color: #666666">.</span>cv_results_[mean]
stds <span style="color: #666666">=</span> method<span style="color: #666666">.</span>cv_results_[sd]
params <span style="color: #666666">=</span> method<span style="color: #666666">.</span>cv_results_[<span style="color: #BA2121">&#39;params&#39;</span>]
<span style="color: #008000; font-weight: bold">for</span> mean, stdev, param <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #008000">zip</span>(means, stds, params):
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">&quot;</span><span style="color: #BB6688; font-weight: bold">%f</span><span style="color: #BA2121"> (</span><span style="color: #BB6688; font-weight: bold">%f</span><span style="color: #BA2121">) with: </span><span style="color: #BB6688; font-weight: bold">%r</span><span style="color: #BA2121">&quot;</span> <span style="color: #666666">%</span> (mean, stdev, param))
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">createConfusionMatrix</span>(method, printOut<span style="color: #666666">=</span><span style="color: #008000">True</span>):
<span style="color: #BA2121; font-style: italic">&quot;&quot;&quot;</span>
<span style="color: #BA2121; font-style: italic"> Computes and prints confusion matrices, accuracy scores,</span>
<span style="color: #BA2121; font-style: italic"> and AUC for test and training sets </span>
<span style="color: #BA2121; font-style: italic"> &quot;&quot;&quot;</span>
confusionArray <span style="color: #666666">=</span> np<span style="color: #666666">.</span>zeros(<span style="color: #666666">6</span>, dtype<span style="color: #666666">=</span><span style="color: #008000">object</span>)
method <span style="color: #666666">=</span> <span style="color: #008000">eval</span>(method)
<span style="color: #408080; font-style: italic"># Train</span>
yPredTrain <span style="color: #666666">=</span> method<span style="color: #666666">.</span>predict(XTrain)
yPredTrain <span style="color: #666666">=</span> (yPredTrain <span style="color: #666666">&gt;</span> <span style="color: #666666">0.5</span>)
cm <span style="color: #666666">=</span> confusion_matrix(
yTrain, yPredTrain)
cm <span style="color: #666666">=</span> np<span style="color: #666666">.</span>around(cm<span style="color: #666666">/</span>cm<span style="color: #666666">.</span>sum(axis<span style="color: #666666">=1</span>)[:,<span style="color: #008000">None</span>], <span style="color: #666666">2</span>)
confusionArray[<span style="color: #666666">0</span>] <span style="color: #666666">=</span> cm
accScore <span style="color: #666666">=</span> accuracy_score(yTrain, yPredTrain)
confusionArray[<span style="color: #666666">1</span>] <span style="color: #666666">=</span> accScore
AUC <span style="color: #666666">=</span> roc_auc_score(yTrain, yPredTrain)
confusionArray[<span style="color: #666666">2</span>] <span style="color: #666666">=</span> AUC
<span style="color: #008000; font-weight: bold">if</span> printOut:
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">&#39;</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">################### Training ###############&#39;</span>)
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">&#39;</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">Training Confusion matrix: </span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">&#39;</span>, cm)
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">&#39;</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">Training Accuracy score: </span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">&#39;</span>, accScore)
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">&#39;</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">Train AUC: </span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">&#39;</span>, AUC)
<span style="color: #408080; font-style: italic"># Test</span>
yPred <span style="color: #666666">=</span> method<span style="color: #666666">.</span>predict(XTest)
yPred <span style="color: #666666">=</span> (yPred <span style="color: #666666">&gt;</span> <span style="color: #666666">0.5</span>)
cm <span style="color: #666666">=</span> confusion_matrix(
yTest, yPred)
cm <span style="color: #666666">=</span> np<span style="color: #666666">.</span>around(cm<span style="color: #666666">/</span>cm<span style="color: #666666">.</span>sum(axis<span style="color: #666666">=1</span>)[:,<span style="color: #008000">None</span>], <span style="color: #666666">2</span>)
confusionArray[<span style="color: #666666">3</span>] <span style="color: #666666">=</span> cm
accScore <span style="color: #666666">=</span> accuracy_score(yTest, yPred)
confusionArray[<span style="color: #666666">4</span>] <span style="color: #666666">=</span> accScore
AUC <span style="color: #666666">=</span> roc_auc_score(yTest, yPred)
confusionArray[<span style="color: #666666">5</span>] <span style="color: #666666">=</span> AUC
<span style="color: #008000; font-weight: bold">if</span> printOut:
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">&#39;</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">################### Testing ###############&#39;</span>)
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">&#39;</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">Test Confusion matrix: </span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">&#39;</span>, cm)
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">&#39;</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">Test Accuracy score: </span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">&#39;</span>, accScore)
<span style="color: #008000; font-weight: bold">print</span>(<span style="color: #BA2121">&#39;</span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">TestAUC: </span><span style="color: #BB6622; font-weight: bold">\n</span><span style="color: #BA2121">&#39;</span>, AUC)
<span style="color: #008000; font-weight: bold">return</span> confusionArray
<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">seaborn</span>
<span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">scikitplot</span> <span style="color: #008000; font-weight: bold">as</span> <span style="color: #0000FF; font-weight: bold">skplt</span>
seaborn<span style="color: #666666">.</span>set(style<span style="color: #666666">=</span><span style="color: #BA2121">&quot;white&quot;</span>, context<span style="color: #666666">=</span><span style="color: #BA2121">&quot;notebook&quot;</span>, font_scale<span style="color: #666666">=1.5</span>,
rc<span style="color: #666666">=</span>{<span style="color: #BA2121">&quot;axes.grid&quot;</span>: <span style="color: #008000">True</span>, <span style="color: #BA2121">&quot;legend.frameon&quot;</span>: <span style="color: #008000">False</span>,
<span style="color: #BA2121">&quot;lines.markeredgewidth&quot;</span>: <span style="color: #666666">1.4</span>, <span style="color: #BA2121">&quot;lines.markersize&quot;</span>: <span style="color: #666666">10</span>})
seaborn<span style="color: #666666">.</span>set_context(<span style="color: #BA2121">&quot;notebook&quot;</span>, font_scale<span style="color: #666666">=1.5</span>, rc<span style="color: #666666">=</span>{<span style="color: #BA2121">&quot;lines.linewidth&quot;</span>: <span style="color: #666666">4.5</span>})
yPred <span style="color: #666666">=</span> gridSearch<span style="color: #666666">.</span>predict_proba(XTest)
<span style="color: #008000; font-weight: bold">print</span>(yTest<span style="color: #666666">.</span>ravel()<span style="color: #666666">.</span>shape, yPred<span style="color: #666666">.</span>shape)
<span style="color: #408080; font-style: italic">#skplt.metrics.plot_cumulative_gain(yTest.ravel(), yPred_onehot)</span>
skplt<span style="color: #666666">.</span>metrics<span style="color: #666666">.</span>plot_cumulative_gain(yTest<span style="color: #666666">.</span>ravel(), yPred)
defaults <span style="color: #666666">=</span> <span style="color: #008000">sum</span>(yTest <span style="color: #666666">==</span> <span style="color: #666666">1</span>)
total <span style="color: #666666">=</span> <span style="color: #008000">len</span>(yTest)
defaultRate <span style="color: #666666">=</span> defaults<span style="color: #666666">/</span>total
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">bestCurve</span>(defaults, total, defaultRate):
x <span style="color: #666666">=</span> np<span style="color: #666666">.</span>linspace(<span style="color: #666666">0</span>, <span style="color: #666666">1</span>, total)
y1 <span style="color: #666666">=</span> np<span style="color: #666666">.</span>linspace(<span style="color: #666666">0</span>, <span style="color: #666666">1</span>, defaults)
y2 <span style="color: #666666">=</span> np<span style="color: #666666">.</span>ones(total<span style="color: #666666">-</span>defaults)
y3 <span style="color: #666666">=</span> np<span style="color: #666666">.</span>concatenate([y1,y2])
<span style="color: #008000; font-weight: bold">return</span> x, y3
x, best <span style="color: #666666">=</span> bestCurve(defaults<span style="color: #666666">=</span>defaults, total<span style="color: #666666">=</span>total, defaultRate<span style="color: #666666">=</span>defaultRate)
plt<span style="color: #666666">.</span>plot(x, best)
plt<span style="color: #666666">.</span>show()
</pre></div>
<p>
<!-- ------------------- end of main content --------------- -->
<center style="font-size:80%">
<!-- copyright --> &copy; 1999-2019, Morten Hjorth-Jensen. Released under CC Attribution-NonCommercial 4.0 license
</center>
</body>
</html>
-880
View File
@@ -1,880 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- dom:TITLE: Data Analysis and Machine Learning: Logistic Regression -->\n",
"# Data Analysis and Machine Learning: Logistic Regression\n",
"<!-- dom:AUTHOR: Morten Hjorth-Jensen at Department of Physics, University of Oslo & Department of Physics and Astronomy and National Superconducting Cyclotron Laboratory, Michigan State University -->\n",
"<!-- Author: --> \n",
"**Morten Hjorth-Jensen**, Department of Physics, University of Oslo and Department of Physics and Astronomy and National Superconducting Cyclotron Laboratory, Michigan State University\n",
"\n",
"Date: **Sep 19, 2019**\n",
"\n",
"Copyright 1999-2019, Morten Hjorth-Jensen. Released under CC Attribution-NonCommercial 4.0 license\n",
"\n",
"\n",
"\n",
"\n",
"<!-- !split -->\n",
"## Logistic Regression\n",
"\n",
"In linear regression our main interest was centered on learning the\n",
"coefficients of a functional fit (say a polynomial) in order to be\n",
"able to predict the response of a continuous variable on some unseen\n",
"data. The fit to the continuous variable $y_i$ is based on some\n",
"independent variables $\\hat{x}_i$. Linear regression resulted in\n",
"analytical expressions for standard ordinary Least Squares or Ridge\n",
"regression (in terms of matrices to invert) for several quantities,\n",
"ranging from the variance and thereby the confidence intervals of the\n",
"parameters $\\hat{\\beta}$ to the mean squared error. If we can invert\n",
"the product of the design matrices, linear regression gives then a\n",
"simple recipe for fitting our data.\n",
"\n",
"\n",
"Classification problems, however, are concerned with outcomes taking\n",
"the form of discrete variables (i.e. categories). We may for example,\n",
"on the basis of DNA sequencing for a number of patients, like to find\n",
"out which mutations are important for a certain disease; or based on\n",
"scans of various patients' brains, figure out if there is a tumor or\n",
"not; or given a specific physical system, we'd like to identify its\n",
"state, say whether it is an ordered or disordered system (typical\n",
"situation in solid state physics); or classify the status of a\n",
"patient, whether she/he has a stroke or not and many other similar\n",
"situations.\n",
"\n",
"The most common situation we encounter when we apply logistic\n",
"regression is that of two possible outcomes, normally denoted as a\n",
"binary outcome, true or false, positive or negative, success or\n",
"failure etc.\n",
"\n",
"## Optimization and Deep learning\n",
"\n",
"Logistic regression will also serve as our stepping stone towards neural\n",
"network algorithms and supervised deep learning. For logistic\n",
"learning, the minimization of the cost function leads to a non-linear\n",
"equation in the parameters $\\hat{\\beta}$. The optimization of the problem calls therefore for minimization algorithms. This forms the bottle neck of all machine learning algorithms, namely how to find reliable minima of a multi-variable function. This leads us to the family of gradient descent methods. The latter are the working horses of basically all modern machine learning algorithms. \n",
"\n",
"We note also that many of the topics discussed here \n",
"regression are also commonly used in modern supervised Deep Learning\n",
"models, as we will see later.\n",
"\n",
"\n",
"<!-- !split -->\n",
"## Basics\n",
"\n",
"We consider the case where the dependent variables, also called the\n",
"responses or the outcomes, $y_i$ are discrete and only take values\n",
"from $k=0,\\dots,K-1$ (i.e. $K$ classes).\n",
"\n",
"The goal is to predict the\n",
"output classes from the design matrix $\\hat{X}\\in\\mathbb{R}^{n\\times p}$\n",
"made of $n$ samples, each of which carries $p$ features or predictors. The\n",
"primary goal is to identify the classes to which new unseen samples\n",
"belong.\n",
"\n",
"Let us specialize to the case of two classes only, with outputs\n",
"$y_i=0$ and $y_i=1$. Our outcomes could represent the status of a\n",
"credit card user that could default or not on her/his credit card\n",
"debt. That is"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"y_i = \\begin{bmatrix} 0 & \\mathrm{no}\\\\ 1 & \\mathrm{yes} \\end{bmatrix}.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Linear classifier\n",
"\n",
"Before moving to the logistic model, let us try to use our linear regression model to classify these two outcomes. We could for example fit a linear model to the default case if $y_i > 0.5$ and the no default case $y_i \\leq 0.5$. \n",
"\n",
"We would then have our \n",
"weighted linear combination, namely"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- Equation labels as ordinary links -->\n",
"<div id=\"_auto1\"></div>\n",
"\n",
"$$\n",
"\\begin{equation}\n",
"\\hat{y} = \\hat{X}^T\\hat{\\beta} + \\hat{\\epsilon},\n",
"\\label{_auto1} \\tag{1}\n",
"\\end{equation}\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"where $\\hat{y}$ is a vector representing the possible outcomes, $\\hat{X}$ is our\n",
"$n\\times p$ design matrix and $\\hat{\\beta}$ represents our estimators/predictors.\n",
"\n",
"## Some selected properties\n",
"\n",
"The main problem with our function is that it \n",
"takes values on the entire real axis. In the case of\n",
"logistic regression, however, the labels $y_i$ are discrete\n",
"variables. A typical example is the credit card data discussed below here, where we can set the state of defaulting the debt to $y_i=1$ and not to $y_i=0$ for one the persons in the data set (see the full example below).\n",
"\n",
"One simple way to get a discrete output is to have sign\n",
"functions that map the output of a linear regressor to values $\\{0,1\\}$,\n",
"$f(s_i)=sign(s_i)=1$ if $s_i\\ge 0$ and 0 if otherwise. \n",
"We will encounter this model in our first demonstration of neural networks. Historically it is called the \"perceptron\" model in the machine learning\n",
"literature. This model is extremely simple. However, in many cases it is more\n",
"favorable to use a ``soft\" classifier that outputs\n",
"the probability of a given category. This leads us to the logistic function.\n",
"\n",
"\n",
"## The logistic function\n",
"\n",
"The perceptron is an example of a ``hard classification\" model. We\n",
"will encounter this model when we discuss neural networks as\n",
"well. Each datapoint is deterministically assigned to a category (i.e\n",
"$y_i=0$ or $y_i=1$). In many cases, it is favorable to have a \"soft\"\n",
"classifier that outputs the probability of a given category rather\n",
"than a single value. For example, given $x_i$, the classifier\n",
"outputs the probability of being in a category $k$. Logistic regression\n",
"is the most common example of a so-called soft classifier. In logistic\n",
"regression, the probability that a data point $x_i$\n",
"belongs to a category $y_i=\\{0,1\\}$ is given by the so-called logit function (or Sigmoid) which is meant to represent the likelihood for a given event,"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"p(t) = \\frac{1}{1+\\mathrm \\exp{-t}}=\\frac{\\exp{t}}{1+\\mathrm \\exp{t}}.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that $1-p(t)= p(-t)$.\n",
"The following code plots the logistic function, the step function and other functions we will encounter from here and on."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"\n",
"\"\"\"The sigmoid function (or the logistic curve) is a\n",
"function that takes any real number, z, and outputs a number (0,1).\n",
"It is useful in neural networks for assigning weights on a relative scale.\n",
"The value z is the weighted sum of parameters involved in the learning algorithm.\"\"\"\n",
"\n",
"import numpy\n",
"import matplotlib.pyplot as plt\n",
"import math as mt\n",
"\n",
"z = numpy.arange(-5, 5, .1)\n",
"sigma_fn = numpy.vectorize(lambda z: 1/(1+numpy.exp(-z)))\n",
"sigma = sigma_fn(z)\n",
"\n",
"fig = plt.figure()\n",
"ax = fig.add_subplot(111)\n",
"ax.plot(z, sigma)\n",
"ax.set_ylim([-0.1, 1.1])\n",
"ax.set_xlim([-5,5])\n",
"ax.grid(True)\n",
"ax.set_xlabel('z')\n",
"ax.set_title('sigmoid function')\n",
"\n",
"plt.show()\n",
"\n",
"\"\"\"Step Function\"\"\"\n",
"z = numpy.arange(-5, 5, .02)\n",
"step_fn = numpy.vectorize(lambda z: 1.0 if z >= 0.0 else 0.0)\n",
"step = step_fn(z)\n",
"\n",
"fig = plt.figure()\n",
"ax = fig.add_subplot(111)\n",
"ax.plot(z, step)\n",
"ax.set_ylim([-0.5, 1.5])\n",
"ax.set_xlim([-5,5])\n",
"ax.grid(True)\n",
"ax.set_xlabel('z')\n",
"ax.set_title('step function')\n",
"\n",
"plt.show()\n",
"\n",
"\"\"\"tanh Function\"\"\"\n",
"z = numpy.arange(-2*mt.pi, 2*mt.pi, 0.1)\n",
"t = numpy.tanh(z)\n",
"\n",
"fig = plt.figure()\n",
"ax = fig.add_subplot(111)\n",
"ax.plot(z, t)\n",
"ax.set_ylim([-1.0, 1.0])\n",
"ax.set_xlim([-2*mt.pi,2*mt.pi])\n",
"ax.grid(True)\n",
"ax.set_xlabel('z')\n",
"ax.set_title('tanh function')\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Two parameters\n",
"\n",
"We assume now that we have two classes with $y_i$ either $0$ or $1$. Furthermore we assume also that we have only two parameters $\\beta$ in our fitting of the Sigmoid function, that is we define probabilities"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\begin{align*}\n",
"p(y_i=1|x_i,\\hat{\\beta}) &= \\frac{\\exp{(\\beta_0+\\beta_1x_i)}}{1+\\exp{(\\beta_0+\\beta_1x_i)}},\\nonumber\\\\\n",
"p(y_i=0|x_i,\\hat{\\beta}) &= 1 - p(y_i=1|x_i,\\hat{\\beta}),\n",
"\\end{align*}\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"where $\\hat{\\beta}$ are the weights we wish to extract from data, in our case $\\beta_0$ and $\\beta_1$. \n",
"\n",
"Note that we used"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"p(y_i=0\\vert x_i, \\hat{\\beta}) = 1-p(y_i=1\\vert x_i, \\hat{\\beta}).\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<!-- !split -->\n",
"## Maximum likelihood\n",
"\n",
"In order to define the total likelihood for all possible outcomes from a \n",
"dataset $\\mathcal{D}=\\{(y_i,x_i)\\}$, with the binary labels\n",
"$y_i\\in\\{0,1\\}$ and where the data points are drawn independently, we use the so-called [Maximum Likelihood Estimation](https://en.wikipedia.org/wiki/Maximum_likelihood_estimation) (MLE) principle. \n",
"We aim thus at maximizing \n",
"the probability of seeing the observed data. We can then approximate the \n",
"likelihood in terms of the product of the individual probabilities of a specific outcome $y_i$, that is"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\begin{align*}\n",
"P(\\mathcal{D}|\\hat{\\beta})& = \\prod_{i=1}^n \\left[p(y_i=1|x_i,\\hat{\\beta})\\right]^{y_i}\\left[1-p(y_i=1|x_i,\\hat{\\beta}))\\right]^{1-y_i}\\nonumber \\\\\n",
"\\end{align*}\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"from which we obtain the log-likelihood and our **cost/loss** function"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\mathcal{C}(\\hat{\\beta}) = \\sum_{i=1}^n \\left( y_i\\log{p(y_i=1|x_i,\\hat{\\beta})} + (1-y_i)\\log\\left[1-p(y_i=1|x_i,\\hat{\\beta}))\\right]\\right).\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The cost function rewritten\n",
"\n",
"Reordering the logarithms, we can rewrite the **cost/loss** function as"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\mathcal{C}(\\hat{\\beta}) = \\sum_{i=1}^n \\left(y_i(\\beta_0+\\beta_1x_i) -\\log{(1+\\exp{(\\beta_0+\\beta_1x_i)})}\\right).\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The maximum likelihood estimator is defined as the set of parameters that maximize the log-likelihood where we maximize with respect to $\\beta$.\n",
"Since the cost (error) function is just the negative log-likelihood, for logistic regression we have that"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\mathcal{C}(\\hat{\\beta})=-\\sum_{i=1}^n \\left(y_i(\\beta_0+\\beta_1x_i) -\\log{(1+\\exp{(\\beta_0+\\beta_1x_i)})}\\right).\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This equation is known in statistics as the **cross entropy**. Finally, we note that just as in linear regression, \n",
"in practice we often supplement the cross-entropy with additional regularization terms, usually $L_1$ and $L_2$ regularization as we did for Ridge and Lasso regression.\n",
"\n",
"## Minimizing the cross entropy\n",
"\n",
"The cross entropy is a convex function of the weights $\\hat{\\beta}$ and,\n",
"therefore, any local minimizer is a global minimizer. \n",
"\n",
"\n",
"Minimizing this\n",
"cost function with respect to the two parameters $\\beta_0$ and $\\beta_1$ we obtain"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\frac{\\partial \\mathcal{C}(\\hat{\\beta})}{\\partial \\beta_0} = -\\sum_{i=1}^n \\left(y_i -\\frac{\\exp{(\\beta_0+\\beta_1x_i)}}{1+\\exp{(\\beta_0+\\beta_1x_i)}}\\right),\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\frac{\\partial \\mathcal{C}(\\hat{\\beta})}{\\partial \\beta_1} = -\\sum_{i=1}^n \\left(y_ix_i -x_i\\frac{\\exp{(\\beta_0+\\beta_1x_i)}}{1+\\exp{(\\beta_0+\\beta_1x_i)}}\\right).\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## A more compact expression\n",
"\n",
"Let us now define a vector $\\hat{y}$ with $n$ elements $y_i$, an\n",
"$n\\times p$ matrix $\\hat{X}$ which contains the $x_i$ values and a\n",
"vector $\\hat{p}$ of fitted probabilities $p(y_i\\vert x_i,\\hat{\\beta})$. We can rewrite in a more compact form the first\n",
"derivative of cost function as"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\frac{\\partial \\mathcal{C}(\\hat{\\beta})}{\\partial \\hat{\\beta}} = -\\hat{X}^T\\left(\\hat{y}-\\hat{p}\\right).\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we in addition define a diagonal matrix $\\hat{W}$ with elements \n",
"$p(y_i\\vert x_i,\\hat{\\beta})(1-p(y_i\\vert x_i,\\hat{\\beta})$, we can obtain a compact expression of the second derivative as"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\frac{\\partial^2 \\mathcal{C}(\\hat{\\beta})}{\\partial \\hat{\\beta}\\partial \\hat{\\beta}^T} = \\hat{X}^T\\hat{W}\\hat{X}.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Extending to more predictors\n",
"\n",
"Within a binary classification problem, we can easily expand our model to include multiple predictors. Our ratio between likelihoods is then with $p$ predictors"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\log{ \\frac{p(\\hat{\\beta}\\hat{x})}{1-p(\\hat{\\beta}\\hat{x})}} = \\beta_0+\\beta_1x_1+\\beta_2x_2+\\dots+\\beta_px_p.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Here we defined $\\hat{x}=[1,x_1,x_2,\\dots,x_p]$ and $\\hat{\\beta}=[\\beta_0, \\beta_1, \\dots, \\beta_p]$ leading to"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"p(\\hat{\\beta}\\hat{x})=\\frac{ \\exp{(\\beta_0+\\beta_1x_1+\\beta_2x_2+\\dots+\\beta_px_p)}}{1+\\exp{(\\beta_0+\\beta_1x_1+\\beta_2x_2+\\dots+\\beta_px_p)}}.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Including more classes\n",
"\n",
"Till now we have mainly focused on two classes, the so-called binary\n",
"system. Suppose we wish to extend to $K$ classes. Let us for the sake\n",
"of simplicity assume we have only two predictors. We have then\n",
"following model"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1\n",
"5\n",
" \n",
"<\n",
"<\n",
"<\n",
"!\n",
"!\n",
"M\n",
"A\n",
"T\n",
"H\n",
"_\n",
"B\n",
"L\n",
"O\n",
"C\n",
"K"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\log{\\frac{p(C=2\\vert x)}{p(K\\vert x)}} = \\beta_{20}+\\beta_{21}x_1,\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and so on till the class $C=K-1$ class"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"\\log{\\frac{p(C=K-1\\vert x)}{p(K\\vert x)}} = \\beta_{(K-1)0}+\\beta_{(K-1)1}x_1,\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and the model is specified in term of $K-1$ so-called log-odds or\n",
"**logit** transformations.\n",
"\n",
"\n",
"## The Softmax function\n",
"\n",
"In our discussion of neural networks we will encounter the above again\n",
"in terms of the so-called **Softmax** function.\n",
"\n",
"The softmax function is used in various multiclass classification\n",
"methods, such as multinomial logistic regression (also known as\n",
"softmax regression), multiclass linear discriminant analysis, naive\n",
"Bayes classifiers, and artificial neural networks. Specifically, in\n",
"multinomial logistic regression and linear discriminant analysis, the\n",
"input to the function is the result of $K$ distinct linear functions,\n",
"and the predicted probability for the $k$-th class given a sample\n",
"vector $\\hat{x}$ and a weighting vector $\\hat{\\beta}$ is (with two\n",
"predictors):"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"p(C=k\\vert \\mathbf {x} )=\\frac{\\exp{(\\beta_{k0}+\\beta_{k1}x_1)}}{1+\\sum_{l=1}^{K-1}\\exp{(\\beta_{l0}+\\beta_{l1}x_1)}}.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is easy to extend to more predictors. The final class is"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"p(C=K\\vert \\mathbf {x} )=\\frac{1}{1+\\sum_{l=1}^{K-1}\\exp{(\\beta_{l0}+\\beta_{l1}x_1)}},\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and they sum to one. Our earlier discussions were all specialized to\n",
"the case with two classes only. It is easy to see from the above that\n",
"what we derived earlier is compatible with these equations.\n",
"\n",
"To find the optimal parameters we would typically use a gradient\n",
"descent method. Newton's method and gradient descent methods are\n",
"discussed in the material on [optimization\n",
"methods](https://compphysics.github.io/MachineLearning/doc/pub/Splines/html/Splines-bs.html).\n",
"\n",
"\n",
"\n",
"\n",
"## A simple classification problem"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import numpy as np\n",
"from sklearn import datasets, linear_model\n",
"import matplotlib.pyplot as plt\n",
"\n",
"\n",
"def generate_data():\n",
" np.random.seed(0)\n",
" X, y = datasets.make_moons(200, noise=0.20)\n",
" return X, y\n",
"\n",
"\n",
"def visualize(X, y, clf):\n",
" plot_decision_boundary(lambda x: clf.predict(x), X, y)\n",
"\n",
"def plot_decision_boundary(pred_func, X, y):\n",
" # Set min and max values and give it some padding\n",
" x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5\n",
" y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5\n",
" h = 0.01\n",
" # Generate a grid of points with distance h between them\n",
" xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))\n",
" # Predict the function value for the whole gid\n",
" Z = pred_func(np.c_[xx.ravel(), yy.ravel()])\n",
" Z = Z.reshape(xx.shape)\n",
" # Plot the contour and training examples\n",
" plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)\n",
" plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)\n",
" plt.show()\n",
"\n",
"\n",
"def classify(X, y):\n",
" clf = linear_model.LogisticRegressionCV()\n",
" clf.fit(X, y)\n",
" return clf\n",
"\n",
"\n",
"def main():\n",
" X, y = generate_data()\n",
" # visualize(X, y)\n",
" clf = classify(X, y)\n",
" visualize(X, y, clf)\n",
"\n",
"if __name__ == \"__main__\":\n",
" main()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The Credit Card example\n",
"Here we use the the [credit card data](https://archive.ics.uci.edu/ml/datasets/default+of+credit+card+clients). More text to come."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import pandas as pd\n",
"import os\n",
"import numpy as np\n",
"\n",
"\n",
"from sklearn.model_selection import train_test_split\n",
"from sklearn.preprocessing import OneHotEncoder\n",
"from sklearn.compose import ColumnTransformer\n",
"from sklearn.preprocessing import StandardScaler, OneHotEncoder\n",
"from sklearn.metrics import confusion_matrix, accuracy_score, roc_auc_score\n",
"\n",
"# Trying to set the seed\n",
"np.random.seed(0)\n",
"import random\n",
"random.seed(0)\n",
"\n",
"# Reading file into data frame\n",
"cwd = os.getcwd()\n",
"filename = cwd + '/default of credit card clients.xls'\n",
"nanDict = {}\n",
"df = pd.read_excel(filename, header=1, skiprows=0, index_col=0, na_values=nanDict)\n",
"\n",
"df.rename(index=str, columns={\"default payment next month\": \"defaultPaymentNextMonth\"}, inplace=True)\n",
"\n",
"# Features and targets \n",
"X = df.loc[:, df.columns != 'defaultPaymentNextMonth'].values\n",
"y = df.loc[:, df.columns == 'defaultPaymentNextMonth'].values\n",
"\n",
"# Categorical variables to one-hot's\n",
"onehotencoder = OneHotEncoder(categories=\"auto\")\n",
"\n",
"X = ColumnTransformer(\n",
" [(\"\", onehotencoder, [3]),],\n",
" remainder=\"passthrough\"\n",
").fit_transform(X)\n",
"\n",
"y.shape\n",
"\n",
"# Train-test split\n",
"trainingShare = 0.5 \n",
"seed = 1\n",
"XTrain, XTest, yTrain, yTest=train_test_split(X, y, train_size=trainingShare, \\\n",
" test_size = 1-trainingShare,\n",
" random_state=seed)\n",
"\n",
"# Input Scaling\n",
"sc = StandardScaler()\n",
"XTrain = sc.fit_transform(XTrain)\n",
"XTest = sc.transform(XTest)\n",
"\n",
"# One-hot's of the target vector\n",
"Y_train_onehot, Y_test_onehot = onehotencoder.fit_transform(yTrain), onehotencoder.fit_transform(yTest)\n",
"\n",
"# Remove instances with zeros only for past bill statements or paid amounts\n",
"'''\n",
"df = df.drop(df[(df.BILL_AMT1 == 0) &\n",
" (df.BILL_AMT2 == 0) &\n",
" (df.BILL_AMT3 == 0) &\n",
" (df.BILL_AMT4 == 0) &\n",
" (df.BILL_AMT5 == 0) &\n",
" (df.BILL_AMT6 == 0) &\n",
" (df.PAY_AMT1 == 0) &\n",
" (df.PAY_AMT2 == 0) &\n",
" (df.PAY_AMT3 == 0) &\n",
" (df.PAY_AMT4 == 0) &\n",
" (df.PAY_AMT5 == 0) &\n",
" (df.PAY_AMT6 == 0)].index)\n",
"'''\n",
"df = df.drop(df[(df.BILL_AMT1 == 0) &\n",
" (df.BILL_AMT2 == 0) &\n",
" (df.BILL_AMT3 == 0) &\n",
" (df.BILL_AMT4 == 0) &\n",
" (df.BILL_AMT5 == 0) &\n",
" (df.BILL_AMT6 == 0)].index)\n",
"\n",
"df = df.drop(df[(df.PAY_AMT1 == 0) &\n",
" (df.PAY_AMT2 == 0) &\n",
" (df.PAY_AMT3 == 0) &\n",
" (df.PAY_AMT4 == 0) &\n",
" (df.PAY_AMT5 == 0) &\n",
" (df.PAY_AMT6 == 0)].index)\n",
"\n",
"from sklearn.linear_model import LogisticRegression\n",
"from sklearn.model_selection import GridSearchCV\n",
"\n",
"lambdas=np.logspace(-5,7,13)\n",
"parameters = [{'C': 1./lambdas, \"solver\":[\"lbfgs\"]}]#*len(parameters)}]\n",
"scoring = ['accuracy', 'roc_auc']\n",
"logReg = LogisticRegression()\n",
"gridSearch = GridSearchCV(logReg, parameters, cv=5, scoring=scoring, refit='roc_auc')"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"\n",
"# \"refit\" gives the metric used deciding best model. \n",
"# See more http://scikit-learn.org/stable/auto_examples/model_selection/plot_multi_metric_evaluation.html\n",
"gridSearch.fit(XTrain, yTrain.ravel())\n",
"\n",
"def gridSearchSummary(method, scoring):\n",
" \"\"\"Prints best parameters from Grid search\n",
" and AUC with standard deviation for all \n",
" parameter combos \"\"\"\n",
" \n",
" method = eval(method)\n",
" if scoring == 'accuracy':\n",
" mean = 'mean_test_score'\n",
" sd = 'std_test_score'\n",
" elif scoring == 'auc':\n",
" mean = 'mean_test_roc_auc'\n",
" sd = 'std_test_roc_auc'\n",
" print(\"Best: %f using %s\" % (method.best_score_, method.best_params_))\n",
" means = method.cv_results_[mean]\n",
" stds = method.cv_results_[sd]\n",
" params = method.cv_results_['params']\n",
" for mean, stdev, param in zip(means, stds, params):\n",
" print(\"%f (%f) with: %r\" % (mean, stdev, param))\n",
"\n",
"def createConfusionMatrix(method, printOut=True):\n",
" \"\"\"\n",
" Computes and prints confusion matrices, accuracy scores,\n",
" and AUC for test and training sets \n",
" \"\"\"\n",
" confusionArray = np.zeros(6, dtype=object)\n",
" method = eval(method)\n",
" \n",
" # Train\n",
" yPredTrain = method.predict(XTrain)\n",
" yPredTrain = (yPredTrain > 0.5)\n",
" cm = confusion_matrix(\n",
" yTrain, yPredTrain) \n",
" cm = np.around(cm/cm.sum(axis=1)[:,None], 2)\n",
" confusionArray[0] = cm\n",
" \n",
" accScore = accuracy_score(yTrain, yPredTrain)\n",
" confusionArray[1] = accScore\n",
" \n",
" AUC = roc_auc_score(yTrain, yPredTrain)\n",
" confusionArray[2] = AUC\n",
" \n",
" if printOut:\n",
" print('\\n################### Training ###############')\n",
" print('\\nTraining Confusion matrix: \\n', cm)\n",
" print('\\nTraining Accuracy score: \\n', accScore)\n",
" print('\\nTrain AUC: \\n', AUC)\n",
" \n",
" # Test\n",
" yPred = method.predict(XTest)\n",
" yPred = (yPred > 0.5)\n",
" cm = confusion_matrix(\n",
" yTest, yPred) \n",
" cm = np.around(cm/cm.sum(axis=1)[:,None], 2)\n",
" confusionArray[3] = cm\n",
" \n",
" accScore = accuracy_score(yTest, yPred)\n",
" confusionArray[4] = accScore\n",
" \n",
" AUC = roc_auc_score(yTest, yPred)\n",
" confusionArray[5] = AUC\n",
" \n",
" if printOut:\n",
" print('\\n################### Testing ###############')\n",
" print('\\nTest Confusion matrix: \\n', cm)\n",
" print('\\nTest Accuracy score: \\n', accScore)\n",
" print('\\nTestAUC: \\n', AUC) \n",
" \n",
" return confusionArray\n",
"\n",
"\n",
"import matplotlib.pyplot as plt\n",
"import seaborn\n",
"import scikitplot as skplt\n",
"\n",
"seaborn.set(style=\"white\", context=\"notebook\", font_scale=1.5, \n",
" rc={\"axes.grid\": True, \"legend.frameon\": False,\n",
"\"lines.markeredgewidth\": 1.4, \"lines.markersize\": 10})\n",
"seaborn.set_context(\"notebook\", font_scale=1.5, rc={\"lines.linewidth\": 4.5})\n",
"\n",
"yPred = gridSearch.predict_proba(XTest) \n",
"print(yTest.ravel().shape, yPred.shape)\n",
"\n",
"#skplt.metrics.plot_cumulative_gain(yTest.ravel(), yPred_onehot)\n",
"skplt.metrics.plot_cumulative_gain(yTest.ravel(), yPred)\n",
"\n",
"defaults = sum(yTest == 1)\n",
"total = len(yTest)\n",
"defaultRate = defaults/total\n",
"def bestCurve(defaults, total, defaultRate):\n",
" x = np.linspace(0, 1, total)\n",
" \n",
" y1 = np.linspace(0, 1, defaults)\n",
" y2 = np.ones(total-defaults)\n",
" y3 = np.concatenate([y1,y2])\n",
" return x, y3\n",
"\n",
"x, best = bestCurve(defaults=defaults, total=total, defaultRate=defaultRate) \n",
"plt.plot(x, best) \n",
"\n",
"\n",
"plt.show()"
]
}
],
"metadata": {},
"nbformat": 4,
"nbformat_minor": 2
}
-768
View File
@@ -1,768 +0,0 @@
%%
%% Automatically generated file from DocOnce source
%% (https://github.com/hplgit/doconce/)
%%
%%
% #ifdef PTEX2TEX_EXPLANATION
%%
%% The file follows the ptex2tex extended LaTeX format, see
%% ptex2tex: http://code.google.com/p/ptex2tex/
%%
%% Run
%% ptex2tex myfile
%% or
%% doconce ptex2tex myfile
%%
%% to turn myfile.p.tex into an ordinary LaTeX file myfile.tex.
%% (The ptex2tex program: http://code.google.com/p/ptex2tex)
%% Many preprocess options can be added to ptex2tex or doconce ptex2tex
%%
%% ptex2tex -DMINTED myfile
%% doconce ptex2tex myfile envir=minted
%%
%% ptex2tex will typeset code environments according to a global or local
%% .ptex2tex.cfg configure file. doconce ptex2tex will typeset code
%% according to options on the command line (just type doconce ptex2tex to
%% see examples). If doconce ptex2tex has envir=minted, it enables the
%% minted style without needing -DMINTED.
% #endif
% #define PREAMBLE
% #ifdef PREAMBLE
%-------------------- begin preamble ----------------------
\documentclass[%
oneside, % oneside: electronic viewing, twoside: printing
final, % draft: marks overfull hboxes, figures with paths
10pt]{article}
\listfiles % print all files needed to compile this document
\usepackage{relsize,makeidx,color,setspace,amsmath,amsfonts,amssymb}
\usepackage[table]{xcolor}
\usepackage{bm,ltablex,microtype}
\usepackage[pdftex]{graphicx}
\usepackage{ptex2tex}
% #ifdef MINTED
\usepackage{minted}
\usemintedstyle{default}
% #endif
\usepackage[T1]{fontenc}
%\usepackage[latin1]{inputenc}
\usepackage{ucs}
\usepackage[utf8x]{inputenc}
\usepackage{lmodern} % Latin Modern fonts derived from Computer Modern
% Hyperlinks in PDF:
\definecolor{linkcolor}{rgb}{0,0,0.4}
\usepackage{hyperref}
\hypersetup{
breaklinks=true,
colorlinks=true,
linkcolor=linkcolor,
urlcolor=linkcolor,
citecolor=black,
filecolor=black,
%filecolor=blue,
pdfmenubar=true,
pdftoolbar=true,
bookmarksdepth=3 % Uncomment (and tweak) for PDF bookmarks with more levels than the TOC
}
%\hyperbaseurl{} % hyperlinks are relative to this root
\setcounter{tocdepth}{2} % levels in table of contents
% --- fancyhdr package for fancy headers ---
\usepackage{fancyhdr}
\fancyhf{} % sets both header and footer to nothing
\renewcommand{\headrulewidth}{0pt}
\fancyfoot[LE,RO]{\thepage}
% Ensure copyright on titlepage (article style) and chapter pages (book style)
\fancypagestyle{plain}{
\fancyhf{}
\fancyfoot[C]{{\footnotesize \copyright\ 1999-2019, Morten Hjorth-Jensen. Released under CC Attribution-NonCommercial 4.0 license}}
% \renewcommand{\footrulewidth}{0mm}
\renewcommand{\headrulewidth}{0mm}
}
% Ensure copyright on titlepages with \thispagestyle{empty}
\fancypagestyle{empty}{
\fancyhf{}
\fancyfoot[C]{{\footnotesize \copyright\ 1999-2019, Morten Hjorth-Jensen. Released under CC Attribution-NonCommercial 4.0 license}}
\renewcommand{\footrulewidth}{0mm}
\renewcommand{\headrulewidth}{0mm}
}
\pagestyle{fancy}
% prevent orhpans and widows
\clubpenalty = 10000
\widowpenalty = 10000
% --- end of standard preamble for documents ---
% insert custom LaTeX commands...
\raggedbottom
\makeindex
\usepackage[totoc]{idxlayout} % for index in the toc
\usepackage[nottoc]{tocbibind} % for references/bibliography in the toc
%-------------------- end preamble ----------------------
\begin{document}
% matching end for #ifdef PREAMBLE
% #endif
\newcommand{\exercisesection}[1]{\subsection*{#1}}
% ------------------- main content ----------------------
% ----------------- title -------------------------
\thispagestyle{empty}
\begin{center}
{\LARGE\bf
\begin{spacing}{1.25}
Data Analysis and Machine Learning: Logistic Regression
\end{spacing}
}
\end{center}
% ----------------- author(s) -------------------------
\begin{center}
{\bf Morten Hjorth-Jensen${}^{1, 2}$} \\ [0mm]
\end{center}
\begin{center}
% List of all institutions:
\centerline{{\small ${}^1$Department of Physics, University of Oslo}}
\centerline{{\small ${}^2$Department of Physics and Astronomy and National Superconducting Cyclotron Laboratory, Michigan State University}}
\end{center}
% ----------------- end author(s) -------------------------
% --- begin date ---
\begin{center}
Sep 19, 2019
\end{center}
% --- end date ---
\vspace{1cm}
% !split
\subsection{Logistic Regression}
In linear regression our main interest was centered on learning the
coefficients of a functional fit (say a polynomial) in order to be
able to predict the response of a continuous variable on some unseen
data. The fit to the continuous variable $y_i$ is based on some
independent variables $\hat{x}_i$. Linear regression resulted in
analytical expressions for standard ordinary Least Squares or Ridge
regression (in terms of matrices to invert) for several quantities,
ranging from the variance and thereby the confidence intervals of the
parameters $\hat{\beta}$ to the mean squared error. If we can invert
the product of the design matrices, linear regression gives then a
simple recipe for fitting our data.
Classification problems, however, are concerned with outcomes taking
the form of discrete variables (i.e.~categories). We may for example,
on the basis of DNA sequencing for a number of patients, like to find
out which mutations are important for a certain disease; or based on
scans of various patients' brains, figure out if there is a tumor or
not; or given a specific physical system, we'd like to identify its
state, say whether it is an ordered or disordered system (typical
situation in solid state physics); or classify the status of a
patient, whether she/he has a stroke or not and many other similar
situations.
The most common situation we encounter when we apply logistic
regression is that of two possible outcomes, normally denoted as a
binary outcome, true or false, positive or negative, success or
failure etc.
% !split
\subsection{Optimization and Deep learning}
Logistic regression will also serve as our stepping stone towards neural
network algorithms and supervised deep learning. For logistic
learning, the minimization of the cost function leads to a non-linear
equation in the parameters $\hat{\beta}$. The optimization of the problem calls therefore for minimization algorithms. This forms the bottle neck of all machine learning algorithms, namely how to find reliable minima of a multi-variable function. This leads us to the family of gradient descent methods. The latter are the working horses of basically all modern machine learning algorithms.
We note also that many of the topics discussed here
regression are also commonly used in modern supervised Deep Learning
models, as we will see later.
% !split
\subsection{Basics}
We consider the case where the dependent variables, also called the
responses or the outcomes, $y_i$ are discrete and only take values
from $k=0,\dots,K-1$ (i.e.~$K$ classes).
The goal is to predict the
output classes from the design matrix $\hat{X}\in\mathbb{R}^{n\times p}$
made of $n$ samples, each of which carries $p$ features or predictors. The
primary goal is to identify the classes to which new unseen samples
belong.
Let us specialize to the case of two classes only, with outputs
$y_i=0$ and $y_i=1$. Our outcomes could represent the status of a
credit card user that could default or not on her/his credit card
debt. That is
\[
y_i = \begin{bmatrix} 0 & \mathrm{no}\\ 1 & \mathrm{yes} \end{bmatrix}.
\]
% !split
\subsection{Linear classifier}
Before moving to the logistic model, let us try to use our linear regression model to classify these two outcomes. We could for example fit a linear model to the default case if $y_i > 0.5$ and the no default case $y_i \leq 0.5$.
We would then have our
weighted linear combination, namely
\begin{equation}
\hat{y} = \hat{X}^T\hat{\beta} + \hat{\epsilon},
\end{equation}
where $\hat{y}$ is a vector representing the possible outcomes, $\hat{X}$ is our
$n\times p$ design matrix and $\hat{\beta}$ represents our estimators/predictors.
% !split
\subsection{Some selected properties}
The main problem with our function is that it
takes values on the entire real axis. In the case of
logistic regression, however, the labels $y_i$ are discrete
variables. A typical example is the credit card data discussed below here, where we can set the state of defaulting the debt to $y_i=1$ and not to $y_i=0$ for one the persons in the data set (see the full example below).
One simple way to get a discrete output is to have sign
functions that map the output of a linear regressor to values $\{0,1\}$,
$f(s_i)=sign(s_i)=1$ if $s_i\ge 0$ and 0 if otherwise.
We will encounter this model in our first demonstration of neural networks. Historically it is called the ``perceptron" model in the machine learning
literature. This model is extremely simple. However, in many cases it is more
favorable to use a ``soft" classifier that outputs
the probability of a given category. This leads us to the logistic function.
% !split
\subsection{The logistic function}
The perceptron is an example of a ``hard classification'' model. We
will encounter this model when we discuss neural networks as
well. Each datapoint is deterministically assigned to a category (i.e
$y_i=0$ or $y_i=1$). In many cases, it is favorable to have a ``soft''
classifier that outputs the probability of a given category rather
than a single value. For example, given $x_i$, the classifier
outputs the probability of being in a category $k$. Logistic regression
is the most common example of a so-called soft classifier. In logistic
regression, the probability that a data point $x_i$
belongs to a category $y_i=\{0,1\}$ is given by the so-called logit function (or Sigmoid) which is meant to represent the likelihood for a given event,
\[
p(t) = \frac{1}{1+\mathrm \exp{-t}}=\frac{\exp{t}}{1+\mathrm \exp{t}}.
\]
Note that $1-p(t)= p(-t)$.
The following code plots the logistic function, the step function and other functions we will encounter from here and on.
\bpycod
"""The sigmoid function (or the logistic curve) is a
function that takes any real number, z, and outputs a number (0,1).
It is useful in neural networks for assigning weights on a relative scale.
The value z is the weighted sum of parameters involved in the learning algorithm."""
import numpy
import matplotlib.pyplot as plt
import math as mt
z = numpy.arange(-5, 5, .1)
sigma_fn = numpy.vectorize(lambda z: 1/(1+numpy.exp(-z)))
sigma = sigma_fn(z)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(z, sigma)
ax.set_ylim([-0.1, 1.1])
ax.set_xlim([-5,5])
ax.grid(True)
ax.set_xlabel('z')
ax.set_title('sigmoid function')
plt.show()
"""Step Function"""
z = numpy.arange(-5, 5, .02)
step_fn = numpy.vectorize(lambda z: 1.0 if z >= 0.0 else 0.0)
step = step_fn(z)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(z, step)
ax.set_ylim([-0.5, 1.5])
ax.set_xlim([-5,5])
ax.grid(True)
ax.set_xlabel('z')
ax.set_title('step function')
plt.show()
"""tanh Function"""
z = numpy.arange(-2*mt.pi, 2*mt.pi, 0.1)
t = numpy.tanh(z)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(z, t)
ax.set_ylim([-1.0, 1.0])
ax.set_xlim([-2*mt.pi,2*mt.pi])
ax.grid(True)
ax.set_xlabel('z')
ax.set_title('tanh function')
plt.show()
\epycod
% !split
\subsection{Two parameters}
We assume now that we have two classes with $y_i$ either $0$ or $1$. Furthermore we assume also that we have only two parameters $\beta$ in our fitting of the Sigmoid function, that is we define probabilities
\begin{align*}
p(y_i=1|x_i,\hat{\beta}) &= \frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}},\nonumber\\
p(y_i=0|x_i,\hat{\beta}) &= 1 - p(y_i=1|x_i,\hat{\beta}),
\end{align*}
where $\hat{\beta}$ are the weights we wish to extract from data, in our case $\beta_0$ and $\beta_1$.
Note that we used
\[
p(y_i=0\vert x_i, \hat{\beta}) = 1-p(y_i=1\vert x_i, \hat{\beta}).
\]
% !split
\subsection{Maximum likelihood}
In order to define the total likelihood for all possible outcomes from a
dataset $\mathcal{D}=\{(y_i,x_i)\}$, with the binary labels
$y_i\in\{0,1\}$ and where the data points are drawn independently, we use the so-called \href{{https://en.wikipedia.org/wiki/Maximum_likelihood_estimation}}{Maximum Likelihood Estimation} (MLE) principle.
We aim thus at maximizing
the probability of seeing the observed data. We can then approximate the
likelihood in terms of the product of the individual probabilities of a specific outcome $y_i$, that is
\begin{align*}
P(\mathcal{D}|\hat{\beta})& = \prod_{i=1}^n \left[p(y_i=1|x_i,\hat{\beta})\right]^{y_i}\left[1-p(y_i=1|x_i,\hat{\beta}))\right]^{1-y_i}\nonumber \\
\end{align*}
from which we obtain the log-likelihood and our \textbf{cost/loss} function
\[
\mathcal{C}(\hat{\beta}) = \sum_{i=1}^n \left( y_i\log{p(y_i=1|x_i,\hat{\beta})} + (1-y_i)\log\left[1-p(y_i=1|x_i,\hat{\beta}))\right]\right).
\]
% !split
\subsection{The cost function rewritten}
Reordering the logarithms, we can rewrite the \textbf{cost/loss} function as
\[
\mathcal{C}(\hat{\beta}) = \sum_{i=1}^n \left(y_i(\beta_0+\beta_1x_i) -\log{(1+\exp{(\beta_0+\beta_1x_i)})}\right).
\]
The maximum likelihood estimator is defined as the set of parameters that maximize the log-likelihood where we maximize with respect to $\beta$.
Since the cost (error) function is just the negative log-likelihood, for logistic regression we have that
\[
\mathcal{C}(\hat{\beta})=-\sum_{i=1}^n \left(y_i(\beta_0+\beta_1x_i) -\log{(1+\exp{(\beta_0+\beta_1x_i)})}\right).
\]
This equation is known in statistics as the \textbf{cross entropy}. Finally, we note that just as in linear regression,
in practice we often supplement the cross-entropy with additional regularization terms, usually $L_1$ and $L_2$ regularization as we did for Ridge and Lasso regression.
% !split
\subsection{Minimizing the cross entropy}
The cross entropy is a convex function of the weights $\hat{\beta}$ and,
therefore, any local minimizer is a global minimizer.
Minimizing this
cost function with respect to the two parameters $\beta_0$ and $\beta_1$ we obtain
\[
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \beta_0} = -\sum_{i=1}^n \left(y_i -\frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}}\right),
\]
and
\[
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \beta_1} = -\sum_{i=1}^n \left(y_ix_i -x_i\frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}}\right).
\]
% !split
\subsection{A more compact expression}
Let us now define a vector $\hat{y}$ with $n$ elements $y_i$, an
$n\times p$ matrix $\hat{X}$ which contains the $x_i$ values and a
vector $\hat{p}$ of fitted probabilities $p(y_i\vert x_i,\hat{\beta})$. We can rewrite in a more compact form the first
derivative of cost function as
\[
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \hat{\beta}} = -\hat{X}^T\left(\hat{y}-\hat{p}\right).
\]
If we in addition define a diagonal matrix $\hat{W}$ with elements
$p(y_i\vert x_i,\hat{\beta})(1-p(y_i\vert x_i,\hat{\beta})$, we can obtain a compact expression of the second derivative as
\[
\frac{\partial^2 \mathcal{C}(\hat{\beta})}{\partial \hat{\beta}\partial \hat{\beta}^T} = \hat{X}^T\hat{W}\hat{X}.
\]
% !split
\subsection{Extending to more predictors}
Within a binary classification problem, we can easily expand our model to include multiple predictors. Our ratio between likelihoods is then with $p$ predictors
\[
\log{ \frac{p(\hat{\beta}\hat{x})}{1-p(\hat{\beta}\hat{x})}} = \beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p.
\]
Here we defined $\hat{x}=[1,x_1,x_2,\dots,x_p]$ and $\hat{\beta}=[\beta_0, \beta_1, \dots, \beta_p]$ leading to
\[
p(\hat{\beta}\hat{x})=\frac{ \exp{(\beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p)}}{1+\exp{(\beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p)}}.
\]
% !split
\subsection{Including more classes}
Till now we have mainly focused on two classes, the so-called binary
system. Suppose we wish to extend to $K$ classes. Let us for the sake
of simplicity assume we have only two predictors. We have then
following model
\[
\log{\frac{p(C=1\vert x)}{p(K\vert x)}} = \beta_{10}+\beta_{11}x_1,
\]
\[
\log{\frac{p(C=2\vert x)}{p(K\vert x)}} = \beta_{20}+\beta_{21}x_1,
\]
and so on till the class $C=K-1$ class
\[
\log{\frac{p(C=K-1\vert x)}{p(K\vert x)}} = \beta_{(K-1)0}+\beta_{(K-1)1}x_1,
\]
and the model is specified in term of $K-1$ so-called log-odds or
\textbf{logit} transformations.
% !split
\subsection{The Softmax function}
In our discussion of neural networks we will encounter the above again
in terms of the so-called \textbf{Softmax} function.
The softmax function is used in various multiclass classification
methods, such as multinomial logistic regression (also known as
softmax regression), multiclass linear discriminant analysis, naive
Bayes classifiers, and artificial neural networks. Specifically, in
multinomial logistic regression and linear discriminant analysis, the
input to the function is the result of $K$ distinct linear functions,
and the predicted probability for the $k$-th class given a sample
vector $\hat{x}$ and a weighting vector $\hat{\beta}$ is (with two
predictors):
\[
p(C=k\vert \mathbf {x} )=\frac{\exp{(\beta_{k0}+\beta_{k1}x_1)}}{1+\sum_{l=1}^{K-1}\exp{(\beta_{l0}+\beta_{l1}x_1)}}.
\]
It is easy to extend to more predictors. The final class is
\[
p(C=K\vert \mathbf {x} )=\frac{1}{1+\sum_{l=1}^{K-1}\exp{(\beta_{l0}+\beta_{l1}x_1)}},
\]
and they sum to one. Our earlier discussions were all specialized to
the case with two classes only. It is easy to see from the above that
what we derived earlier is compatible with these equations.
To find the optimal parameters we would typically use a gradient
descent method. Newton's method and gradient descent methods are
discussed in the material on \href{{https://compphysics.github.io/MachineLearning/doc/pub/Splines/html/Splines-bs.html}}{optimization
methods}.
% !split
\subsection{A simple classification problem}
\bpycod
import numpy as np
from sklearn import datasets, linear_model
import matplotlib.pyplot as plt
def generate_data():
np.random.seed(0)
X, y = datasets.make_moons(200, noise=0.20)
return X, y
def visualize(X, y, clf):
plot_decision_boundary(lambda x: clf.predict(x), X, y)
def plot_decision_boundary(pred_func, X, y):
# Set min and max values and give it some padding
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
h = 0.01
# Generate a grid of points with distance h between them
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
# Predict the function value for the whole gid
Z = pred_func(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# Plot the contour and training examples
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)
plt.show()
def classify(X, y):
clf = linear_model.LogisticRegressionCV()
clf.fit(X, y)
return clf
def main():
X, y = generate_data()
# visualize(X, y)
clf = classify(X, y)
visualize(X, y, clf)
if __name__ == "__main__":
main()
\epycod
% !split
\subsection{The Credit Card example}
Here we use the the \href{{https://archive.ics.uci.edu/ml/datasets/default+of+credit+card+clients}}{credit card data}. More text to come.
\bpycod
import pandas as pd
import os
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.metrics import confusion_matrix, accuracy_score, roc_auc_score
# Trying to set the seed
np.random.seed(0)
import random
random.seed(0)
# Reading file into data frame
cwd = os.getcwd()
filename = cwd + '/default of credit card clients.xls'
nanDict = {}
df = pd.read_excel(filename, header=1, skiprows=0, index_col=0, na_values=nanDict)
df.rename(index=str, columns={"default payment next month": "defaultPaymentNextMonth"}, inplace=True)
# Features and targets
X = df.loc[:, df.columns != 'defaultPaymentNextMonth'].values
y = df.loc[:, df.columns == 'defaultPaymentNextMonth'].values
# Categorical variables to one-hot's
onehotencoder = OneHotEncoder(categories="auto")
X = ColumnTransformer(
[("", onehotencoder, [3]),],
remainder="passthrough"
).fit_transform(X)
y.shape
# Train-test split
trainingShare = 0.5
seed = 1
XTrain, XTest, yTrain, yTest=train_test_split(X, y, train_size=trainingShare, \
test_size = 1-trainingShare,
random_state=seed)
# Input Scaling
sc = StandardScaler()
XTrain = sc.fit_transform(XTrain)
XTest = sc.transform(XTest)
# One-hot's of the target vector
Y_train_onehot, Y_test_onehot = onehotencoder.fit_transform(yTrain), onehotencoder.fit_transform(yTest)
# Remove instances with zeros only for past bill statements or paid amounts
'''
df = df.drop(df[(df.BILL_AMT1 == 0) &
(df.BILL_AMT2 == 0) &
(df.BILL_AMT3 == 0) &
(df.BILL_AMT4 == 0) &
(df.BILL_AMT5 == 0) &
(df.BILL_AMT6 == 0) &
(df.PAY_AMT1 == 0) &
(df.PAY_AMT2 == 0) &
(df.PAY_AMT3 == 0) &
(df.PAY_AMT4 == 0) &
(df.PAY_AMT5 == 0) &
(df.PAY_AMT6 == 0)].index)
'''
df = df.drop(df[(df.BILL_AMT1 == 0) &
(df.BILL_AMT2 == 0) &
(df.BILL_AMT3 == 0) &
(df.BILL_AMT4 == 0) &
(df.BILL_AMT5 == 0) &
(df.BILL_AMT6 == 0)].index)
df = df.drop(df[(df.PAY_AMT1 == 0) &
(df.PAY_AMT2 == 0) &
(df.PAY_AMT3 == 0) &
(df.PAY_AMT4 == 0) &
(df.PAY_AMT5 == 0) &
(df.PAY_AMT6 == 0)].index)
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
lambdas=np.logspace(-5,7,13)
parameters = [{'C': 1./lambdas, "solver":["lbfgs"]}]#*len(parameters)}]
scoring = ['accuracy', 'roc_auc']
logReg = LogisticRegression()
gridSearch = GridSearchCV(logReg, parameters, cv=5, scoring=scoring, refit='roc_auc')
\epycod
\bpycod
# "refit" gives the metric used deciding best model.
# See more http://scikit-learn.org/stable/auto_examples/model_selection/plot_multi_metric_evaluation.html
gridSearch.fit(XTrain, yTrain.ravel())
def gridSearchSummary(method, scoring):
"""Prints best parameters from Grid search
and AUC with standard deviation for all
parameter combos """
method = eval(method)
if scoring == 'accuracy':
mean = 'mean_test_score'
sd = 'std_test_score'
elif scoring == 'auc':
mean = 'mean_test_roc_auc'
sd = 'std_test_roc_auc'
print("Best: %f using %s" % (method.best_score_, method.best_params_))
means = method.cv_results_[mean]
stds = method.cv_results_[sd]
params = method.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
print("%f (%f) with: %r" % (mean, stdev, param))
def createConfusionMatrix(method, printOut=True):
"""
Computes and prints confusion matrices, accuracy scores,
and AUC for test and training sets
"""
confusionArray = np.zeros(6, dtype=object)
method = eval(method)
# Train
yPredTrain = method.predict(XTrain)
yPredTrain = (yPredTrain > 0.5)
cm = confusion_matrix(
yTrain, yPredTrain)
cm = np.around(cm/cm.sum(axis=1)[:,None], 2)
confusionArray[0] = cm
accScore = accuracy_score(yTrain, yPredTrain)
confusionArray[1] = accScore
AUC = roc_auc_score(yTrain, yPredTrain)
confusionArray[2] = AUC
if printOut:
print('\n################### Training ###############')
print('\nTraining Confusion matrix: \n', cm)
print('\nTraining Accuracy score: \n', accScore)
print('\nTrain AUC: \n', AUC)
# Test
yPred = method.predict(XTest)
yPred = (yPred > 0.5)
cm = confusion_matrix(
yTest, yPred)
cm = np.around(cm/cm.sum(axis=1)[:,None], 2)
confusionArray[3] = cm
accScore = accuracy_score(yTest, yPred)
confusionArray[4] = accScore
AUC = roc_auc_score(yTest, yPred)
confusionArray[5] = AUC
if printOut:
print('\n################### Testing ###############')
print('\nTest Confusion matrix: \n', cm)
print('\nTest Accuracy score: \n', accScore)
print('\nTestAUC: \n', AUC)
return confusionArray
import matplotlib.pyplot as plt
import seaborn
import scikitplot as skplt
seaborn.set(style="white", context="notebook", font_scale=1.5,
rc={"axes.grid": True, "legend.frameon": False,
"lines.markeredgewidth": 1.4, "lines.markersize": 10})
seaborn.set_context("notebook", font_scale=1.5, rc={"lines.linewidth": 4.5})
yPred = gridSearch.predict_proba(XTest)
print(yTest.ravel().shape, yPred.shape)
#skplt.metrics.plot_cumulative_gain(yTest.ravel(), yPred_onehot)
skplt.metrics.plot_cumulative_gain(yTest.ravel(), yPred)
defaults = sum(yTest == 1)
total = len(yTest)
defaultRate = defaults/total
def bestCurve(defaults, total, defaultRate):
x = np.linspace(0, 1, total)
y1 = np.linspace(0, 1, defaults)
y2 = np.ones(total-defaults)
y3 = np.concatenate([y1,y2])
return x, y3
x, best = bestCurve(defaults=defaults, total=total, defaultRate=defaultRate)
plt.plot(x, best)
plt.show()
\epycod
% ------------------- end of main content ---------------
% #ifdef PREAMBLE
\end{document}
% #endif
-738
View File
@@ -1,738 +0,0 @@
%%
%% Automatically generated file from DocOnce source
%% (https://github.com/hplgit/doconce/)
%%
%%
%-------------------- begin preamble ----------------------
\documentclass[%
oneside, % oneside: electronic viewing, twoside: printing
final, % draft: marks overfull hboxes, figures with paths
10pt]{article}
\listfiles % print all files needed to compile this document
\usepackage{relsize,makeidx,color,setspace,amsmath,amsfonts,amssymb}
\usepackage[table]{xcolor}
\usepackage{bm,ltablex,microtype}
\usepackage[pdftex]{graphicx}
\usepackage{fancyvrb} % packages needed for verbatim environments
\usepackage{minted}
\usemintedstyle{default}
\usepackage[T1]{fontenc}
%\usepackage[latin1]{inputenc}
\usepackage{ucs}
\usepackage[utf8x]{inputenc}
\usepackage{lmodern} % Latin Modern fonts derived from Computer Modern
% Hyperlinks in PDF:
\definecolor{linkcolor}{rgb}{0,0,0.4}
\usepackage{hyperref}
\hypersetup{
breaklinks=true,
colorlinks=true,
linkcolor=linkcolor,
urlcolor=linkcolor,
citecolor=black,
filecolor=black,
%filecolor=blue,
pdfmenubar=true,
pdftoolbar=true,
bookmarksdepth=3 % Uncomment (and tweak) for PDF bookmarks with more levels than the TOC
}
%\hyperbaseurl{} % hyperlinks are relative to this root
\setcounter{tocdepth}{2} % levels in table of contents
% --- fancyhdr package for fancy headers ---
\usepackage{fancyhdr}
\fancyhf{} % sets both header and footer to nothing
\renewcommand{\headrulewidth}{0pt}
\fancyfoot[LE,RO]{\thepage}
% Ensure copyright on titlepage (article style) and chapter pages (book style)
\fancypagestyle{plain}{
\fancyhf{}
\fancyfoot[C]{{\footnotesize \copyright\ 1999-2019, Morten Hjorth-Jensen. Released under CC Attribution-NonCommercial 4.0 license}}
% \renewcommand{\footrulewidth}{0mm}
\renewcommand{\headrulewidth}{0mm}
}
% Ensure copyright on titlepages with \thispagestyle{empty}
\fancypagestyle{empty}{
\fancyhf{}
\fancyfoot[C]{{\footnotesize \copyright\ 1999-2019, Morten Hjorth-Jensen. Released under CC Attribution-NonCommercial 4.0 license}}
\renewcommand{\footrulewidth}{0mm}
\renewcommand{\headrulewidth}{0mm}
}
\pagestyle{fancy}
% prevent orhpans and widows
\clubpenalty = 10000
\widowpenalty = 10000
% --- end of standard preamble for documents ---
% insert custom LaTeX commands...
\raggedbottom
\makeindex
\usepackage[totoc]{idxlayout} % for index in the toc
\usepackage[nottoc]{tocbibind} % for references/bibliography in the toc
%-------------------- end preamble ----------------------
\begin{document}
% matching end for #ifdef PREAMBLE
\newcommand{\exercisesection}[1]{\subsection*{#1}}
% ------------------- main content ----------------------
% ----------------- title -------------------------
\thispagestyle{empty}
\begin{center}
{\LARGE\bf
\begin{spacing}{1.25}
Data Analysis and Machine Learning: Logistic Regression
\end{spacing}
}
\end{center}
% ----------------- author(s) -------------------------
\begin{center}
{\bf Morten Hjorth-Jensen${}^{1, 2}$} \\ [0mm]
\end{center}
\begin{center}
% List of all institutions:
\centerline{{\small ${}^1$Department of Physics, University of Oslo}}
\centerline{{\small ${}^2$Department of Physics and Astronomy and National Superconducting Cyclotron Laboratory, Michigan State University}}
\end{center}
% ----------------- end author(s) -------------------------
% --- begin date ---
\begin{center}
Sep 19, 2019
\end{center}
% --- end date ---
\vspace{1cm}
% !split
\subsection*{Logistic Regression}
In linear regression our main interest was centered on learning the
coefficients of a functional fit (say a polynomial) in order to be
able to predict the response of a continuous variable on some unseen
data. The fit to the continuous variable $y_i$ is based on some
independent variables $\hat{x}_i$. Linear regression resulted in
analytical expressions for standard ordinary Least Squares or Ridge
regression (in terms of matrices to invert) for several quantities,
ranging from the variance and thereby the confidence intervals of the
parameters $\hat{\beta}$ to the mean squared error. If we can invert
the product of the design matrices, linear regression gives then a
simple recipe for fitting our data.
Classification problems, however, are concerned with outcomes taking
the form of discrete variables (i.e.~categories). We may for example,
on the basis of DNA sequencing for a number of patients, like to find
out which mutations are important for a certain disease; or based on
scans of various patients' brains, figure out if there is a tumor or
not; or given a specific physical system, we'd like to identify its
state, say whether it is an ordered or disordered system (typical
situation in solid state physics); or classify the status of a
patient, whether she/he has a stroke or not and many other similar
situations.
The most common situation we encounter when we apply logistic
regression is that of two possible outcomes, normally denoted as a
binary outcome, true or false, positive or negative, success or
failure etc.
% !split
\subsection*{Optimization and Deep learning}
Logistic regression will also serve as our stepping stone towards neural
network algorithms and supervised deep learning. For logistic
learning, the minimization of the cost function leads to a non-linear
equation in the parameters $\hat{\beta}$. The optimization of the problem calls therefore for minimization algorithms. This forms the bottle neck of all machine learning algorithms, namely how to find reliable minima of a multi-variable function. This leads us to the family of gradient descent methods. The latter are the working horses of basically all modern machine learning algorithms.
We note also that many of the topics discussed here
regression are also commonly used in modern supervised Deep Learning
models, as we will see later.
% !split
\subsection*{Basics}
We consider the case where the dependent variables, also called the
responses or the outcomes, $y_i$ are discrete and only take values
from $k=0,\dots,K-1$ (i.e.~$K$ classes).
The goal is to predict the
output classes from the design matrix $\hat{X}\in\mathbb{R}^{n\times p}$
made of $n$ samples, each of which carries $p$ features or predictors. The
primary goal is to identify the classes to which new unseen samples
belong.
Let us specialize to the case of two classes only, with outputs
$y_i=0$ and $y_i=1$. Our outcomes could represent the status of a
credit card user that could default or not on her/his credit card
debt. That is
\[
y_i = \begin{bmatrix} 0 & \mathrm{no}\\ 1 & \mathrm{yes} \end{bmatrix}.
\]
% !split
\subsection*{Linear classifier}
Before moving to the logistic model, let us try to use our linear regression model to classify these two outcomes. We could for example fit a linear model to the default case if $y_i > 0.5$ and the no default case $y_i \leq 0.5$.
We would then have our
weighted linear combination, namely
\begin{equation}
\hat{y} = \hat{X}^T\hat{\beta} + \hat{\epsilon},
\end{equation}
where $\hat{y}$ is a vector representing the possible outcomes, $\hat{X}$ is our
$n\times p$ design matrix and $\hat{\beta}$ represents our estimators/predictors.
% !split
\subsection*{Some selected properties}
The main problem with our function is that it
takes values on the entire real axis. In the case of
logistic regression, however, the labels $y_i$ are discrete
variables. A typical example is the credit card data discussed below here, where we can set the state of defaulting the debt to $y_i=1$ and not to $y_i=0$ for one the persons in the data set (see the full example below).
One simple way to get a discrete output is to have sign
functions that map the output of a linear regressor to values $\{0,1\}$,
$f(s_i)=sign(s_i)=1$ if $s_i\ge 0$ and 0 if otherwise.
We will encounter this model in our first demonstration of neural networks. Historically it is called the ``perceptron" model in the machine learning
literature. This model is extremely simple. However, in many cases it is more
favorable to use a ``soft" classifier that outputs
the probability of a given category. This leads us to the logistic function.
% !split
\subsection*{The logistic function}
The perceptron is an example of a ``hard classification'' model. We
will encounter this model when we discuss neural networks as
well. Each datapoint is deterministically assigned to a category (i.e
$y_i=0$ or $y_i=1$). In many cases, it is favorable to have a ``soft''
classifier that outputs the probability of a given category rather
than a single value. For example, given $x_i$, the classifier
outputs the probability of being in a category $k$. Logistic regression
is the most common example of a so-called soft classifier. In logistic
regression, the probability that a data point $x_i$
belongs to a category $y_i=\{0,1\}$ is given by the so-called logit function (or Sigmoid) which is meant to represent the likelihood for a given event,
\[
p(t) = \frac{1}{1+\mathrm \exp{-t}}=\frac{\exp{t}}{1+\mathrm \exp{t}}.
\]
Note that $1-p(t)= p(-t)$.
The following code plots the logistic function, the step function and other functions we will encounter from here and on.
\begin{minted}[fontsize=\fontsize{9pt}{9pt},linenos=false,mathescape,baselinestretch=1.0,fontfamily=tt,xleftmargin=7mm]{python}
"""The sigmoid function (or the logistic curve) is a
function that takes any real number, z, and outputs a number (0,1).
It is useful in neural networks for assigning weights on a relative scale.
The value z is the weighted sum of parameters involved in the learning algorithm."""
import numpy
import matplotlib.pyplot as plt
import math as mt
z = numpy.arange(-5, 5, .1)
sigma_fn = numpy.vectorize(lambda z: 1/(1+numpy.exp(-z)))
sigma = sigma_fn(z)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(z, sigma)
ax.set_ylim([-0.1, 1.1])
ax.set_xlim([-5,5])
ax.grid(True)
ax.set_xlabel('z')
ax.set_title('sigmoid function')
plt.show()
"""Step Function"""
z = numpy.arange(-5, 5, .02)
step_fn = numpy.vectorize(lambda z: 1.0 if z >= 0.0 else 0.0)
step = step_fn(z)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(z, step)
ax.set_ylim([-0.5, 1.5])
ax.set_xlim([-5,5])
ax.grid(True)
ax.set_xlabel('z')
ax.set_title('step function')
plt.show()
"""tanh Function"""
z = numpy.arange(-2*mt.pi, 2*mt.pi, 0.1)
t = numpy.tanh(z)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(z, t)
ax.set_ylim([-1.0, 1.0])
ax.set_xlim([-2*mt.pi,2*mt.pi])
ax.grid(True)
ax.set_xlabel('z')
ax.set_title('tanh function')
plt.show()
\end{minted}
% !split
\subsection*{Two parameters}
We assume now that we have two classes with $y_i$ either $0$ or $1$. Furthermore we assume also that we have only two parameters $\beta$ in our fitting of the Sigmoid function, that is we define probabilities
\begin{align*}
p(y_i=1|x_i,\hat{\beta}) &= \frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}},\nonumber\\
p(y_i=0|x_i,\hat{\beta}) &= 1 - p(y_i=1|x_i,\hat{\beta}),
\end{align*}
where $\hat{\beta}$ are the weights we wish to extract from data, in our case $\beta_0$ and $\beta_1$.
Note that we used
\[
p(y_i=0\vert x_i, \hat{\beta}) = 1-p(y_i=1\vert x_i, \hat{\beta}).
\]
% !split
\subsection*{Maximum likelihood}
In order to define the total likelihood for all possible outcomes from a
dataset $\mathcal{D}=\{(y_i,x_i)\}$, with the binary labels
$y_i\in\{0,1\}$ and where the data points are drawn independently, we use the so-called \href{{https://en.wikipedia.org/wiki/Maximum_likelihood_estimation}}{Maximum Likelihood Estimation} (MLE) principle.
We aim thus at maximizing
the probability of seeing the observed data. We can then approximate the
likelihood in terms of the product of the individual probabilities of a specific outcome $y_i$, that is
\begin{align*}
P(\mathcal{D}|\hat{\beta})& = \prod_{i=1}^n \left[p(y_i=1|x_i,\hat{\beta})\right]^{y_i}\left[1-p(y_i=1|x_i,\hat{\beta}))\right]^{1-y_i}\nonumber \\
\end{align*}
from which we obtain the log-likelihood and our \textbf{cost/loss} function
\[
\mathcal{C}(\hat{\beta}) = \sum_{i=1}^n \left( y_i\log{p(y_i=1|x_i,\hat{\beta})} + (1-y_i)\log\left[1-p(y_i=1|x_i,\hat{\beta}))\right]\right).
\]
% !split
\subsection*{The cost function rewritten}
Reordering the logarithms, we can rewrite the \textbf{cost/loss} function as
\[
\mathcal{C}(\hat{\beta}) = \sum_{i=1}^n \left(y_i(\beta_0+\beta_1x_i) -\log{(1+\exp{(\beta_0+\beta_1x_i)})}\right).
\]
The maximum likelihood estimator is defined as the set of parameters that maximize the log-likelihood where we maximize with respect to $\beta$.
Since the cost (error) function is just the negative log-likelihood, for logistic regression we have that
\[
\mathcal{C}(\hat{\beta})=-\sum_{i=1}^n \left(y_i(\beta_0+\beta_1x_i) -\log{(1+\exp{(\beta_0+\beta_1x_i)})}\right).
\]
This equation is known in statistics as the \textbf{cross entropy}. Finally, we note that just as in linear regression,
in practice we often supplement the cross-entropy with additional regularization terms, usually $L_1$ and $L_2$ regularization as we did for Ridge and Lasso regression.
% !split
\subsection*{Minimizing the cross entropy}
The cross entropy is a convex function of the weights $\hat{\beta}$ and,
therefore, any local minimizer is a global minimizer.
Minimizing this
cost function with respect to the two parameters $\beta_0$ and $\beta_1$ we obtain
\[
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \beta_0} = -\sum_{i=1}^n \left(y_i -\frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}}\right),
\]
and
\[
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \beta_1} = -\sum_{i=1}^n \left(y_ix_i -x_i\frac{\exp{(\beta_0+\beta_1x_i)}}{1+\exp{(\beta_0+\beta_1x_i)}}\right).
\]
% !split
\subsection*{A more compact expression}
Let us now define a vector $\hat{y}$ with $n$ elements $y_i$, an
$n\times p$ matrix $\hat{X}$ which contains the $x_i$ values and a
vector $\hat{p}$ of fitted probabilities $p(y_i\vert x_i,\hat{\beta})$. We can rewrite in a more compact form the first
derivative of cost function as
\[
\frac{\partial \mathcal{C}(\hat{\beta})}{\partial \hat{\beta}} = -\hat{X}^T\left(\hat{y}-\hat{p}\right).
\]
If we in addition define a diagonal matrix $\hat{W}$ with elements
$p(y_i\vert x_i,\hat{\beta})(1-p(y_i\vert x_i,\hat{\beta})$, we can obtain a compact expression of the second derivative as
\[
\frac{\partial^2 \mathcal{C}(\hat{\beta})}{\partial \hat{\beta}\partial \hat{\beta}^T} = \hat{X}^T\hat{W}\hat{X}.
\]
% !split
\subsection*{Extending to more predictors}
Within a binary classification problem, we can easily expand our model to include multiple predictors. Our ratio between likelihoods is then with $p$ predictors
\[
\log{ \frac{p(\hat{\beta}\hat{x})}{1-p(\hat{\beta}\hat{x})}} = \beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p.
\]
Here we defined $\hat{x}=[1,x_1,x_2,\dots,x_p]$ and $\hat{\beta}=[\beta_0, \beta_1, \dots, \beta_p]$ leading to
\[
p(\hat{\beta}\hat{x})=\frac{ \exp{(\beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p)}}{1+\exp{(\beta_0+\beta_1x_1+\beta_2x_2+\dots+\beta_px_p)}}.
\]
% !split
\subsection*{Including more classes}
Till now we have mainly focused on two classes, the so-called binary
system. Suppose we wish to extend to $K$ classes. Let us for the sake
of simplicity assume we have only two predictors. We have then
following model
\[
\log{\frac{p(C=1\vert x)}{p(K\vert x)}} = \beta_{10}+\beta_{11}x_1,
\]
\[
\log{\frac{p(C=2\vert x)}{p(K\vert x)}} = \beta_{20}+\beta_{21}x_1,
\]
and so on till the class $C=K-1$ class
\[
\log{\frac{p(C=K-1\vert x)}{p(K\vert x)}} = \beta_{(K-1)0}+\beta_{(K-1)1}x_1,
\]
and the model is specified in term of $K-1$ so-called log-odds or
\textbf{logit} transformations.
% !split
\subsection*{The Softmax function}
In our discussion of neural networks we will encounter the above again
in terms of the so-called \textbf{Softmax} function.
The softmax function is used in various multiclass classification
methods, such as multinomial logistic regression (also known as
softmax regression), multiclass linear discriminant analysis, naive
Bayes classifiers, and artificial neural networks. Specifically, in
multinomial logistic regression and linear discriminant analysis, the
input to the function is the result of $K$ distinct linear functions,
and the predicted probability for the $k$-th class given a sample
vector $\hat{x}$ and a weighting vector $\hat{\beta}$ is (with two
predictors):
\[
p(C=k\vert \mathbf {x} )=\frac{\exp{(\beta_{k0}+\beta_{k1}x_1)}}{1+\sum_{l=1}^{K-1}\exp{(\beta_{l0}+\beta_{l1}x_1)}}.
\]
It is easy to extend to more predictors. The final class is
\[
p(C=K\vert \mathbf {x} )=\frac{1}{1+\sum_{l=1}^{K-1}\exp{(\beta_{l0}+\beta_{l1}x_1)}},
\]
and they sum to one. Our earlier discussions were all specialized to
the case with two classes only. It is easy to see from the above that
what we derived earlier is compatible with these equations.
To find the optimal parameters we would typically use a gradient
descent method. Newton's method and gradient descent methods are
discussed in the material on \href{{https://compphysics.github.io/MachineLearning/doc/pub/Splines/html/Splines-bs.html}}{optimization
methods}.
% !split
\subsection*{A simple classification problem}
\begin{minted}[fontsize=\fontsize{9pt}{9pt},linenos=false,mathescape,baselinestretch=1.0,fontfamily=tt,xleftmargin=7mm]{python}
import numpy as np
from sklearn import datasets, linear_model
import matplotlib.pyplot as plt
def generate_data():
np.random.seed(0)
X, y = datasets.make_moons(200, noise=0.20)
return X, y
def visualize(X, y, clf):
plot_decision_boundary(lambda x: clf.predict(x), X, y)
def plot_decision_boundary(pred_func, X, y):
# Set min and max values and give it some padding
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
h = 0.01
# Generate a grid of points with distance h between them
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
# Predict the function value for the whole gid
Z = pred_func(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# Plot the contour and training examples
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)
plt.show()
def classify(X, y):
clf = linear_model.LogisticRegressionCV()
clf.fit(X, y)
return clf
def main():
X, y = generate_data()
# visualize(X, y)
clf = classify(X, y)
visualize(X, y, clf)
if __name__ == "__main__":
main()
\end{minted}
% !split
\subsection*{The Credit Card example}
Here we use the the \href{{https://archive.ics.uci.edu/ml/datasets/default+of+credit+card+clients}}{credit card data}. More text to come.
\begin{minted}[fontsize=\fontsize{9pt}{9pt},linenos=false,mathescape,baselinestretch=1.0,fontfamily=tt,xleftmargin=7mm]{python}
import pandas as pd
import os
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.metrics import confusion_matrix, accuracy_score, roc_auc_score
# Trying to set the seed
np.random.seed(0)
import random
random.seed(0)
# Reading file into data frame
cwd = os.getcwd()
filename = cwd + '/default of credit card clients.xls'
nanDict = {}
df = pd.read_excel(filename, header=1, skiprows=0, index_col=0, na_values=nanDict)
df.rename(index=str, columns={"default payment next month": "defaultPaymentNextMonth"}, inplace=True)
# Features and targets
X = df.loc[:, df.columns != 'defaultPaymentNextMonth'].values
y = df.loc[:, df.columns == 'defaultPaymentNextMonth'].values
# Categorical variables to one-hot's
onehotencoder = OneHotEncoder(categories="auto")
X = ColumnTransformer(
[("", onehotencoder, [3]),],
remainder="passthrough"
).fit_transform(X)
y.shape
# Train-test split
trainingShare = 0.5
seed = 1
XTrain, XTest, yTrain, yTest=train_test_split(X, y, train_size=trainingShare, \
test_size = 1-trainingShare,
random_state=seed)
# Input Scaling
sc = StandardScaler()
XTrain = sc.fit_transform(XTrain)
XTest = sc.transform(XTest)
# One-hot's of the target vector
Y_train_onehot, Y_test_onehot = onehotencoder.fit_transform(yTrain), onehotencoder.fit_transform(yTest)
# Remove instances with zeros only for past bill statements or paid amounts
'''
df = df.drop(df[(df.BILL_AMT1 == 0) &
(df.BILL_AMT2 == 0) &
(df.BILL_AMT3 == 0) &
(df.BILL_AMT4 == 0) &
(df.BILL_AMT5 == 0) &
(df.BILL_AMT6 == 0) &
(df.PAY_AMT1 == 0) &
(df.PAY_AMT2 == 0) &
(df.PAY_AMT3 == 0) &
(df.PAY_AMT4 == 0) &
(df.PAY_AMT5 == 0) &
(df.PAY_AMT6 == 0)].index)
'''
df = df.drop(df[(df.BILL_AMT1 == 0) &
(df.BILL_AMT2 == 0) &
(df.BILL_AMT3 == 0) &
(df.BILL_AMT4 == 0) &
(df.BILL_AMT5 == 0) &
(df.BILL_AMT6 == 0)].index)
df = df.drop(df[(df.PAY_AMT1 == 0) &
(df.PAY_AMT2 == 0) &
(df.PAY_AMT3 == 0) &
(df.PAY_AMT4 == 0) &
(df.PAY_AMT5 == 0) &
(df.PAY_AMT6 == 0)].index)
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
lambdas=np.logspace(-5,7,13)
parameters = [{'C': 1./lambdas, "solver":["lbfgs"]}]#*len(parameters)}]
scoring = ['accuracy', 'roc_auc']
logReg = LogisticRegression()
gridSearch = GridSearchCV(logReg, parameters, cv=5, scoring=scoring, refit='roc_auc')
\end{minted}
\begin{minted}[fontsize=\fontsize{9pt}{9pt},linenos=false,mathescape,baselinestretch=1.0,fontfamily=tt,xleftmargin=7mm]{python}
# "refit" gives the metric used deciding best model.
# See more http://scikit-learn.org/stable/auto_examples/model_selection/plot_multi_metric_evaluation.html
gridSearch.fit(XTrain, yTrain.ravel())
def gridSearchSummary(method, scoring):
"""Prints best parameters from Grid search
and AUC with standard deviation for all
parameter combos """
method = eval(method)
if scoring == 'accuracy':
mean = 'mean_test_score'
sd = 'std_test_score'
elif scoring == 'auc':
mean = 'mean_test_roc_auc'
sd = 'std_test_roc_auc'
print("Best: %f using %s" % (method.best_score_, method.best_params_))
means = method.cv_results_[mean]
stds = method.cv_results_[sd]
params = method.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
print("%f (%f) with: %r" % (mean, stdev, param))
def createConfusionMatrix(method, printOut=True):
"""
Computes and prints confusion matrices, accuracy scores,
and AUC for test and training sets
"""
confusionArray = np.zeros(6, dtype=object)
method = eval(method)
# Train
yPredTrain = method.predict(XTrain)
yPredTrain = (yPredTrain > 0.5)
cm = confusion_matrix(
yTrain, yPredTrain)
cm = np.around(cm/cm.sum(axis=1)[:,None], 2)
confusionArray[0] = cm
accScore = accuracy_score(yTrain, yPredTrain)
confusionArray[1] = accScore
AUC = roc_auc_score(yTrain, yPredTrain)
confusionArray[2] = AUC
if printOut:
print('\n################### Training ###############')
print('\nTraining Confusion matrix: \n', cm)
print('\nTraining Accuracy score: \n', accScore)
print('\nTrain AUC: \n', AUC)
# Test
yPred = method.predict(XTest)
yPred = (yPred > 0.5)
cm = confusion_matrix(
yTest, yPred)
cm = np.around(cm/cm.sum(axis=1)[:,None], 2)
confusionArray[3] = cm
accScore = accuracy_score(yTest, yPred)
confusionArray[4] = accScore
AUC = roc_auc_score(yTest, yPred)
confusionArray[5] = AUC
if printOut:
print('\n################### Testing ###############')
print('\nTest Confusion matrix: \n', cm)
print('\nTest Accuracy score: \n', accScore)
print('\nTestAUC: \n', AUC)
return confusionArray
import matplotlib.pyplot as plt
import seaborn
import scikitplot as skplt
seaborn.set(style="white", context="notebook", font_scale=1.5,
rc={"axes.grid": True, "legend.frameon": False,
"lines.markeredgewidth": 1.4, "lines.markersize": 10})
seaborn.set_context("notebook", font_scale=1.5, rc={"lines.linewidth": 4.5})
yPred = gridSearch.predict_proba(XTest)
print(yTest.ravel().shape, yPred.shape)
#skplt.metrics.plot_cumulative_gain(yTest.ravel(), yPred_onehot)
skplt.metrics.plot_cumulative_gain(yTest.ravel(), yPred)
defaults = sum(yTest == 1)
total = len(yTest)
defaultRate = defaults/total
def bestCurve(defaults, total, defaultRate):
x = np.linspace(0, 1, total)
y1 = np.linspace(0, 1, defaults)
y2 = np.ones(total-defaults)
y3 = np.concatenate([y1,y2])
return x, y3
x, best = bestCurve(defaults=defaults, total=total, defaultRate=defaultRate)
plt.plot(x, best)
plt.show()
\end{minted}
% ------------------- end of main content ---------------
\end{document}
-2
View File
@@ -1,2 +0,0 @@
This IPython notebook LogReg.ipynb does not require any additional
programs.
Binary file not shown.
@@ -1,8 +0,0 @@
.DS_Store
.svn
log/*.log
tmp/**
node_modules/
.sass-cache
css/reveal.min.css
js/reveal.min.js
@@ -1,5 +0,0 @@
language: node_js
node_js:
- 0.10
before_script:
- npm install -g grunt-cli
@@ -1,23 +0,0 @@
## Contributing
Please keep the [issue tracker](http://github.com/hakimel/reveal.js/issues) limited to **bug reports**, **feature requests** and **pull requests**.
### Personal Support
If you have personal support or setup questions the best place to ask those are [StackOverflow](http://stackoverflow.com/questions/tagged/reveal.js).
### Bug Reports
When reporting a bug make sure to include information about which browser and operating system you are on as well as the necessary steps to reproduce the issue. If possible please include a link to a sample presentation where the bug can be tested.
### Pull Requests
- Should follow the coding style of the file you work in, most importantly:
- Tabs to indent
- Single-quoted strings
- Should be made towards the **dev branch**
- Should be submitted from a feature/topic branch (not your master)
### Plugins
Please do not submit plugins as pull requests. They should be maintained in their own separate repository. More information here: https://github.com/hakimel/reveal.js/wiki/Plugin-Guidelines
@@ -1,140 +0,0 @@
/* global module:false */
module.exports = function(grunt) {
var port = grunt.option('port') || 8000;
// Project configuration
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
meta: {
banner:
'/*!\n' +
' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
' * http://lab.hakim.se/reveal-js\n' +
' * MIT licensed\n' +
' *\n' +
' * Copyright (C) 2014 Hakim El Hattab, http://hakim.se\n' +
' */'
},
qunit: {
files: [ 'test/*.html' ]
},
uglify: {
options: {
banner: '<%= meta.banner %>\n'
},
build: {
src: 'js/reveal.js',
dest: 'js/reveal.min.js'
}
},
cssmin: {
compress: {
files: {
'css/reveal.min.css': [ 'css/reveal.css' ]
}
}
},
sass: {
main: {
files: {
'css/theme/darkgray.css': 'css/theme/source/darkgray.scss',
'css/theme/beigesmall.css': 'css/theme/source/beigesmall.scss',
'css/theme/cbc.css': 'css/theme/source/cbc.scss',
'css/theme/default.css': 'css/theme/source/default.scss',
'css/theme/beige.css': 'css/theme/source/beige.scss',
'css/theme/night.css': 'css/theme/source/night.scss',
'css/theme/serif.css': 'css/theme/source/serif.scss',
'css/theme/simple.css': 'css/theme/source/simple.scss',
'css/theme/sky.css': 'css/theme/source/sky.scss',
'css/theme/moon.css': 'css/theme/source/moon.scss',
'css/theme/solarized.css': 'css/theme/source/solarized.scss',
'css/theme/blood.css': 'css/theme/source/blood.scss'
}
}
},
jshint: {
options: {
curly: false,
eqeqeq: true,
immed: true,
latedef: true,
newcap: true,
noarg: true,
sub: true,
undef: true,
eqnull: true,
browser: true,
expr: true,
globals: {
head: false,
module: false,
console: false,
unescape: false
}
},
files: [ 'Gruntfile.js', 'js/reveal.js' ]
},
connect: {
server: {
options: {
port: port,
base: '.'
}
}
},
zip: {
'reveal-js-presentation.zip': [
'index.html',
'css/**',
'js/**',
'lib/**',
'images/**',
'plugin/**'
]
},
watch: {
main: {
files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
tasks: 'default'
},
theme: {
files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
tasks: 'themes'
}
}
});
// Dependencies
grunt.loadNpmTasks( 'grunt-contrib-qunit' );
grunt.loadNpmTasks( 'grunt-contrib-jshint' );
grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
grunt.loadNpmTasks( 'grunt-contrib-uglify' );
grunt.loadNpmTasks( 'grunt-contrib-watch' );
grunt.loadNpmTasks( 'grunt-contrib-sass' );
grunt.loadNpmTasks( 'grunt-contrib-connect' );
grunt.loadNpmTasks( 'grunt-zip' );
// Default task
grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify', 'qunit' ] );
// Theme task
grunt.registerTask( 'themes', [ 'sass' ] );
// Package presentation to archive
grunt.registerTask( 'package', [ 'default', 'zip' ] );
// Serve presentation locally
grunt.registerTask( 'serve', [ 'connect', 'watch' ] );
// Run tests
grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );
};
@@ -1,19 +0,0 @@
Copyright (C) 2015 Hakim El Hattab, http://hakim.se
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
File diff suppressed because it is too large Load Diff
@@ -1,27 +0,0 @@
{
"name": "reveal.js",
"version": "3.1.0",
"main": [
"js/reveal.js",
"css/reveal.css"
],
"homepage": "http://lab.hakim.se/reveal-js/",
"license": "MIT",
"description": "The HTML Presentation Framework",
"authors": [
"Hakim El Hattab <hakim.elhattab@gmail.com>"
],
"dependencies": {
"headjs": "~0.9.6"
},
"repository": {
"type": "git",
"url": "git://github.com/hakimel/reveal.js.git"
},
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test"
]
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

@@ -1,202 +0,0 @@
/* Default Print Stylesheet Template
by Rob Glazebrook of CSSnewbie.com
Last Updated: June 4, 2008
Feel free (nay, compelled) to edit, append, and
manipulate this file as you see fit. */
@media print {
/* SECTION 1: Set default width, margin, float, and
background. This prevents elements from extending
beyond the edge of the printed page, and prevents
unnecessary background images from printing */
html {
background: #fff;
width: auto;
height: auto;
overflow: visible;
}
body {
background: #fff;
font-size: 20pt;
width: auto;
height: auto;
border: 0;
margin: 0 5%;
padding: 0;
overflow: visible;
float: none !important;
}
/* SECTION 2: Remove any elements not needed in print.
This would include navigation, ads, sidebars, etc. */
.nestedarrow,
.controls,
.fork-reveal,
.share-reveal,
.state-background,
.reveal .progress,
.reveal .backgrounds {
display: none !important;
}
/* SECTION 3: Set body font face, size, and color.
Consider using a serif font for readability. */
body, p, td, li, div {
font-size: 20pt!important;
font-family: Georgia, "Times New Roman", Times, serif !important;
color: #000;
}
/* SECTION 4: Set heading font face, sizes, and color.
Differentiate your headings from your body text.
Perhaps use a large sans-serif for distinction. */
h1,h2,h3,h4,h5,h6 {
color: #000!important;
height: auto;
line-height: normal;
font-family: Georgia, "Times New Roman", Times, serif !important;
text-shadow: 0 0 0 #000 !important;
text-align: left;
letter-spacing: normal;
}
/* Need to reduce the size of the fonts for printing */
h1 { font-size: 28pt !important; }
h2 { font-size: 24pt !important; }
h3 { font-size: 22pt !important; }
h4 { font-size: 22pt !important; font-variant: small-caps; }
h5 { font-size: 21pt !important; }
h6 { font-size: 20pt !important; font-style: italic; }
/* SECTION 5: Make hyperlinks more usable.
Ensure links are underlined, and consider appending
the URL to the end of the link for usability. */
a:link,
a:visited {
color: #000 !important;
font-weight: bold;
text-decoration: underline;
}
/*
.reveal a:link:after,
.reveal a:visited:after {
content: " (" attr(href) ") ";
color: #222 !important;
font-size: 90%;
}
*/
/* SECTION 6: more reveal.js specific additions by @skypanther */
ul, ol, div, p {
visibility: visible;
position: static;
width: auto;
height: auto;
display: block;
overflow: visible;
margin: 0;
text-align: left !important;
}
.reveal pre,
.reveal table {
margin-left: 0;
margin-right: 0;
}
.reveal pre code {
padding: 20px;
border: 1px solid #ddd;
}
.reveal blockquote {
margin: 20px 0;
}
.reveal .slides {
position: static !important;
width: auto !important;
height: auto !important;
left: 0 !important;
top: 0 !important;
margin-left: 0 !important;
margin-top: 0 !important;
padding: 0 !important;
zoom: 1 !important;
overflow: visible !important;
display: block !important;
text-align: left !important;
-webkit-perspective: none;
-moz-perspective: none;
-ms-perspective: none;
perspective: none;
-webkit-perspective-origin: 50% 50%;
-moz-perspective-origin: 50% 50%;
-ms-perspective-origin: 50% 50%;
perspective-origin: 50% 50%;
}
.reveal .slides section {
visibility: visible !important;
position: static !important;
width: 100% !important;
height: auto !important;
display: block !important;
overflow: visible !important;
left: 0 !important;
top: 0 !important;
margin-left: 0 !important;
margin-top: 0 !important;
padding: 60px 20px !important;
z-index: auto !important;
opacity: 1 !important;
page-break-after: always !important;
-webkit-transform-style: flat !important;
-moz-transform-style: flat !important;
-ms-transform-style: flat !important;
transform-style: flat !important;
-webkit-transform: none !important;
-moz-transform: none !important;
-ms-transform: none !important;
transform: none !important;
-webkit-transition: none !important;
-moz-transition: none !important;
-ms-transition: none !important;
transition: none !important;
}
.reveal .slides section.stack {
padding: 0 !important;
}
.reveal section:last-of-type {
page-break-after: avoid !important;
}
.reveal section .fragment {
opacity: 1 !important;
visibility: visible !important;
-webkit-transform: none !important;
-moz-transform: none !important;
-ms-transform: none !important;
transform: none !important;
}
.reveal section img {
display: block;
margin: 15px 0px;
background: rgba(255,255,255,1);
border: 1px solid #666;
box-shadow: none;
}
.reveal section small {
font-size: 0.8em;
}
}
@@ -1,157 +0,0 @@
/* Default Print Stylesheet Template
by Rob Glazebrook of CSSnewbie.com
Last Updated: June 4, 2008
Feel free (nay, compelled) to edit, append, and
manipulate this file as you see fit. */
/* SECTION 1: Set default width, margin, float, and
background. This prevents elements from extending
beyond the edge of the printed page, and prevents
unnecessary background images from printing */
* {
-webkit-print-color-adjust: exact;
}
body {
margin: 0 auto !important;
border: 0;
padding: 0;
float: none !important;
overflow: visible;
}
html {
width: 100%;
height: 100%;
overflow: visible;
}
/* SECTION 2: Remove any elements not needed in print.
This would include navigation, ads, sidebars, etc. */
.nestedarrow,
.reveal .controls,
.reveal .progress,
.reveal .slide-number,
.reveal .playback,
.reveal.overview,
.fork-reveal,
.share-reveal,
.state-background {
display: none !important;
}
/* SECTION 3: Set body font face, size, and color.
Consider using a serif font for readability. */
body, p, td, li, div {
}
/* SECTION 4: Set heading font face, sizes, and color.
Differentiate your headings from your body text.
Perhaps use a large sans-serif for distinction. */
h1,h2,h3,h4,h5,h6 {
text-shadow: 0 0 0 #000 !important;
}
.reveal pre code {
overflow: hidden !important;
font-family: Courier, 'Courier New', monospace !important;
}
/* SECTION 5: more reveal.js specific additions by @skypanther */
ul, ol, div, p {
visibility: visible;
position: static;
width: auto;
height: auto;
display: block;
overflow: visible;
margin: auto;
}
.reveal {
width: auto !important;
height: auto !important;
overflow: hidden !important;
}
.reveal .slides {
position: static;
width: 100%;
height: auto;
left: auto;
top: auto;
margin: 0 !important;
padding: 0 !important;
overflow: visible;
display: block;
-webkit-perspective: none;
-moz-perspective: none;
-ms-perspective: none;
perspective: none;
-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
-moz-perspective-origin: 50% 50%;
-ms-perspective-origin: 50% 50%;
perspective-origin: 50% 50%;
}
.reveal .slides section {
page-break-after: always !important;
visibility: visible !important;
position: relative !important;
display: block !important;
position: relative !important;
margin: 0 !important;
padding: 0 !important;
box-sizing: border-box !important;
min-height: 1px;
opacity: 1 !important;
-webkit-transform-style: flat !important;
-moz-transform-style: flat !important;
-ms-transform-style: flat !important;
transform-style: flat !important;
-webkit-transform: none !important;
-moz-transform: none !important;
-ms-transform: none !important;
transform: none !important;
}
.reveal section.stack {
margin: 0 !important;
padding: 0 !important;
page-break-after: avoid !important;
height: auto !important;
min-height: auto !important;
}
.reveal img {
box-shadow: none;
}
.reveal .roll {
overflow: visible;
line-height: 1em;
}
/* Slide backgrounds are placed inside of their slide when exporting to PDF */
.reveal section .slide-background {
display: block !important;
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: -1;
}
/* All elements should be above the slide-background */
.reveal section>* {
position: relative;
z-index: 1;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,23 +0,0 @@
## Dependencies
Themes are written using Sass to keep things modular and reduce the need for repeated selectors across files. Make sure that you have the reveal.js development environment including the Grunt dependencies installed before proceding: https://github.com/hakimel/reveal.js#full-setup
## Creating a Theme
To create your own theme, start by duplicating any ```.scss``` file in [/css/theme/source](https://github.com/hakimel/reveal.js/blob/master/css/theme/source) and adding it to the compilation list in the [Gruntfile](https://github.com/hakimel/reveal.js/blob/master/Gruntfile.js).
Each theme file does four things in the following order:
1. **Include [/css/theme/template/mixins.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/mixins.scss)**
Shared utility functions.
2. **Include [/css/theme/template/settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss)**
Declares a set of custom variables that the template file (step 4) expects. Can be overridden in step 3.
3. **Override**
This is where you override the default theme. Either by specifying variables (see [settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss) for reference) or by adding any selectors and styles you please.
4. **Include [/css/theme/template/theme.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/theme.scss)**
The template theme file which will generate final CSS output based on the currently defined variables.
When you are done, run `grunt css-themes` to compile the Sass file to CSS and you are ready to use your new theme.
@@ -1,154 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
/**
* Beige theme for reveal.js.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
@font-face {
font-family: 'League Gothic';
src: url("../../lib/font/league_gothic-webfont.eot");
src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
font-weight: normal;
font-style: normal; }
/* changed (by hpl) from #333; */
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #f7f2d3;
background: -moz-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, white), color-stop(100%, #f7f2d3));
background: -webkit-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
background: -o-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
background: -ms-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
background: radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
background-color: #f7f3de; }
.reveal {
font-family: "Lato", sans-serif;
font-size: 30px;
font-weight: normal;
letter-spacing: -0.02em;
color: #333333; }
::selection {
color: white;
background: rgba(79, 64, 28, 0.99);
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #222222;
font-family: "Helvetica", Impact, sans-serif;
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: 0.02em;
text-transform: none;
text-shadow: none; }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: #8b743d;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #c0a86e;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #564826; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #333333;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #8b743d;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: #8b743d; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: #8b743d; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: #8b743d; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: #8b743d; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #c0a86e; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #c0a86e; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #c0a86e; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #c0a86e; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #8b743d;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #8b743d; }
@@ -1,155 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
/**
* Beige theme for reveal.js.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
@font-face {
font-family: 'League Gothic';
src: url("../../lib/font/league_gothic-webfont.eot");
src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
font-weight: normal;
font-style: normal; }
/* added/changed by hpl */
/* changed (by hpl) from #333; */
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #f7f2d3;
background: -moz-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, white), color-stop(100%, #f7f2d3));
background: -webkit-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
background: -o-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
background: -ms-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
background: radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
background-color: #f7f3de; }
.reveal {
font-family: "Lato", sans-serif;
font-size: 25px;
font-weight: normal;
letter-spacing: -0.02em;
color: #333333; }
::selection {
color: white;
background: rgba(79, 64, 28, 0.99);
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #222222;
font-family: "Helvetica", Impact, sans-serif;
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: 0.02em;
text-transform: none;
text-shadow: none; }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: #8b743d;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #c0a86e;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #564826; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #333333;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #8b743d;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: #8b743d; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: #8b743d; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: #8b743d; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: #8b743d; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #c0a86e; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #c0a86e; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #c0a86e; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #c0a86e; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #8b743d;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #8b743d; }
@@ -1,273 +0,0 @@
@import url(../../lib/font/source-sans-pro/source-sans-pro.css);
/**
* Black theme for reveal.js. This is the opposite of the 'white' theme.
*
* Copyright (C) 2015 Hakim El Hattab, http://hakim.se
*/
section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
color: #222; }
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #222;
background-color: #222; }
.reveal {
font-family: 'Source Sans Pro', Helvetica, sans-serif;
font-size: 30px; /* changed by hpl from 38px */
font-weight: normal;
color: #fff; }
::selection {
color: #fff;
background: #bee4fd;
text-shadow: none; }
.reveal .slides > section, .reveal .slides > section > section {
/* removed by hpl: line-height: 1.3; */
font-weight: inherit; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6 {
margin: 0 0 20px 0;
color: #fff;
font-family: 'Source Sans Pro', Helvetica, sans-serif;
font-weight: 600;
line-height: 1.1em; /* changed by hpl from 1.2; */
letter-spacing: normal;
/* text-transform: uppercase; removed by hpl */
text-shadow: none;
word-wrap: break-word; }
.reveal h1 {
line-height: 1.2em;
}
/* Removed by hpl
.reveal h1 {
font-size: 2.5em; }
.reveal h2 {
font-size: 1.6em; }
.reveal h3 {
font-size: 1.3em; }
.reveal h4 {
font-size: 1em; }
*/
.reveal h1 {
text-shadow: none; }
/*********************************************
* OTHER
*********************************************/
.reveal p {
margin: 20px 0;
line-height: 1.3; }
/* Ensure certain elements are never larger than the slide itself */
.reveal img, .reveal video, .reveal iframe {
max-width: 95%;
max-height: 95%; }
.reveal strong, .reveal b {
font-weight: bold; }
.reveal em {
font-style: italic; }
.reveal ol, .reveal dl, .reveal ul {
display: inline-block;
text-align: left;
margin: 0 0 0 1em; }
.reveal ol {
list-style-type: decimal; }
.reveal ul {
list-style-type: disc; }
.reveal ul ul {
list-style-type: square; }
.reveal ul ul ul {
list-style-type: circle; }
.reveal ul ul, .reveal ul ol, .reveal ol ol, .reveal ol ul {
display: block;
margin-left: 40px; }
.reveal dt {
font-weight: bold; }
.reveal dd {
margin-left: 40px; }
.reveal q, .reveal blockquote {
quotes: none; }
.reveal blockquote {
display: block;
position: relative;
width: 70%;
margin: 20px auto;
padding: 5px;
font-style: italic;
background: rgba(255, 255, 255, 0.05);
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
.reveal blockquote p:first-child, .reveal blockquote p:last-child {
display: inline-block; }
.reveal q {
font-style: italic; }
.reveal pre {
display: block;
position: relative;
width: 90%;
margin: 20px auto;
text-align: left;
font-size: 0.55em;
font-family: monospace;
line-height: 1.2em;
word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
.reveal code {
font-family: monospace; }
.reveal pre code {
display: block;
padding: 5px;
overflow: auto;
max-height: 400px;
word-wrap: normal;
background: #3F3F3F;
color: #DCDCDC; }
.reveal table {
margin: auto;
border-collapse: collapse;
border-spacing: 0; }
.reveal table th {
font-weight: bold; }
.reveal table th, .reveal table td {
/*text-align: left; */ /* hpl modification */
padding: 0.2em 0.5em 0.2em 0.5em;
border-bottom: 1px solid; }
.reveal table th[align="center"], .reveal table td[align="center"] {
text-align: center; }
.reveal table th[align="right"], .reveal table td[align="right"] {
text-align: right; }
.reveal table tr:last-child td {
border-bottom: none; }
.reveal sup {
vertical-align: super; }
.reveal sub {
vertical-align: sub; }
.reveal small {
display: inline-block;
font-size: 0.6em;
line-height: 1.2em;
vertical-align: top; }
.reveal small * {
vertical-align: top; }
/*********************************************
* LINKS
*********************************************/
.reveal a {
color: #42affa;
text-decoration: none;
-webkit-transition: color 0.15s ease;
-moz-transition: color 0.15s ease;
transition: color 0.15s ease; }
.reveal a:hover {
color: #8dcffc;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #068ee9; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
.reveal a img {
-webkit-transition: all 0.15s linear;
-moz-transition: all 0.15s linear;
transition: all 0.15s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #42affa;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left, .reveal .controls div.navigate-left.enabled {
border-right-color: #42affa; }
.reveal .controls div.navigate-right, .reveal .controls div.navigate-right.enabled {
border-left-color: #42affa; }
.reveal .controls div.navigate-up, .reveal .controls div.navigate-up.enabled {
border-bottom-color: #42affa; }
.reveal .controls div.navigate-down, .reveal .controls div.navigate-down.enabled {
border-top-color: #42affa; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #8dcffc; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #8dcffc; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #8dcffc; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #8dcffc; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #42affa;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #42affa; }
@@ -1,180 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic);
/**
* Blood theme for reveal.js
* Author: Walther http://github.com/Walther
*
* Designed to be used with highlight.js theme
* "monokai_sublime.css" available from
* https://github.com/isagalaev/highlight.js/
*
* For other themes, change $codeBackground accordingly.
*
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #222222;
background: -moz-radial-gradient(center, circle cover, #626262 0%, #222222 100%);
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #626262), color-stop(100%, #222222));
background: -webkit-radial-gradient(center, circle cover, #626262 0%, #222222 100%);
background: -o-radial-gradient(center, circle cover, #626262 0%, #222222 100%);
background: -ms-radial-gradient(center, circle cover, #626262 0%, #222222 100%);
background: radial-gradient(center, circle cover, #626262 0%, #222222 100%);
background-color: #2b2b2b; }
.reveal {
font-family: Ubuntu, "sans-serif";
font-size: 30px;
font-weight: normal;
letter-spacing: -0.02em;
color: #eeeeee; }
::selection {
color: white;
background: #aa2233;
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #eeeeee;
font-family: Ubuntu, "sans-serif";
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: 0.02em;
text-transform: none;
text-shadow: 2px 2px 2px #222222; }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: #aa2233;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #dd5566;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #6a1520; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #eeeeee;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #aa2233;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: #aa2233; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: #aa2233; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: #aa2233; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: #aa2233; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #dd5566; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #dd5566; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #dd5566; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #dd5566; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #aa2233;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #aa2233; }
.reveal p {
font-weight: 300;
text-shadow: 1px 1px #222222; }
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
font-weight: 700; }
.reveal a:not(.image),
.reveal a:not(.image):hover {
text-shadow: 2px 2px 2px #000; }
.reveal small a:not(.image),
.reveal small a:not(.image):hover {
text-shadow: 1px 1px 1px #000; }
.reveal p code {
background-color: #23241f;
display: inline-block;
border-radius: 7px; }
.reveal small code {
vertical-align: baseline; }
@@ -1,144 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
/**
* A simple theme for reveal.js presentations, similar
* to the default theme. The accent color is darkblue.
*
* This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
* reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
* Center for Biomedical Computing theme made by Hans Petter Langtangen.
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: white;
background-color: white; }
.reveal {
font-family: "Lato", sans-serif;
font-size: 30px;
font-weight: normal;
letter-spacing: -0.02em;
color: #404040; }
::selection {
color: white;
background: rgba(0, 0, 0, 0.99);
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #8a0808;
font-family: "Helvetica", Impact, sans-serif;
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: 0.02em;
text-transform: none;
text-shadow: none; }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: #8a0808;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #ea0e0e;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #420404; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #404040;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #8a0808;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: #8a0808; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: #8a0808; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: #8a0808; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: #8a0808; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #ea0e0e; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #ea0e0e; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #ea0e0e; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #ea0e0e; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #8a0808;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #8a0808; }
@@ -1,153 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
/**
* Default theme for reveal.js.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
@font-face {
font-family: 'League Gothic';
src: url("../../lib/font/league_gothic-webfont.eot");
src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
font-weight: normal;
font-style: normal; }
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #1c1e20;
background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20));
background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background-color: #2b2b2b; }
.reveal {
font-family: "Lato", sans-serif;
font-size: 30px;
font-weight: normal;
letter-spacing: -0.02em;
color: #eeeeee; }
::selection {
color: white;
background: #ff5e99;
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #eeeeee;
font-family: "Helvetica", Impact, sans-serif;
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: 0.02em;
text-transform: none;
text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: #13daec;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #71e9f4;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #0d99a5; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #eeeeee;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #13daec;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: #13daec; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: #13daec; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: #13daec; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: #13daec; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #71e9f4; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #71e9f4; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #71e9f4; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #71e9f4; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #13daec;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #13daec; }
@@ -1,153 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
/**
* Default theme for reveal.js.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
@font-face {
font-family: 'League Gothic';
src: url("../../lib/font/league_gothic-webfont.eot");
src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
font-weight: normal;
font-style: normal; }
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #1c1e20;
background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20));
background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background-color: #2b2b2b; }
.reveal {
font-family: "Lato", sans-serif;
font-size: 30px;
font-weight: normal;
letter-spacing: -0.02em;
color: #eeeeee; }
::selection {
color: white;
background: #ff5e99;
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #eeeeee;
font-family: "Helvetica", Impact, sans-serif;
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: 0.02em;
text-transform: none;
text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: #13daec;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #71e9f4;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #0d99a5; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #eeeeee;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #13daec;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: #13daec; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: #13daec; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: #13daec; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: #13daec; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #71e9f4; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #71e9f4; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #71e9f4; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #71e9f4; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #13daec;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #13daec; }
@@ -1,279 +0,0 @@
@import url(../../lib/font/league-gothic/league-gothic.css);
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
/**
* League theme for reveal.js.
*
* This was the default theme pre-3.0.0.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #1c1e20;
background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20));
background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
background-color: #2b2b2b; }
.reveal {
font-family: 'Lato', sans-serif;
font-size: 30px; /* changed by hpl from 36px */
font-weight: normal;
color: #eee; }
::selection {
color: #fff;
background: #FF5E99;
text-shadow: none; }
.reveal .slides > section, .reveal .slides > section > section {
/* removed by hpl: line-height: 1.3; */
font-weight: inherit; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6 {
margin: 0 0 20px 0;
color: #eee;
font-family: 'Helvetica', Impact, sans-serif;
font-weight: normal;
line-height: 1.1em; /* changed by hpl from 1.2; */
letter-spacing: normal;
/* text-transform: uppercase; removed by hpl */
text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2);
word-wrap: break-word; }
.reveal h1 {
line-height: 1.2em;
}
/* removed by hpl:
.reveal h1 {
font-size: 3.77em; }
.reveal h2 {
font-size: 2.11em; }
.reveal h3 {
font-size: 1.55em; }
.reveal h4 {
font-size: 1em; }
*/
.reveal h1 {
text-shadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15); }
/*********************************************
* OTHER
*********************************************/
.reveal p {
margin: 20px 0;
line-height: 1.3; }
/* Ensure certain elements are never larger than the slide itself */
.reveal img, .reveal video, .reveal iframe {
max-width: 95%;
max-height: 95%; }
.reveal strong, .reveal b {
font-weight: bold; }
.reveal em {
font-style: italic; }
.reveal ol, .reveal dl, .reveal ul {
display: inline-block;
text-align: left;
margin: 0 0 0 1em; }
.reveal ol {
list-style-type: decimal; }
.reveal ul {
list-style-type: disc; }
.reveal ul ul {
list-style-type: square; }
.reveal ul ul ul {
list-style-type: circle; }
.reveal ul ul, .reveal ul ol, .reveal ol ol, .reveal ol ul {
display: block;
margin-left: 40px; }
.reveal dt {
font-weight: bold; }
.reveal dd {
margin-left: 40px; }
.reveal q, .reveal blockquote {
quotes: none; }
.reveal blockquote {
display: block;
position: relative;
width: 70%;
margin: 20px auto;
padding: 5px;
font-style: italic;
background: rgba(255, 255, 255, 0.05);
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
.reveal blockquote p:first-child, .reveal blockquote p:last-child {
display: inline-block; }
.reveal q {
font-style: italic; }
.reveal pre {
display: block;
position: relative;
width: 90%;
margin: 20px auto;
text-align: left;
font-size: 0.55em;
font-family: monospace;
line-height: 1.2em;
word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
.reveal code {
font-family: monospace; }
.reveal pre code {
display: block;
padding: 5px;
overflow: auto;
max-height: 400px;
word-wrap: normal;
background: #3F3F3F;
color: #DCDCDC; }
.reveal table {
margin: auto;
border-collapse: collapse;
border-spacing: 0; }
.reveal table th {
font-weight: bold; }
.reveal table th, .reveal table td {
/* text-align: left; */ /* hpl modification */
padding: 0.2em 0.5em 0.2em 0.5em;
border-bottom: 1px solid; }
.reveal table th[align="center"], .reveal table td[align="center"] {
text-align: center; }
.reveal table th[align="right"], .reveal table td[align="right"] {
text-align: right; }
.reveal table tr:last-child td {
border-bottom: none; }
.reveal sup {
vertical-align: super; }
.reveal sub {
vertical-align: sub; }
.reveal small {
display: inline-block;
font-size: 0.6em;
line-height: 1.2em;
vertical-align: top; }
.reveal small * {
vertical-align: top; }
/*********************************************
* LINKS
*********************************************/
.reveal a {
color: #13DAEC;
text-decoration: none;
-webkit-transition: color 0.15s ease;
-moz-transition: color 0.15s ease;
transition: color 0.15s ease; }
.reveal a:hover {
color: #71ebf4;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #0d9ba5; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #eee;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
.reveal a img {
-webkit-transition: all 0.15s linear;
-moz-transition: all 0.15s linear;
transition: all 0.15s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #13DAEC;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left, .reveal .controls div.navigate-left.enabled {
border-right-color: #13DAEC; }
.reveal .controls div.navigate-right, .reveal .controls div.navigate-right.enabled {
border-left-color: #13DAEC; }
.reveal .controls div.navigate-up, .reveal .controls div.navigate-up.enabled {
border-bottom-color: #13DAEC; }
.reveal .controls div.navigate-down, .reveal .controls div.navigate-down.enabled {
border-top-color: #13DAEC; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #71ebf4; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #71ebf4; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #71ebf4; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #71ebf4; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #13DAEC;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #13DAEC; }
@@ -1,153 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
/**
* Solarized Dark theme for reveal.js.
* Author: Achim Staebler
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
@font-face {
font-family: 'League Gothic';
src: url("../../lib/font/league_gothic-webfont.eot");
src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
font-weight: normal;
font-style: normal; }
/**
* Solarized colors by Ethan Schoonover
*/
html * {
color-profile: sRGB;
rendering-intent: auto; }
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #002b36;
background-color: #002b36; }
.reveal {
font-family: "Lato", sans-serif;
font-size: 30px;
font-weight: normal;
letter-spacing: -0.02em;
color: #93a1a1; }
::selection {
color: white;
background: #d33682;
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #eee8d5;
font-family: "Helvetica", Impact, sans-serif;
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: 0.02em;
text-transform: none;
text-shadow: none; }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: #268bd2;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #78b9e6;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #1a6091; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #93a1a1;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #268bd2;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: #268bd2; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: #268bd2; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: #268bd2; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: #268bd2; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #78b9e6; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #78b9e6; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #78b9e6; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #78b9e6; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #268bd2;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #268bd2; }
@@ -1,141 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Montserrat:700);
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
/**
* Black theme for reveal.js.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #111111;
background-color: #111111; }
.reveal {
font-family: "Open Sans", sans-serif;
font-size: 30px;
font-weight: normal;
letter-spacing: -0.02em;
color: #eeeeee; }
::selection {
color: white;
background: #e7ad52;
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #eeeeee;
font-family: "Montserrat", Impact, sans-serif;
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: -0.03em;
text-transform: none;
text-shadow: none; }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: #e7ad52;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #f3d7ac;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #d08a1d; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #eeeeee;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #e7ad52;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: #e7ad52; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: #e7ad52; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: #e7ad52; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: #e7ad52; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #f3d7ac; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #f3d7ac; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #f3d7ac; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #f3d7ac; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #e7ad52;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #e7ad52; }
@@ -1,143 +0,0 @@
/**
* A simple theme for reveal.js presentations, similar
* to the default theme. The accent color is brown.
*
* This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
.reveal a:not(.image) {
line-height: 1.3em; }
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #f0f1eb;
background-color: #f0f1eb; }
.reveal {
font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
font-size: 30px;
font-weight: normal;
letter-spacing: -0.02em;
color: black; }
::selection {
color: white;
background: #26351c;
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #383d3d;
font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: 0.02em;
text-transform: none;
text-shadow: none; }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: #51483d;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #8b7c69;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #25211c; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid black;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #51483d;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: #51483d; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: #51483d; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: #51483d; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: #51483d; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #8b7c69; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #8b7c69; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #8b7c69; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #8b7c69; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #51483d;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #51483d; }
@@ -1,144 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700);
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
/**
* A simple theme for reveal.js presentations, similar
* to the default theme. The accent color is darkblue.
*
* This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
* reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
/* changed (by hpl) from 'News Cycle', Impact, sans-serif; */
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: white;
background-color: white; }
.reveal {
font-family: "Lato", sans-serif;
font-size: 30px;
font-weight: normal;
letter-spacing: -0.02em;
color: black; }
::selection {
color: white;
background: rgba(0, 0, 0, 0.99);
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: black;
font-family: "Helvetica", Impact, sans-serif;
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: 0.02em;
text-transform: none;
text-shadow: none; }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: darkblue;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #0000f1;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #00003f; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid black;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: darkblue;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: darkblue; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: darkblue; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: darkblue; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: darkblue; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #0000f1; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #0000f1; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #0000f1; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #0000f1; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: darkblue;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: darkblue; }
@@ -1,144 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
/**
* A simple theme for reveal.js presentations, similar
* to the default theme. The accent color is darkblue.
*
* This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
* reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
* Simula theme made by Hans Petter Langtangen.
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: white;
background-color: white; }
.reveal {
font-family: "Lato", sans-serif;
font-size: 30px;
font-weight: normal;
letter-spacing: -0.02em;
color: #404040; }
::selection {
color: white;
background: rgba(0, 0, 0, 0.99);
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #ff8800;
font-family: "Helvetica", Impact, sans-serif;
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: 0.02em;
text-transform: none;
text-shadow: none; }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: #ff8800;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #ffb866;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #b35f00; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #404040;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #ff8800;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: #ff8800; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: #ff8800; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: #ff8800; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: #ff8800; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #ffb866; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #ffb866; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #ffb866; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #ffb866; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #ff8800;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #ff8800; }
@@ -1,150 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
/**
* Sky theme for reveal.js.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
.reveal a:not(.image) {
line-height: 1.3em; }
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #add9e4;
background: -moz-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #f7fbfc), color-stop(100%, #add9e4));
background: -webkit-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
background: -o-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
background: -ms-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
background: radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
background-color: #f7fbfc; }
.reveal {
font-family: "Open Sans", sans-serif;
font-size: 30px;
font-weight: normal;
letter-spacing: -0.02em;
color: #333333; }
::selection {
color: white;
background: #134674;
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #333333;
font-family: "Quicksand", sans-serif;
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: -0.08em;
text-transform: none;
text-shadow: none; }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: #3b759e;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #74a7cb;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #264c66; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #333333;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #3b759e;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: #3b759e; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: #3b759e; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: #3b759e; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: #3b759e; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #74a7cb; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #74a7cb; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #74a7cb; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #74a7cb; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #3b759e;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #3b759e; }
@@ -1,153 +0,0 @@
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
/**
* Solarized Light theme for reveal.js.
* Author: Achim Staebler
*/
/* changed by hpl from 36px; */
/* changed by hpl from 'League Gothic', Impact, sans-serif; */
/* changed by hpl from uppercase; */
@font-face {
font-family: 'League Gothic';
src: url("../../lib/font/league_gothic-webfont.eot");
src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
font-weight: normal;
font-style: normal; }
/**
* Solarized colors by Ethan Schoonover
*/
html * {
color-profile: sRGB;
rendering-intent: auto; }
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #fdf6e3;
background-color: #fdf6e3; }
.reveal {
font-family: "Lato", sans-serif;
font-size: 30px;
font-weight: normal;
letter-spacing: -0.02em;
color: #657b83; }
::selection {
color: white;
background: #d33682;
text-shadow: none; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
margin: 0 0 20px 0;
color: #586e75;
font-family: "Helvetica", Impact, sans-serif;
line-height: 1.1em; /* changed (by hpl) from 0.9em */
letter-spacing: 0.02em;
text-transform: none;
text-shadow: none; }
.reveal h1 {
line-height: 1.2em;
/* added by hpl */
text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2); }
/*********************************************
* LINKS
*********************************************/
.reveal a:not(.image) {
color: #268bd2;
text-decoration: none;
-webkit-transition: color .15s ease;
-moz-transition: color .15s ease;
-ms-transition: color .15s ease;
-o-transition: color .15s ease;
transition: color .15s ease; }
.reveal a:not(.image):hover {
color: #78b9e6;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #1a6091; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #657b83;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-ms-transition: all .2s linear;
-o-transition: all .2s linear;
transition: all .2s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #268bd2;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left,
.reveal .controls div.navigate-left.enabled {
border-right-color: #268bd2; }
.reveal .controls div.navigate-right,
.reveal .controls div.navigate-right.enabled {
border-left-color: #268bd2; }
.reveal .controls div.navigate-up,
.reveal .controls div.navigate-up.enabled {
border-bottom-color: #268bd2; }
.reveal .controls div.navigate-down,
.reveal .controls div.navigate-down.enabled {
border-top-color: #268bd2; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #78b9e6; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #78b9e6; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #78b9e6; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #78b9e6; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #268bd2;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #268bd2; }
@@ -1,50 +0,0 @@
/**
* Beige theme for reveal.js.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@font-face {
font-family: 'League Gothic';
src: url('../../lib/font/league_gothic-webfont.eot');
src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
url('../../lib/font/league_gothic-webfont.woff') format('woff'),
url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
font-weight: normal;
font-style: normal;
}
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
// Override theme settings (see ../template/settings.scss)
$mainColor: #333;
$headingColor: #222; /* changed (by hpl) from #333; */
$headingTextShadow: none;
$backgroundColor: #f7f3de;
$linkColor: #8b743d;
$linkColorHover: lighten( $linkColor, 20% );
$selectionBackgroundColor: rgba(79, 64, 28, 0.99);
$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
// Background generator
@mixin bodyBackground() {
@include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) );
}
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,51 +0,0 @@
/**
* Beige theme for reveal.js.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@font-face {
font-family: 'League Gothic';
src: url('../../lib/font/league_gothic-webfont.eot');
src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
url('../../lib/font/league_gothic-webfont.woff') format('woff'),
url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
font-weight: normal;
font-style: normal;
}
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
// Override theme settings (see ../template/settings.scss)
$mainColor: #333;
$mainFontSize: 25px; /* added/changed by hpl */
$headingColor: #222; /* changed (by hpl) from #333; */
$headingTextShadow: none;
$backgroundColor: #f7f3de;
$linkColor: #8b743d;
$linkColorHover: lighten( $linkColor, 20% );
$selectionBackgroundColor: rgba(79, 64, 28, 0.99);
$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
// Background generator
@mixin bodyBackground() {
@include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) );
}
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,49 +0,0 @@
/**
* Black theme for reveal.js. This is the opposite of the 'white' theme.
*
* Copyright (C) 2015 Hakim El Hattab, http://hakim.se
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@import url(../../lib/font/source-sans-pro/source-sans-pro.css);
// Override theme settings (see ../template/settings.scss)
$backgroundColor: #222;
$mainColor: #fff;
$headingColor: #fff;
$mainFontSize: 38px;
$mainFont: 'Source Sans Pro', Helvetica, sans-serif;
$headingFont: 'Source Sans Pro', Helvetica, sans-serif;
$headingTextShadow: none;
$headingLetterSpacing: normal;
$headingTextTransform: uppercase;
$headingFontWeight: 600;
$linkColor: #42affa;
$linkColorHover: lighten( $linkColor, 15% );
$selectionBackgroundColor: lighten( $linkColor, 25% );
$heading1Size: 2.5em;
$heading2Size: 1.6em;
$heading3Size: 1.3em;
$heading4Size: 1.0em;
section.has-light-background {
&, h1, h2, h3, h4, h5, h6 {
color: #222;
}
}
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,91 +0,0 @@
/**
* Blood theme for reveal.js
* Author: Walther http://github.com/Walther
*
* Designed to be used with highlight.js theme
* "monokai_sublime.css" available from
* https://github.com/isagalaev/highlight.js/
*
* For other themes, change $codeBackground accordingly.
*
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic);
// Colors used in the theme
$blood: #a23;
$coal: #222;
$codeBackground: #23241f;
// Main text
$mainFont: Ubuntu, 'sans-serif';
$mainFontSize: 30px;
$mainColor: #eee;
// Headings
$headingFont: Ubuntu, 'sans-serif';
$headingTextShadow: 2px 2px 2px $coal;
// h1 shadow, borrowed humbly from
// (c) Default theme by Hakim El Hattab
$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
// Links
$linkColor: $blood;
$linkColorHover: lighten( $linkColor, 20% );
// Text selection
$selectionBackgroundColor: $blood;
$selectionColor: #fff;
// Background generator
@mixin bodyBackground() {
@include radial-gradient( $coal, lighten( $coal, 25% ) );
}
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
// some overrides after theme template import
.reveal p {
font-weight: 300;
text-shadow: 1px 1px $coal;
}
.reveal h1,
.reveal h2,
.reveal h3,
.reveal h4,
.reveal h5,
.reveal h6 {
font-weight: 700;
}
.reveal a:not(.image),
.reveal a:not(.image):hover {
text-shadow: 2px 2px 2px #000;
}
.reveal small a:not(.image),
.reveal small a:not(.image):hover {
text-shadow: 1px 1px 1px #000;
}
.reveal p code {
background-color: $codeBackground;
display: inline-block;
border-radius: 7px;
}
.reveal small code {
vertical-align: baseline;
}
@@ -1,39 +0,0 @@
/**
* A simple theme for reveal.js presentations, similar
* to the default theme. The accent color is darkblue.
*
* This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
* reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
* Center for Biomedical Computing theme made by Hans Petter Langtangen.
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
// Override theme settings (see ../template/settings.scss)
$mainFont: 'Lato', sans-serif;
$mainColor: #404040;
$headingFont: 'Helvetica', Impact, sans-serif;
$headingColor: #8A0808;
$headingTextShadow: none;
$headingTextTransform: none;
$backgroundColor: #fff;
$linkColor: #8A0808;
$linkColorHover: lighten( $linkColor, 20% );
$selectionBackgroundColor: rgba(0, 0, 0, 0.99);
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,42 +0,0 @@
/**
* Default theme for reveal.js.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@font-face {
font-family: 'League Gothic';
src: url('../../lib/font/league_gothic-webfont.eot');
src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
url('../../lib/font/league_gothic-webfont.woff') format('woff'),
url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
font-weight: normal;
font-style: normal;
}
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
// Override theme settings (see ../template/settings.scss)
$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
// Background generator
@mixin bodyBackground() {
@include radial-gradient( rgba(28,30,32,1), rgba(85,90,95,1) );
}
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,42 +0,0 @@
/**
* Default theme for reveal.js.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@font-face {
font-family: 'League Gothic';
src: url('../../lib/font/league_gothic-webfont.eot');
src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
url('../../lib/font/league_gothic-webfont.woff') format('woff'),
url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
font-weight: normal;
font-style: normal;
}
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
// Override theme settings (see ../template/settings.scss)
$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
// Background generator
@mixin bodyBackground() {
@include radial-gradient( rgba(28,30,32,1), rgba(85,90,95,1) );
}
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,34 +0,0 @@
/**
* League theme for reveal.js.
*
* This was the default theme pre-3.0.0.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@import url(../../lib/font/league-gothic/league-gothic.css);
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
// Override theme settings (see ../template/settings.scss)
$headingTextShadow: 0px 0px 6px rgba(0,0,0,0.2);
$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
// Background generator
@mixin bodyBackground() {
@include radial-gradient( rgba(28,30,32,1), rgba(85,90,95,1) );
}
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,68 +0,0 @@
/**
* Solarized Dark theme for reveal.js.
* Author: Achim Staebler
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@font-face {
font-family: 'League Gothic';
src: url('../../lib/font/league_gothic-webfont.eot');
src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
url('../../lib/font/league_gothic-webfont.woff') format('woff'),
url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
font-weight: normal;
font-style: normal;
}
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
/**
* Solarized colors by Ethan Schoonover
*/
html * {
color-profile: sRGB;
rendering-intent: auto;
}
// Solarized colors
$base03: #002b36;
$base02: #073642;
$base01: #586e75;
$base00: #657b83;
$base0: #839496;
$base1: #93a1a1;
$base2: #eee8d5;
$base3: #fdf6e3;
$yellow: #b58900;
$orange: #cb4b16;
$red: #dc322f;
$magenta: #d33682;
$violet: #6c71c4;
$blue: #268bd2;
$cyan: #2aa198;
$green: #859900;
// Override theme settings (see ../template/settings.scss)
$mainColor: $base1;
$headingColor: $base2;
$headingTextShadow: none;
$backgroundColor: $base03;
$linkColor: $blue;
$linkColorHover: lighten( $linkColor, 20% );
$selectionBackgroundColor: $magenta;
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,35 +0,0 @@
/**
* Black theme for reveal.js.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@import url(https://fonts.googleapis.com/css?family=Montserrat:700);
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
// Override theme settings (see ../template/settings.scss)
$backgroundColor: #111;
$mainFont: 'Open Sans', sans-serif;
$linkColor: #e7ad52;
$linkColorHover: lighten( $linkColor, 20% );
$headingFont: 'Montserrat', Impact, sans-serif;
$headingTextShadow: none;
$headingLetterSpacing: -0.03em;
$headingTextTransform: none;
$selectionBackgroundColor: #e7ad52;
$mainFontSize: 30px;
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,35 +0,0 @@
/**
* A simple theme for reveal.js presentations, similar
* to the default theme. The accent color is brown.
*
* This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Override theme settings (see ../template/settings.scss)
$mainFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
$mainColor: #000;
$headingFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
$headingColor: #383D3D;
$headingTextShadow: none;
$headingTextTransform: none;
$backgroundColor: #F0F1EB;
$linkColor: #51483D;
$linkColorHover: lighten( $linkColor, 20% );
$selectionBackgroundColor: #26351C;
.reveal a:not(.image) {
line-height: 1.3em;
}
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,38 +0,0 @@
/**
* A simple theme for reveal.js presentations, similar
* to the default theme. The accent color is darkblue.
*
* This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
* reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700);
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
// Override theme settings (see ../template/settings.scss)
$mainFont: 'Lato', sans-serif;
$mainColor: #000;
$headingFont: 'Helvetica', Impact, sans-serif; /* changed (by hpl) from 'News Cycle', Impact, sans-serif; */
$headingColor: #000;
$headingTextShadow: none;
$headingTextTransform: none;
$backgroundColor: #fff;
$linkColor: #00008B;
$linkColorHover: lighten( $linkColor, 20% );
$selectionBackgroundColor: rgba(0, 0, 0, 0.99);
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,39 +0,0 @@
/**
* A simple theme for reveal.js presentations, similar
* to the default theme. The accent color is darkblue.
*
* This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
* reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
* Simula theme made by Hans Petter Langtangen.
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
// Override theme settings (see ../template/settings.scss)
$mainFont: 'Lato', sans-serif;
$mainColor: #404040;
$headingFont: 'Helvetica', Impact, sans-serif;
$headingColor: #ff8800;
$headingTextShadow: none;
$headingTextTransform: none;
$backgroundColor: #fff;
$linkColor: #ff8800;
$linkColorHover: lighten( $linkColor, 20% );
$selectionBackgroundColor: rgba(0, 0, 0, 0.99);
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,46 +0,0 @@
/**
* Sky theme for reveal.js.
*
* Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@import url(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
// Override theme settings (see ../template/settings.scss)
$mainFont: 'Open Sans', sans-serif;
$mainColor: #333;
$headingFont: 'Quicksand', sans-serif;
$headingColor: #333;
$headingLetterSpacing: -0.08em;
$headingTextShadow: none;
$backgroundColor: #f7fbfc;
$linkColor: #3b759e;
$linkColorHover: lighten( $linkColor, 20% );
$selectionBackgroundColor: #134674;
// Fix links so they are not cut off
.reveal a:not(.image) {
line-height: 1.3em;
}
// Background generator
@mixin bodyBackground() {
@include radial-gradient( #add9e4, #f7fbfc );
}
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,74 +0,0 @@
/**
* Solarized Light theme for reveal.js.
* Author: Achim Staebler
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@font-face {
font-family: 'League Gothic';
src: url('../../lib/font/league_gothic-webfont.eot');
src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
url('../../lib/font/league_gothic-webfont.woff') format('woff'),
url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
font-weight: normal;
font-style: normal;
}
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
/**
* Solarized colors by Ethan Schoonover
*/
html * {
color-profile: sRGB;
rendering-intent: auto;
}
// Solarized colors
$base03: #002b36;
$base02: #073642;
$base01: #586e75;
$base00: #657b83;
$base0: #839496;
$base1: #93a1a1;
$base2: #eee8d5;
$base3: #fdf6e3;
$yellow: #b58900;
$orange: #cb4b16;
$red: #dc322f;
$magenta: #d33682;
$violet: #6c71c4;
$blue: #268bd2;
$cyan: #2aa198;
$green: #859900;
// Override theme settings (see ../template/settings.scss)
$mainColor: $base00;
$headingColor: $base01;
$headingTextShadow: none;
$backgroundColor: $base3;
$linkColor: $blue;
$linkColorHover: lighten( $linkColor, 20% );
$selectionBackgroundColor: $magenta;
// Background generator
// @mixin bodyBackground() {
// @include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) );
// }
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,49 +0,0 @@
/**
* White theme for reveal.js. This is the opposite of the 'black' theme.
*
* Copyright (C) 2015 Hakim El Hattab, http://hakim.se
*/
// Default mixins and settings -----------------
@import "../template/mixins";
@import "../template/settings";
// ---------------------------------------------
// Include theme-specific fonts
@import url(../../lib/font/source-sans-pro/source-sans-pro.css);
// Override theme settings (see ../template/settings.scss)
$backgroundColor: #fff;
$mainColor: #222;
$headingColor: #222;
$mainFontSize: 38px;
$mainFont: 'Source Sans Pro', Helvetica, sans-serif;
$headingFont: 'Source Sans Pro', Helvetica, sans-serif;
$headingTextShadow: none;
$headingLetterSpacing: normal;
$headingTextTransform: uppercase;
$headingFontWeight: 600;
$linkColor: #2a76dd;
$linkColorHover: lighten( $linkColor, 15% );
$selectionBackgroundColor: lighten( $linkColor, 25% );
$heading1Size: 2.5em;
$heading2Size: 1.6em;
$heading3Size: 1.3em;
$heading4Size: 1.0em;
section.has-dark-background {
&, h1, h2, h3, h4, h5, h6 {
color: #fff;
}
}
// Theme template ------------------------------
@import "../template/theme";
// ---------------------------------------------
@@ -1,273 +0,0 @@
@import url(../../lib/font/source-sans-pro/source-sans-pro.css);
/**
* White theme for reveal.js. This is the opposite of the 'black' theme.
*
* Copyright (C) 2015 Hakim El Hattab, http://hakim.se
*/
section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
color: #fff; }
/*********************************************
* GLOBAL STYLES
*********************************************/
body {
background: #fff;
background-color: #fff; }
.reveal {
font-family: 'Source Sans Pro', Helvetica, sans-serif;
font-size: 30px; /* changed by hpl from 38px */
font-weight: normal;
color: #222; }
::selection {
color: #fff;
background: #98bdef;
text-shadow: none; }
.reveal .slides > section, .reveal .slides > section > section {
line-height: 1.1em; /* changed by hpl from 1.2; */
font-weight: inherit; }
/*********************************************
* HEADERS
*********************************************/
.reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6 {
margin: 0 0 20px 0;
color: #222;
font-family: 'Source Sans Pro', Helvetica, sans-serif;
font-weight: 600;
line-height: 1.1em; /* changed by hpl from 1.2; */
letter-spacing: normal;
/* text-transform: uppercase; removed by hpl */
text-shadow: none;
word-wrap: break-word; }
.reveal h1 {
line-height: 1.2em;
}
/* removed by hpl
.reveal h1 {
font-size: 2.5em; }
.reveal h2 {
font-size: 1.6em; }
.reveal h3 {
font-size: 1.3em; }
.reveal h4 {
font-size: 1em; }
*/
.reveal h1 {
text-shadow: none; }
/*********************************************
* OTHER
*********************************************/
.reveal p {
margin: 20px 0;
line-height: 1.3; }
/* Ensure certain elements are never larger than the slide itself */
.reveal img, .reveal video, .reveal iframe {
max-width: 95%;
max-height: 95%; }
.reveal strong, .reveal b {
font-weight: bold; }
.reveal em {
font-style: italic; }
.reveal ol, .reveal dl, .reveal ul {
display: inline-block;
text-align: left;
margin: 0 0 0 1em; }
.reveal ol {
list-style-type: decimal; }
.reveal ul {
list-style-type: disc; }
.reveal ul ul {
list-style-type: square; }
.reveal ul ul ul {
list-style-type: circle; }
.reveal ul ul, .reveal ul ol, .reveal ol ol, .reveal ol ul {
display: block;
margin-left: 40px; }
.reveal dt {
font-weight: bold; }
.reveal dd {
margin-left: 40px; }
.reveal q, .reveal blockquote {
quotes: none; }
.reveal blockquote {
display: block;
position: relative;
width: 70%;
margin: 20px auto;
padding: 5px;
font-style: italic;
background: rgba(255, 255, 255, 0.05);
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
.reveal blockquote p:first-child, .reveal blockquote p:last-child {
display: inline-block; }
.reveal q {
font-style: italic; }
.reveal pre {
display: block;
position: relative;
width: 90%;
margin: 20px auto;
text-align: left;
font-size: 0.55em;
font-family: monospace;
line-height: 1.2em;
word-wrap: break-word;
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
.reveal code {
font-family: monospace; }
.reveal pre code {
display: block;
padding: 5px;
overflow: auto;
max-height: 400px;
word-wrap: normal;
background: #3F3F3F;
color: #DCDCDC; }
.reveal table {
margin: auto;
border-collapse: collapse;
border-spacing: 0; }
.reveal table th {
font-weight: bold; }
.reveal table th, .reveal table td {
/* text-align: left; */ /* hpl modification */
padding: 0.2em 0.5em 0.2em 0.5em;
border-bottom: 1px solid; }
.reveal table th[align="center"], .reveal table td[align="center"] {
text-align: center; }
.reveal table th[align="right"], .reveal table td[align="right"] {
text-align: right; }
.reveal table tr:last-child td {
border-bottom: none; }
.reveal sup {
vertical-align: super; }
.reveal sub {
vertical-align: sub; }
.reveal small {
display: inline-block;
font-size: 0.6em;
line-height: 1.2em;
vertical-align: top; }
.reveal small * {
vertical-align: top; }
/*********************************************
* LINKS
*********************************************/
.reveal a {
color: #2a76dd;
text-decoration: none;
-webkit-transition: color 0.15s ease;
-moz-transition: color 0.15s ease;
transition: color 0.15s ease; }
.reveal a:hover {
color: #6ca2e8;
text-shadow: none;
border: none; }
.reveal .roll span:after {
color: #fff;
background: #1a54a1; }
/*********************************************
* IMAGES
*********************************************/
.reveal section img {
margin: 15px 0px;
background: rgba(255, 255, 255, 0.12);
border: 4px solid #222;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
.reveal a img {
-webkit-transition: all 0.15s linear;
-moz-transition: all 0.15s linear;
transition: all 0.15s linear; }
.reveal a:hover img {
background: rgba(255, 255, 255, 0.2);
border-color: #2a76dd;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
/*********************************************
* NAVIGATION CONTROLS
*********************************************/
.reveal .controls div.navigate-left, .reveal .controls div.navigate-left.enabled {
border-right-color: #2a76dd; }
.reveal .controls div.navigate-right, .reveal .controls div.navigate-right.enabled {
border-left-color: #2a76dd; }
.reveal .controls div.navigate-up, .reveal .controls div.navigate-up.enabled {
border-bottom-color: #2a76dd; }
.reveal .controls div.navigate-down, .reveal .controls div.navigate-down.enabled {
border-top-color: #2a76dd; }
.reveal .controls div.navigate-left.enabled:hover {
border-right-color: #6ca2e8; }
.reveal .controls div.navigate-right.enabled:hover {
border-left-color: #6ca2e8; }
.reveal .controls div.navigate-up.enabled:hover {
border-bottom-color: #6ca2e8; }
.reveal .controls div.navigate-down.enabled:hover {
border-top-color: #6ca2e8; }
/*********************************************
* PROGRESS BAR
*********************************************/
.reveal .progress {
background: rgba(0, 0, 0, 0.2); }
.reveal .progress span {
background: #2a76dd;
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
/*********************************************
* SLIDE NUMBER
*********************************************/
.reveal .slide-number {
color: #2a76dd; }
@@ -1,411 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reveal.js - The HTML Presentation Framework</title>
<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
<meta name="author" content="Hakim El Hattab">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/black.css" id="theme">
<!-- Code syntax highlighting -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<!--[if lt IE 9]>
<script src="lib/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="reveal">
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<section>
<h1>Reveal.js</h1>
<h3>The HTML Presentation Framework</h3>
<p>
<small>Created by <a href="http://hakim.se">Hakim El Hattab</a> / <a href="http://twitter.com/hakimel">@hakimel</a></small>
</p>
</section>
<section>
<h2>Hello There</h2>
<p>
reveal.js enables you to create beautiful interactive slide decks using HTML. This presentation will show you examples of what it can do.
</p>
</section>
<!-- Example of nested vertical slides -->
<section>
<section>
<h2>Vertical Slides</h2>
<p>Slides can be nested inside of each other.</p>
<p>Use the <em>Space</em> key to navigate through all slides.</p>
<br>
<a href="#" class="navigate-down">
<img width="178" height="238" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
</a>
</section>
<section>
<h2>Basement Level 1</h2>
<p>Nested slides are useful for adding additional detail underneath a high level horizontal slide.</p>
</section>
<section>
<h2>Basement Level 2</h2>
<p>That's it, time to go back up.</p>
<br>
<a href="#/2">
<img width="178" height="238" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Up arrow" style="transform: rotate(180deg); -webkit-transform: rotate(180deg);">
</a>
</section>
</section>
<section>
<h2>Slides</h2>
<p>
Not a coder? Not a problem. There's a fully-featured visual editor for authoring these, try it out at <a href="http://slides.com" target="_blank">http://slides.com</a>.
</p>
</section>
<section>
<h2>Point of View</h2>
<p>
Press <strong>ESC</strong> to enter the slide overview.
</p>
<p>
Hold down alt and click on any element to zoom in on it using <a href="http://lab.hakim.se/zoom-js">zoom.js</a>. Alt + click anywhere to zoom back out.
</p>
</section>
<section>
<h2>Touch Optimized</h2>
<p>
Presentations look great on touch devices, like mobile phones and tablets. Simply swipe through your slides.
</p>
</section>
<section data-markdown>
<script type="text/template">
## Markdown support
Write content using inline or external Markdown.
Instructions and more info available in the [readme](https://github.com/hakimel/reveal.js#markdown).
```
<section data-markdown>
## Markdown support
Write content using inline or external Markdown.
Instructions and more info available in the [readme](https://github.com/hakimel/reveal.js#markdown).
</section>
```
</script>
</section>
<section>
<section id="fragments">
<h2>Fragments</h2>
<p>Hit the next arrow...</p>
<p class="fragment">... to step through ...</p>
<p><span class="fragment">... a</span> <span class="fragment">fragmented</span> <span class="fragment">slide.</span></p>
<aside class="notes">
This slide has fragments which are also stepped through in the notes window.
</aside>
</section>
<section>
<h2>Fragment Styles</h2>
<p>There's different types of fragments, like:</p>
<p class="fragment grow">grow</p>
<p class="fragment shrink">shrink</p>
<p class="fragment fade-out">fade-out</p>
<p class="fragment current-visible">current-visible</p>
<p class="fragment highlight-red">highlight-red</p>
<p class="fragment highlight-blue">highlight-blue</p>
</section>
</section>
<section id="transitions">
<h2>Transition Styles</h2>
<p>
You can select from different transitions, like: <br>
<a href="?transition=none#/transitions">None</a> -
<a href="?transition=fade#/transitions">Fade</a> -
<a href="?transition=slide#/transitions">Slide</a> -
<a href="?transition=convex#/transitions">Convex</a> -
<a href="?transition=concave#/transitions">Concave</a> -
<a href="?transition=zoom#/transitions">Zoom</a>
</p>
</section>
<section id="themes">
<h2>Themes</h2>
<p>
reveal.js comes with a few themes built in: <br>
<!-- Hacks to swap themes after the page has loaded. Not flexible and only intended for the reveal.js demo deck. -->
<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/black.css'); return false;">Black (default)</a> -
<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/white.css'); return false;">White</a> -
<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/league.css'); return false;">League</a> -
<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/sky.css'); return false;">Sky</a> -
<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/beige.css'); return false;">Beige</a> -
<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/simple.css'); return false;">Simple</a> <br>
<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/serif.css'); return false;">Serif</a> -
<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/blood.css'); return false;">Blood</a> -
<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/night.css'); return false;">Night</a> -
<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/moon.css'); return false;">Moon</a> -
<a href="#" onclick="document.getElementById('theme').setAttribute('href','css/theme/solarized.css'); return false;">Solarized</a>
</p>
</section>
<section>
<section data-background="#dddddd">
<h2>Slide Backgrounds</h2>
<p>
Set <code>data-background="#dddddd"</code> on a slide to change the background color. All CSS color formats are supported.
</p>
<a href="#" class="navigate-down">
<img width="178" height="238" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
</a>
</section>
<section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/image-placeholder.png">
<h2>Image Backgrounds</h2>
<pre><code>&lt;section data-background="image.png"&gt;</code></pre>
</section>
<section data-background="https://s3.amazonaws.com/hakim-static/reveal-js/image-placeholder.png" data-background-repeat="repeat" data-background-size="100px">
<h2>Tiled Backgrounds</h2>
<pre><code style="word-wrap: break-word;">&lt;section data-background="image.png" data-background-repeat="repeat" data-background-size="100px"&gt;</code></pre>
</section>
<section data-background-video="https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.mp4,https://s3.amazonaws.com/static.slid.es/site/homepage/v1/homepage-video-editor.webm" data-background-color="#000000">
<div style="background-color: rgba(0, 0, 0, 0.9); color: #fff; padding: 20px;">
<h2>Video Backgrounds</h2>
<pre><code style="word-wrap: break-word;">&lt;section data-background-video="video.mp4,video.webm"&gt;</code></pre>
</div>
</section>
<section data-background="http://i.giphy.com/90F8aUepslB84.gif">
<h2>... and GIFs!</h2>
</section>
</section>
<section data-transition="slide" data-background="#4d7e65" data-background-transition="zoom">
<h2>Background Transitions</h2>
<p>
Different background transitions are available via the backgroundTransition option. This one's called "zoom".
</p>
<pre><code>Reveal.configure({ backgroundTransition: 'zoom' })</code></pre>
</section>
<section data-transition="slide" data-background="#b5533c" data-background-transition="zoom">
<h2>Background Transitions</h2>
<p>
You can override background transitions per-slide.
</p>
<pre><code style="word-wrap: break-word;">&lt;section data-background-transition="zoom"&gt;</code></pre>
</section>
<section>
<h2>Pretty Code</h2>
<pre><code data-trim contenteditable>
function linkify( selector ) {
if( supports3DTransforms ) {
var nodes = document.querySelectorAll( selector );
for( var i = 0, len = nodes.length; i &lt; len; i++ ) {
var node = nodes[i];
if( !node.className ) {
node.className += ' roll';
}
}
}
}
</code></pre>
<p>Code syntax highlighting courtesy of <a href="http://softwaremaniacs.org/soft/highlight/en/description/">highlight.js</a>.</p>
</section>
<section>
<h2>Marvelous List</h2>
<ul>
<li>No order here</li>
<li>Or here</li>
<li>Or here</li>
<li>Or here</li>
</ul>
</section>
<section>
<h2>Fantastic Ordered List</h2>
<ol>
<li>One is smaller than...</li>
<li>Two is smaller than...</li>
<li>Three!</li>
</ol>
</section>
<section>
<h2>Tabular Tables</h2>
<table>
<thead>
<tr>
<th>Item</th>
<th>Value</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr>
<td>Apples</td>
<td>$1</td>
<td>7</td>
</tr>
<tr>
<td>Lemonade</td>
<td>$2</td>
<td>18</td>
</tr>
<tr>
<td>Bread</td>
<td>$3</td>
<td>2</td>
</tr>
</tbody>
</table>
</section>
<section>
<h2>Clever Quotes</h2>
<p>
These guys come in two forms, inline: <q cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">
&ldquo;The nice thing about standards is that there are so many to choose from&rdquo;</q> and block:
</p>
<blockquote cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">
&ldquo;For years there has been a theory that millions of monkeys typing at random on millions of typewriters would
reproduce the entire works of Shakespeare. The Internet has proven this theory to be untrue.&rdquo;
</blockquote>
</section>
<section>
<h2>Intergalactic Interconnections</h2>
<p>
You can link between slides internally,
<a href="#/2/3">like this</a>.
</p>
</section>
<section>
<h2>Speaker View</h2>
<p>There's a <a href="https://github.com/hakimel/reveal.js#speaker-notes">speaker view</a>. It includes a timer, preview of the upcoming slide as well as your speaker notes.</p>
<p>Press the <em>S</em> key to try it out.</p>
<aside class="notes">
Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
</aside>
</section>
<section>
<h2>Export to PDF</h2>
<p>Presentations can be <a href="https://github.com/hakimel/reveal.js#pdf-export">exported to PDF</a>, here's an example:</p>
<iframe src="//www.slideshare.net/slideshow/embed_code/42840540" width="445" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:3px solid #666; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe>
</section>
<section>
<h2>Global State</h2>
<p>
Set <code>data-state="something"</code> on a slide and <code>"something"</code>
will be added as a class to the document element when the slide is open. This lets you
apply broader style changes, like switching the page background.
</p>
</section>
<section data-state="customevent">
<h2>State Events</h2>
<p>
Additionally custom events can be triggered on a per slide basis by binding to the <code>data-state</code> name.
</p>
<pre><code class="javascript" data-trim contenteditable style="font-size: 18px;">
Reveal.addEventListener( 'customevent', function() {
console.log( '"customevent" has fired' );
} );
</code></pre>
</section>
<section>
<h2>Take a Moment</h2>
<p>
Press B or . on your keyboard to pause the presentation. This is helpful when you're on stage and want to take distracting slides off the screen.
</p>
</section>
<section>
<h2>Much more</h2>
<ul>
<li>Right-to-left support</li>
<li><a href="https://github.com/hakimel/reveal.js#api">Extensive JavaScript API</a></li>
<li><a href="https://github.com/hakimel/reveal.js#auto-sliding">Auto-progression</a></li>
<li><a href="https://github.com/hakimel/reveal.js#parallax-background">Parallax backgrounds</a></li>
<li><a href="https://github.com/hakimel/reveal.js#keyboard-bindings">Custom keyboard bindings</a></li>
</ul>
</section>
<section style="text-align: left;">
<h1>THE END</h1>
<p>
- <a href="http://slides.com">Try the online editor</a> <br>
- <a href="https://github.com/hakimel/reveal.js">Source code &amp; documentation</a>
</p>
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
// Full list of configuration options available at:
// https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: true,
transition: 'slide', // none/fade/slide/convex/concave/zoom
// Optional reveal.js plugins
dependencies: [
{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/highlight/highlight.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
{ src: 'plugin/zoom-js/zoom.js', async: true },
{ src: 'plugin/notes/notes.js', async: true }
]
});
</script>
</body>
</html>
File diff suppressed because it is too large Load Diff
@@ -1,117 +0,0 @@
/*
Zenburn style from voldmar.ru (c) Vladimir Epifanov <voldmar@voldmar.ru>
based on dark.css by Ivan Sagalaev
*/
.hljs {
display: block; padding: 0.5em;
background: #3F3F3F;
color: #DCDCDC;
}
.hljs-keyword,
.hljs-tag,
.css .hljs-class,
.css .hljs-id,
.lisp .hljs-title,
.nginx .hljs-title,
.hljs-request,
.hljs-status,
.clojure .hljs-attribute {
color: #E3CEAB;
}
.django .hljs-template_tag,
.django .hljs-variable,
.django .hljs-filter .hljs-argument {
color: #DCDCDC;
}
.hljs-number,
.hljs-date {
color: #8CD0D3;
}
.dos .hljs-envvar,
.dos .hljs-stream,
.hljs-variable,
.apache .hljs-sqbracket {
color: #EFDCBC;
}
.dos .hljs-flow,
.diff .hljs-change,
.python .exception,
.python .hljs-built_in,
.hljs-literal,
.tex .hljs-special {
color: #EFEFAF;
}
.diff .hljs-chunk,
.hljs-subst {
color: #8F8F8F;
}
.dos .hljs-keyword,
.python .hljs-decorator,
.hljs-title,
.haskell .hljs-type,
.diff .hljs-header,
.ruby .hljs-class .hljs-parent,
.apache .hljs-tag,
.nginx .hljs-built_in,
.tex .hljs-command,
.hljs-prompt {
color: #efef8f;
}
.dos .hljs-winutils,
.ruby .hljs-symbol,
.ruby .hljs-symbol .hljs-string,
.ruby .hljs-string {
color: #DCA3A3;
}
.diff .hljs-deletion,
.hljs-string,
.hljs-tag .hljs-value,
.hljs-preprocessor,
.hljs-pragma,
.hljs-built_in,
.sql .hljs-aggregate,
.hljs-javadoc,
.smalltalk .hljs-class,
.smalltalk .hljs-localvars,
.smalltalk .hljs-array,
.css .hljs-rules .hljs-value,
.hljs-attr_selector,
.hljs-pseudo,
.apache .hljs-cbracket,
.tex .hljs-formula,
.coffeescript .hljs-attribute {
color: #CC9393;
}
.hljs-shebang,
.diff .hljs-addition,
.hljs-comment,
.java .hljs-annotation,
.hljs-template_comment,
.hljs-pi,
.hljs-doctype {
color: #7F9F7F;
}
.coffeescript .javascript,
.javascript .xml,
.tex .hljs-formula,
.xml .javascript,
.xml .vbscript,
.xml .css,
.xml .hljs-cdata {
opacity: 0.5;
}
@@ -1,2 +0,0 @@
SIL Open Font License (OFL)
http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL
@@ -1,10 +0,0 @@
@font-face {
font-family: 'League Gothic';
src: url('league-gothic.eot');
src: url('league-gothic.eot?#iefix') format('embedded-opentype'),
url('league-gothic.woff') format('woff'),
url('league-gothic.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@@ -1,45 +0,0 @@
SIL Open Font License
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name Source. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
—————————————————————————————-
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
—————————————————————————————-
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
DEFINITIONS
“Font Software” refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
“Reserved Font Name” refers to any names specified as such after the copyright statement(s).
“Original Version” refers to the collection of Font Software components as distributed by the Copyright Holder(s).
“Modified Version” refers to any derivative made by adding to, deleting, or substituting—in part or in whole—any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
“Author” refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE.
@@ -1,39 +0,0 @@
@font-face {
font-family: 'Source Sans Pro';
src: url('source-sans-pro-regular.eot');
src: url('source-sans-pro-regular.eot?#iefix') format('embedded-opentype'),
url('source-sans-pro-regular.woff') format('woff'),
url('source-sans-pro-regular.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@font-face {
font-family: 'Source Sans Pro';
src: url('source-sans-pro-italic.eot');
src: url('source-sans-pro-italic.eot?#iefix') format('embedded-opentype'),
url('source-sans-pro-italic.woff') format('woff'),
url('source-sans-pro-italic.ttf') format('truetype');
font-weight: normal;
font-style: italic;
}
@font-face {
font-family: 'Source Sans Pro';
src: url('source-sans-pro-semibold.eot');
src: url('source-sans-pro-semibold.eot?#iefix') format('embedded-opentype'),
url('source-sans-pro-semibold.woff') format('woff'),
url('source-sans-pro-semibold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'Source Sans Pro';
src: url('source-sans-pro-semibolditalic.eot');
src: url('source-sans-pro-semibolditalic.eot?#iefix') format('embedded-opentype'),
url('source-sans-pro-semibolditalic.woff') format('woff'),
url('source-sans-pro-semibolditalic.ttf') format('truetype');
font-weight: 600;
font-style: italic;
}
@@ -1,2 +0,0 @@
/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
if(typeof document!=="undefined"&&!("classList" in document.createElement("a"))){(function(j){var a="classList",f="prototype",m=(j.HTMLElement||j.Element)[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p<o;p++){if(p in this&&this[p]===q){return p}}return -1},n=function(o,p){this.name=o;this.code=DOMException[o];this.message=p},g=function(p,o){if(o===""){throw new n("SYNTAX_ERR","An invalid or illegal string was specified")}if(/\s/.test(o)){throw new n("INVALID_CHARACTER_ERR","String contains an invalid character")}return c.call(p,o)},d=function(s){var r=k.call(s.className),q=r?r.split(/\s+/):[],p=0,o=q.length;for(;p<o;p++){this.push(q[p])}this._updateClassName=function(){s.className=this.toString()}},e=d[f]=[],i=function(){return new d(this)};n[f]=Error[f];e.item=function(o){return this[o]||null};e.contains=function(o){o+="";return g(this,o)!==-1};e.add=function(o){o+="";if(g(this,o)===-1){this.push(o);this._updateClassName()}};e.remove=function(p){p+="";var o=g(this,p);if(o!==-1){this.splice(o,1);this._updateClassName()}};e.toggle=function(o){o+="";if(g(this,o)===-1){this.add(o)}else{this.remove(o)}};e.toString=function(){return this.join(" ")};if(b.defineProperty){var l={get:i,enumerable:true,configurable:true};try{b.defineProperty(m,a,l)}catch(h){if(h.number===-2146823252){l.enumerable=false;b.defineProperty(m,a,l)}}}else{if(b[f].__defineGetter__){m.__defineGetter__(a,i)}}}(self))};
@@ -1,8 +0,0 @@
/**
Head JS The only script in your <HEAD>
Copyright Tero Piirainen (tipiirai)
License MIT / http://bit.ly/mit-license
Version 0.96
http://headjs.com
*/(function(a){function z(){d||(d=!0,s(e,function(a){p(a)}))}function y(c,d){var e=a.createElement("script");e.type="text/"+(c.type||"javascript"),e.src=c.src||c,e.async=!1,e.onreadystatechange=e.onload=function(){var a=e.readyState;!d.done&&(!a||/loaded|complete/.test(a))&&(d.done=!0,d())},(a.body||b).appendChild(e)}function x(a,b){if(a.state==o)return b&&b();if(a.state==n)return k.ready(a.name,b);if(a.state==m)return a.onpreload.push(function(){x(a,b)});a.state=n,y(a.url,function(){a.state=o,b&&b(),s(g[a.name],function(a){p(a)}),u()&&d&&s(g.ALL,function(a){p(a)})})}function w(a,b){a.state===undefined&&(a.state=m,a.onpreload=[],y({src:a.url,type:"cache"},function(){v(a)}))}function v(a){a.state=l,s(a.onpreload,function(a){a.call()})}function u(a){a=a||h;var b;for(var c in a){if(a.hasOwnProperty(c)&&a[c].state!=o)return!1;b=!0}return b}function t(a){return Object.prototype.toString.call(a)=="[object Function]"}function s(a,b){if(!!a){typeof a=="object"&&(a=[].slice.call(a));for(var c=0;c<a.length;c++)b.call(a,a[c],c)}}function r(a){var b;if(typeof a=="object")for(var c in a)a[c]&&(b={name:c,url:a[c]});else b={name:q(a),url:a};var d=h[b.name];if(d&&d.url===b.url)return d;h[b.name]=b;return b}function q(a){var b=a.split("/"),c=b[b.length-1],d=c.indexOf("?");return d!=-1?c.substring(0,d):c}function p(a){a._done||(a(),a._done=1)}var b=a.documentElement,c,d,e=[],f=[],g={},h={},i=a.createElement("script").async===!0||"MozAppearance"in a.documentElement.style||window.opera,j=window.head_conf&&head_conf.head||"head",k=window[j]=window[j]||function(){k.ready.apply(null,arguments)},l=1,m=2,n=3,o=4;i?k.js=function(){var a=arguments,b=a[a.length-1],c={};t(b)||(b=null),s(a,function(d,e){d!=b&&(d=r(d),c[d.name]=d,x(d,b&&e==a.length-2?function(){u(c)&&p(b)}:null))});return k}:k.js=function(){var a=arguments,b=[].slice.call(a,1),d=b[0];if(!c){f.push(function(){k.js.apply(null,a)});return k}d?(s(b,function(a){t(a)||w(r(a))}),x(r(a[0]),t(d)?d:function(){k.js.apply(null,b)})):x(r(a[0]));return k},k.ready=function(b,c){if(b==a){d?p(c):e.push(c);return k}t(b)&&(c=b,b="ALL");if(typeof b!="string"||!t(c))return k;var f=h[b];if(f&&f.state==o||b=="ALL"&&u()&&d){p(c);return k}var i=g[b];i?i.push(c):i=g[b]=[c];return k},k.ready(a,function(){u()&&s(g.ALL,function(a){p(a)}),k.feature&&k.feature("domloaded",!0)});if(window.addEventListener)a.addEventListener("DOMContentLoaded",z,!1),window.addEventListener("load",z,!1);else if(window.attachEvent){a.attachEvent("onreadystatechange",function(){a.readyState==="complete"&&z()});var A=1;try{A=window.frameElement}catch(B){}!A&&b.doScroll&&function(){try{b.doScroll("left"),z()}catch(a){setTimeout(arguments.callee,1);return}}(),window.attachEvent("onload",z)}!a.readyState&&a.addEventListener&&(a.readyState="loading",a.addEventListener("DOMContentLoaded",handler=function(){a.removeEventListener("DOMContentLoaded",handler,!1),a.readyState="complete"},!1)),setTimeout(function(){c=!0,s(f,function(a){a()})},300)})(document)
@@ -1,7 +0,0 @@
document.createElement('header');
document.createElement('nav');
document.createElement('section');
document.createElement('article');
document.createElement('aside');
document.createElement('footer');
document.createElement('hgroup');
@@ -1,45 +0,0 @@
{
"name": "reveal.js",
"version": "3.1.0",
"description": "The HTML Presentation Framework",
"homepage": "http://lab.hakim.se/reveal-js",
"subdomain": "revealjs",
"main": "js/reveal.js",
"scripts": {
"test": "grunt test",
"start": "grunt serve"
},
"author": {
"name": "Hakim El Hattab",
"email": "hakim.elhattab@gmail.com",
"web": "http://hakim.se"
},
"repository": {
"type": "git",
"url": "git://github.com/hakimel/reveal.js.git"
},
"engines": {
"node": "~0.10.0"
},
"dependencies": {
"underscore": "~1.5.1",
"express": "~2.5.9",
"mustache": "~0.7.2",
"socket.io": "~0.9.16"
},
"devDependencies": {
"grunt-contrib-qunit": "~0.5.2",
"grunt-contrib-jshint": "~0.6.4",
"grunt-contrib-cssmin": "~0.12.2",
"grunt-contrib-uglify": "~0.2.4",
"grunt-contrib-watch": "~0.5.3",
"grunt-sass": "~0.14.0",
"grunt-contrib-connect": "~0.8.0",
"grunt-autoprefixer": "~1.0.1",
"grunt-zip": "~0.7.0",
"grunt": "~0.4.0",
"node-sass": "~0.9.3"
},
"license": "MIT"
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,129 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reveal.js - Markdown Demo</title>
<link rel="stylesheet" href="../../css/reveal.css">
<link rel="stylesheet" href="../../css/theme/white.css" id="theme">
<link rel="stylesheet" href="../../lib/css/zenburn.css">
</head>
<body>
<div class="reveal">
<div class="slides">
<!-- Use external markdown resource, separate slides by three newlines; vertical slides by two newlines -->
<section data-markdown="example.md" data-separator="^\n\n\n" data-separator-vertical="^\n\n"></section>
<!-- Slides are separated by three dashes (quick 'n dirty regular expression) -->
<section data-markdown data-separator="---">
<script type="text/template">
## Demo 1
Slide 1
---
## Demo 1
Slide 2
---
## Demo 1
Slide 3
</script>
</section>
<!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
<section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$">
<script type="text/template">
## Demo 2
Slide 1.1
--
## Demo 2
Slide 1.2
---
## Demo 2
Slide 2
</script>
</section>
<!-- No "extra" slides, since there are no separators defined (so they'll become horizontal rulers) -->
<section data-markdown>
<script type="text/template">
A
---
B
---
C
</script>
</section>
<!-- Slide attributes -->
<section data-markdown>
<script type="text/template">
<!-- .slide: data-background="#000000" -->
## Slide attributes
</script>
</section>
<!-- Element attributes -->
<section data-markdown>
<script type="text/template">
## Element attributes
- Item 1 <!-- .element: class="fragment" data-fragment-index="2" -->
- Item 2 <!-- .element: class="fragment" data-fragment-index="1" -->
</script>
</section>
<!-- Code -->
<section data-markdown>
<script type="text/template">
```php
public function foo()
{
$foo = array(
'bar' => 'bar'
)
}
```
</script>
</section>
</div>
</div>
<script src="../../lib/js/head.min.js"></script>
<script src="../../js/reveal.js"></script>
<script>
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: true,
// Optional libraries used to extend on reveal.js
dependencies: [
{ src: '../../lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: '../highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
{ src: '../notes/notes.js' }
]
});
</script>
</body>
</html>
@@ -1,31 +0,0 @@
# Markdown Demo
## External 1.1
Content 1.1
Note: This will only appear in the speaker notes window.
## External 1.2
Content 1.2
## External 2
Content 2.1
## External 3.1
Content 3.1
## External 3.2
Content 3.2
@@ -1,393 +0,0 @@
/**
* The reveal.js markdown plugin. Handles parsing of
* markdown inside of presentations as well as loading
* of external markdown documents.
*/
(function( root, factory ) {
if( typeof exports === 'object' ) {
module.exports = factory( require( './marked' ) );
}
else {
// Browser globals (root is window)
root.RevealMarkdown = factory( root.marked );
root.RevealMarkdown.initialize();
}
}( this, function( marked ) {
if( typeof marked === 'undefined' ) {
throw 'The reveal.js Markdown plugin requires marked to be loaded';
}
if( typeof hljs !== 'undefined' ) {
marked.setOptions({
highlight: function( lang, code ) {
return hljs.highlightAuto( lang, code ).value;
}
});
}
var DEFAULT_SLIDE_SEPARATOR = '^\r?\n---\r?\n$',
DEFAULT_NOTES_SEPARATOR = 'note:',
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
/**
* Retrieves the markdown contents of a slide section
* element. Normalizes leading tabs/whitespace.
*/
function getMarkdownFromSlide( section ) {
var template = section.querySelector( 'script' );
// strip leading whitespace so it isn't evaluated as code
var text = ( template || section ).textContent;
var leadingWs = text.match( /^\n?(\s*)/ )[1].length,
leadingTabs = text.match( /^\n?(\t*)/ )[1].length;
if( leadingTabs > 0 ) {
text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
}
else if( leadingWs > 1 ) {
text = text.replace( new RegExp('\\n? {' + leadingWs + '}', 'g'), '\n' );
}
return text;
}
/**
* Given a markdown slide section element, this will
* return all arguments that aren't related to markdown
* parsing. Used to forward any other user-defined arguments
* to the output markdown slide.
*/
function getForwardedAttributes( section ) {
var attributes = section.attributes;
var result = [];
for( var i = 0, len = attributes.length; i < len; i++ ) {
var name = attributes[i].name,
value = attributes[i].value;
// disregard attributes that are used for markdown loading/parsing
if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
if( value ) {
result.push( name + '="' + value + '"' );
}
else {
result.push( name );
}
}
return result.join( ' ' );
}
/**
* Inspects the given options and fills out default
* values for what's not defined.
*/
function getSlidifyOptions( options ) {
options = options || {};
options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
options.attributes = options.attributes || '';
return options;
}
/**
* Helper function for constructing a markdown slide.
*/
function createMarkdownSlide( content, options ) {
options = getSlidifyOptions( options );
var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
if( notesMatch.length === 2 ) {
content = notesMatch[0] + '<aside class="notes" data-markdown>' + notesMatch[1].trim() + '</aside>';
}
return '<script type="text/template">' + content + '</script>';
}
/**
* Parses a data string into multiple slides based
* on the passed in separator arguments.
*/
function slidify( markdown, options ) {
options = getSlidifyOptions( options );
var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
horizontalSeparatorRegex = new RegExp( options.separator );
var matches,
lastIndex = 0,
isHorizontal,
wasHorizontal = true,
content,
sectionStack = [];
// iterate until all blocks between separators are stacked up
while( matches = separatorRegex.exec( markdown ) ) {
notes = null;
// determine direction (horizontal by default)
isHorizontal = horizontalSeparatorRegex.test( matches[0] );
if( !isHorizontal && wasHorizontal ) {
// create vertical stack
sectionStack.push( [] );
}
// pluck slide content from markdown input
content = markdown.substring( lastIndex, matches.index );
if( isHorizontal && wasHorizontal ) {
// add to horizontal stack
sectionStack.push( content );
}
else {
// add to vertical stack
sectionStack[sectionStack.length-1].push( content );
}
lastIndex = separatorRegex.lastIndex;
wasHorizontal = isHorizontal;
}
// add the remaining slide
( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
var markdownSections = '';
// flatten the hierarchical stack, and insert <section data-markdown> tags
for( var i = 0, len = sectionStack.length; i < len; i++ ) {
// vertical
if( sectionStack[i] instanceof Array ) {
markdownSections += '<section '+ options.attributes +'>';
sectionStack[i].forEach( function( child ) {
markdownSections += '<section data-markdown>' + createMarkdownSlide( child, options ) + '</section>';
} );
markdownSections += '</section>';
}
else {
markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
}
}
return markdownSections;
}
/**
* Parses any current data-markdown slides, splits
* multi-slide markdown into separate sections and
* handles loading of external markdown.
*/
function processSlides() {
var sections = document.querySelectorAll( '[data-markdown]'),
section;
for( var i = 0, len = sections.length; i < len; i++ ) {
section = sections[i];
if( section.getAttribute( 'data-markdown' ).length ) {
var xhr = new XMLHttpRequest(),
url = section.getAttribute( 'data-markdown' );
datacharset = section.getAttribute( 'data-charset' );
// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
if( datacharset != null && datacharset != '' ) {
xhr.overrideMimeType( 'text/html; charset=' + datacharset );
}
xhr.onreadystatechange = function() {
if( xhr.readyState === 4 ) {
// file protocol yields status code 0 (useful for local debug, mobile applications etc.)
if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) {
section.outerHTML = slidify( xhr.responseText, {
separator: section.getAttribute( 'data-separator' ),
verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
notesSeparator: section.getAttribute( 'data-separator-notes' ),
attributes: getForwardedAttributes( section )
});
}
else {
section.outerHTML = '<section data-state="alert">' +
'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
'Check your browser\'s JavaScript console for more details.' +
'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' +
'</section>';
}
}
};
xhr.open( 'GET', url, false );
try {
xhr.send();
}
catch ( e ) {
alert( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
}
}
else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) {
section.outerHTML = slidify( getMarkdownFromSlide( section ), {
separator: section.getAttribute( 'data-separator' ),
verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
notesSeparator: section.getAttribute( 'data-separator-notes' ),
attributes: getForwardedAttributes( section )
});
}
else {
section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
}
}
}
/**
* Check if a node value has the attributes pattern.
* If yes, extract it and add that value as one or several attributes
* the the terget element.
*
* You need Cache Killer on Chrome to see the effect on any FOM transformation
* directly on refresh (F5)
* http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
*/
function addAttributeInElement( node, elementTarget, separator ) {
var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"=]+?)\"", 'mg' );
var nodeValue = node.nodeValue;
if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
var classes = matches[1];
nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
node.nodeValue = nodeValue;
while( matchesClass = mardownClassRegex.exec( classes ) ) {
elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
}
return true;
}
return false;
}
/**
* Add attributes to the parent element of a text node,
* or the element of an attribute node.
*/
function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
previousParentElement = element;
for( var i = 0; i < element.childNodes.length; i++ ) {
childElement = element.childNodes[i];
if ( i > 0 ) {
j = i - 1;
while ( j >= 0 ) {
aPreviousChildElement = element.childNodes[j];
if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
previousParentElement = aPreviousChildElement;
break;
}
j = j - 1;
}
}
parentSection = section;
if( childElement.nodeName == "section" ) {
parentSection = childElement ;
previousParentElement = childElement ;
}
if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
}
}
}
if ( element.nodeType == Node.COMMENT_NODE ) {
if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
addAttributeInElement( element, section, separatorSectionAttributes );
}
}
}
/**
* Converts any current data-markdown slides in the
* DOM to HTML.
*/
function convertSlides() {
var sections = document.querySelectorAll( '[data-markdown]');
for( var i = 0, len = sections.length; i < len; i++ ) {
var section = sections[i];
// Only parse the same slide once
if( !section.getAttribute( 'data-markdown-parsed' ) ) {
section.setAttribute( 'data-markdown-parsed', true )
var notes = section.querySelector( 'aside.notes' );
var markdown = getMarkdownFromSlide( section );
section.innerHTML = marked( markdown );
addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) ||
section.parentNode.getAttribute( 'data-element-attributes' ) ||
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
section.getAttribute( 'data-attributes' ) ||
section.parentNode.getAttribute( 'data-attributes' ) ||
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
// If there were notes, we need to re-add them after
// having overwritten the section's HTML
if( notes ) {
section.appendChild( notes );
}
}
}
}
// API
return {
initialize: function() {
processSlides();
convertSlides();
},
// TODO: Do these belong in the API?
processSlides: processSlides,
convertSlides: convertSlides,
slidify: slidify
};
}));
File diff suppressed because one or more lines are too long
@@ -1,64 +0,0 @@
/**
* A plugin which enables rendering of math equations inside
* of reveal.js slides. Essentially a thin wrapper for MathJax.
*
* @author Hakim El Hattab
*/
var RevealMath = window.RevealMath || (function(){
var options = Reveal.getConfig().math || {};
options.mathjax = options.mathjax || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js';
options.config = options.config || 'TeX-AMS_HTML-full';
loadScript( options.mathjax + '?config=' + options.config, function() {
MathJax.Hub.Config({
messageStyle: 'none',
tex2jax: { inlineMath: [['$','$'],['\\(','\\)']] },
skipStartupTypeset: true
});
// Typeset followed by an immediate reveal.js layout since
// the typesetting process could affect slide height
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] );
MathJax.Hub.Queue( Reveal.layout );
// Reprocess equations in slides when they turn visible
Reveal.addEventListener( 'slidechanged', function( event ) {
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
} );
} );
function loadScript( url, callback ) {
var head = document.querySelector( 'head' );
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
// Wrapper for callback to make sure it only fires once
var finish = function() {
if( typeof callback === 'function' ) {
callback.call();
callback = null;
}
}
script.onload = finish;
// IE
script.onreadystatechange = function() {
if ( this.readyState === 'loaded' ) {
finish();
}
}
// Normal browsers
head.appendChild( script );
}
})();
@@ -1,13 +0,0 @@
(function() {
var multiplex = Reveal.getConfig().multiplex;
var socketId = multiplex.id;
var socket = io.connect(multiplex.url);
socket.on(multiplex.id, function(data) {
// ignore data from sockets that aren't ours
if (data.socketId !== socketId) { return; }
if( window.location.host === 'localhost:1947' ) return;
Reveal.slide(data.indexh, data.indexv, data.indexf, 'remote');
});
}());
@@ -1,56 +0,0 @@
var express = require('express');
var fs = require('fs');
var io = require('socket.io');
var crypto = require('crypto');
var app = express.createServer();
var staticDir = express.static;
io = io.listen(app);
var opts = {
port: process.env.PORT || 1948,
baseDir : __dirname + '/../../'
};
io.sockets.on('connection', function(socket) {
socket.on('slidechanged', function(slideData) {
if (typeof slideData.secret == 'undefined' || slideData.secret == null || slideData.secret === '') return;
if (createHash(slideData.secret) === slideData.socketId) {
slideData.secret = null;
socket.broadcast.emit(slideData.socketId, slideData);
};
});
});
app.configure(function() {
[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) {
app.use('/' + dir, staticDir(opts.baseDir + dir));
});
});
app.get("/", function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
});
app.get("/token", function(req,res) {
var ts = new Date().getTime();
var rand = Math.floor(Math.random()*9999999);
var secret = ts.toString() + rand.toString();
res.send({secret: secret, socketId: createHash(secret)});
});
var createHash = function(secret) {
var cipher = crypto.createCipher('blowfish', secret);
return(cipher.final('hex'));
};
// Actually listen
app.listen(opts.port || null);
var brown = '\033[33m',
green = '\033[32m',
reset = '\033[0m';
console.log( brown + "reveal.js:" + reset + " Multiplex running on port " + green + opts.port + reset );
@@ -1,51 +0,0 @@
(function() {
// Don't emit events from inside of notes windows
if ( window.location.search.match( /receiver/gi ) ) { return; }
var multiplex = Reveal.getConfig().multiplex;
var socket = io.connect(multiplex.url);
var notify = function( slideElement, indexh, indexv, origin ) {
if( typeof origin === 'undefined' && origin !== 'remote' ) {
var nextindexh;
var nextindexv;
var fragmentindex = Reveal.getIndices().f;
if (typeof fragmentindex == 'undefined') {
fragmentindex = 0;
}
if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
nextindexh = indexh;
nextindexv = indexv + 1;
} else {
nextindexh = indexh + 1;
nextindexv = 0;
}
var slideData = {
indexh : indexh,
indexv : indexv,
indexf : fragmentindex,
nextindexh : nextindexh,
nextindexv : nextindexv,
secret: multiplex.secret,
socketId : multiplex.id
};
socket.emit('slidechanged', slideData);
}
}
Reveal.addEventListener( 'slidechanged', function( event ) {
notify( event.currentSlide, event.indexh, event.indexv, event.origin );
} );
var fragmentNotify = function( event ) {
notify( Reveal.getCurrentSlide(), Reveal.getIndices().h, Reveal.getIndices().v, event.origin );
};
Reveal.addEventListener( 'fragmentshown', fragmentNotify );
Reveal.addEventListener( 'fragmenthidden', fragmentNotify );
}());

Some files were not shown because too many files have changed in this diff Show More