Curso de Matemáticas para IA · Lección 44 de 180
Ángulos y similitud del coseno
Calcula ángulos y similitud del coseno a partir de coordenadas vectoriales, normaliza embeddings de forma responsable y gestiona los vectores nulos en código de recuperación.
Dos documentos pueden representarse mediante los vectores y . Su producto escalar sin normalizar es , así que una búsqueda basada en el producto escalar considera que el segundo vector es mucho mayor. Sin embargo, sus direcciones son idénticas: después de dividir por las longitudes de ambos vectores, su similitud del coseno es . La regla de puntuación cambia lo que significa “similar”.
Al terminar esta lección, podrás calcular un ángulo y la similitud del coseno a partir de coordenadas, explicar por qué un reescalado positivo no cambia el coseno y gestionar un vector nulo sin asignarle una dirección que no tiene.
Resultado de aprendizaje: Calcular un ángulo y la similitud del coseno, y gestionar los límites de los vectores nulos.
Esta lección combina dos ideas anteriores: la Lección 039: Las normas miden el tamaño de un vector nos proporciona longitudes euclídeas, y la Lección 041: Los productos internos miden la alineación nos proporciona productos escalares. La Lección 043: La distancia depende de la geometría elegida mostró después por qué una distancia conserva la magnitud en la comparación. La sección 3.4 del libro oficial Mathematics for Machine Learning desarrolla la relación angular. Los ejemplos, el código, el visual y las evaluaciones de aquí son originales.
Un ángulo separa la dirección de la longitud
Para dos vectores no nulos , usamos para representar el ángulo entre ellos. El producto escalar y la norma euclídea habituales son
La primera expresión combina las coordenadas correspondientes en un escalar. La segunda mide la longitud euclídea de cada vector. La tercera divide la puntuación de alineación por las dos longitudes y deja una comparación direccional. La desigualdad de Cauchy–Schwarz garantiza que el cociente final está entre y para vectores no nulos, por lo que el ángulo se recupera de forma unívoca en el intervalo :
Este valor normalizado es la similitud del coseno. Un valor cercano a significa que los vectores apuntan casi en la misma dirección; significa un ángulo recto bajo la geometría habitual del producto escalar; y significa direcciones opuestas. Estas interpretaciones suponen que ambos vectores son no nulos y que usamos el producto interno euclídeo estándar.
Un ángulo calculado a partir de coordenadas
Tomemos y . Son vectores bidimensionales, así que cada uno tiene dos coordenadas y no se sobreentiende ninguna unidad física. Podemos calcular cada parte antes de aplicar un coseno inverso.
Los valores intermedios importan. Un producto escalar de por sí solo no nos dice cuál es el ángulo, porque otro par de vectores podría tener el mismo producto escalar pero longitudes distintas. Dividir por ambas normas hace que el resultado sea comparable entre distintas magnitudes vectoriales.
El reescalado positivo no cambia el coseno
Supón que un vector no nulo se estira mediante un número positivo . Su dirección no cambia, y el álgebra muestra por qué la puntuación del coseno permanece fija:
La misma cancelación ocurre cuando se reescala positivamente. Esta es una característica útil para comparar embeddings por su dirección: un vector de documento con la misma orientación pero una norma mayor recibe la misma puntuación del coseno. También es una decisión de modelado. Si la magnitud contiene una señal sobre confianza, frecuencia u otra propiedad de la representación, eliminarla puede descartar información.
Explora el ángulo, la puntuación y las longitudes juntos
El explorador comienza con dos vectores no nulos. Mueve cualquier coordenada con el ratón, una entrada táctil o las teclas de flecha. El gráfico muestra los mismos vectores desde el origen, mientras que la tabla repite en texto el producto escalar, ambas normas, la similitud del coseno y el ángulo recuperado. Establece cualquiera de los vectores en para ver el límite del vector nulo.
x = (1, 0,5); y = (0,5, 1,5); producto escalar = 1,25; norma de x = 1,118; norma de y = 1,581; similitud del coseno = 0,707; ángulo = 0,785 radianes (45 grados). Interpretación: la puntuación refleja una alineación direccional parcial.
| Cantidad | Valor |
|---|---|
| Producto escalar x · y | 1,25 |
| Norma de x | 1,118 |
| Norma de y | 1,581 |
| Similitud del coseno | 0,707 |
| Ángulo | 0,785 radianes / 45 grados |
Las líneas de los vectores usan patrones de guiones y etiquetas distintos, no solo color. La tabla numérica sigue siendo significativa cuando el gráfico no está disponible o se reduce el movimiento.
El ángulo representado es una ayuda para razonar, no una definición distinta. Cuando cambian los controles, la tabla numérica vuelve a calcular la misma fórmula mostrada arriba. Un par que se hace más largo sin cambiar de dirección conserva el valor del coseno, mientras que girar cualquiera de los vectores cambia tanto el ángulo como la puntuación.
Usa la puntuación con cuidado en la recuperación mediante embeddings
Un embedding es una representación vectorial de un elemento, como un documento, una consulta, una imagen o un usuario. Si la coincidencia buscada depende de la orientación, la similitud del coseno es una puntuación natural: compara vectores normalizados en lugar de sus longitudes sin procesar. La puntuación sigue dependiendo del modelo de embedding, el preprocesamiento, el corpus y la tarea; no convierte “similar” en una propiedad universal de los documentos subyacentes.
La guía actual de métricas por pares de scikit-learn describe la similitud del coseno como un producto escalar normalizado mediante L2 y señala su uso para vectores de documentos. Su API cosine_similarity trata las filas como muestras y devuelve una matriz de puntuaciones por pares. Es fácil perder esa forma al pasar de un vector a un lote, así que haz explícita la convención de las filas:
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
query = np.array([[3.0, 1.0]]) # shape (1 sample, 2 features)
documents = np.array([
[3.0, 1.0],
[1.0, 2.0],
[30.0, 10.0],
]) # shape (3 samples, 2 features)
scores = cosine_similarity(query, documents)
print(scores.round(4))
# [[1. 0.7071 1. ]]
Para una implementación transparente en NumPy, bastan el producto escalar unidimensional y las normas vectoriales. La documentación de dot de NumPy define el caso 1-D como el producto interno de dos vectores, mientras que numpy.linalg.norm acepta un argumento axis cuando un array contiene varios vectores. La comprobación forma parte de la implementación, no es una comprobación decorativa:
import numpy as np
def cosine_similarity(x, y):
x = np.asarray(x, dtype=float)
y = np.asarray(y, dtype=float)
x_norm = np.linalg.norm(x)
y_norm = np.linalg.norm(y)
if x_norm == 0 or y_norm == 0:
raise ValueError('cosine similarity needs two nonzero vectors')
raw = np.dot(x, y) / (x_norm * y_norm)
return np.clip(raw, -1.0, 1.0)
print(cosine_similarity(np.array([3.0, 1.0]), np.array([1.0, 2.0])))
# 0.7071067811865475
clip evita que un pequeño exceso de coma flotante envíe arccos fuera de su dominio. No debe usarse para ocultar un error numérico o de forma de los datos más grande. Para un lote con forma (number_of_samples, number_of_features), calcula la norma en axis=1 y conserva una puntuación por fila; la documentación actual de NumPy muestra esta convención de eje para las normas vectoriales.
Límites que cambian la interpretación
Un vector nulo no tiene ángulo
Si , entonces y la fórmula del coseno divide por cero. El producto escalar sigue estando definido, pero eso no significa que el vector nulo forme un ángulo recto con . Un vector nulo no tiene dirección, así que matemáticamente el ángulo y la similitud del coseno no están definidos.
Las bibliotecas pueden elegir una política para esta entrada. El ejemplo actual de cosine_similarity incluye una fila nula y muestra una puntuación de 0.0; es una convención de la API que debes comprobar para la versión y la ruta de datos que uses, no una dirección recién definida. Un sistema de recuperación en producción debe decidir si rechaza, filtra o enruta por separado los embeddings nulos, y probar explícitamente esa política.
Los vectores opuestos no son “no relacionados”
Para un no nulo, el par cumple
La puntuación es máximamente negativa porque los vectores apuntan en direcciones opuestas. Una puntuación cercana a significa ortogonalidad bajo esta geometría; no significa automáticamente que dos elementos no estén relacionados semánticamente. La interpretación pertenece a la representación y a la tarea.
El coseno no es lo mismo que una distancia o un producto escalar sin normalizar
La similitud del coseno ignora el reescalado positivo. La distancia euclídea no lo hace. Para y , la similitud del coseno es , pero
El par es idéntico en dirección y aun así está muy separado como puntos. En cambio, un producto escalar sin normalizar mezcla la dirección con ambas longitudes. Elige el coseno cuando la concordancia direccional sea la señal buscada; elige una distancia inducida por una norma o una puntuación sin normalizar cuando la magnitud deba seguir formando parte de la decisión. La API cosine_distances de scikit-learn define su valor como menos la similitud del coseno, así que conserva la misma elección direccional en lugar de recuperar la separación euclídea.
La siguiente lección, Lección 045: La ortogonalidad significa que no hay solapamiento lineal, se centra en el caso especial en que el producto interno es cero y explica qué significa “no hay solapamiento lineal” (este enlace abre contenido en inglés). La página del curso Math for AI mantiene visible la secuencia de dependencias a medida que cada lección está disponible.
Comprueba tu comprensión
Question 1
Para x = (3, 1) e y = (1, 2), calcula el producto escalar, ambas normas L2, la similitud del coseno y el ángulo.
Show the step-by-step solution
El producto escalar es . Las normas son y . Por tanto, . Aplicar el coseno inverso da radianes, o . Cada paso usa los vectores de dos coordenadas y la suposición de normas no nulas.
Question 2
¿Por qué x = (1, 2) e y = (10, 20) tienen productos escalares y longitudes propias distintos, pero la misma similitud del coseno?
Show the step-by-step solution
Los vectores cumplen , así que . Sus normas son y . La puntuación normalizada es . El producto escalar crece con la escala de , pero esa misma escala aparece en su norma y se cancela en el coseno.
Question 3
Sean x = (1, 0) e y = (0, 2). ¿Cuáles son su similitud del coseno y su ángulo, y qué relación geométrica muestran?
Show the step-by-step solution
El producto escalar es . Las normas son y , así que la similitud del coseno es . Como , el ángulo es . Por tanto, los vectores son ortogonales en la geometría estándar del producto escalar, aunque ninguno de los dos sea nulo.
Question 4
Para x = (1, 0) e y = (−4, 0), calcula la similitud del coseno y el ángulo. ¿Por qué la puntuación no es cero?
Show the step-by-step solution
El producto escalar es , y las normas son y . Por tanto, . El coseno inverso da . Los vectores están en la misma recta pero apuntan en direcciones opuestas, así que tienen una alineación negativa máxima, no son perpendiculares.
Question 5
¿Qué debería hacer una implementación de similitud del coseno con x = (0, 0) e y = (2, 3), y por qué devolver 0 no es un ángulo matemático?
Show the step-by-step solution
La norma de es , así que el denominador es cero. La fórmula no está definida y no tiene dirección. Una implementación puede rechazar el par, filtrar el vector nulo o adoptar una convención de API documentada, como devolver ; esa convención debe probarse y no debe describirse como un ángulo recto.
Question 6
Si x = (1, 2), y = (2, 1) y x se sustituye por −3x, ¿cómo cambia la similitud del coseno? Muestra el cálculo del signo.
Show the step-by-step solution
Primero, y , por lo que el coseno original es . Con , el numerador se multiplica por , mientras que la norma de es . Por tanto, la nueva puntuación es : el reescalado negativo invierte la dirección.
Question 7
¿Por qué la implementación de NumPy recorta el producto escalar normalizado antes de llamar a arccos, y qué debería indicar un exceso grande?
Show the step-by-step solution
Matemáticamente, Cauchy–Schwarz sitúa el coseno en , pero la
aritmética de coma flotante puede producir un valor como
después de un cálculo largo o casi paralelo. Como
solo tiene valores reales en ese intervalo, np.clip(raw, -1.0, 1.0) elimina un pequeño exceso de redondeo. Un exceso grande sugiere un
problema de datos, forma o condicionamiento numérico; el recorte no debe
utilizarse para ocultarlo.
Question 8
Una consulta es q = (3, 1) y tres vectores de documentos son a = (3, 1), b = (1, 2) y c = (30, 10). Compara la clasificación por producto escalar sin normalizar con la clasificación por similitud del coseno.
Show the step-by-step solution
Los productos escalares sin normalizar son , y , así que la clasificación por producto escalar es , después y después . Como , . Para , . Por tanto, la clasificación por coseno empata a y en la primera posición y después coloca a . La diferencia expone la decisión de modelado: los productos escalares premian tanto la magnitud como la dirección, mientras que el coseno elimina la escala positiva.
Fuentes
- Mathematics for Machine Learning book PDF, Section 3.4
- NumPy documentation: numpy.dot
- NumPy documentation: numpy.linalg.norm
- NumPy documentation: numpy.arccos
- scikit-learn documentation: Pairwise metrics, affinities and kernels
- scikit-learn documentation: cosine_similarity
- scikit-learn documentation: cosine_distances