0% encontró este documento útil (0 votos)
0 vistas88 páginas

Manual Python

El manual de Python de Carmen Reina es una guía integral para estudiantes de Machine Learning, cubriendo desde fundamentos hasta técnicas avanzadas y librerías como NumPy, Pandas y Scikit-learn. Se destaca la facilidad de uso de Python y su ecosistema robusto, así como la recomendación de utilizar Google Colab como entorno de trabajo. Incluye secciones sobre estructuras de datos, control de flujo, funciones y manejo de excepciones, proporcionando una base sólida para el aprendizaje y aplicación de Python en ciencia de datos.

Cargado por

achilipun
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
0 vistas88 páginas

Manual Python

El manual de Python de Carmen Reina es una guía integral para estudiantes de Machine Learning, cubriendo desde fundamentos hasta técnicas avanzadas y librerías como NumPy, Pandas y Scikit-learn. Se destaca la facilidad de uso de Python y su ecosistema robusto, así como la recomendación de utilizar Google Colab como entorno de trabajo. Incluye secciones sobre estructuras de datos, control de flujo, funciones y manejo de excepciones, proporcionando una base sólida para el aprendizaje y aplicación de Python en ciencia de datos.

Cargado por

achilipun
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Manual de Python

Carmen Reina
Enero 2026

[Link]
Índice de Contenidos
1. Introducción a Python

2. Fundamentos de Python

3. Python Avanzado

4. NumPy: Computación Numérica

5. NumPy Avanzado

6. Pandas: Manipulación de Datos

7. Pandas Avanzado

8. Matplotlib: Visualización Básica

9. Seaborn: Visualización Estadística

10. Scikit-learn: Machine Learning

11. Scikit-learn Avanzado

12. Introducción a Transformers

13. Buenas Prácticas y Consejos

2
1. Introducción a Python
Este manual es una guía completa de Python y sus librerías fundamentales para el Machine
Learning, diseñada específicamente para los alumnos de la Microcredencial en Machine Learning y
Modelos de Lenguaje de la UNED. El objetivo es proporcionar una base sólida que os permita seguir
el curso con fluidez, incluso si vuestra experiencia previa en programación es limitada.

1.1. ¿Por qué Python?


Python se ha convertido en el lenguaje de facto para la ciencia de datos y el Machine Learning.
Según el índice TIOBE de 2024, Python es el lenguaje de programación más popular del mundo.
Las razones de su éxito son múltiples:

• Sintaxis Clara: Es fácil de leer y escribir, lo que acelera el desarrollo y reduce errores.

• Ecosistema Rico: Dispone de una vasta colección de librerías especializadas como NumPy,
Pandas, Scikit-learn, TensorFlow, PyTorch y Transformers.

• Comunidad Activa: Una comunidad global de millones de desarrolladores y científicos de


datos que contribuyen con nuevas herramientas y ofrecen soporte.

• Interoperabilidad: Se integra fácilmente con otros lenguajes como C, C++ y Java,


permitiendo optimizar partes críticas del código.

1.2. Entorno de Trabajo: Google Colab


Para evitar problemas de instalación y configuración, recomendamos utilizar Google Colaboratory
(Colab). Es un entorno de Jupyter Notebook gratuito que se ejecuta en la nube y que incluye la
mayoría de las librerías que necesitaremos. Solo necesitáis una cuenta de Google para empezar.

Ventajas de Google Colab:

• Sin configuración: No requiere instalación local de Python ni librerías.

• Acceso a GPUs: Ofrece GPUs y TPUs gratuitas para acelerar el entrenamiento de modelos.

• Almacenamiento en la nube: Los notebooks se guardan automáticamente en Google Drive.

• Colaboración: Podéis compartir notebooks con compañeros y tutores fácilmente.

1.3. Instalación Local (Alternativa)


Si preferís trabajar en vuestro ordenador, podéis instalar Python usando Anaconda, una distribución
que incluye Python y las principales librerías de ciencia de datos.

3
# Verificar la versión de Python instalada

python --version

# Instalar librerías con pip

pip install numpy pandas matplotlib seaborn scikit-learn

# Instalar librerías con conda (si usáis Anaconda)

conda install numpy pandas matplotlib seaborn scikit-learn

4
2. Fundamentos de Python
2.1. Variables y Tipos de Datos
En Python, no es necesario declarar el tipo de una variable. El tipo se asigna dinámicamente en
tiempo de ejecución. Python es un lenguaje de tipado dinámico y fuerte.

# Variables numéricas

numero_entero = 10 # int

numero_flotante = 3.14159 # float

numero_complejo = 3 + 4j # complex

# Cadena de texto (string)

texto = "Hola, UNED"

texto_multilinea = '''Este es un texto

que ocupa varias líneas'''

# Booleano

es_verdadero = True

es_falso = False

# Verificar tipos

print(type(numero_entero)) # <class 'int'>

print(type(numero_flotante)) # <class 'float'>

print(type(texto)) # <class 'str'>

print(type(es_verdadero)) # <class 'bool'>

5
2.2. Operadores
Python soporta diversos tipos de operadores para realizar operaciones aritméticas, comparaciones
y operaciones lógicas.

Operadores Aritméticos

a = 10

b = 3

print(f"Suma: {a + b}") # 13

print(f"Resta: {a - b}") # 7

print(f"Multiplicación: {a * b}") # 30

print(f"División: {a / b}") # 3.333...

print(f"División entera: {a // b}") # 3

print(f"Módulo: {a % b}") # 1

print(f"Potencia: {a ** b}") # 1000

Operadores de Comparación

x = 5

y = 10

print(f"x == y: {x == y}") # False

print(f"x != y: {x != y}") # True

print(f"x < y: {x < y}") # True

print(f"x > y: {x > y}") # False

print(f"x <= y: {x <= y}") # True

6
print(f"x >= y: {x >= y}") # False

Operadores Lógicos

p = True

q = False

print(f"p and q: {p and q}") # False

print(f"p or q: {p or q}") # True

print(f"not p: {not p}") # False

# Evaluación de cortocircuito

resultado = p or (1/0) # No lanza error porque p es True

2.3. Estructuras de Datos


Python ofrece varias estructuras de datos integradas que son fundamentales para la programación.

Listas

Las listas son colecciones ordenadas y modificables que pueden contener elementos de diferentes
tipos.

# Crear una lista

modulos = ["Fundamentos de ML", "Aprendizaje Supervisado", "LLMs"]

# Acceder a elementos (índice comienza en 0)

print(modulos[0]) # "Fundamentos de ML"

7
print(modulos[-1]) # "LLMs" (último elemento)

# Modificar elementos

modulos[1] = "Clasificación y Regresión"

# Añadir elementos

[Link]("Agentes Inteligentes")

[Link](0, "Introducción")

# Eliminar elementos

[Link]("Introducción")

ultimo = [Link]() # Elimina y devuelve el último

# Slicing (rebanado)

primeros_dos = modulos[0:2]

desde_segundo = modulos[1:]

hasta_penultimo = modulos[:-1]

# Longitud de la lista

print(f"Número de módulos: {len(modulos)}")

# Verificar si un elemento existe

if "LLMs" in modulos:

print("El módulo de LLMs está incluido")

8
Tuplas

Las tuplas son similares a las listas, pero son inmutables (no se pueden modificar después de
crearlas).

# Crear una tupla

coordenadas = (40.4168, -3.7038) # Madrid

# Acceder a elementos

latitud = coordenadas[0]

longitud = coordenadas[1]

# Desempaquetado de tuplas

lat, lon = coordenadas

# Las tuplas son inmutables

# coordenadas[0] = 41.0 # Esto lanzaría un error

# Tuplas con un solo elemento (necesitan coma)

tupla_un_elemento = (42,)

# Uso común: devolver múltiples valores de una función

def obtener_estadisticas(numeros):

return min(numeros), max(numeros), sum(numeros)/len(numeros)

minimo, maximo, media = obtener_estadisticas([1, 2, 3, 4, 5])

9
Diccionarios

Los diccionarios son colecciones de pares clave-valor, muy útiles para almacenar datos
estructurados.

# Crear un diccionario

alumno = {

"nombre": "Ana García",

"edad": 30,

"curso": "Microcredencial ML",

"notas": [8.5, 9.0, 7.5]

# Acceder a valores

print(alumno["nombre"])

print([Link]("email", "No disponible")) # Con valor por defecto

# Modificar valores

alumno["edad"] = 31

# Añadir nuevos pares

alumno["email"] = "ana@[Link]"

# Eliminar pares

del alumno["email"]

edad = [Link]("edad")

10
# Iterar sobre un diccionario

for clave, valor in [Link]():

print(f"{clave}: {valor}")

# Obtener solo claves o valores

claves = [Link]()

valores = [Link]()

# Diccionarios anidados

curso = {

"nombre": "ML y LLMs",

"modulos": {

"m1": "Fundamentos",

"m2": "Supervisado",

"m3": "LLMs"

print(curso["modulos"]["m3"]) # "LLMs"

Conjuntos (Sets)

Los conjuntos son colecciones desordenadas de elementos únicos, útiles para eliminar duplicados
y operaciones matemáticas de conjuntos.

# Crear un conjunto

lenguajes = {"Python", "R", "Julia", "Python"} # "Python" aparece solo una vez

print(lenguajes) # {'Python', 'R', 'Julia'}

11
# Añadir y eliminar elementos

[Link]("Scala")

[Link]("R")

# Operaciones de conjuntos

ml_lenguajes = {"Python", "R", "Julia"}

web_lenguajes = {"Python", "JavaScript", "TypeScript"}

# Unión

todos = ml_lenguajes | web_lenguajes

# Intersección

comunes = ml_lenguajes & web_lenguajes

# Diferencia

solo_ml = ml_lenguajes - web_lenguajes

print(f"Comunes: {comunes}") # {'Python'}

12
2.4. Estructuras de Control
Condicionales

nota = 7.5

if nota >= 9:

calificacion = "Sobresaliente"

elif nota >= 7:

calificacion = "Notable"

elif nota >= 5:

calificacion = "Aprobado"

else:

calificacion = "Suspenso"

print(f"Calificación: {calificacion}")

# Operador ternario

resultado = "Aprobado" if nota >= 5 else "Suspenso"

# Condiciones múltiples

edad = 25

tiene_carnet = True

if edad >= 18 and tiene_carnet:

print("Puede conducir")

13
Bucles For

# Iterar sobre una lista

modulos = ["ML", "LLMs", "Agentes"]

for modulo in modulos:

print(f"Estudiando: {modulo}")

# Iterar con índice

for i, modulo in enumerate(modulos):

print(f"Módulo {i+1}: {modulo}")

# Iterar sobre un rango

for i in range(5):

print(i) # 0, 1, 2, 3, 4

# Iterar sobre un diccionario

alumno = {"nombre": "Ana", "edad": 30}

for clave, valor in [Link]():

print(f"{clave}: {valor}")

# Iterar sobre múltiples listas simultáneamente

nombres = ["Ana", "Luis", "Marta"]

edades = [30, 25, 35]

for nombre, edad in zip(nombres, edades):

print(f"{nombre} tiene {edad} años")

14
Bucles While

# Bucle while básico

contador = 0

while contador < 5:

print(f"Contador: {contador}")

contador += 1

# Break y continue

numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

for num in numeros:

if num == 3:

continue # Salta al siguiente

if num == 8:

break # Sale del bucle

print(num)

# While con else (se ejecuta si no hay break)

i = 0

while i < 5:

i += 1

else:

print("Bucle completado sin break")

2.5. Funciones
Las funciones permiten encapsular código reutilizable y organizar mejor los programas.

15
# Función básica

def saludar(nombre):

"""Saluda a una persona por su nombre."""

return f"Hola, {nombre}!"

mensaje = saludar("Ana")

print(mensaje)

# Función con múltiples parámetros

def calcular_media(numeros):

"""Calcula la media de una lista de números."""

if not numeros:

return 0

return sum(numeros) / len(numeros)

# Parámetros con valores por defecto

def crear_alumno(nombre, edad=18, curso="General"):

return {

"nombre": nombre,

"edad": edad,

"curso": curso

alumno1 = crear_alumno("Ana", 30, "ML")

alumno2 = crear_alumno("Luis") # Usa valores por defecto

16
# Argumentos arbitrarios (*args)

def sumar_todos(*numeros):

return sum(numeros)

total = sumar_todos(1, 2, 3, 4, 5)

# Argumentos con nombre arbitrarios (**kwargs)

def mostrar_info(**datos):

for clave, valor in [Link]():

print(f"{clave}: {valor}")

mostrar_info(nombre="Ana", edad=30, ciudad="Madrid")

2.6. Manejo de Excepciones


El manejo de excepciones permite controlar errores de forma elegante sin que el programa se
detenga abruptamente.

# Try-except básico

try:

resultado = 10 / 0

except ZeroDivisionError:

print("Error: No se puede dividir por cero")

# Capturar múltiples excepciones

17
try:

numero = int("abc")

except ValueError:

print("Error: No es un número válido")

except TypeError:

print("Error: Tipo incorrecto")

# Capturar cualquier excepción

try:

resultado = operacion_riesgosa()

except Exception as e:

print(f"Error inesperado: {e}")

# Try-except-else-finally

try:

archivo = open("[Link]", "r")

contenido = [Link]()

except FileNotFoundError:

print("El archivo no existe")

else:

print("Archivo leído correctamente")

finally:

print("Esto siempre se ejecuta")

# Lanzar excepciones

18
def dividir(a, b):

if b == 0:

raise ValueError("El divisor no puede ser cero")

return a / b

19
3. Python Avanzado
3.1. Comprensiones de Listas
Las comprensiones de listas (list comprehensions) son una forma concisa y elegante de crear listas
en Python.

# Forma tradicional

cuadrados = []

for x in range(10):

[Link](x ** 2)

# Con comprensión de lista

cuadrados = [x ** 2 for x in range(10)]

# Con condición

pares = [x for x in range(20) if x % 2 == 0]

# Con transformación y condición

mayusculas = [[Link]() for palabra in ["hola", "mundo"] if len(palabra) > 3]

# Comprensiones anidadas

matriz = [[i * j for j in range(1, 4)] for i in range(1, 4)]

# [[1, 2, 3], [2, 4, 6], [3, 6, 9]]

# Aplanar una matriz

matriz = [[1, 2], [3, 4], [5, 6]]

20
plana = [num for fila in matriz for num in fila]

# [1, 2, 3, 4, 5, 6]

3.2. Comprensiones de Diccionarios y Conjuntos

# Comprensión de diccionario

nombres = ["Ana", "Luis", "Marta"]

longitudes = {nombre: len(nombre) for nombre in nombres}

# {'Ana': 3, 'Luis': 4, 'Marta': 5}

# Invertir un diccionario

original = {"a": 1, "b": 2, "c": 3}

invertido = {v: k for k, v in [Link]()}

# {1: 'a', 2: 'b', 3: 'c'}

# Comprensión de conjunto

numeros = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

unicos = {x for x in numeros}

# {1, 2, 3, 4}

# Filtrar diccionario

datos = {"a": 1, "b": 2, "c": 3, "d": 4}

filtrado = {k: v for k, v in [Link]() if v > 2}

# {'c': 3, 'd': 4}

21
3.3. Funciones Lambda
Las funciones lambda son funciones anónimas de una sola expresión, útiles para operaciones
simples.

# Función lambda básica

cuadrado = lambda x: x ** 2

print(cuadrado(5)) # 25

# Lambda con múltiples argumentos

suma = lambda a, b: a + b

print(suma(3, 4)) # 7

# Uso con sorted()

alumnos = [

{"nombre": "Ana", "nota": 8.5},

{"nombre": "Luis", "nota": 9.0},

{"nombre": "Marta", "nota": 7.5}

ordenados = sorted(alumnos, key=lambda x: x["nota"], reverse=True)

# Uso con filter()

numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

pares = list(filter(lambda x: x % 2 == 0, numeros))

# Uso con map()

cuadrados = list(map(lambda x: x ** 2, numeros))

22
# Uso con reduce()

from functools import reduce

producto = reduce(lambda x, y: x * y, numeros)

3.4. Generadores
Los generadores son funciones que producen una secuencia de valores de forma perezosa (lazy
evaluation), ahorrando memoria.

# Generador con yield

def contador(n):

i = 0

while i < n:

yield i

i += 1

# Usar el generador

for num in contador(5):

print(num)

# Expresión generadora (similar a comprensión de lista)

cuadrados_gen = (x ** 2 for x in range(1000000))

# Generador infinito

def numeros_pares():

23
n = 0

while True:

yield n

n += 2

# Usar con next()

gen = numeros_pares()

print(next(gen)) # 0

print(next(gen)) # 2

print(next(gen)) # 4

# Generador para leer archivos grandes línea a línea

def leer_archivo_grande(ruta):

with open(ruta, 'r') as f:

for linea in f:

yield [Link]()

3.5. Decoradores
Los decoradores son funciones que modifican el comportamiento de otras funciones, muy útiles
para logging, timing, validación, etc.

# Decorador básico

def mi_decorador(func):

def wrapper(*args, **kwargs):

print(f"Llamando a {func.__name__}")

resultado = func(*args, **kwargs)

24
print(f"Función {func.__name__} completada")

return resultado

return wrapper

@mi_decorador

def saludar(nombre):

return f"Hola, {nombre}!"

# Decorador para medir tiempo de ejecución

import time

def medir_tiempo(func):

def wrapper(*args, **kwargs):

inicio = [Link]()

resultado = func(*args, **kwargs)

fin = [Link]()

print(f"{func.__name__} tardó {fin - inicio:.4f} segundos")

return resultado

return wrapper

@medir_tiempo

def operacion_lenta():

[Link](1)

return "Completado"

25
# Decorador con parámetros

def repetir(veces):

def decorador(func):

def wrapper(*args, **kwargs):

for _ in range(veces):

resultado = func(*args, **kwargs)

return resultado

return wrapper

return decorador

@repetir(3)

def saludar():

print("Hola!")

3.6. Context Managers (with)

# Uso básico con archivos

with open("[Link]", "w") as f:

[Link]("Hola, mundo!")

# El archivo se cierra automáticamente

# Crear un context manager con clase

class MiContextManager:

def __enter__(self):

print("Entrando al contexto")

26
return self

def __exit__(self, exc_type, exc_val, exc_tb):

print("Saliendo del contexto")

return False

with MiContextManager() as cm:

print("Dentro del contexto")

# Crear un context manager con contextlib

from contextlib import contextmanager

@contextmanager

def medir_tiempo():

inicio = [Link]()

yield

fin = [Link]()

print(f"Tiempo transcurrido: {fin - inicio:.4f} segundos")

with medir_tiempo():

[Link](0.5)

27
4. NumPy: Computación Numérica
NumPy (Numerical Python) es la librería fundamental para la computación científica en Python. Su
principal objeto es el ndarray (array n-dimensional), que es mucho más rápido y eficiente que las
listas de Python para operaciones numéricas.

4.1. Creación de Arrays

import numpy as np

# Crear un array desde una lista

a = [Link]([1, 2, 3, 4, 5])

print(f"Array 1D: {a}")

print(f"Tipo: {[Link]}")

print(f"Forma: {[Link]}")

# Crear una matriz (array 2D)

b = [Link]([[1, 2, 3], [4, 5, 6]])

print(f"Matriz 2D:\n{b}")

print(f"Forma: {[Link]}") # (2, 3)

# Especificar el tipo de datos

c = [Link]([1, 2, 3], dtype=np.float64)

# Arrays especiales

zeros = [Link]((3, 4)) # Matriz de ceros

ones = [Link]((2, 3)) # Matriz de unos

empty = [Link]((2, 2)) # Matriz sin inicializar

28
full = [Link]((2, 3), 7) # Matriz llena de 7s

eye = [Link](3) # Matriz identidad 3x3

# Secuencias

rango = [Link](0, 10, 2) # [0, 2, 4, 6, 8]

linspace = [Link](0, 1, 5) # 5 números entre 0 y 1

# Arrays aleatorios

aleatorio = [Link](3, 3) # Uniforme [0, 1)

normal = [Link](3, 3) # Normal estándar

enteros = [Link](0, 10, (3, 3)) # Enteros

4.2. Indexación y Slicing

# Array 1D

a = [Link]([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

print(a[0]) # Primer elemento: 0

print(a[-1]) # Último elemento: 9

print(a[2:5]) # Elementos 2 a 4: [2, 3, 4]

print(a[::2]) # Cada 2 elementos: [0, 2, 4, 6, 8]

print(a[::-1]) # Invertido: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

# Array 2D

b = [Link]([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

29
print(b[0, 0]) # Elemento (0,0): 1

print(b[1, :]) # Segunda fila: [4, 5, 6]

print(b[:, 1]) # Segunda columna: [2, 5, 8]

print(b[0:2, 1:3]) # Submatriz

# Indexación booleana

a = [Link]([1, 2, 3, 4, 5])

mask = a > 3

print(a[mask]) # [4, 5]

print(a[a > 3]) # Forma abreviada

# Indexación con arrays

indices = [Link]([0, 2, 4])

print(a[indices]) # [1, 3, 5]

4.3. Operaciones Básicas

a = [Link]([1, 2, 3, 4, 5])

b = [Link]([10, 20, 30, 40, 50])

# Operaciones elemento a elemento

print(a + b) # [11, 22, 33, 44, 55]

print(a * b) # [10, 40, 90, 160, 250]

print(a ** 2) # [1, 4, 9, 16, 25]

30
print([Link](a)) # [1., 1.41, 1.73, 2., 2.24]

# Funciones de agregación

print([Link](a)) # 15

print([Link](a)) # 3.0

print([Link](a)) # 1.41

print([Link](a)) # 1

print([Link](a)) # 5

print([Link](a)) # 4 (índice del máximo)

# Operaciones a lo largo de un eje

matriz = [Link]([[1, 2, 3], [4, 5, 6]])

print([Link](matriz, axis=0)) # Suma por columnas: [5, 7, 9]

print([Link](matriz, axis=1)) # Suma por filas: [6, 15]

# Operaciones de comparación

print(a > 3) # [False, False, False, True, True]

print([Link](a > 4)) # True

print([Link](a > 0)) # True

4.4. Reshape y Manipulación de Forma

a = [Link](12)

# Reshape

31
b = [Link](3, 4)

print(b)

# [[ 0, 1, 2, 3],

# [ 4, 5, 6, 7],

# [ 8, 9, 10, 11]]

# Reshape con -1 (dimensión automática)

c = [Link](2, -1) # 2 filas, columnas automáticas

print([Link]) # (2, 6)

# Aplanar

d = [Link]() # Copia

e = [Link]() # Vista (más eficiente)

# Transponer

print(b.T)

# Añadir dimensiones

f = [Link]([1, 2, 3])

print([Link]) # (3,)

print(f[[Link], :].shape) # (1, 3)

print(f[:, [Link]].shape) # (3, 1)

# Concatenar arrays

x = [Link]([[1, 2], [3, 4]])

32
y = [Link]([[5, 6], [7, 8]])

print([Link]([x, y], axis=0)) # Vertical

print([Link]([x, y], axis=1)) # Horizontal

print([Link]([x, y])) # Equivalente a axis=0

print([Link]([x, y])) # Equivalente a axis=1

33
5. NumPy Avanzado
5.1. Broadcasting
Broadcasting es una técnica que permite a NumPy realizar operaciones entre arrays de diferentes
formas de manera eficiente.

# Broadcasting básico

a = [Link]([1, 2, 3])

b = 2

print(a * b) # [2, 4, 6]

# Broadcasting con matrices

matriz = [Link]([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

vector = [Link]([1, 0, 1])

# Sumar vector a cada fila

print(matriz + vector)

# [[2, 2, 4],

# [5, 5, 7],

# [8, 8, 10]]

# Normalizar columnas (restar media, dividir por std)

media = [Link](axis=0)

std = [Link](axis=0)

normalizado = (matriz - media) / std

34
# Broadcasting con diferentes formas

a = [Link](3).reshape(3, 1) # (3, 1)

b = [Link](3) # (3,)

print(a + b)

# [[0, 1, 2],

# [1, 2, 3],

# [2, 3, 4]]

5.2. Álgebra Lineal

# Producto punto

a = [Link]([1, 2, 3])

b = [Link]([4, 5, 6])

print([Link](a, b)) # 32

# Producto matricial

A = [Link]([[1, 2], [3, 4]])

B = [Link]([[5, 6], [7, 8]])

print([Link](A, B)) # o A @ B

# [[19, 22],

# [43, 50]]

# Determinante

print([Link](A)) # -2.0

35
# Inversa

print([Link](A))

# Autovalores y autovectores

eigenvalues, eigenvectors = [Link](A)

# Resolver sistema de ecuaciones Ax = b

A = [Link]([[3, 1], [1, 2]])

b = [Link]([9, 8])

x = [Link](A, b)

print(x) # [2., 3.]

# Descomposición SVD

U, s, Vt = [Link](A)

# Norma

print([Link](a)) # Norma L2

5.3. Funciones Universales (ufuncs)

# Funciones trigonométricas

angulos = [Link]([0, [Link]/4, [Link]/2, [Link]])

print([Link](angulos))

print([Link](angulos))

36
# Funciones exponenciales y logarítmicas

x = [Link]([1, 2, 3])

print([Link](x)) # e^x

print([Link](x)) # ln(x)

print(np.log10(x)) # log10(x)

# Funciones de redondeo

y = [Link]([1.2, 2.5, 3.7, 4.1])

print([Link](y)) # [1., 2., 3., 4.]

print([Link](y)) # [2., 3., 4., 5.]

print([Link](y)) # [1., 2., 4., 4.]

# Funciones de comparación

a = [Link]([1, 5, 3, 8, 2])

b = [Link]([2, 4, 3, 7, 5])

print([Link](a, b)) # [2, 5, 3, 8, 5]

print([Link](a, b)) # [1, 4, 3, 7, 2]

# Funciones especiales

print([Link]([Link]([-1, -2, 3]))) # [1, 2, 3]

print([Link]([Link]([-5, 0, 5]))) # [-1, 0, 1]

5.4. Estadística con NumPy

# Generar datos

37
[Link](42)

datos = [Link](1000)

# Estadísticas descriptivas

print(f"Media: {[Link](datos):.4f}")

print(f"Mediana: {[Link](datos):.4f}")

print(f"Desviación estándar: {[Link](datos):.4f}")

print(f"Varianza: {[Link](datos):.4f}")

print(f"Mínimo: {[Link](datos):.4f}")

print(f"Máximo: {[Link](datos):.4f}")

# Percentiles

print(f"Percentil 25: {[Link](datos, 25):.4f}")

print(f"Percentil 50: {[Link](datos, 50):.4f}")

print(f"Percentil 75: {[Link](datos, 75):.4f}")

# Correlación

x = [Link](100)

y = 2 * x + [Link](100) * 0.5

correlacion = [Link](x, y)

print(f"Correlación: {correlacion[0, 1]:.4f}")

# Histograma

counts, bins = [Link](datos, bins=20)

38
39
6. Pandas: Manipulación de Datos
Pandas es la librería esencial para la manipulación y análisis de datos tabulares en Python.
Introduce dos estructuras de datos principales: Series (1D) y DataFrame (2D).

6.1. Series

import pandas as pd

# Crear una Serie desde una lista

s = [Link]([1, 3, 5, 7, 9])

print(s)

# Serie con índice personalizado

notas = [Link]([8.5, 9.0, 7.5], index=["Ana", "Luis", "Marta"])

print(notas)

print(notas["Ana"]) # 8.5

# Serie desde un diccionario

datos = {"a": 1, "b": 2, "c": 3}

s = [Link](datos)

# Operaciones con Series

print([Link]()) # Media

print([Link]()) # Máximo

print(notas > 8) # Comparación booleana

print(notas[notas > 8]) # Filtrado

40
6.2. DataFrames

# Crear un DataFrame desde un diccionario

datos = {

"Nombre": ["Ana", "Luis", "Marta", "Juan"],

"Edad": [30, 25, 35, 28],

"Ciudad": ["Madrid", "Barcelona", "Sevilla", "Valencia"],

"Salario": [45000, 38000, 52000, 41000]

df = [Link](datos)

print(df)

# Información básica

print([Link]) # (4, 4)

print([Link]) # Nombres de columnas

print([Link]) # Tipos de datos

print([Link]()) # Información completa

print([Link]()) # Estadísticas descriptivas

# Acceder a columnas

print(df["Nombre"]) # Como Serie

print(df[["Nombre", "Edad"]]) # Múltiples columnas

# Acceder a filas

print([Link][0]) # Primera fila por posición

print([Link][0]) # Primera fila por índice

41
print([Link][0:2]) # Primeras dos filas

# Acceder a celdas específicas

print([Link][0, 1]) # Fila 0, columna 1

print([Link][0, "Edad"]) # Fila 0, columna "Edad"

6.3. Lectura y Escritura de Archivos

# Leer CSV

df = pd.read_csv("[Link]")

# Opciones de lectura

df = pd.read_csv("[Link]",

sep=";", # Separador

header=0, # Fila de encabezados

index_col=0, # Columna como índice

usecols=["A", "B"], # Solo estas columnas

nrows=100, # Primeras 100 filas

na_values=["NA", "?"]) # Valores nulos

# Escribir CSV

df.to_csv("[Link]", index=False)

# Leer/escribir Excel

df = pd.read_excel("[Link]", sheet_name="Hoja1")

42
df.to_excel("[Link]", index=False)

# Leer/escribir JSON

df = pd.read_json("[Link]")

df.to_json("[Link]", orient="records")

# Leer desde URL

url = "[Link]

df = pd.read_csv(url)

6.4. Selección y Filtrado

# Filtrado por condición

mayores_30 = df[df["Edad"] > 30]

print(mayores_30)

# Múltiples condiciones

filtro = (df["Edad"] > 25) & (df["Salario"] > 40000)

resultado = df[filtro]

# Usar query()

resultado = [Link]("Edad > 25 and Salario > 40000")

# Filtrar por valores en una lista

ciudades = ["Madrid", "Barcelona"]

43
resultado = df[df["Ciudad"].isin(ciudades)]

# Filtrar por texto

resultado = df[df["Nombre"].[Link]("a")]

resultado = df[df["Nombre"].[Link]("A")]

# Seleccionar columnas por tipo

numericas = df.select_dtypes(include=["int64", "float64"])

texto = df.select_dtypes(include=["object"])

6.5. Modificación de Datos

# Añadir columna

df["Bonus"] = df["Salario"] * 0.1

# Añadir columna calculada

df["Salario_Total"] = df["Salario"] + df["Bonus"]

# Modificar valores

[Link][df["Nombre"] == "Ana", "Salario"] = 50000

# Renombrar columnas

df = [Link](columns={"Nombre": "Name", "Edad": "Age"})

# Eliminar columnas

44
df = [Link](columns=["Bonus"])

# Eliminar filas

df = [Link](index=[0, 1])

# Ordenar

df = df.sort_values("Salario", ascending=False)

df = df.sort_values(["Ciudad", "Salario"])

# Resetear índice

df = df.reset_index(drop=True)

45
7. Pandas Avanzado
7.1. Valores Nulos

# Detectar valores nulos

print([Link]()) # DataFrame booleano

print([Link]().sum()) # Conteo por columna

print([Link]().any()) # ¿Hay nulos en cada columna?

# Eliminar filas con nulos

df_limpio = [Link]() # Cualquier nulo

df_limpio = [Link](subset=["Edad"]) # Solo en "Edad"

df_limpio = [Link](thresh=3) # Mínimo 3 no-nulos

# Rellenar valores nulos

df["Edad"] = df["Edad"].fillna(0) # Con valor fijo

df["Edad"] = df["Edad"].fillna(df["Edad"].mean()) # Con media

df["Edad"] = df["Edad"].fillna(method="ffill") # Forward fill

df["Edad"] = df["Edad"].fillna(method="bfill") # Backward fill

# Interpolar valores

df["Valor"] = df["Valor"].interpolate()

7.2. Agrupación (GroupBy)

# Datos de ejemplo

46
ventas = [Link]({

"Producto": ["A", "B", "A", "B", "A", "B"],

"Region": ["Norte", "Norte", "Sur", "Sur", "Norte", "Sur"],

"Ventas": [100, 150, 200, 120, 180, 90],

"Cantidad": [10, 15, 20, 12, 18, 9]

})

# Agrupar y agregar

por_producto = [Link]("Producto")["Ventas"].sum()

print(por_producto)

# Múltiples agregaciones

resumen = [Link]("Producto").agg({

"Ventas": ["sum", "mean", "max"],

"Cantidad": ["sum", "count"]

})

# Agrupar por múltiples columnas

por_producto_region = [Link](["Producto", "Region"])["Ventas"].sum()

# Funciones de agregación personalizadas

def rango(x):

return [Link]() - [Link]()

resumen = [Link]("Producto")["Ventas"].agg(rango)

47
# Transform (mantiene la forma original)

ventas["Ventas_Media_Producto"] = [Link]("Producto")["Ventas"].transform("mean")

7.3. Merge y Join

# DataFrames de ejemplo

clientes = [Link]({

"cliente_id": [1, 2, 3, 4],

"nombre": ["Ana", "Luis", "Marta", "Juan"]

})

pedidos = [Link]({

"pedido_id": [101, 102, 103, 104],

"cliente_id": [1, 2, 1, 5],

"total": [150, 200, 75, 300]

})

# Inner join (solo coincidencias)

resultado = [Link](clientes, pedidos, on="cliente_id")

# Left join (todos los clientes)

resultado = [Link](clientes, pedidos, on="cliente_id", how="left")

# Right join (todos los pedidos)

48
resultado = [Link](clientes, pedidos, on="cliente_id", how="right")

# Outer join (todos)

resultado = [Link](clientes, pedidos, on="cliente_id", how="outer")

# Merge con diferentes nombres de columna

resultado = [Link](clientes, pedidos,

left_on="cliente_id",

right_on="cliente_id")

# Concatenar DataFrames

df1 = [Link]({"A": [1, 2], "B": [3, 4]})

df2 = [Link]({"A": [5, 6], "B": [7, 8]})

concatenado = [Link]([df1, df2], ignore_index=True)

7.4. Pivot Tables

# Pivot table

pivot = ventas.pivot_table(

values="Ventas",

index="Producto",

columns="Region",

aggfunc="sum",

fill_value=0

49
print(pivot)

# Múltiples valores y funciones

pivot = ventas.pivot_table(

values=["Ventas", "Cantidad"],

index="Producto",

columns="Region",

aggfunc={"Ventas": "sum", "Cantidad": "mean"}

# Melt (inverso de pivot)

df_largo = [Link](pivot.reset_index(),

id_vars=["Producto"],

var_name="Region",

value_name="Ventas")

7.5. Apply y Map

# Apply a una columna

df["Nombre_Upper"] = df["Nombre"].apply([Link])

# Apply con función personalizada

def categorizar_edad(edad):

if edad < 30:

return "Joven"

50
elif edad < 50:

return "Adulto"

else:

return "Senior"

df["Categoria"] = df["Edad"].apply(categorizar_edad)

# Apply con lambda

df["Salario_Miles"] = df["Salario"].apply(lambda x: x / 1000)

# Apply a filas (axis=1)

def calcular_total(row):

return row["Salario"] + row["Bonus"]

df["Total"] = [Link](calcular_total, axis=1)

# Map para reemplazar valores

mapeo = {"Madrid": "MAD", "Barcelona": "BCN", "Sevilla": "SVQ"}

df["Codigo_Ciudad"] = df["Ciudad"].map(mapeo)

# Replace

df["Ciudad"] = df["Ciudad"].replace({"Madrid": "MAD", "Barcelona": "BCN"})

51
8. Matplotlib: Visualización Básica
Matplotlib es la librería base para crear visualizaciones estáticas en Python. Proporciona control
total sobre cada aspecto de los gráficos.

8.1. Gráficos de Líneas

import [Link] as plt

import numpy as np

# Datos

x = [Link](0, 10, 100)

y1 = [Link](x)

y2 = [Link](x)

# Gráfico básico

[Link](figsize=(10, 6))

[Link](x, y1, label="Seno", color="blue", linewidth=2)

[Link](x, y2, label="Coseno", color="red", linestyle="--")

[Link]("Funciones Trigonométricas", fontsize=14)

[Link]("X", fontsize=12)

[Link]("Y", fontsize=12)

[Link]()

[Link](True, alpha=0.3)

[Link]()

52
# Múltiples subplots

fig, axes = [Link](2, 2, figsize=(12, 8))

axes[0, 0].plot(x, y1)

axes[0, 0].set_title("Seno")

axes[0, 1].plot(x, y2)

axes[0, 1].set_title("Coseno")

axes[1, 0].plot(x, y1 ** 2)

axes[1, 0].set_title("Seno²")

axes[1, 1].plot(x, y2 ** 2)

axes[1, 1].set_title("Coseno²")

plt.tight_layout()

[Link]()

8.2. Gráficos de Barras

# Datos

categorias = ["A", "B", "C", "D", "E"]

valores = [23, 45, 56, 78, 32]

# Gráfico de barras vertical

53
[Link](figsize=(8, 5))

[Link](categorias, valores, color="steelblue", edgecolor="black")

[Link]("Ventas por Categoría")

[Link]("Categoría")

[Link]("Ventas")

[Link]()

# Gráfico de barras horizontal

[Link](figsize=(8, 5))

[Link](categorias, valores, color="coral")

[Link]("Ventas por Categoría")

[Link]("Ventas")

[Link]("Categoría")

[Link]()

# Barras agrupadas

x = [Link](len(categorias))

width = 0.35

valores2 = [30, 40, 50, 60, 40]

fig, ax = [Link](figsize=(10, 6))

bars1 = [Link](x - width/2, valores, width, label="2023")

bars2 = [Link](x + width/2, valores2, width, label="2024")

ax.set_xticks(x)

54
ax.set_xticklabels(categorias)

[Link]()

[Link]()

8.3. Histogramas y Distribuciones

# Datos aleatorios

[Link](42)

datos = [Link](1000)

# Histograma básico

[Link](figsize=(10, 6))

[Link](datos, bins=30, color="steelblue", edgecolor="black", alpha=0.7)

[Link]("Distribución Normal")

[Link]("Valor")

[Link]("Frecuencia")

[Link]([Link](), color="red", linestyle="--", label=f"Media: {[Link]():.2f}")

[Link]()

[Link]()

# Histograma con densidad

[Link](figsize=(10, 6))

[Link](datos, bins=30, density=True, alpha=0.7)

[Link]("Distribución Normal (Densidad)")

[Link]()

55
# Múltiples histogramas

datos1 = [Link](1000)

datos2 = [Link](1000) + 2

[Link](figsize=(10, 6))

[Link](datos1, bins=30, alpha=0.5, label="Grupo A")

[Link](datos2, bins=30, alpha=0.5, label="Grupo B")

[Link]()

[Link]()

8.4. Scatter Plots

# Datos

[Link](42)

x = [Link](100)

y = 2 * x + [Link](100) * 0.5

colores = [Link](100)

tamaños = [Link]([Link](100)) * 100

# Scatter básico

[Link](figsize=(10, 6))

[Link](x, y, alpha=0.7)

[Link]("Relación entre X e Y")

[Link]("X")

56
[Link]("Y")

[Link]()

# Scatter con colores y tamaños

[Link](figsize=(10, 6))

scatter = [Link](x, y, c=colores, s=tamaños, alpha=0.6, cmap="viridis")

[Link](scatter, label="Color")

[Link]("Scatter con Colores y Tamaños")

[Link]()

57
9. Seaborn: Visualización Estadística
Seaborn está construida sobre Matplotlib y proporciona una interfaz de alto nivel para crear gráficos
estadísticos atractivos con menos código.

9.1. Configuración y Estilos

import seaborn as sns

# Configurar estilo

sns.set_theme(style="whitegrid") # darkgrid, white, dark, ticks

# Paletas de colores

sns.set_palette("viridis") # husl, Set2, coolwarm, etc.

# Configuración personalizada

sns.set_theme(

style="whitegrid",

palette="deep",

font_scale=1.2

9.2. Gráficos de Distribución

# Datos

[Link](42)

datos = [Link](1000)

58
# Histograma con KDE

[Link](figsize=(10, 6))

[Link](datos, kde=True, color="steelblue")

[Link]("Histograma con KDE")

[Link]()

# Solo KDE

[Link](figsize=(10, 6))

[Link](datos, fill=True, color="coral")

[Link]("Estimación de Densidad")

[Link]()

# Distribución por grupos

df = [Link]({

"valor": [Link]([[Link](500), [Link](500) + 2]),

"grupo": ["A"] * 500 + ["B"] * 500

})

[Link](figsize=(10, 6))

[Link](data=df, x="valor", hue="grupo", kde=True)

[Link]("Distribución por Grupos")

[Link]()

9.3. Gráficos Categóricos

59
# Datos de ejemplo

tips = sns.load_dataset("tips")

# Box plot

[Link](figsize=(10, 6))

[Link](data=tips, x="day", y="total_bill", hue="sex")

[Link]("Propinas por Día y Género")

[Link]()

# Violin plot

[Link](figsize=(10, 6))

[Link](data=tips, x="day", y="total_bill", hue="sex", split=True)

[Link]("Distribución de Propinas")

[Link]()

# Strip plot

[Link](figsize=(10, 6))

[Link](data=tips, x="day", y="total_bill", hue="sex", dodge=True)

[Link]("Propinas Individuales")

[Link]()

# Bar plot con error bars

[Link](figsize=(10, 6))

[Link](data=tips, x="day", y="total_bill", hue="sex", errorbar="sd")

[Link]("Media de Propinas con Desviación Estándar")

60
[Link]()

9.4. Gráficos de Relación

# Scatter plot con regresión

[Link](figsize=(10, 6))

[Link](data=tips, x="total_bill", y="tip")

[Link]("Relación entre Cuenta y Propina")

[Link]()

# lmplot (scatter + regresión por grupos)

[Link](data=tips, x="total_bill", y="tip", hue="smoker", col="time")

[Link]()

# Pair plot (matriz de scatter plots)

iris = sns.load_dataset("iris")

[Link](iris, hue="species")

[Link]()

# Joint plot

[Link](data=tips, x="total_bill", y="tip", kind="hex")

[Link]()

9.5. Heatmaps

61
# Matriz de correlación

iris = sns.load_dataset("iris")

correlacion = [Link]("species", axis=1).corr()

[Link](figsize=(8, 6))

[Link](correlacion, annot=True, cmap="coolwarm", center=0,

fmt=".2f", linewidths=0.5)

[Link]("Matriz de Correlación - Iris")

[Link]()

# Heatmap de datos

datos = [Link](10, 12)

meses = ["Ene", "Feb", "Mar", "Abr", "May", "Jun",

"Jul", "Ago", "Sep", "Oct", "Nov", "Dic"]

[Link](figsize=(12, 6))

[Link](datos, annot=True, fmt=".2f", cmap="YlGnBu",

xticklabels=meses)

[Link]("Datos Mensuales")

[Link]()

62
10. Scikit-learn: Machine Learning
Scikit-learn es la librería de referencia para Machine Learning en Python. Ofrece una API
consistente para preprocesamiento, clasificación, regresión, clustering y evaluación de modelos.

10.1. Flujo de Trabajo Básico

from sklearn.model_selection import train_test_split

from [Link] import StandardScaler

from sklearn.linear_model import LogisticRegression

from [Link] import accuracy_score, classification_report

# 1. Cargar datos

from [Link] import load_iris

iris = load_iris()

X, y = [Link], [Link]

# 2. Dividir en entrenamiento y prueba

X_train, X_test, y_train, y_test = train_test_split(

X, y, test_size=0.2, random_state=42, stratify=y

# 3. Preprocesar (escalar)

scaler = StandardScaler()

X_train_scaled = scaler.fit_transform(X_train)

X_test_scaled = [Link](X_test)

63
# 4. Entrenar modelo

model = LogisticRegression(random_state=42)

[Link](X_train_scaled, y_train)

# 5. Predecir

y_pred = [Link](X_test_scaled)

# 6. Evaluar

print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")

print(classification_report(y_test, y_pred))

10.2. Preprocesamiento

from [Link] import (

StandardScaler, MinMaxScaler, RobustScaler,

LabelEncoder, OneHotEncoder

from [Link] import SimpleImputer

# Escalado

scaler = StandardScaler() # Media 0, std 1

scaler = MinMaxScaler() # Rango [0, 1]

scaler = RobustScaler() # Robusto a outliers

X_scaled = scaler.fit_transform(X_train)

64
X_test_scaled = [Link](X_test)

# Imputación de valores nulos

imputer = SimpleImputer(strategy="mean") # mean, median, most_frequent

X_imputed = imputer.fit_transform(X)

# Codificación de variables categóricas

# Label Encoding (para ordinales)

le = LabelEncoder()

y_encoded = le.fit_transform(["bajo", "medio", "alto", "medio"])

# One-Hot Encoding (para nominales)

ohe = OneHotEncoder(sparse_output=False)

X_encoded = ohe.fit_transform([["rojo"], ["verde"], ["azul"]])

10.3. Regresión

from sklearn.linear_model import LinearRegression, Ridge, Lasso

from [Link] import RandomForestRegressor

from [Link] import mean_squared_error, r2_score

# Datos de ejemplo

from [Link] import make_regression

X, y = make_regression(n_samples=100, n_features=5, noise=10, random_state=42)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

65
# Regresión Lineal

lr = LinearRegression()

[Link](X_train, y_train)

y_pred = [Link](X_test)

print(f"MSE: {mean_squared_error(y_test, y_pred):.4f}")

print(f"R²: {r2_score(y_test, y_pred):.4f}")

# Ridge (L2 regularization)

ridge = Ridge(alpha=1.0)

[Link](X_train, y_train)

# Lasso (L1 regularization)

lasso = Lasso(alpha=0.1)

[Link](X_train, y_train)

# Random Forest Regressor

rf = RandomForestRegressor(n_estimators=100, random_state=42)

[Link](X_train, y_train)

10.4. Clasificación

from sklearn.linear_model import LogisticRegression

from [Link] import DecisionTreeClassifier

66
from [Link] import RandomForestClassifier

from [Link] import SVC

from [Link] import KNeighborsClassifier

# Datos

from [Link] import load_breast_cancer

data = load_breast_cancer()

X, y = [Link], [Link]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# Logistic Regression

lr = LogisticRegression(max_iter=1000)

[Link](X_train, y_train)

# Decision Tree

dt = DecisionTreeClassifier(max_depth=5, random_state=42)

[Link](X_train, y_train)

# Random Forest

rf = RandomForestClassifier(n_estimators=100, random_state=42)

[Link](X_train, y_train)

# SVM

svm = SVC(kernel="rbf", C=1.0)

[Link](X_train, y_train)

67
# KNN

knn = KNeighborsClassifier(n_neighbors=5)

[Link](X_train, y_train)

# Comparar modelos

modelos = [lr, dt, rf, svm, knn]

nombres = ["Logistic", "DecisionTree", "RandomForest", "SVM", "KNN"]

for nombre, modelo in zip(nombres, modelos):

y_pred = [Link](X_test)

acc = accuracy_score(y_test, y_pred)

print(f"{nombre}: {acc:.4f}")

68
11. Scikit-learn Avanzado
11.1. Validación Cruzada

from sklearn.model_selection import cross_val_score, KFold, StratifiedKFold

# Cross-validation básica

scores = cross_val_score(rf, X, y, cv=5, scoring="accuracy")

print(f"Accuracy: {[Link]():.4f} (+/- {[Link]()*2:.4f})")

# KFold personalizado

kfold = KFold(n_splits=5, shuffle=True, random_state=42)

scores = cross_val_score(rf, X, y, cv=kfold)

# StratifiedKFold (mantiene proporción de clases)

skfold = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

scores = cross_val_score(rf, X, y, cv=skfold)

# Múltiples métricas

from sklearn.model_selection import cross_validate

resultados = cross_validate(

rf, X, y, cv=5,

scoring=["accuracy", "precision_macro", "recall_macro", "f1_macro"],

return_train_score=True

69
for metrica, valores in [Link]():

print(f"{metrica}: {[Link]():.4f}")

11.2. Grid Search y Random Search

from sklearn.model_selection import GridSearchCV, RandomizedSearchCV

# Grid Search

param_grid = {

"n_estimators": [50, 100, 200],

"max_depth": [5, 10, 15, None],

"min_samples_split": [2, 5, 10],

"min_samples_leaf": [1, 2, 4]

grid_search = GridSearchCV(

RandomForestClassifier(random_state=42),

param_grid,

cv=5,

scoring="accuracy",

n_jobs=-1,

verbose=1

70
grid_search.fit(X_train, y_train)

print(f"Mejores parámetros: {grid_search.best_params_}")

print(f"Mejor score: {grid_search.best_score_:.4f}")

# Random Search (más eficiente para espacios grandes)

from [Link] import randint, uniform

param_dist = {

"n_estimators": randint(50, 300),

"max_depth": randint(3, 20),

"min_samples_split": randint(2, 20),

"min_samples_leaf": randint(1, 10)

random_search = RandomizedSearchCV(

RandomForestClassifier(random_state=42),

param_dist,

n_iter=50,

cv=5,

scoring="accuracy",

n_jobs=-1,

random_state=42

71
random_search.fit(X_train, y_train)

11.3. Pipelines

from [Link] import Pipeline

from [Link] import ColumnTransformer

# Pipeline simple

pipeline = Pipeline([

("scaler", StandardScaler()),

("classifier", RandomForestClassifier(random_state=42))

])

[Link](X_train, y_train)

y_pred = [Link](X_test)

# Pipeline con preprocesamiento diferenciado

from [Link] import StandardScaler, OneHotEncoder

# Supongamos columnas numéricas y categóricas

num_features = [0, 1, 2]

cat_features = [3, 4]

preprocessor = ColumnTransformer(

transformers=[

72
("num", StandardScaler(), num_features),

("cat", OneHotEncoder(), cat_features)

pipeline = Pipeline([

("preprocessor", preprocessor),

("classifier", RandomForestClassifier())

])

# Grid Search con Pipeline

param_grid = {

"classifier__n_estimators": [100, 200],

"classifier__max_depth": [5, 10, None]

grid_search = GridSearchCV(pipeline, param_grid, cv=5)

grid_search.fit(X_train, y_train)

11.4. Métricas de Evaluación

from [Link] import (

accuracy_score, precision_score, recall_score, f1_score,

confusion_matrix, classification_report, roc_auc_score, roc_curve

73
# Métricas básicas

y_pred = [Link](X_test)

print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")

print(f"Precision: {precision_score(y_test, y_pred, average='weighted'):.4f}")

print(f"Recall: {recall_score(y_test, y_pred, average='weighted'):.4f}")

print(f"F1-Score: {f1_score(y_test, y_pred, average='weighted'):.4f}")

# Matriz de confusión

cm = confusion_matrix(y_test, y_pred)

print("Matriz de Confusión:")

print(cm)

# Classification report completo

print(classification_report(y_test, y_pred, target_names=data.target_names))

# ROC-AUC (para clasificación binaria)

y_proba = model.predict_proba(X_test)[:, 1]

auc = roc_auc_score(y_test, y_proba)

print(f"ROC-AUC: {auc:.4f}")

# Curva ROC

fpr, tpr, thresholds = roc_curve(y_test, y_proba)

[Link](figsize=(8, 6))

74
[Link](fpr, tpr, label=f"AUC = {auc:.4f}")

[Link]([0, 1], [0, 1], "k--")

[Link]("False Positive Rate")

[Link]("True Positive Rate")

[Link]("Curva ROC")

[Link]()

[Link]()

75
12. Introducción a Transformers
La librería Transformers de Hugging Face proporciona acceso a miles de modelos pre-entrenados
para tareas de Procesamiento del Lenguaje Natural (NLP), visión por computador y más.

12.1. Instalación y Configuración

# Instalar transformers

# pip install transformers

# Importar la librería

from transformers import pipeline

# Verificar instalación

import transformers

print(f"Transformers version: {transformers.__version__}")

12.2. Pipelines Básicos

from transformers import pipeline

# Análisis de sentimiento

sentiment_analyzer = pipeline("sentiment-analysis")

resultado = sentiment_analyzer("I love this course! It's amazing!")

print(resultado)

# [{'label': 'POSITIVE', 'score': 0.9998}]

76
# Clasificación de texto

classifier = pipeline("zero-shot-classification")

resultado = classifier(

"This is a tutorial about machine learning",

candidate_labels=["education", "politics", "sports"]

print(resultado)

# Generación de texto

generator = pipeline("text-generation", model="gpt2")

resultado = generator("Machine learning is", max_length=50)

print(resultado[0]["generated_text"])

# Resumen de texto

summarizer = pipeline("summarization")

texto_largo = '''

Machine learning is a subset of artificial intelligence that focuses on

building systems that learn from data. These systems can improve their

performance over time without being explicitly programmed. Machine learning

algorithms are used in a wide variety of applications, from email filtering

to computer vision.

'''

resumen = summarizer(texto_largo, max_length=50, min_length=25)

print(resumen[0]["summary_text"])

77
12.3. Modelos y Tokenizers

from transformers import AutoTokenizer, AutoModel

# Cargar tokenizer y modelo

model_name = "bert-base-uncased"

tokenizer = AutoTokenizer.from_pretrained(model_name)

model = AutoModel.from_pretrained(model_name)

# Tokenizar texto

texto = "Hello, how are you?"

tokens = tokenizer(texto, return_tensors="pt")

print(f"Input IDs: {tokens['input_ids']}")

print(f"Attention Mask: {tokens['attention_mask']}")

# Decodificar tokens

decoded = [Link](tokens['input_ids'][0])

print(f"Decoded: {decoded}")

# Obtener embeddings

import torch

with torch.no_grad():

outputs = model(**tokens)

embeddings = outputs.last_hidden_state

print(f"Embeddings shape: {[Link]}")

78
12.4. Fine-tuning Básico

from transformers import (

AutoModelForSequenceClassification,

TrainingArguments,

Trainer

from datasets import load_dataset

# Cargar dataset

dataset = load_dataset("imdb")

# Cargar modelo para clasificación

model = AutoModelForSequenceClassification.from_pretrained(

"bert-base-uncased",

num_labels=2

# Tokenizar dataset

def tokenize_function(examples):

return tokenizer(examples["text"], padding="max_length", truncation=True)

tokenized_datasets = [Link](tokenize_function, batched=True)

# Configurar entrenamiento

training_args = TrainingArguments(

79
output_dir="./results",

num_train_epochs=3,

per_device_train_batch_size=8,

per_device_eval_batch_size=8,

warmup_steps=500,

weight_decay=0.01,

logging_dir="./logs",

# Crear Trainer

trainer = Trainer(

model=model,

args=training_args,

train_dataset=tokenized_datasets["train"].shuffle(seed=42).select(range(1000)),

eval_dataset=tokenized_datasets["test"].shuffle(seed=42).select(range(100)),

# Entrenar (comentado para no ejecutar)

# [Link]()

80
13. Buenas Prácticas y Consejos
13.1. Organización del Código
Una buena organización del código facilita su mantenimiento y colaboración con otros
desarrolladores.

# Estructura recomendada de un proyecto

# proyecto/

# ├── data/

# │ ├── raw/

# │ └── processed/

# ├── notebooks/

# │ └── [Link]

# ├── src/

# │ ├── __init__.py

# │ ├── data_processing.py

# │ ├── [Link]

# │ ├── [Link]

# │ └── [Link]

# ├── tests/

# │ └── test_models.py

# ├── [Link]

# └── [Link]

# Ejemplo de módulo bien organizado

# src/data_processing.py

81
import pandas as pd

import numpy as np

def cargar_datos(ruta):

"""Carga un archivo CSV y realiza limpieza básica."""

df = pd.read_csv(ruta)

df = [Link]()

return df

def preprocesar(df, columnas_numericas):

"""Normaliza las columnas numéricas."""

from [Link] import StandardScaler

scaler = StandardScaler()

df[columnas_numericas] = scaler.fit_transform(df[columnas_numericas])

return df, scaler

13.2. Documentación

def entrenar_modelo(X, y, modelo="rf", **kwargs):

"""

Entrena un modelo de clasificación.

Parameters

----------

82
X : array-like of shape (n_samples, n_features)

Matriz de características.

y : array-like of shape (n_samples,)

Vector de etiquetas.

modelo : str, default="rf"

Tipo de modelo: "rf" (Random Forest), "lr" (Logistic Regression).

**kwargs : dict

Parámetros adicionales para el modelo.

Returns

-------

model : estimator

Modelo entrenado.

Examples

--------

>>> X = [[1, 2], [3, 4], [5, 6]]

>>> y = [0, 1, 0]

>>> model = entrenar_modelo(X, y, modelo="rf", n_estimators=100)

"""

if modelo == "rf":

from [Link] import RandomForestClassifier

model = RandomForestClassifier(**kwargs)

elif modelo == "lr":

from sklearn.linear_model import LogisticRegression

83
model = LogisticRegression(**kwargs)

else:

raise ValueError(f"Modelo no soportado: {modelo}")

[Link](X, y)

return model

13.3. Reproducibilidad

import numpy as np

import random

import os

def establecer_semillas(seed=42):

"""Establece semillas para reproducibilidad."""

[Link](seed)

[Link](seed)

[Link]["PYTHONHASHSEED"] = str(seed)

# Para PyTorch

# import torch

# torch.manual_seed(seed)

# [Link].manual_seed_all(seed)

# Para TensorFlow

84
# import tensorflow as tf

# [Link].set_seed(seed)

# Usar al inicio del script

establecer_semillas(42)

# Guardar configuración del experimento

config = {

"seed": 42,

"test_size": 0.2,

"model": "RandomForest",

"n_estimators": 100,

"max_depth": 10

import json

with open("[Link]", "w") as f:

[Link](config, f, indent=2)

13.4. Gestión de Memoria

# Liberar memoria

import gc

# Eliminar variables grandes

85
del df_grande

[Link]()

# Usar tipos de datos eficientes

df["columna_int"] = df["columna_int"].astype("int32") # En lugar de int64

df["columna_float"] = df["columna_float"].astype("float32")

# Leer archivos grandes por chunks

for chunk in pd.read_csv("archivo_grande.csv", chunksize=10000):

procesar(chunk)

# Usar generadores en lugar de listas

def procesar_lineas(archivo):

with open(archivo) as f:

for linea in f:

yield procesar_linea(linea)

13.5. Debugging y Logging

import logging

# Configurar logging

[Link](

level=[Link],

format="%(asctime)s - %(levelname)s - %(message)s",

86
handlers=[

[Link]("[Link]"),

[Link]()

logger = [Link](__name__)

def entrenar_modelo(X, y):

[Link]("Iniciando entrenamiento...")

try:

model = RandomForestClassifier()

[Link](X, y)

[Link](f"Modelo entrenado. Score: {[Link](X, y):.4f}")

return model

except Exception as e:

[Link](f"Error durante el entrenamiento: {e}")

raise

# Usar assertions para validación

def dividir_datos(X, y, test_size=0.2):

assert len(X) == len(y), "X e y deben tener la misma longitud"

assert 0 < test_size < 1, "test_size debe estar entre 0 y 1"

return train_test_split(X, y, test_size=test_size)

87
Conclusión
Este manual ha cubierto los conceptos fundamentales y avanzados de Python y sus librerías
esenciales para el Machine Learning. Desde los fundamentos del lenguaje hasta técnicas
avanzadas de Scikit-learn y una introducción a los Transformers, ahora tenéis las herramientas
necesarias para abordar los proyectos del curso.

La clave para dominar estas herramientas es la práctica constante. Os animamos a experimentar


con el código, modificar los ejemplos y aplicar estos conocimientos a los ejercicios de cada módulo.
Recordad que en la plataforma Ágora tenéis acceso a recursos adicionales, notebooks de ejemplo
y el foro de la comunidad donde podéis resolver vuestras dudas.

¡Mucho éxito en vuestro aprendizaje!

88

También podría gustarte