%% compilado con exporter=pdflatex weaver=sweave-ess
\documentclass{beamer} % símbolos menos ambiguos
\usefonttheme{serif}
\usepackage{neuralnetwork}
\usepackage[spanish]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{dsfont}               % para \mathds (double stroke)
\usepackage[cal=boondox]{mathalfa}% para "o" manuscrita
\newcommand{\oo}{{\mathcal o}}
\newcommand{\phio}{\phi_{\oo}}
\newcommand{\por}{\,}             % multiplicar
% \renewcommand{\v}[1]{{\vec #1}}
\renewcommand{\v}[1]{{\bf #1}}
\newcommand{\x}{\v x}
\newcommand{\w}{\v w}
\usepackage{Sweave}
\begin{document}
\title{Neuronas artificiales}
\author{Análisis de Datos}

\begin{frame} [fragile]
  \maketitle
\end{frame}
\section{Introducción}
\begin{frame} [fragile]
  \frametitle{Introducción}
  \begin{itemize}
  \item inspirado en las conexiones (sinapsis)\\ entre neuronas cerebrales
  \item aprendizaje supervisado: clasificación o regresión
  \item son modelos de regresión no lineal con muchos parámetros\\
    (caja negra: el ajuste no es constructivo)
  \item permiten extraer patrones de información no estructurada \\(textos, fotos...) pero
    % \url{https://techcrunch.com/2018/01/02/these-psychedelic-stickers-blow-ai-minds/}
    a veces alucinan
  \item tipos
    \begin{itemize}
    \item perceptrón multicapa ({\sc mlp})
    \item base radial ({\sc rbf})
    \item mapas autoorganizados ({\sc som}; no supervisado)
    \item convolucionales ({\sc cnn}) 
    \item recurrentes ({\sc rnn})
    \item adversativas ({\sc gan})
    \item trasformadores (p.ej. {\sc gpt})
    \item ...
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Índice}
  \begin{itemize}
  \item Clasificación
    \begin{itemize}
    \item Perceptrón simple
    \item Perceptrón multicapa (1 oculta)
    \end{itemize}
  \item Regresión
  \item Parámetros
  \item Recomendaciones
  \end{itemize}
\end{frame}

\section{Clasificación}
\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
  \begin{neuralnetwork}[height=5]
    \newcommand{\nodetextx}[2]{$\ifnum0=#2 \alpha \else x_{#2}\fi$}
    \newcommand{\nodetexty}[2]{$y_{#2}$}
    \inputlayer[count=4, bias=false, title=Capa de\\entrada, text=\nodetextx]
    \outputlayer[count=3, title=Capa de\\salida, text=\nodetexty] \linklayers
  \end{neuralnetwork}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
  \begin{neuralnetwork}[height=5]
    \newcommand{\nodetextx}[2]{$\ifnum0=#2 \alpha \else x_{#2}\fi$}
    \newcommand{\nodetexty}[2]{$y_{#2}$}
    \inputlayer[count=4, bias=true, title=Capa de\\entrada, text=\nodetextx]
    \outputlayer[count=3, title=Capa de\\salida, text=\nodetexty] \linklayers
  \end{neuralnetwork}
\end{frame}

\newcommand{\peso}[4]{\ensuremath{w_{#2k}}}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
  \begin{neuralnetwork}[height=5]
    \newcommand{\nodetextx}[2]{$\ifnum0=#2 \alpha_k \else x_{#2}\fi$}
    \newcommand{\nodetexty}[2]{$y_{k}$}
    \inputlayer[count=4, bias=true, title=Capa de\\entrada, text=\nodetextx]
    \outputlayer[count=1, title=Capa de\\salida, text=\nodetexty] %\linklayers
    \link[from layer=0, to layer=1, from node=0, to node=1]
    \link[from layer=0, to layer=1, from node=1, to node=1, label=\peso]
    \link[from layer=0, to layer=1, from node=2, to node=1, label=\peso]
    \link[from layer=0, to layer=1, from node=3, to node=1, label=\peso]
    \link[from layer=0, to layer=1, from node=4, to node=1, label=\peso]
  \end{neuralnetwork}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
  \begin{neuralnetwork}[height=5]
    \newcommand{\nodetextx}[2]{$\ifnum0=#2 1 \else x_{#2}\fi$}
    \newcommand{\nodetexty}[2]{$y_{k}$}
    \newcommand{\pesa}[4]{\ensuremath{\alpha_{k}}}
    \inputlayer[count=4, bias=true, title=Capa de\\entrada, text=\nodetextx]
    \outputlayer[count=1, title=Capa de\\salida, text=\nodetexty] %\linklayers
    \link[from layer=0, to layer=1, from node=0, to node=1, label=\pesa]
    \link[from layer=0, to layer=1, from node=1, to node=1, label=\peso]
    \link[from layer=0, to layer=1, from node=2, to node=1, label=\peso]
    \link[from layer=0, to layer=1, from node=3, to node=1, label=\peso]
    \link[from layer=0, to layer=1, from node=4, to node=1, label=\peso]
  \end{neuralnetwork}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
  \begin{neuralnetwork}[height=5]
    \newcommand{\nodetextx}[2]{$x_{#2}$}
    \newcommand{\nodetexty}[2]{$y_{k}$}
    \inputlayer[count=4, bias=true, title=Capa de\\entrada, text=\nodetextx]
    \outputlayer[count=1, title=Capa de\\salida, text=\nodetexty] %\linklayers
    \link[from layer=0, to layer=1, from node=0, to node=1, label=\peso]
    \link[from layer=0, to layer=1, from node=1, to node=1, label=\peso]
    \link[from layer=0, to layer=1, from node=2, to node=1, label=\peso]
    \link[from layer=0, to layer=1, from node=3, to node=1, label=\peso]
    \link[from layer=0, to layer=1, from node=4, to node=1, label=\peso]
  \end{neuralnetwork}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
    \begin{itemize}
  \item \(x_i\) = variable de entrada (\(i=1,\dots,I\))
  \item \(y_k\) = variable de salida (\(k=1,\dots,K\))
  \item \(\phi_\oo\) = función de activación en la capa de salida ({\em output\/})
  \item \(\alpha_k\) = constante, sesgo ({\em bias\/}) para la salida \(k\)
  \item \(w_{ik}\) = peso ({\em weight\/}), coeficiente de sinapsis entre \(x_i\) y \(y_k\)
    \[ y_k = \phio \left( \alpha_k + \sum_{i=1}^I w_{ik}\por x_i \right) = 
    \phio \left( \sum_{i=0}^I w_{ik}\por x_i \right) \]
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Perceptrón simple}

  Sean \(\x=(x_1,\dots,x_I)^\top \in \mathbb{R}^I\) y \(\x_1=(1,x_1,\dots,x_I)^\top\). \\Definimos el modelo como una familia
  de aplicaciones:
  \[
  f_\w : \mathbb{R}^I \to \mathbb{R}^K,
    \quad
  \v y=f_\w(\x)=g\left[\phi_\oo\left( \w_1^\top \x_1 \right),
    \dots,\phi_\oo\left( \w_K^\top \x_1 \right)\right]
\]
donde \(g\in\{\text{identidad},\text{softmax}\}\) \\[2ex]
Sean\quad\(\v t\)=\emph{target} (respuesta) \quad
\(\v y\)=predicción (salida)
\\[2ex]
Error o pérdida
\(  E(\w) = E\left[\v y, \v t\right]= E\left[f_\w(\x),\v t\right] \)
  
  \vspace{2mm}

  \begin{itemize}
  \item \(E\) es diferenciable si \(\phi\) lo es.
    \begin{itemize}
    \item esto permite calcular gradientes respecto a \(\x\) y a \(\w\)
    \item esencial para optimización mediante retropropagación
    \end{itemize}
  % \item La familia \(\{f_\theta\}\) es un subconjunto de
  %   \(C(\mathbb{R}^d)\).
  \item El entrenamiento consiste en resolver:
  \(\displaystyle
  \min_{\w \in \mathbb{R}^{I+1}} E(\w)%\qquad\text{con \(E\) función de error o pérdida}
  \)
  \end{itemize}

  \vspace{2mm}

  Interpretación: modelo no lineal en \(\x\), pero
  lineal en los parámetros antes de la activación.
\end{frame}

\begin{frame} [fragile,t]
   \frametitle{Perceptrón simple}

     \begin{itemize}
     \item lineal \[\phio(x) = x\]
       \only<1>{
\includegraphics{neuronas-woven-001}
         }
     \item<2-> logística 
       \[ \phio (x)=\ell(x) = \frac {\exp(x)} {1+\exp(x)} = \frac {1} {1+\exp(-x)} \]
       \only<2>{
\includegraphics{neuronas-woven-002}
         }
 \end{itemize}
\end{frame}

\begin{frame} [fragile,t]
  \frametitle{Perceptrón simple}
\begin{itemize}
   \item indicatriz, umbral, característica, Heaviside
       \[ \phio(x)= \mathds1_{[0,\infty)}(x) =
       \begin{cases}
         0&\text{si }x<0\\
         1&\text{si }x\geqslant0
       \end{cases}
     \]
     \only<1>{
\includegraphics{neuronas-woven-003}
}
%     
% % <<results=tex,echo=FALSE>>=
% % temporal <- "/tmp/temporal.pdf"
% % pdf(temporal,width=5,height=3)
% % par(mar=c(0,4,0,2)+.1)
% % plot(function(x)pmax(sign(x),0),-10,10,xlab="",ylab="",n=1000)
% % invisible(dev.off())
% % cat(paste0("\\includegraphics{",temporal,"}\n\n"))
% % @ 
% }
     \only<2->{
       \begin{itemize}
   \item no es derivable
   \item no es adecuada para optimización por gradiente
   \item se aproxima en la práctica por funciones suaves ; \\p.ej. mediante la logística :
 \[
 \ell_\beta(x)=\frac{1}{1+\exp(-\beta x)},\quad
 \ell_\beta(x)\to \mathds1_{[0,\infty)}(x)\ \text{cuando }\beta\to\infty
 \]
 \end{itemize}
 }
\end{itemize}
\end{frame}

% \begin{frame} [fragile,t]
%   \frametitle{Perceptrón simple}
%     \begin{itemize}
%     \item ReLU
%     \[
%     \phio(x)=\max\{0,x\}
%     \]
%     \begin{itemize}
%     \item continua, no derivable en \(0\)
%     \item muy usada en la práctica
%     \end{itemize}
% \end{itemize}\vspace{5mm}
% <<fig=TRUE,echo=FALSE,width=5,height=5>>=
% par(mar=c(12, 4, 0, 2) + 0.1)  # margen inferior grande (10 líneas)
% plot(function(x)pmax(x,0),-10,10,xlab="",ylab="",n=1000)
% @ 
% \end{frame}

% \begin{frame} [fragile]
%   \frametitle{Perceptrón simple}
% <<fig=TRUE,echo=FALSE>>=
% set.seed (3) # para que quepan las salidas
% data(mtcars) # porque lo modificamos después
% xx <- seq(-4,4,.1)
% plot (xx, xx, type="l", ylim=c(-2,2), lwd=2, xlab="", ylab="")
% lines (xx, 1/(1+exp(-xx)), col=2, lwd=2, lty=2)
% lines (xx, xx>=0, type="s", col=3, lwd=2, lty=1)
% lines (xx, pmax(xx,0), col=4, lwd=4, lty=2)
% legend ("bottomright", legend=c("lineal","logit","indicatriz","ReLU"), 
%         col=1:4, lwd=2, lty=1:2)
% @ 
% \end{frame}


% \begin{frame} [fragile]
%   \frametitle{Perceptrón simple}
% <<fig=TRUE,echo=FALSE>>=
% set.seed (3) # para que quepan las salidas
% data(mtcars) # porque lo modificamos después
% xx <- seq(-4,4,.1)
% plot (xx, xx, type="l", ylim=c(-2,2), lwd=2, xlab="", ylab="")
% lines (xx, 1/(1+exp(-10*xx)), col=2, lwd=2, lty=2)
% lines (xx, xx>=0, type="s", col=3, lwd=2, lty=1)
% lines (xx, pmax(xx,0), col=4, lwd=4, lty=2)
% legend ("bottomright", legend=c("lineal","logit(10x)","indicatriz","ReLU"), 
%         col=1:4, lwd=2, lty=1:2)
% @ 
% \end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple: ajuste}
  \begin{itemize}
  \item función de activación:
    \begin{itemize}
    \item para respuesta dicótoma, logística: \( \phi_\oo(x)= \frac {\exp(x)} {1+\exp(x)} \)
    \item para tres o más categorías, lineal: \(\phi_\oo(x)=x\) 
    \end{itemize}
  \item criterios de ajuste \\ 
    \(n=\text{instancia}\quad t=\text{respuesta}\in\{0;1\}
    \quad y=\text{predicción}\)
    \begin{itemize}
    \item para respuesta dicótoma: una neurona de salida, \(y\in[0;1]\)
      \[E=\sum_{n=1}^N\left[
        {t^{(n)}}\por\ln\frac{t^{(n)}}{y^{(n)}} +(1-t^{(n)})\por\ln\frac{1-t^{(n)}}{1-y^{(n)}}\right]\]
    \item para respuesta múltiple, \emph{softmax} (\(y\in\mathds R\))
      \[ E = \sum_n\sum_k-t^{(n)}_k\por\ln {\widehat\Pr}[t_n=k]\qquad
        {\widehat\Pr}[t_n=k]=\frac{\exp\bigl({y^{(n)}_k}\bigr)}{\sum_{c=1}^K \exp\bigl({y^{(n)}_c}\bigr)} \]
    \end{itemize}
  \end{itemize}
\end{frame}
\begin{frame}[fragile]
  \frametitle{Entropía, entropía cruzada y divergencia KL}
  
  \textbf{Entropía de Shannon}
  \begin{itemize}
    \item Distribución discreta sobre \(K\) clases:
  \(\displaystyle
  H(\v p) = -\sum_{k=1}^K p_k \ln p_k
  \)
  \item
  Mide la incertidumbre o la cantidad media de información.
\end{itemize}
\vspace{2mm}
  
  \textbf{\(H\) cruzada} entre \(\v p\) (real) y \(\v q\) (modelo):\\
  \hfill\(
  H(\v p,\v q) = -\sum_{k} p_k \ln q_k
  \)
  \begin{itemize}
  \item No es simétrica: \(H(\v p,\v q) \neq H(\v q,\v p)\).
  \item En aprendizaje supervisado, \(\v p\) es la distribución empírica (degenerada o \emph{one‑hot}\/: un 1 y el resto 0).
  \end{itemize}

  \vspace{2mm}
  
  \textbf{Divergencia de Kullback–Leibler} (o entropía relativa):

    \vspace{-2ex}
  \[
  D_{\rm KL}(\v p \| \v q) = \sum_{k} p_k \ln\frac{p_k}{q_k}
      = H(\v p,\v q) - H(\v p)
    \]

  \vspace{-2ex}
  \begin{itemize}
  \item Mide la “distancia” (no simétrica) entre dos distribuciones.
  \item \(D_{\rm KL}(\v p\|\v q)\ge 0\) y es cero si y solo si \(\v p=\v q\) (casi seguro).
  \end{itemize}
\end{frame}

\begin{frame}[fragile]
  \frametitle{Aplicación a los criterios de ajuste}
    \begin{itemize}
  \item El término \(H(\v t)\) es constante (depende sólo de los datos).
  \item Minimizar \(D_{\rm KL}\) equivale a minimizar \(H(\v t,\v y)\).
  \item \(H(\v t)=0\) si \(\v t\) es degenerada.
  \end{itemize}
\vspace{3ex}
  \textbf{Caso binario} (una salida logística \(y\), objetivo \(t\in\{0,1\}\)) :
  \[
  \begin{gathered}
  D_{\rm KL}\bigl((t,1-t)\,\|\,(y,1-y)\bigr)
  = t\ln\frac{t}{y} + (1-t)\ln\frac{1-t}{1-y} ={}\\
  {}= \underbrace{\bigl[-t\ln y -(1-t)\ln(1-y)\bigr]}_{H(\v t,\v y)} - \underbrace{\bigl[-t\ln t -(1-t)\ln(1-t)\bigr]}_{H(\v t)}
  \end{gathered}
  \]

  \textbf{Caso multiclase} (\(\v p\) = softmax(\(\v y\)), objetivo \(\v t\)):
  \[
  D_{\rm KL}(\mathbf{t}\|\mathbf{p}) = \sum_{k} t_k \ln\frac{t_k}{p_k}
%  = \underbrace{-\sum_{k} t_k \ln y_k}_{\text{entropía cruzada}} - H(\mathbf{t})
  = H(\v t,\v p) - H(\mathbf{t})
  \]\vspace{-2ex}
\end{frame}
\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
\begin{Schunk}
\begin{Sinput}
> ## para ahorrar espacio en esta presentación:
> options (width = 58)  
> names(iris)[1:4] <- c("Lsep","Asep","Lpet","Apet")
> library (nnet)   # biblioteca distribuida con R básico
> red <- nnet (Species ~ ., iris, size = 0, skip = TRUE)
\end{Sinput}
\begin{Soutput}
# weights:  15
initial  value 733.700647 
iter  10 value 31.866291
iter  20 value 6.864117
iter  30 value 6.052776
iter  40 value 5.957074
iter  50 value 5.951153
iter  60 value 5.949332
final  value 5.949330 
converged
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
\begin{Schunk}
\begin{Sinput}
> red
\end{Sinput}
\begin{Soutput}
a 4-0-3 network with 15 weights
inputs: Lsep Asep Lpet Apet 
output(s): Species 
options were - skip-layer connections  softmax modelling 
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
\begin{Schunk}
\begin{Sinput}
> summary (red)
\end{Sinput}
\begin{Soutput}
a 4-0-3 network with 15 weights
options were - skip-layer connections  softmax modelling 
 b->o1 i1->o1 i2->o1 i3->o1 i4->o1 
  6.16   6.23   4.19 -12.85  -9.84 
 b->o2 i1->o2 i2->o2 i3->o2 i4->o2 
 17.84  -2.50   1.26   2.05  -4.09 
 b->o3 i1->o3 i2->o3 i3->o3 i4->o3 
-24.80  -4.97  -5.42  11.48  14.20 
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
\begin{Schunk}
\begin{Sinput}
> names (red)
\end{Sinput}
\begin{Soutput}
 [1] "n"             "nunits"        "nconn"        
 [4] "conn"          "nsunits"       "decay"        
 [7] "entropy"       "softmax"       "censored"     
[10] "value"         "wts"           "convergence"  
[13] "fitted.values" "residuals"     "lev"          
[16] "call"          "terms"         "coefnames"    
[19] "xlevels"      
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
\begin{Schunk}
\begin{Sinput}
> red $ wts
\end{Sinput}
\begin{Soutput}
 [1]   6.163855   6.230980   4.193952 -12.853916
 [5]  -9.835551  17.836360  -2.502295   1.261397
 [9]   2.047186  -4.088112 -24.798713  -4.967447
[13]  -5.418728  11.476033  14.196443
\end{Soutput}
\begin{Sinput}
> head (red $ fitted.values)
\end{Sinput}
\begin{Soutput}
     setosa   versicolor    virginica
1 1.0000000 6.724377e-10 1.043378e-36
2 1.0000000 1.671133e-08 1.198096e-33
3 1.0000000 1.201458e-08 1.444082e-34
4 0.9999992 7.596998e-07 1.502031e-31
5 1.0000000 1.201086e-09 1.222672e-36
6 1.0000000 4.178565e-09 1.402248e-34
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
\begin{Schunk}
\begin{Sinput}
> tail (red $ fitted.values)
\end{Sinput}
\begin{Soutput}
          setosa   versicolor virginica
145 3.073995e-27 1.174533e-08 1.0000000
146 4.035095e-21 6.841385e-06 0.9999932
147 7.257596e-19 8.938795e-04 0.9991061
148 5.805305e-19 1.006592e-03 0.9989934
149 5.379827e-24 4.378460e-06 0.9999956
150 9.559532e-19 2.232494e-02 0.9776751
\end{Soutput}
\begin{Sinput}
> summary (apply (red $ fitted.values, 1, sum))
\end{Sinput}
\begin{Soutput}
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
      1       1       1       1       1       1 
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
\begin{Schunk}
\begin{Sinput}
> red $ value
\end{Sinput}
\begin{Soutput}
[1] 5.94933
\end{Soutput}
\begin{Sinput}
> indices.fila    <- 1 : nrow (iris)
> indices.columna <- match (iris$Species, 
+                           levels(iris$Species))
> indices <- cbind (indices.fila, indices.columna)
> - sum (log (red$fitted.values [indices]))
\end{Sinput}
\begin{Soutput}
[1] 5.94933
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
\begin{Schunk}
\begin{Sinput}
> aggregate (iris[,1:4], list(iris$Species), median)
\end{Sinput}
\begin{Soutput}
     Group.1 Lsep Asep Lpet Apet
1     setosa  5.0  3.4 1.50  0.2
2 versicolor  5.9  2.8 4.35  1.3
3  virginica  6.5  3.0 5.55  2.0
\end{Soutput}
\begin{Sinput}
> flor <- data.frame(Lsep=6,Asep=2.9,Lpet=5,Apet=1.7)
> predict (red, flor)
\end{Sinput}
\begin{Soutput}
        setosa versicolor virginica
1 1.164748e-16  0.1931563 0.8068437
\end{Soutput}
\begin{Sinput}
> predict (red, flor, type="class")
\end{Sinput}
\begin{Soutput}
[1] "virginica"
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
\begin{Schunk}
\begin{Sinput}
> predict (red, flor)
\end{Sinput}
\begin{Soutput}
        setosa versicolor virginica
1 1.164748e-16  0.1931563 0.8068437
\end{Soutput}
\begin{Sinput}
> summary (red)
\end{Sinput}
\begin{Soutput}
a 4-0-3 network with 15 weights
options were - skip-layer connections  softmax modelling 
 b->o1 i1->o1 i2->o1 i3->o1 i4->o1 
  6.16   6.23   4.19 -12.85  -9.84 
 b->o2 i1->o2 i2->o2 i3->o2 i4->o2 
 17.84  -2.50   1.26   2.05  -4.09 
 b->o3 i1->o3 i2->o3 i3->o3 i4->o3 
-24.80  -4.97  -5.42  11.48  14.20 
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón simple}
\begin{Schunk}
\begin{Sinput}
> predict (red, flor)
\end{Sinput}
\begin{Soutput}
        setosa versicolor virginica
1 1.164748e-16  0.1931563 0.8068437
\end{Soutput}
\begin{Sinput}
> flor1 <- c (1, as.numeric (flor))
> e1 <- exp (as.numeric (flor1 %*% red$wts[1:5]))
> e2 <- exp (as.numeric (flor1 %*% red$wts[6:10]))
> e3 <- exp (as.numeric (flor1 %*% red$wts[11:15]))
> c(e1,e2,e3) / (e1+e2+e3)
\end{Sinput}
\begin{Soutput}
[1] 1.164748e-16 1.931563e-01 8.068437e-01
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Respuesta dicótoma}
\begin{Schunk}
\begin{Sinput}
> red2 <- nnet (factor(am)~mpg, mtcars, 
+               size=0, skip=TRUE, trace=FALSE)
> predict (red2, data.frame (mpg = 20))
\end{Sinput}
\begin{Soutput}
       [,1]
1 0.3862902
\end{Soutput}
\begin{Sinput}
> 1 / (1 + 1/exp (red2$wts[1] + red2$wts[2] * 20)) #logit
\end{Sinput}
\begin{Soutput}
[1] 0.3862902
\end{Soutput}
\begin{Sinput}
> red2 $ value
\end{Sinput}
\begin{Soutput}
[1] 14.83758
\end{Soutput}
\begin{Sinput}
> p <- red2 $ fitted.values             #una sola columna
> t <- +(mtcars$am == mtcars$am[1])
> n0 <- function (x) ifelse (is.na(x), 0, x)
> sum (n0(t*log(t/p)) + n0((1-t)*log((1-t)/(1-p))))
\end{Sinput}
\begin{Soutput}
[1] 14.83758
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón multicapa (1 oculta)}
  \begin{neuralnetwork}[height=5]
    \newcommand{\nodetextclear}[2]{}
    \newcommand{\nodetextx}[2]{$x_#2$}
    \newcommand{\nodetexty}[2]{$y_#2$}
    \inputlayer[count=4, bias=false, title=Entrada, text=\nodetextx]
    \hiddenlayer[count=2, bias=false, title=Capa\\oculta, text=\nodetextclear] \linklayers
    \outputlayer[count=3, title=Salida, text=\nodetexty] \linklayers
    \renewcommand{\peso}[4]{\ensuremath{w_{ij}}}
    \link[from layer=0, to layer=1, from node=1, to node=1, label=\peso]
    \renewcommand{\peso}[4]{\ensuremath{w_{jk}}}
    \link[from layer=1, to layer=2, from node=1, to node=1, label=\peso]
  \end{neuralnetwork}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón multicapa (1 oculta)}
  \begin{neuralnetwork}[height=5]
    \newcommand{\nodetextclear}[2]{}
    \newcommand{\nodetextx}[2]{$x_#2$}
    \newcommand{\nodetexty}[2]{$y_#2$}
    \inputlayer[count=4, bias=true, title=Entrada, text=\nodetextx]
    \hiddenlayer[count=2, bias=true, title=Oculta, text=\nodetextclear] \linklayers
    \outputlayer[count=3, title=Salida, text=\nodetexty] \linklayers
    \renewcommand{\peso}[4]{\ensuremath{\alpha_{j}}}
    \link[from layer=0, to layer=1, from node=0, to node=1, label=\peso]
    \renewcommand{\peso}[4]{\ensuremath{\beta_{k}}}
    \link[from layer=1, to layer=2, from node=0, to node=1, label=\peso]
  \end{neuralnetwork}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón multicapa (1 oculta)}
  \begin{itemize}
  \item  \(j\) = índice de neuronas en capa oculta (\emph{hidden})
    \[ y_k = \phi_{\oo} \left( \beta_k + \sum_{j=1}^J w_{jk}\por \phi_h \Biggl( \alpha_j + \sum_{i=1}^I w_{ij}\por x_i  \Biggr) \right) \]
    \[ y_k = \phi_{\oo} \left( \sum_{j=0}^J w_{jk} \por\phi_h \Biggl( \sum_{i=0}^I w_{ij}\por x_i  \Biggr) \right) \]
  \item \(\phi\) casi siempre logística en la oculta
    \[ \phi_h(x)=\ell(x) = \frac {\exp(x)} {1+\exp(x)} \]
  \end{itemize}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón multicapa (1 oculta, \texttt{skip=FALSE})}
  \begin{neuralnetwork}[height=5]
    \newcommand{\nodetextclear}[2]{}
    \newcommand{\nodetextx}[2]{$x_#2$}
    \newcommand{\nodetexty}[2]{$y_k$}
    \renewcommand{\peso}[4]{\ensuremath{w_{#2k}}}
    \inputlayer[count=2, bias=true, title=Entrada, text=\nodetextx]
    \hiddenlayer[count=3, bias=true, title=Oculta, text=\nodetextclear, exclude={1,2}]
    \outputlayer[count=1, title=Salida, text=\nodetexty] 
    \link[from layer=0, to layer=1, from node=0, to node=3]
    \link[from layer=0, to layer=1, from node=1, to node=3]
    \link[from layer=0, to layer=1, from node=2, to node=3]
    \link[from layer=1, to layer=2, from node=0, to node=1]
    \link[from layer=1, to layer=2, from node=3, to node=1]
  \end{neuralnetwork}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón multicapa (1 oculta, \texttt{skip=TRUE})}
  \begin{neuralnetwork}[height=5]
    \newcommand{\nodetextclear}[2]{}
    \newcommand{\nodetextx}[2]{$x_#2$}
    \newcommand{\nodetexty}[2]{$y_k$}
    \renewcommand{\peso}[4]{\ensuremath{w_{#2k}}}
    \inputlayer[count=2, bias=true, title=Entrada, text=\nodetextx]
    \hiddenlayer[count=3, bias=true, title=Oculta, text=\nodetextclear, exclude={1,2}]
    \outputlayer[count=1, title=Salida, text=\nodetexty] 
    \link[from layer=0, to layer=1, from node=0, to node=3]
    \link[from layer=0, to layer=1, from node=1, to node=3]
    \link[from layer=0, to layer=1, from node=2, to node=3]
    \link[from layer=1, to layer=2, from node=0, to node=1]
    \link[from layer=1, to layer=2, from node=3, to node=1]
%    \link[from layer=0, to layer=2, from node=0, to node=1, label=\peso] % no en nnet
    \link[from layer=0, to layer=2, from node=1, to node=1, label=\peso]
    \link[from layer=0, to layer=2, from node=2, to node=1, label=\peso]
  \end{neuralnetwork}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón multicapa (1 oculta)}
  \begin{itemize}
  \item  \texttt{skip=FALSE}
    \[ y_k = \phi_{\oo} \left( \sum_{j} w_{jk} \por\phi_h \Biggl( \sum_{i} w_{ij}\por x_i  \Biggr)  \right) \] 
  \item  \texttt{skip=TRUE}
    \[ y_k = \phi_{\oo} \left( \sum_{j} w_{jk} \por\phi_h \Biggl( \sum_{i} w_{ij}\por x_i  \Biggr)  + \sum_i w_{ik}\por x_i \right) \] 
  \item los atajos o conexiones soslayantes (\emph{skip}) pueden facilitar\\la interpretación de la red neuronal
  \end{itemize}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón multicapa (1 oculta)}
\begin{Schunk}
\begin{Sinput}
> red0 <- nnet (Species ~ ., iris, size = 2,
+               skip = FALSE, trace = FALSE)
> red0
\end{Sinput}
\begin{Soutput}
a 4-2-3 network with 19 weights
inputs: Lsep Asep Lpet Apet 
output(s): Species 
options were - softmax modelling 
\end{Soutput}
\begin{Sinput}
> red1 <- nnet (Species ~ ., iris, size = 2,
+               skip = TRUE, trace = FALSE)
> red1
\end{Sinput}
\begin{Soutput}
a 4-2-3 network with 31 weights
inputs: Lsep Asep Lpet Apet 
output(s): Species 
options were - skip-layer connections  softmax modelling 
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón multicapa (1 oculta)}
\begin{Schunk}
\begin{Sinput}
> summary (red0)
\end{Sinput}
\begin{Soutput}
a 4-2-3 network with 19 weights
options were - softmax modelling 
  b->h1  i1->h1  i2->h1  i3->h1  i4->h1 
  79.27  111.02   83.46 -242.90 -114.89 
  b->h2  i1->h2  i2->h2  i3->h2  i4->h2 
   2.88  158.40 -112.52  470.73  185.39 
  b->o1  h1->o1  h2->o1 
 -99.26  204.70   38.22 
  b->o2  h1->o2  h2->o2 
 417.44  -84.87 -386.84 
  b->o3  h1->o3  h2->o3 
-318.89 -119.03  349.52 
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Perceptrón multicapa (1 oculta)}
\begin{Schunk}
\begin{Sinput}
> summary (red1)
\end{Sinput}
\begin{Soutput}
a 4-2-3 network with 31 weights
options were - skip-layer connections  softmax modelling 
 b->h1 i1->h1 i2->h1 i3->h1 i4->h1 
 -0.79  -1.30  -0.01  -2.28  -0.57 
 b->h2 i1->h2 i2->h2 i3->h2 i4->h2 
  5.37  25.28  15.20  11.53   2.21 
 b->o1 h1->o1 h2->o1 i1->o1 i2->o1 i3->o1 i4->o1 
  1.62   0.33   0.47   4.47  15.48 -17.22 -10.69 
 b->o2 h1->o2 h2->o2 i1->o2 i2->o2 i3->o2 i4->o2 
  7.40  -3.89  13.09  -1.39  -4.69   3.91  -4.10 
 b->o3 h1->o3 h2->o3 i1->o3 i2->o3 i3->o3 i4->o3 
 -8.75   4.03 -13.41  -3.85 -11.37  13.35  14.19 
\end{Soutput}
\end{Schunk}
\end{frame}
\section{Regresión}
\begin{frame} [fragile]
  \frametitle{Regresión}
  \begin{itemize}
  \item función de activación de salida lineal: \(\phi_\oo(x)=x\)
  \item teorema de aproximación universal (Cybenko, Hornik, etc.)
    \begin{itemize}
    \item sea \(f:(C\text{ compacto})\subset\mathbb R^I\to\mathbb R\) continua
    \item existe perceptrón que aproxima \(f\) uniformemente en \(C\)
    \item basta
      \begin{itemize}
      \item elegir funciones de activación adecuadas
      \item incrementar el número de neuronas en la capa oculta
      \end{itemize}
    \end{itemize}
  \item la aproximación es ``no constructiva''
    \begin{itemize}
    \item el número de neuronas se decide por validación
    \end{itemize}
  \item criterios de ajuste (\(n\)=instancia, \(t\)=objetivo, \(y\)=predicción)
    \begin{itemize}
    \item mínimos cuadrados: \(E = \sum_n\Vert t^{(n)}-y^{(n)}\Vert^2\)
    \end{itemize}
  \end{itemize}
\end{frame}

% \begin{frame}[fragile]
%   \frametitle{Regresión}
%   \begin{itemize}
%   \item Función de activación en la capa de salida: lineal, \(\phi_\oo(x)=x\).
%     \begin{itemize}
%     \item Así la red puede aproximar cualquier valor real (no solo probabilidades).
%     \end{itemize}
%   \item \textbf{Teorema de aproximación universal} (Cybenko, Hornik, etc.):
%     \begin{itemize}
%     \item Sea \(f: \mathbb{R}^I \supset K \to \mathbb{R}\) una función continua sobre un compacto \(K\).
%     \item Existe una red neuronal con una sola capa oculta (con suficientes neuronas) y activación no lineal (p.ej. logística) que aproxima \(f\) uniformemente en \(K\).
%     \item Basta incrementar el número de neuronas en la capa oculta; no se necesitan más capas ocultas para aproximar funciones continuas.
%     \end{itemize}
%   \item La aproximación es \textbf{no constructiva}:
%     \begin{itemize}
%     \item El teorema garantiza la existencia, pero no dice cuántas neuronas ni cómo ajustar los pesos.
%     \item En la práctica, el número de neuronas se elige mediante validación o heurísticas.
%     \end{itemize}
%   \item Criterios de ajuste (para regresión): minimizar el error cuadrático medio.
%     \begin{itemize}
%     \item Dados patrones \(n=1,\dots,N\), con objetivo \(t^{(n)}\in\mathbb{R}^K\) y predicción \(y^{(n)}\in\mathbb{R}^K\):
%     \[
%     E = \sum_{n=1}^N \bigl\| t^{(n)} - y^{(n)} \bigr\|^2
%     \]
%     \item Es la suma de cuadrados de los residuos, igual que en regresión lineal múltiple.
%     \end{itemize}
%   \item \textbf{Relación con regresión lineal}:
%     \begin{itemize}
%     \item Si no hay capa oculta (tamaño 0) y activación lineal, se obtiene exactamente una regresión lineal múltiple.
%     \item La capa oculta con activación no lineal permite modelar relaciones no lineales.
%     \end{itemize}
%   \end{itemize}
% \end{frame}


\begin{frame} [fragile,t]
  \frametitle{Parámetros}
  \begin{itemize}
  \item \texttt{maxit}: límite del número de iteraciones\\antes de alcanzar convergencia
  \item \texttt{rang}: pesos inicializados según
    \(\mathcal U(-\text{rang}, +\text{rang})\)
  \item \texttt{decay}: coeficiente \(\lambda\) de decaimiento de pesos
      \begin{itemize}%\addtolength{\itemsep}{1ex}
  \item pretende evitar óptimos locales al ajustar los pesos \(w\)
  \item minimizar \(\displaystyle E+\lambda\por\sum_{i,j,k} w^2\)
  \item se aconseja \( 0.001 \lessapprox \lambda \lessapprox 0.1\)
  \item recuerda: conviene tipificar las instancias
  \end{itemize}
\end{itemize}
\begin{Schunk}
\begin{Sinput}
> E <- function (l) {
+  red <- nnet(Species~., iris,, 2, decay=l, trace=FALSE)
+  c(red$value,
+   -sum(log(red$fitted[cbind(1:150,rep(1:3,each=50))]))+
+   + l * sum(red$wts^2)) }
> E (0) ; E (.1)
\end{Sinput}
\begin{Soutput}
[1] 5.9724 5.9724
\end{Soutput}
\begin{Soutput}
[1] 52.72997 52.72997
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> reg <- lm (mpg ~ wt, mtcars)
> print (summary (reg))
\end{Sinput}
\begin{Soutput}
[...]

Coefficients:
            Estimate Std. Error t value Pr(>|t|)
(Intercept)  37.2851     1.8776  19.858  < 2e-16
wt           -5.3445     0.5591  -9.559 1.29e-10

Residual standard error: 3.046 on 30 degrees of freedom
Multiple R-squared: 0.7528, Adjusted R-squared: 0.7446 
F-statistic: 91.38 on 1 and 30 DF,  p-value: 1.294e-10
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-021}
\end{frame}

\begin{frame} [fragile]
\frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # para reproducir ejemplo malo
> red <- nnet (mpg ~ wt, mtcars, size = 2, linout = TRUE)
\end{Sinput}
\begin{Soutput}
# weights:  7
initial  value 13690.144505 
iter  10 value 1126.051149
final  value 1126.047233 
converged
\end{Soutput}
\begin{Sinput}
> summary (red)
\end{Sinput}
\begin{Soutput}
a 1-2-1 network with 7 weights
options were - linear output units 
 b->h1 i1->h1 
  3.94   7.04 
 b->h2 i1->h2 
  5.78   9.94 
 b->o h1->o h2->o 
 7.57  4.78  7.75 
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> red $ value
\end{Sinput}
\begin{Soutput}
[1] 1126.047
\end{Soutput}
\begin{Sinput}
> sum (red $ residuals ^ 2)
\end{Sinput}
\begin{Soutput}
[1] 1126.047
\end{Soutput}
\begin{Sinput}
> sum (reg $ residuals ^ 2)
\end{Sinput}
\begin{Soutput}
[1] 278.3219
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-024}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(2) # mucho mejor cambiando la semilla
> red <- nnet (mpg ~ wt, mtcars, size = 2, linout = TRUE)
\end{Sinput}
\begin{Soutput}
# weights:  7
initial  value 12943.660208 
iter  10 value 962.385509
iter  20 value 251.143680
iter  30 value 202.430605
iter  40 value 202.330422
final  value 202.291329 
converged
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-026}
\end{frame}


\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # caso malo; pesos com mayor rango inicial
> red <- nnet (mpg ~ wt, mtcars, size = 2, linout = TRUE,
+              rang = 5)
\end{Sinput}
\begin{Soutput}
# weights:  7
initial  value 12211.292513 
iter  10 value 744.853983
iter  20 value 205.109500
iter  30 value 202.359319
final  value 202.291137 
converged
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-028}
\end{frame}


\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # caso malo; tipificando; sobreajuste
> red <- nnet (mpg ~ wt, scale(mtcars), size = 2,
+              linout = TRUE)
\end{Sinput}
\begin{Soutput}
# weights:  7
initial  value 34.908961 
iter  10 value 6.037538
iter  20 value 5.526884
iter  30 value 5.265161
iter  40 value 4.800987
iter  50 value 4.798314
iter  60 value 4.792750
iter  70 value 4.792613
iter  80 value 4.792603
final  value 4.792594 
converged
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-030}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # decay para evitar sobreajuste
> red <- nnet (mpg ~ wt, scale(mtcars), size = 2,
+              linout = TRUE, decay=.001)
\end{Sinput}
\begin{Soutput}
# weights:  7
initial  value 34.910311 
iter  10 value 6.087401
iter  20 value 5.574842
iter  30 value 5.178789
iter  40 value 4.927741
iter  50 value 4.924397
iter  60 value 4.924349
iter  60 value 4.924349
iter  60 value 4.924349
final  value 4.924349 
converged
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-032}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # decay para evitar sobreajuste
> red <- nnet (mpg ~ wt, scale(mtcars), size = 2,
+              linout = TRUE, decay=.01)
\end{Sinput}
\begin{Soutput}
# weights:  7
initial  value 34.922460 
iter  10 value 6.544019
iter  20 value 5.954441
iter  30 value 5.895883
iter  40 value 5.893031
iter  50 value 5.791990
iter  60 value 5.779464
iter  60 value 5.779464
iter  60 value 5.779464
final  value 5.779464 
converged
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-034}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # decay para evitar sobreajuste
> red <- nnet (mpg ~ wt, scale(mtcars), size = 2,
+              linout = TRUE, decay=.1)
\end{Sinput}
\begin{Soutput}
# weights:  7
initial  value 35.043951 
iter  10 value 8.545438
iter  20 value 7.131476
iter  30 value 7.103682
final  value 7.103680 
converged
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-036}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # muchas neuronas ocultas; sobreajuste
> red <- nnet (mpg~wt, mtcars, size = 100, linout = TRUE)
\end{Sinput}
\begin{Soutput}
# weights:  301
initial  value 21248.821010 
iter  10 value 229.802676
iter  20 value 203.348311
iter  30 value 200.484030
iter  40 value 191.191581
iter  50 value 169.455915
iter  60 value 144.765317
iter  70 value 134.589994
iter  80 value 116.245707
iter  90 value 101.921759
iter 100 value 91.396961
final  value 91.396961 
stopped after 100 iterations
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-038}
\end{frame}


\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # rang no evita sobreajuste
> red <- nnet (mpg~wt, mtcars, size = 100, linout = TRUE,
+              rang=5)
\end{Sinput}
\begin{Soutput}
# weights:  301
initial  value 113453.230339 
iter  10 value 268.817455
iter  20 value 204.853381
iter  30 value 189.632583
iter  40 value 180.592357
iter  50 value 155.232946
iter  60 value 146.266433
iter  70 value 143.899068
iter  80 value 141.962872
iter  90 value 140.209864
iter 100 value 137.646885
final  value 137.646885 
stopped after 100 iterations
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-040}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # decay evita sobreajuste pero no converge
> red <- nnet (mpg~wt, mtcars, size = 100, linout = TRUE,
+              decay=.1)
\end{Sinput}
\begin{Soutput}
# weights:  301
initial  value 21253.252588 
iter  10 value 289.968862
iter  20 value 238.766078
iter  30 value 226.206939
iter  40 value 219.981624
iter  50 value 218.469071
iter  60 value 217.911102
iter  70 value 217.510822
iter  80 value 216.974718
iter  90 value 216.531471
iter 100 value 216.264122
final  value 216.264122 
stopped after 100 iterations
\end{Soutput}
\end{Schunk}
\end{frame}
\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # decay evita sobreajuste si aumentamos maxit
> salida <- capture.output (
+   red <- nnet (mpg~wt, mtcars, size = 100, linout = TRUE,
+                decay=.1, maxit=1000))
> tail (salida)
\end{Sinput}
\begin{Soutput}
[1] "iter 660 value 213.940852"
[2] "iter 670 value 213.935819"
[3] "iter 680 value 213.932913"
[4] "iter 690 value 213.932841"
[5] "final  value 213.932819 " 
[6] "converged"                
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-043}
\end{frame}

% \begin{frame} [fragile]
%   \frametitle{Regresión}
% <<>>=
% set.seed(1)
% red <- nnet (mpg ~ wt, mtcars, size = 100, linout = TRUE,
%              trace = FALSE, maxit = 1000)
% red $ value
% set.seed(1)
% red <- nnet (mpg ~ wt, mtcars, size = 100, linout = TRUE,
%              trace = FALSE, maxit = 1e6)
% red $ value
% @ 
% \end{frame}

% \begin{frame}[fragile]
%   \frametitle{}
% <<fig=TRUE,echo=FALSE>>=
% grafpred (red, mtcars)
% @ 
% \end{frame}

\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # decay no funciona siempre
> red <- nnet (mpg ~ wt, mtcars, size = 2, linout = TRUE,
+              decay = 0.001)
\end{Sinput}
\begin{Soutput}
# weights:  7
initial  value 13690.145855 
iter  10 value 1126.294236
final  value 1126.291748 
converged
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-045}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # decay no funciona siempre
> red <- nnet (mpg ~ wt, mtcars, size = 2, linout = TRUE,
+              decay = 0.01)
\end{Sinput}
\begin{Soutput}
# weights:  7
initial  value 13690.158004 
iter  10 value 1128.325971
iter  20 value 1128.069333
final  value 1127.956753 
converged
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-047}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Regresión}
\begin{Schunk}
\begin{Sinput}
> set.seed(1) # decay no funciona siempre
> red <- nnet (mpg ~ wt, mtcars, size = 2, linout = TRUE,
+              decay = 0.1)
\end{Sinput}
\begin{Soutput}
# weights:  7
initial  value 13690.279495 
iter  10 value 1145.255981
final  value 1143.101582 
converged
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\includegraphics{neuronas-woven-049}
\end{frame}

\begin{frame} [fragile]
  \frametitle{Recomendaciones}
  \begin{itemize}
  \item tipificar / normalizar / rescalar las variables
  \item ejecutar varias veces (probar distintas semillas)
  \item validación cruzada
  \item promediar las predicciones de varias redes (ensamblar) para
    mejorar la generalización
  \end{itemize}
\end{frame}

\begin{frame} [fragile]
  \frametitle{}
\begin{Schunk}
\begin{Sinput}
> valcruz <- function (numneur, decai, partes=10)
+ {
+     iparte <- sample (rep (1:partes,
+                            length.out = nrow(mtcars)))
+     mean (sapply (1:partes,
+             function (i)
+             {
+                 red <- nnet (mpg ~ wt, 
+                              mtcars[iparte!=i,],
+                              linout = TRUE,
+                              size = numneur, 
+                              decay = decai,
+                              trace = FALSE)
+                 mean ((predict (red, 
+                                 mtcars[iparte==i,]) -
+                        mtcars$mpg[iparte==i]) ^ 2)
+             }))
+ }
\end{Sinput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{}
\begin{Schunk}
\begin{Sinput}
> valcruz (  2, 0.001)
\end{Sinput}
\begin{Soutput}
[1] 13.09448
\end{Soutput}
\begin{Sinput}
> valcruz (  2, 0.001)
\end{Sinput}
\begin{Soutput}
[1] 28.91391
\end{Soutput}
\begin{Sinput}
> valcruz ( 10, 0.001)
\end{Sinput}
\begin{Soutput}
[1] 11.78668
\end{Soutput}
\begin{Sinput}
> valcruz ( 10, 0.001)
\end{Sinput}
\begin{Soutput}
[1] 11.84809
\end{Soutput}
\begin{Sinput}
> valcruz (100, 0.001)
\end{Sinput}
\begin{Soutput}
[1] 11.53392
\end{Soutput}
\begin{Sinput}
> valcruz (100, 0.001)
\end{Sinput}
\begin{Soutput}
[1] 11.5865
\end{Soutput}
\begin{Sinput}
> mean (reg $ residuals ^ 2)
\end{Sinput}
\begin{Soutput}
[1] 8.697561
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{}
\begin{Schunk}
\begin{Sinput}
> valcruzreg <- function (partes=10)
+ {
+     iparte <- sample (rep (1:partes,
+                            length.out = nrow(mtcars)))
+     mean (sapply (1:partes,
+             function (i)
+             {
+                 reg <- lm (mpg ~ wt, 
+                            mtcars[iparte!=i,])
+                 mean ((predict (reg, 
+                                 mtcars[iparte==i,]) -
+                        mtcars$mpg[iparte==i]) ^ 2)
+             }))
+ }
\end{Sinput}
\end{Schunk}
\end{frame}
\begin{frame} [fragile]
  \frametitle{}
\begin{Schunk}
\begin{Sinput}
> valcruzreg ()
\end{Sinput}
\begin{Soutput}
[1] 9.345148
\end{Soutput}
\begin{Sinput}
> mean (reg $ residuals ^ 2)
\end{Sinput}
\begin{Soutput}
[1] 8.697561
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame} [fragile]
  \frametitle{}
\begin{Schunk}
\begin{Sinput}
> valcruz01 <- function (numneur, decai, partes=10)
+ {
+     iparte <- sample (rep (1:partes,
+                            length.out=nrow(mtcars01)))
+     mean (sapply (1:partes,
+             function (i)
+             {
+                 red <- nnet (mpg ~ wt, 
+                              mtcars01[iparte!=i,],
+                              linout = TRUE,
+                              size = numneur, 
+                              decay = decai,
+                              trace = FALSE)
+                 mean ((predict (red, 
+                                 mtcars01[iparte==i,])
+                        - mtcars01$mpg[iparte==i]) ^ 2)
+             }))
+ }
\end{Sinput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
  \frametitle{}
\begin{Schunk}
\begin{Sinput}
> mtcars01 <- data.frame (scale (mtcars))
> mean (lm(mpg~wt,mtcars01) $ residuals ^ 2)
\end{Sinput}
\begin{Soutput}
[1] 0.2394432
\end{Soutput}
\begin{Sinput}
> valcruz01 (2, 0.001)
\end{Sinput}
\begin{Soutput}
[1] 0.2467679
\end{Soutput}
\begin{Sinput}
> valcruz01 (2, 0.001)
\end{Sinput}
\begin{Soutput}
[1] 0.2425711
\end{Soutput}
\begin{Sinput}
> valcruz01 (2, 0.001)
\end{Sinput}
\begin{Soutput}
[1] 0.3180561
\end{Soutput}
\begin{Sinput}
> valcruz01 (2, 0.001)
\end{Sinput}
\begin{Soutput}
[1] 0.2629049
\end{Soutput}
\end{Schunk}
\end{frame}
\begin{frame} [fragile]
  \frametitle{Bibliografía}
  \begin{itemize}
  \item \url{https://cran.r-project.org/view=MachineLearning}
  \item Ripley B.; 1996; Pattern recognition and neural networks; Cambridge University Press
  \item Venables W., Ripley B.; 2002; Modern applied statistics with S; Springer
  \end{itemize}
\end{frame}

\section{Anexo: Retropropagación}

\begin{frame}[plain]
  \title{Anexo: Retropropagación}\author{}\date{}
  \titlepage
\end{frame}

\begin{frame}[fragile]
  \frametitle{Perceptrón simple: retropropagación}

  Para una instancia \(n\in\{1,\dots,N\}\) :

  \[
  y_k^{(n)} =
  \phio\!\left(
  \sum_{i=0}^I w_{ik}\por x_i^{(n)}
  \right)
  \]

 Error (p.ej. divergencia en \(k\) respuestas dicótomas):
   \begin{eqnarray*}
   E &=& \sum_n \sum_k
   \left[
   t_k^{(n)} \por \ln\frac{t_k^{(n)}}{y_k^{(n)}}
   + (1-t_k^{(n)}) \por
   \ln\frac{1-t_k^{(n)}}{1-y_k^{(n)}}
         \right]\\
   &=&\sum_n \sum_k\left[ -t_k^{(n)}\ln y_k^{(n)} - (1-t_k^{(n)})\ln(1-y_k^{(n)})\right] + \text{cte.}
   \end{eqnarray*}
  
  Objetivo: minimizar \(E\) respecto a \(w_{ik}\)
\end{frame}

\begin{frame}[fragile]
  \frametitle{Perceptrón simple: derivada de \(E\) respecto a \(w_{ik}\)}
  \begin{eqnarray*}
  y_k^{(n)} &=& \phio\!\left(\sum_{i=0}^I w_{ik} x_i^{(n)}\right) \qquad
  \phio(z)=\frac{1}{1+e^{-z}} \quad\text{(logística)}
  \\
  E &=& \sum_n \sum_k\left[ -t_k^{(n)}\ln y_k^{(n)} - (1-t_k^{(n)})\ln(1-y_k^{(n)}) \right]
  \\
  \frac{\partial E}{\partial w_{ik}}
  &=& \sum_n \frac{\partial E^{(n)}}{\partial y_k^{(n)}} \;
    \frac{\partial y_k^{(n)}}{\partial a_k^{(n)}} \;
    \frac{\partial a_k^{(n)}}{\partial w_{ik}}
  \qquad
  a_k^{(n)} = \sum_{i} w_{ik} x_i^{(n)}
  \\
    \frac{\partial E^{(n)}}{\partial y_k^{(n)}}
    &=& -\frac{t_k^{(n)}}{y_k^{(n)}} + \frac{1-t_k^{(n)}}{1-y_k^{(n)}}
    = \frac{y_k^{(n)}-t_k^{(n)}}{y_k^{(n)}(1-y_k^{(n)})} \\
    \frac{\partial y_k^{(n)}}{\partial a_k^{(n)}}
    &=& \phio'(a_k^{(n)}) = y_k^{(n)}\bigl(1-y_k^{(n)}\bigr) \qquad\text{(derivada de la logística)} \\
    \frac{\partial a_k^{(n)}}{\partial w_{ik}}
    &=& x_i^{(n)}
  \end{eqnarray*}

\end{frame}

\begin{frame}[fragile]
  \frametitle{Perceptrón simple: derivada de \(E\) respecto a \(w_{ik}\)}
  \vspace{2mm}
  Multiplicando los tres factores:

  \[
  \frac{\partial E^{(n)}}{\partial w_{ik}}
  = \frac{y_k^{(n)}-t_k^{(n)}}{y_k^{(n)}(1-y_k^{(n)})} \;\cdot\;
    y_k^{(n)}\bigl(1-y_k^{(n)}\bigr) \;\cdot\; x_i^{(n)}
  = \bigl(y_k^{(n)}-t_k^{(n)}\bigr)\, x_i^{(n)}
  \]

  Sumando para todas las instancias:

  \[
    \frac{\partial E}{\partial w_{ik}} = \sum_{n=1}^N \bigl(y_k^{(n)}-t_k^{(n)}\bigr)\, x_i^{(n)}
  \]
\end{frame}

\begin{frame}[fragile]
  \frametitle{Perceptrón simple: gradiente}

  Para activación logística:
  \[
  \phio'(z) = y_k(1-y_k)
  \]

  Derivada del error:
  \[
  \frac{\partial E}{\partial w_{ik}}
  =
  \sum_n
  \left(y_k^{(n)} - t_k^{(n)}\right)
  \por x_i^{(n)}
  \]

  Regla de actualización (descenso por gradiente):
  \[
  w_{ik}
  \leftarrow
  w_{ik}
  - \eta
  \sum_n
  \left(y_k^{(n)} - t_k^{(n)}\right)
  \por x_i^{(n)}
  \]

  \(\eta>0\) es la tasa de aprendizaje.
\end{frame}

\begin{frame}[fragile]
  \frametitle{Perceptrón multicapa (1 oculta)}

  Capa oculta:
  \[
  h_j^{(n)} =
  \phi\!\left(
  \sum_{i=0}^I w_{ij}\por x_i^{(n)}
  \right)
  \]

  Capa de salida:
  \[
  y_k^{(n)} =
  \phio\!\left(
  \sum_{j=0}^J v_{jk}\por h_j^{(n)}
  \right)
  \]

  El error \(E\) es el mismo que antes.
\end{frame}

\begin{frame}[fragile]
  \frametitle{Multicapa: retropropagación}

  Definimos el \emph{error local} en salida:

  \[
  \delta_k^{(n)} =
  y_k^{(n)} - t_k^{(n)}
  \]

  Gradiente en la capa de salida:
  \[
  \frac{\partial E}{\partial v_{jk}}
  =
  \sum_n
  \delta_k^{(n)} \por h_j^{(n)}
  \]

  Actualización:
  \[
  v_{jk}
  \leftarrow
  v_{jk}
  - \eta
  \sum_n
  \delta_k^{(n)} \por h_j^{(n)}
  \]
\end{frame}

\begin{frame}[fragile]
  \frametitle{Multicapa: error en capa oculta}

  Error propagado a la neurona oculta:

  \[
  \delta_j^{(n)}
  =
  \phi'\!\left(
  \sum_i w_{ij}\por x_i^{(n)}
  \right)
  \sum_k
  \delta_k^{(n)} \por v_{jk}
  \]

  Gradiente en pesos de entrada:
  \[
  \frac{\partial E}{\partial w_{ij}}
  =
  \sum_n
  \delta_j^{(n)} \por x_i^{(n)}
  \]

  Actualización:
  \[
  w_{ij}
  \leftarrow
  w_{ij}
  - \eta
  \sum_n
  \delta_j^{(n)} \por x_i^{(n)}
  \]
\end{frame}

\begin{frame}[fragile]
  \frametitle{Resumen: algoritmo de retropropagación}

  Para cada instancia \(n\):

  \begin{enumerate}
  \item Propagación hacia delante:
    calcular \(h_j^{(n)}\), luego \(y_k^{(n)}\).
  \item Calcular errores en salida:
    \(\delta_k^{(n)}\).
  \item Propagar errores hacia atrás:
    \(\delta_j^{(n)}\).
  \item Actualizar pesos:
    \(v_{jk}\), luego \(w_{ij}\).
  \end{enumerate}

  Es un descenso por gradiente aplicado \\mediante
  regla de la cadena.
\end{frame}

\begin{frame}[fragile]
  \frametitle{Descenso por gradiente vs BFGS (lo que usa \texttt{nnet})}

  Sean \(E(\mathbf{w})\) la función de error y
  \(\nabla E(\mathbf{w})\) su gradiente.

  Sea \(t\) el índice de iteración.

  \vspace{2mm}

  \textbf{1. Descenso por gradiente clásico}

  \[
  \mathbf{w}^{(t+1)}
  =
  \mathbf{w}^{(t)}
  -
  \eta
  \nabla E\!\left(\mathbf{w}^{(t)}\right)
  \]

  \begin{itemize}
  \item \(\eta>0\) tasa de aprendizaje explícita.
  \item Dirección: gradiente negativo.
  \item Convergencia lineal.
  \item Sensible a la elección de \(\eta\).
  \end{itemize}

\end{frame}

\begin{frame}[fragile]
  \frametitle{Descenso por gradiente vs BFGS (lo que usa \texttt{nnet})}

  \vspace{3mm}

  \textbf{2. BFGS (cuasi-Newton)}

  \[
  \mathbf{w}^{(t+1)}
  =
  \mathbf{w}^{(t)}
  -
  H_t^{-1}
  \nabla E\!\left(\mathbf{w}^{(t)}\right)
  \]

  donde \(H_t^{-1}\) aproxima la inversa del Hessiano.

  \begin{itemize}
  \item No hay parámetro \(\eta\) explícito.
  \item Dirección adaptativa usando curvatura.
  \item Búsqueda en línea interna para el tamaño de paso.
  \item Convergencia superlineal (en condiciones regulares).
  \end{itemize}

\end{frame}

\begin{frame}[fragile]
  \frametitle{¿Qué implementa \texttt{nnet} en R?}

  Paquete: \texttt{nnet}

  \vspace{2mm}

  \begin{itemize}
  \item Optimización mediante algoritmo BFGS.
  \item Minimiza directamente la entropía o la SCE.
  \item El tamaño del paso se determina por búsqueda en línea.
  \item No existe parámetro de tasa de aprendizaje \(\eta\).
  \item El argumento \texttt{decay} implementa regularización:
  \[
  E_{\mathrm{reg}}
  =
  E + \lambda \sum w^2
  \]
  \end{itemize}

  \vspace{3mm}

  Por tanto:

  \[
  \texttt{nnet}
  \quad \neq \quad
  \text{descenso por gradiente con tasa fija}
  \]

  Es un método cuasi-Newton determinista,
  adecuado para redes pequeñas y medianas.
\end{frame}

\begin{frame}[fragile]
  \frametitle{Búsqueda en línea: condición de Armijo}

  Sea \(E(\mathbf{w})\) diferenciable y
  \(\mathbf{d}_t\) una dirección de descenso:

  \[
  \nabla E(\mathbf{w}^{(t)})^{\!\top}\mathbf{d}_t < 0
  \]

  Se actualiza:

  \[
  \mathbf{w}^{(t+1)}
  =
  \mathbf{w}^{(t)}
  +
  \alpha_t \mathbf{d}_t
  \]

  \vspace{2mm}

  \textbf{Condición de Armijo (suficiente descenso)}

  Dado \(c \in (0,1)\), se busca \(\alpha_t>0\) tal que:

  \[
  E(\mathbf{w}^{(t)} + \alpha_t \mathbf{d}_t)
  \le
  E(\mathbf{w}^{(t)})
  +
  c \alpha_t
  \nabla E(\mathbf{w}^{(t)})^{\!\top}\mathbf{d}_t
  \]

  \vspace{2mm}

  Interpretación:
  el descenso real debe ser proporcional
  al descenso lineal predicho por el gradiente.
\end{frame}

\begin{frame}[fragile]
  \frametitle{Búsqueda en línea: \it backtracking}

  Procedimiento típico:

  \begin{enumerate}
  \item Fijar \(\alpha = \alpha_0\) (p.ej. 1).
  \item Mientras no se cumpla Armijo:
    \[
    \alpha \leftarrow \rho \alpha,
    \qquad \rho \in (0,1)
    \]
  \item Tomar \(\alpha_t = \alpha\).
  \end{enumerate}

  \vspace{2mm}

  Propiedades:

  \begin{itemize}
  \item Garantiza descenso.
  \item Evita pasos excesivos.
  \item Compatible con descenso por gradiente y BFGS.
  \end{itemize}
\end{frame}

\section{Anexo: Hiperparámetros}

\begin{frame}[plain]
  \title{Anexo: Hiperparámetros}\author{}\date{}
  \titlepage
\end{frame}

\begin{frame}[fragile]
\begin{Schunk}
\begin{Sinput}
> library(e1071) # para tune
> tune(lm, mpg~., data=mtcars, # CV para lm
+      tunecontrol=tune.control(cross=32))
\end{Sinput}
\begin{Soutput}
Error estimation of ‘lm’ using leave-one-out: 12.18156
\end{Soutput}
\begin{Sinput}
> library(rpart) # para rpart
> tune(rpart, mpg~., data=mtcars,
+      ranges=list(minsplit=c(5,10)))
\end{Sinput}
\begin{Soutput}
Parameter tuning of ‘rpart’:

- sampling method: 10-fold cross validation 

- best parameters:
 minsplit
        5

- best performance: 12.96652 
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
\begin{Schunk}
\begin{Sinput}
> library(nnet) # para nnet
> tune(nnet, mpg~., data=mtcars,
+      linout=TRUE, trace=FALSE,
+      ranges=list(size=c(2,10), decay=.1^(1:2)))
\end{Sinput}
\begin{Soutput}
Parameter tuning of ‘nnet’:

- sampling method: 10-fold cross validation 

- best parameters:
 size decay
   10   0.1

- best performance: 9.599455 
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]
\begin{Schunk}
\begin{Sinput}
> library(caret, quietly=TRUE)
> salida <- capture.output(
+  res <- train(mpg ~ ., data=mtcars, method="nnet",
+          trControl = trainControl("repeatedcv",32),
+          tuneGrid = expand.grid(size=c(2,10),
+                                 decay=c(.1,.01))))
> names(res)
\end{Sinput}
\begin{Soutput}
 [1] "method"       "modelInfo"    "modelType"   
 [4] "results"      "pred"         "bestTune"    
 [7] "call"         "dots"         "metric"      
[10] "control"      "finalModel"   "preProcess"  
[13] "trainingData" "ptype"        "resample"    
[16] "resampledCM"  "perfNames"    "maximize"    
[19] "yLimits"      "times"        "levels"      
[22] "terms"        "coefnames"    "xlevels"     
\end{Soutput}
\end{Schunk}
\end{frame}

\begin{frame}[fragile]\footnotesize
\begin{Schunk}
\begin{Sinput}
> res
\end{Sinput}
\begin{Soutput}
Neural Network 

32 samples
10 predictors

No pre-processing
Resampling: Cross-Validated (32 fold, repeated 1 times) 
Summary of sample sizes: 31, 31, 31, 31, 31, 31, ... 
Resampling results across tuning parameters:

  size  decay  RMSE      Rsquared  MAE     
   2    0.01   19.09069  NaN       19.09069
   2    0.10   19.09106  NaN       19.09106
  10    0.01   19.09064  NaN       19.09064
  10    0.10   19.09076  NaN       19.09076

RMSE was used to select the optimal model using
 the smallest value.
The final values used for the model were size = 10
 and decay = 0.01.
\end{Soutput}
\end{Schunk}
\end{frame}

\end{document}

% ## ejemplo de que la expresión suma(p.ln(p)+(1-p).ln(1-p)) no es válida:


% ## R version 4.3.3 (2024-02-29) -- "Angel Food Cake"
% ## Copyright (C) 2024 The R Foundation for Statistical Computing
% ## Platform: x86_64-pc-linux-gnu (64-bit)

% ## R es un software libre y viene sin GARANTIA ALGUNA.
% ## Usted puede redistribuirlo bajo ciertas circunstancias.
% ## Escriba 'license()' o 'licence()' para detalles de distribucion.

% ## R es un proyecto colaborativo con muchos contribuyentes.
% ## Escriba 'contributors()' para obtener más información y
% ## 'citation()' para saber cómo citar R o paquetes de R en publicaciones.

% ## Escriba 'demo()' para demostraciones, 'help()' para el sistema on-line de ayuda,
% ## o 'help.start()' para abrir el sistema de ayuda HTML con su navegador.
% ## Escriba 'q()' para salir de R.

% ## > setwd('/tmp/')
% ## > library(nnet)
% ## > red2 <- nnet (factor(am)~mpg, mtcars, size=0, skip=TRUE, trace=FALSE)
% ## > p <- red2 $ fitted.values
% ## > p
% ##                           [,1]
% ## Mazda RX4           0.46108985
% ## Mazda RX4 Wag       0.46108985
% ## Datsun 710          0.59789043
% ## Hornet 4 Drive      0.49171393
% ## Hornet Sportabout   0.29689962
% ## Valiant             0.25993267
% ## Duster 360          0.09858910
% ## Merc 240D           0.70846021
% ## Merc 230            0.59789043
% ## Merc 280            0.32990942
% ## Merc 280C           0.24260965
% ## Merc 450SE          0.17246527
% ## Merc 450SL          0.21552534
% ## Merc 450SLC         0.12601293
% ## Cadillac Fleetwood  0.03197249
% ## Lincoln Continental 0.03197249
% ## Chrysler Imperial   0.11005378
% ## Fiat 128            0.96591077
% ## Honda Civic         0.93877653
% ## Toyota Corolla      0.97821744
% ## Toyota Corona       0.49938871
% ## Dodge Challenger    0.13651116
% ## AMC Javelin         0.12601293
% ## Camaro Z28          0.07446642
% ## Pontiac Firebird    0.32990942
% ## Fiat X1-9           0.85548435
% ## Porsche 914-2       0.79885476
% ## Lotus Europa        0.93877653
% ## Ford Pantera L      0.14773616
% ## Ferrari Dino        0.36468569
% ## Maserati Bora       0.11940409
% ## Volvo 142E          0.49171393
% ## > predict(red2,type="class")
% ##  [1] "0" "0" "1" "0" "0" "0" "0" "1" "1" "0" "0" "0" "0" "0" "0" "0" "0" "1" "1"
% ## [20] "1" "0" "0" "0" "0" "0" "1" "1" "1" "0" "0" "0" "0"
% ## > mtcars$am
% ##  [1] 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1
% ## > table(real=mtcars$am, pred=predict(red2,type="class"))
% ##     pred
% ## real  0  1
% ##    0 17  2
% ##    1  6  7
% ## > - sum (p * log(p) + (1-p) * log(1-p))
% ## [1] 14.83771
% ## > red2$value
% ## [1] 14.83758
% ## > t <- +(mtcars$am == mtcars$am[1])
% ## > n0 <- function (x) ifelse (is.na(x), 0, x)
% ## > sum (n0(t*log(t/p)) + n0((1-t)*log((1-t)/(1-p))))
% ## [1] 14.83758
% ## >


% ## - sum (p * log(p) + (1-p) * log(1-p)) #entropía
% ## @ 
% ## \end{frame}

% ## \begin{frame} [fragile]
% ##   \frametitle{Respuesta dicótoma}
% ## <<>>=
% ## p <- red2 $ fitted.values             #una sola columna
% ## - sum (p * log(p) + (1-p) * log(1-p)) #entropía
% ## ## equivale a 
