00 - A - Introducción a Aprendizaje Automático#

Versión v.3#

El notebook lo puedo modificar, esta versión es la v.1 a 30/10/2024 a 9 am de Caracas.

1 Aprendizaje automático#

Nuestro objetivo en todo el curso es entender, adaptar y resolver el siguiente concepto:

“Se dice que un programa aprende de la experiencia E respecto a una clase de tareas T y una medida de rendimiento R, si su rendimiento en las tareas de T, medidas respecto a R, mejoran con la experiencia E.”

Tom Mitchell. Machine Learning. Página 3-4 (1997), McGraw-Hill, New York

1.1 Noción básica#

Tomemos en cuenta el caso más básico posible. Tenemos una tabla de datos con dos variables y 10 entradas. Nuestro objetivo, de ser posible, es predecir \(y\) en base a \(x\).

x

y

1

.7

2

3.1

3

2.6

4

3.1

5

5.1

6

7.3

7

8.3

8

9.2

9

5.4

10

10.9

1.2 Representación#

Para entender mejor los datos, podemos siempre buscar métodos que nos ayuden a representarlos de tal manera que sea más sencillo visualizarlos.

El siguiente es un gráfico de dispersión donde buscamos ver gráficamente nuestros datos. El gráfico busca representar cada par ordenado \((x_i, y_i)\) de nuestra tabla. Por convención, el eje X (o abscisas) es la variable que recibe nuestra función y el eje Y (ordenadas) es el eje de predicción.

image.png

1.3 Otros ejemplos#

1.3.1 Detección de correos SPAM#

image.png

  1. Problema: Entender si un correos electrónico es ”spam” o ”no spam”.

  2. función?: image.png

  3. Cómo definir la representación?: Defino \(X\) como el conjunto de secuencias que representan documentos de texto. $\( X = \{x_1, x_2, x_3, \ldots, x_N\} \)$

    • Donde:

      1. \(x_i\) representa una secuencia de caracteres arbitraria.

      2. \(N\) es el número de secuencias disponibles.

    • Discusión

      1. Cada \(x_i\) puede contener palabras, frases o caracteres que conforman el contenido del documento.

      2. El objetivo de la función es etiquetar cada \(x_i\) como “spam” o “no spam” según su contenido.

Es fácil saber el rango de la función $\(f(x_i) \in \{ spam, no\;\;spam \}\)$

Ahora, supongamos que intentamos representar todas las oraciones y de alguna manera obtenemos \(f\)

  1. \(f(\textbf{Abbiamo notato una nuova connessione}) = spam\)

  2. \(f(\textbf{Abbiamo notato una nuova}) = spam\)

  3. \(\cdots\)

  4. \(f(\textbf{Abbiamo})=?\)

Buscamos resolver el mismo problema pero se pueden tener muchos enfoques:

  1. Diccionario de Palabras: Se tiene un diccionario que asigna cada palabra a un índice único. $\( \text{Diccionario: } w_i \rightarrow i \)$

  2. Matriz de Embedding: Se utiliza una matriz de embedding para representar cada palabra como un vector de características. $\(\text{Embedding de } w_i: \vec{v}_i \in \mathbb{R}^d \)$

  • Ejemplo: Si (d = 3) (vectores tridimensionales), el embedding de la palabra “manzana” puede ser representado como $\(\vec{v}_{\text{manzana}} = [0.2, 0.8, 0.5]\)$.

  • No solo eso, en el futuro podremos hacer: image.png

Nikhil Birajdar

1.3.2 Predicción de precios de inmuebles#

image.png

1.3.3 Segmentación de imágenes médicas#

image.png

Esto nos permite, por ejemplo, dividir zonas de interés del cerebro para predecir si una persona es propensa o no a desarrollar neuropatologías como Alzheimer, Demencia, etc.

image.png

import requests

def download_video(url, output_path='video.mp4'):
    try:
        # Send GET request
        response = requests.get(url, stream=True)
        response.raise_for_status()  # Raise exception for bad status codes

        # Open file and write the content
        with open(output_path, 'wb') as f:
            for chunk in response.iter_content(chunk_size=8192):
                if chunk:
                    f.write(chunk)

        print(f"Video downloaded successfully to {output_path}")

    except requests.exceptions.RequestException as e:
        print(f"Error downloading video: {str(e)}")
# Example usage
video_url = "https://github.com/ucvia/ml-book/blob/main/videos/Normal_vesus_rank_40_and_100_legend.mp4"  # Must be direct link to video file
download_video(video_url, "Normal_vesus_rank_40_and_100_legend.mp4")
Video downloaded successfully to Normal_vesus_rank_40_and_100_legend.mp4
import moviepy.editor
moviepy.editor.ipython_display("Normal_vesus_rank_40_and_100_legend.mp4")
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
File ~/.local/share/mise/installs/python/3.8.20/lib/python3.8/site-packages/moviepy/video/io/ffmpeg_reader.py:285, in ffmpeg_parse_infos(filename, print_infos, check_duration, fps_source)
    284 index = -1 if is_GIF else 0
--> 285 line = [l for l in lines if keyword in l][index]
    286 match = re.findall("([0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9][0-9])", line)[0]

IndexError: list index out of range

During handling of the above exception, another exception occurred:

OSError                                   Traceback (most recent call last)
Cell In[3], line 2
      1 import moviepy.editor
----> 2 moviepy.editor.ipython_display("Normal_vesus_rank_40_and_100_legend.mp4")

File ~/.local/share/mise/installs/python/3.8.20/lib/python3.8/site-packages/moviepy/video/io/html_tools.py:220, in ipython_display(clip, filetype, maxduration, t, fps, rd_kwargs, center, **html_kwargs)
    217 if t is not None:
    218     clip = clip.to_ImageClip(t)
--> 220 return HTML2(html_embed(clip, filetype=filetype, maxduration=maxduration,
    221             center=center, rd_kwargs=rd_kwargs, **html_kwargs))

File ~/.local/share/mise/installs/python/3.8.20/lib/python3.8/site-packages/moviepy/video/io/html_tools.py:140, in html_embed(clip, filetype, maxduration, rd_kwargs, center, **html_kwargs)
    135         raise ValueError("This video extension cannot be displayed in the "
    136                "IPython Notebook. Allowed extensions: "+allowed_exts)
    138 if filetype in ['audio', 'video']:
--> 140     duration = ffmpeg_parse_infos(filename)['duration']
    141     if duration > maxduration:
    142         raise ValueError("The duration of video %s (%.1f) exceeds the 'maxduration' "%(filename, duration)+
    143                          "attribute. You can increase 'maxduration', by passing 'maxduration' parameter"
    144                          "to ipython_display function."
    145                          "But note that embedding large videos may take all the memory away !")

File ~/.local/share/mise/installs/python/3.8.20/lib/python3.8/site-packages/moviepy/video/io/ffmpeg_reader.py:289, in ffmpeg_parse_infos(filename, print_infos, check_duration, fps_source)
    287         result['duration'] = cvsecs(match)
    288     except:
--> 289         raise IOError(("MoviePy error: failed to read the duration of file %s.\n"
    290                        "Here are the file infos returned by ffmpeg:\n\n%s")%(
    291                           filename, infos))
    293 # get the output line that speaks about video
    294 lines_video = [l for l in lines if ' Video: ' in l and re.search('\d+x\d+', l)]

OSError: MoviePy error: failed to read the duration of file Normal_vesus_rank_40_and_100_legend.mp4.
Here are the file infos returned by ffmpeg:

ffmpeg version 4.2.2-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 8 (Debian 8.3.0-6)
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
  libpostproc    55.  5.100 / 55.  5.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x67e5500] Format mov,mp4,m4a,3gp,3g2,mj2 detected only with low score of 1, misdetection possible!
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x67e5500] moov atom not found
Normal_vesus_rank_40_and_100_legend.mp4: Invalid data found when processing input
import moviepy.editor
moviepy.editor.ipython_display("https://github.com/ucvia/ml-book/raw/refs/heads/main/videos/Normal_vesus_rank_40_and_100_legend.mp4")

1.3.4 Predicción de ganador en un juego de League of Legends#

image.png

1.3.5 Predicción de ganador en juegos de MLB#

image.png

1.4 Mismo input, distinto objetivo#

Muchas veces, dado un un conjunto de datos \(X\) podemos buscar distintas funciones \(f_1, f_2, \cdots, f_k\) que varían dependiendo del objetivo que queramos conseguir.

Imaginemos que tenemos la siguiente imagen

image.png

Qué podríamos intentar predecir?

  1. Quiero solamente la región donde aparezcan animales.

  2. Cuántas aves hay en la imagen?

  3. Describe la imagen.

1.4.1 Eliminar fondo de una imagen#

image.png

1.4.2 Conseguir aves y contarlas#

image.png

image.png

1.4.3 En funcionamento (ChatGPT - GPT4)#

image.png

image.png

image.png

2 Objetivo principal (por ahora) de ML#

El caso simple es asumir que buscamos predecir un valor en base a conocimiento del pasado.

Encontrar una función, denotada como \(f\), que mapee los datos de entrada \(X\) a las etiquetas de salida \(Y\).

\[ Y = f(x) \text{ para } x \in X \]

o de igual forma

\[ f: X \rightarrow Y \]

Donde:

  1. \(X\) representa los datos de entrada.

  2. \(Y\) son las etiquetas de salida o las respuestas deseadas.

  3. \(f(\cdot)\) es la función que el modelo de aprendizaje supervisado busca “aprender”.