Generación de Búsquedas Relacionadas: Coincidencia Semántica de Tres Niveles
Este artículo explica cómo generamos enlaces de búsqueda relacionada para cada página del sitio utilizando una estrategia de tres niveles que equilibra relevancia semántica, distribución de tráfico y diversidad de consultas.
El Problema: Enlaces de Navegación Relevantes
Cada página necesita enlaces de búsqueda relacionada para ayudar a los usuarios a descubrir más contenido. ¿Pero qué consultas deberíamos mostrar?
El desafío es equilibrar múltiples objetivos:
-
Relevancia: Los enlaces deben estar semánticamente relacionados con la página actual
-
Distribución de tráfico: Las consultas de alto tráfico deben aparecer en páginas de alto tráfico
-
Diversidad de consultas: Cada consulta debe aparecer en múltiples páginas (10+ veces)
-
Unicidad de URL: No enlazar dos veces al mismo destino
-
Cobertura: Cada página debe tener 8 enlaces de calidad
Un enfoque ingenuo (similitud semántica pura) podría mostrar las mismas consultas en cada página. Un mejor enfoque utiliza una estrategia de tres niveles con procesamiento consciente del tráfico.
Estrategia de Tres Niveles
Generamos búsquedas relacionadas utilizando tres niveles de relevancia decreciente:
Nivel 1: Búsquedas Relacionadas (Alta Similitud)
Consultas de alta similitud semántica directamente relacionadas con el contenido de la página:
-
Página de ejemplo: "Treo N100 Mini PC"
-
Consultas de ejemplo: "n100 mini pc", "mini pc 8gb", "compact desktop n100"
Estas son las coincidencias más relevantes.
Nivel 2: Búsquedas Populares (Similitud Media)
Consultas de similitud media que están relacionadas temáticamente pero menos específicas:
-
Página de ejemplo: "Treo N100 Mini PC"
-
Consultas de ejemplo: "mini pc", "small computer", "fanless pc"
Estas son consultas más amplias en la misma categoría.
Nivel 3: Búsquedas Tendencia (Respaldo)
Consultas de poder global (más tráfico) utilizadas cuando se agotan las coincidencias semánticas:
-
Página de ejemplo: Cualquier página
-
Consultas de ejemplo: "mini pc", "thin client", "industrial pc", "all in one pc"
Estas son las consultas más populares en todo el sitio.
El Algoritmo: Procesamiento Primero por Tráfico
Paso 1: Recopilar Todas las Páginas
Recopilamos cada página del sitio:
-
Productos (/p/): Desde los datos fuente del Paso 0
-
Partes (/i/): Desde los datos fuente del Paso 0
-
Artículos (/a/): Desde los datos fuente del Paso 0
-
Familias (/f/): Desde los datos fuente del Paso 0
-
Categorías (/c/): Desde los datos fuente del Paso 0
-
Páginas de consulta (/q/): Desde los datos de enrutamiento (Paso 7)
-
Páginas estáticas: Inicio, acerca de, contacto, etc.
Esto típicamente produce ~64,000 páginas.
Paso 2: Cargar Incrustaciones
Cargamos incrustaciones precalculadas para:
- Páginas: Reutilizamos del Paso 0 (productos, partes, artículos) y Paso 6 (páginas de consulta)
- Consultas: Desde el Paso 3b (todas las 65K consultas)
Reutilizar incrustaciones evita re-incrustar datos sin cambios:
-
Reutilización Paso 0: ~5,000 incrustaciones de producto/parte/artículo
-
Reutilización Paso 6: ~12,500 incrustaciones de páginas de consulta
-
Nuevas incrustaciones: ~46,500 páginas restantes
Paso 3: Cargar Tráfico de Páginas
Consultamos Athena para obtener vistas de página de los últimos 90 días:
traffic_data = generate_all_pages_traffic_index(lookback_days=90)
Esto devuelve un diccionario que mapea URLs a recuentos de vistas:
{
"/p/Treo-N100-8-256-2H-W6-11P": 5000,
"/q/mini-pc": 3000,
"/": 50000
}
Paso 4: Ordenar Páginas por Tráfico
Procesamos las páginas en orden descendente de tráfico:
sorted_pages = sorted(all_pages, key=lambda p: page_traffic[p['url']], reverse=True)
Esto asegura que las páginas de alto tráfico obtengan la primera selección de consultas.
Paso 5: Calcular Similitud (Por Lotes)
Procesamos páginas en lotes de 1,000 para eficiencia de memoria:
batch_page_embeddings = all_page_embeddings[batch_indices]
batch_similarities = util.cos_sim(batch_page_embeddings, query_embeddings)
# ... (detalles de implementación omitidos)
Esto produce una matriz de similitud para el lote.
Paso 6: Seleccionar Consultas (Tres Niveles)
Para cada página, seleccionamos consultas usando la estrategia de tres niveles:
Nivel 1: Alta Similitud
for idx, similarity in enumerate(sorted_similarities):
if similarity < threshold_high:
break
# ... (detalles de implementación omitidos)
Nivel 2: Similitud Media (0.60-0.85)
if len(selected_queries) < 8:
for idx, similarity in enumerate(sorted_similarities):
if similarity < 0.60:
break
if try_add_query(queries[idx]):
continue
Nivel 3: Consultas de Poder (Respaldo)
if len(selected_queries) < 8:
for power_query in power_query_list:
if try_add_query(power_query):
continue
Paso 7: Aplicar Restricciones
La función try_add_query() aplica múltiples restricciones:
Límite de Uso de Consulta (10 apariciones):
if query_usage[query] >= MAX_APPEARANCES:
return False
Unicidad de URL (sin destinos duplicados):
url = get_dest_url(query)
if url in selected_urls:
return False
selected_urls.add(url)
Prevención de Autoenlaces:
selected_urls = {page_url} # Inicializar con la página actual
Límite de 8 Enlaces:
if len(selected_queries) >= 8:
return False
Paso 8: Convertir Consultas a URLs
Usamos los datos de enrutamiento del Paso 7 para convertir consultas a URLs de destino:
query_to_url_map = {}
for route in routing_data['routes']:
for query in route['queries']:
query_to_url_map[query] = route['destination']
Esto crea una búsqueda rápida O(1) para destinos de consulta.
Paso 9: Propagación de Idioma (Opcional)
Si la propagación de idioma está habilitada, añadimos el idioma de la consulta a la URL:
lang = detect_query_language(query)
if lang != "en":
url = f"{url}?lang={lang}"
Esto asegura que los usuarios permanezcan en su idioma preferido al hacer clic en búsquedas relacionadas.
Paso 10: Guardar en DynamoDB
Guardamos las búsquedas relacionadas en DynamoDB usando escrituras por lotes:
with RelatedSearchWidget.batch_write() as batch:
for page in batch_pages:
widget = RelatedSearchWidget(
page_url=page['url'],
links=[...],
tier_label="Related Searches"
)
batch.save(widget)
Las escrituras por lotes proporcionan una mejora significativa de rendimiento sobre escrituras individuales.
Seguimiento del Uso de Consultas
Realizamos un seguimiento de cuántas veces se ha usado cada consulta:
query_usage = {query: 0 for query in all_queries}
MAX_APPEARANCES = 10
A medida que se seleccionan las consultas, incrementamos su uso:
query_usage[query] += 1
Una vez que una consulta alcanza 10 apariciones, se excluye de selecciones futuras:
available_mask[query_idx] = False
Esto asegura la diversidad de consultas en todo el sitio.
Beneficios del Procesamiento Primero por Tráfico
Procesar páginas por tráfico (más alto primero) tiene ventajas:
Las páginas de alto tráfico obtienen las mejores coincidencias:
-
Página de inicio (50K vistas) → Las 8 consultas más relevantes
-
Producto popular (5K vistas) → Las siguientes 8 consultas más relevantes
-
Producto de nicho (100 vistas) → Consultas relevantes restantes
Respaldo automático:
-
Si se agotan las consultas de alta similitud, se usan consultas de similitud media
-
Si se agotan las consultas de similitud media, se usan consultas de poder
Distribución de tráfico:
-
Las consultas de alto tráfico aparecen en páginas de alto tráfico
-
Las consultas de bajo tráfico aparecen en páginas de nicho
-
Maximiza el potencial general de clics
Manejo de Páginas Estáticas
Las páginas estáticas (inicio, acerca de, contacto) omiten el Nivel 1 y el Nivel 2, yendo directamente al Nivel 3:
if page_type == 'static':
for power_query in power_query_list:
try_add_query(power_query)
tier_label = "Trending Searches"
Esto asegura que las páginas estáticas muestren las consultas más populares en todo el sitio.
Estrategia de Reutilización de Incrustaciones
Reutilizamos incrustaciones de pasos anteriores del pipeline:
Paso 0 (Datos Fuente):
-
Productos:
/p/Treo-N100-8-256-2H-W6-11P -
Partes:
/i/N100 -
Artículos:
/a/mini-pc-guide
Paso 6 (Agrupar Consultas):
- Páginas de consulta:
/q/mini-pc(slug → texto de consulta)
Nuevas Incrustaciones:
- Páginas restantes no en el Paso 0 o Paso 6
Esto reduce el tiempo de incrustación de ~2 horas a ~20 minutos.
Incrustación Incremental
Para páginas que necesitan nuevas incrustaciones, usamos caché incremental:
new_embeddings = incremental_embed_with_keys(
items=page_contents,
keys=page_urls,
cache_embeddings_path=SEO_PAGE_EMBEDDINGS_PATH,
cache_keys_path=SEO_PAGE_URLS_PATH,
model_name='all-mpnet-base-v2'
)
Esto almacena en caché las incrustaciones para ejecuciones futuras. Ver Estrategia de Incrustación para detalles.
Formato de Salida
Las búsquedas relacionadas se almacenan en DynamoDB:
{
"page_url": "/p/Treo-N100-8-256-2H-W6-11P",
"tier_label": "Related Searches",
# ... (detalles de implementación omitidos)
La aplicación web consulta esta tabla para mostrar búsquedas relacionadas en cada página.
Características de Rendimiento
En un servidor típico:
-
Tiempo de procesamiento: Varía según el recuento de páginas
-
Uso de memoria: Depende del tamaño de incrustación y tamaño del lote
-
Escrituras en DynamoDB: Escrituras por lotes para todas las páginas
-
Reutilización de incrustaciones: Alto porcentaje desde caché incremental
El proceso está limitado por la CPU durante el cálculo de similitud. Usar NumPy con aceleración BLAS acelera significativamente las operaciones matriciales.
Integración con el Pipeline SEO
La generación de búsquedas relacionadas es el Paso 8 en el pipeline SEO:
- Paso 0: Incrustar Datos Fuente - Productos, partes, artículos
- Paso 1: Obtener Consultas - GSC, Google Ads, en vivo, Algolia
- Paso 2: Combinar Consultas - Fusionar todas las fuentes
- Paso 3a: Generar Mapeos de Frase Base - Filtros iniciales
- Paso 3b: Incrustar Consultas - Convertir a vectores
- Paso 4: Expandir Mapeos de Frase - Encontrar frases similares
- Paso 5: Agrupar Consultas - Agrupar en páginas
- Paso 6: Emparejar Productos - Emparejamiento consulta-producto
- Paso 7: Construir Páginas de Consulta - Generar HTML
- Paso 8: Generar Búsquedas Relacionadas ← Usted está aquí
- Paso 11: Migrar a Valkey - Cargar en servicio de búsqueda
Ver Descripción General del Pipeline SEO para el flujo completo.
¿Por Qué Tres Niveles?
Nivel 1 (Alta Similitud) proporciona:
-
✅ Máxima relevancia
-
✅ Mejor experiencia de usuario
-
❌ Cobertura limitada (no todas las páginas tienen coincidencias de alta similitud)
Nivel 2 (Similitud Media) proporciona:
-
✅ Buena relevancia
-
✅ Cobertura más amplia
-
❌ Coincidencias menos específicas
Nivel 3 (Consultas de Poder) proporciona:
-
✅ Cobertura universal (cada página obtiene 8 enlaces)
-
✅ Alto clic (consultas populares)
-
❌ Relevancia más baja
Juntos, aseguran que cada página tenga enlaces de calidad con la mejor relevancia posible.
Estadísticas y Monitoreo
Después de la generación, calculamos estadísticas:
-
Páginas totales: Todas las páginas en el sistema
-
Enlaces salientes totales: Páginas × enlaces por página
-
Consultas usadas: Subconjunto de consultas disponibles
-
Distribución de consultas: La mayoría de las consultas aparecen en múltiples páginas
-
Consultas no utilizadas: Consultas de bajo tráfico o baja similitud
También registramos el enlace cruzado de páginas de categoría y familia para análisis.
Referencias
Conceptos Técnicos
-
Similitud del Coseno - Wikipedia
-
NumPy - Documentación oficial
-
BLAS - Wikipedia
-
DynamoDB - Documentación de AWS
-
Athena - Documentación de AWS
Documentación del Modelo
-
all-mpnet-base-v2 - Hugging Face
-
Sentence Transformers - Documentación oficial
Artículos Relacionados
-
Estrategia de Incrustación - Cómo generamos incrustaciones
-
Agrupación de Consultas - Agrupar consultas similares
-
Emparejamiento de Productos - Coincidencia semántica
-
[Descripción General del Pipeline SEO](/a/seo-pipeline-overview