Una base de datos vectorial es una colección de datos donde cada dato se almacena como un vector (numérico). Un vector representa un objeto o entidad, como una imagen, persona, lugar, etc. en el espacio abstracto de N dimensiones.

Los vectores, como se explicó en el capítulo anterior, son cruciales para identificar cómo se relacionan las entidades y pueden usarse para encontrar su similitud semántica. Esto se puede aplicar de varias maneras para SEO, como agrupar palabras clave o contenido similares (usando kNN).

En este artículo, aprenderemos algunas formas de aplicar la IA al SEO, incluida la búsqueda de contenido semánticamente similar para enlaces internos. Esto puede ayudarlo a perfeccionar su estrategia de contenido en una era en la que los motores de búsqueda dependen cada vez más de los LLM.

También puede leer un artículo anterior de esta serie sobre cómo encontrar canibalización de palabras clave utilizando las incrustaciones de texto de OpenAI.

Profundicemos aquí para comenzar a construir la base de nuestra herramienta.

Comprensión de las bases de datos vectoriales

Si tiene miles de artículos y desea encontrar la similitud semántica más cercana para su consulta de destino, no puede crear incrustaciones de vectores para todos ellos sobre la marcha para compararlos, ya que es altamente ineficiente.

Para que eso suceda, necesitaríamos generar incrustaciones de vectores solo una vez y mantenerlas en una base de datos que podamos consultar y encontrar el artículo más parecido.

Y eso es lo que hacen las bases de datos vectoriales: son tipos especiales de bases de datos que almacenan incrustaciones (vectores).

Cuando consulta la base de datos, a diferencia de las bases de datos tradicionales, realizan una coincidencia de similitud de coseno y devuelven los vectores (en este caso, artículos) más cercanos a otro vector (en este caso, una frase de palabras clave) que se está consultando.

Esto es lo que parece:

Ejemplo de registro de incrustación de texto en la base de datos vectorial.

En la base de datos de vectores, puede ver los vectores junto con los metadatos almacenados, que podemos consultar fácilmente utilizando el lenguaje de programación de nuestra elección.

En este artículo, usaremos Pinecone debido a su facilidad de comprensión y simplicidad de uso, pero existen otros proveedores como Chroma, BigQuery o Qdrant que quizás quieras consultar.

Vamos a sumergirnos.

1. Cree una base de datos de vectores

Primero, registre una cuenta en Pinecone y cree un índice con una configuración de “text-embedding-ada-002” con ‘coseno’ como métrica para medir la distancia vectorial. Puedes nombrar el índice como quieras, nosotros lo nombraremos.article-index-all-ada‘.

Creando una base de datos vectorial Creación de una base de datos vectorial.

Esta interfaz de usuario auxiliar es solo para ayudarlo durante la configuración, en caso de que desee almacenar la incrustación de vectores de Vertex AI, debe configurar las ‘dimensiones’ en 768 en la pantalla de configuración manualmente para que coincida con la dimensionalidad predeterminada y puede almacenar los vectores de texto de Vertex AI (usted Puede establecer un valor de dimensión entre 1 y 768 para ahorrar memoria).

En este artículo, aprenderemos a utilizar los modelos ‘text-embedding-ada-002’ de OpenAi y ‘text-embedding-005’ de Vertex AI de Google.

Una vez creada, necesitamos una clave API para poder conectarnos a la base de datos utilizando una URL de host de la base de datos vectorial.

A continuación, necesitará utilizar Jupyter Notebook. Si no lo tiene instalado, siga esta guía para instalarlo y luego ejecute este comando (a continuación) en la terminal de su PC para instalar todos los paquetes necesarios.

pip install openai google-cloud-aiplatform google-auth pandas pinecone-client tabulate ipython numpy

¡Y recuerda que ChatGPT es muy útil cuando tienes problemas durante la codificación!

2. Exporta tus artículos desde tu CMS

A continuación, debemos preparar un archivo de exportación CSV de artículos desde su CMS. Si usa WordPress, puede usar un complemento para realizar exportaciones personalizadas.

Como nuestro objetivo final es crear una herramienta de enlace interno, debemos decidir qué datos deben enviarse a la base de datos vectorial como metadatos. Esencialmente, el filtrado basado en metadatos actúa como una capa adicional de orientación de recuperación, alineándolo con el marco general de RAG mediante la incorporación de conocimiento externo, lo que ayudará a mejorar la calidad de la recuperación.

Por ejemplo, si estamos editando un artículo sobre “PPC” y queremos insertar un enlace a la frase “Investigación de palabras clave”, podemos especificar en nuestra herramienta que “Categoría = PPC”. Esto permitirá que la herramienta consulte solo artículos dentro de la categoría “PPC”, asegurando enlaces precisos y contextualmente relevantes, o es posible que queramos vincular a la frase “actualización más reciente de Google” y limitar la coincidencia solo a artículos de noticias usando ‘Tipo ‘ y publicado este año.

En nuestro caso, estaremos exportando:

  • Título.
  • Categoría.
  • Tipo.
  • Fecha de publicación.
  • Año de publicación.
  • Enlace permanente.
  • Meta descripción.
  • Contenido.

Para ayudar a obtener los mejores resultados, concatenaríamos los campos de título y metadescripciones, ya que son la mejor representación del artículo que podemos vectorizar y son ideales para fines de incrustación y enlaces internos.

El uso del contenido completo del artículo para incrustaciones puede reducir la precisión y diluir la relevancia de los vectores.

Esto sucede porque una única inserción grande intenta representar varios temas cubiertos en el artículo a la vez, lo que lleva a una representación menos enfocada y relevante. Es necesario aplicar estrategias de fragmentación (dividir el artículo en títulos naturales o segmentos semánticamente significativos), pero éstas no son el tema central de este artículo.

Aquí está el archivo de exportación de muestra que puede descargar y usar para nuestro ejemplo de código a continuación.

2. Insertar incrustaciones de texto de OpenAi en la base de datos de vectores

Suponiendo que ya tiene una clave API de OpenAI, este código generará incrustaciones de vectores a partir del texto y las insertará en la base de datos de vectores en Pinecone.

import pandas as pd
from openai import OpenAI
from pinecone import Pinecone
from IPython.display import clear_output

# Setup your OpenAI and Pinecone API keys
openai_client = OpenAI(api_key='YOUR_OPENAI_API_KEY')  # Instantiate OpenAI client
pinecone = Pinecone(api_key='YOUR_PINECON_API_KEY')

# Connect to an existing Pinecone index
index_name = "article-index-all-ada"
index = pinecone.Index(index_name)

def generate_embeddings(text):
    """
    Generates an embedding for the given text using OpenAI's API.
    Returns None if text is invalid or an error occurs.
    """
    try:
        if not text or not isinstance(text, str):
            raise ValueError("Input text must be a non-empty string.")

        result = openai_client.embeddings.create(
            input=text,
            model="text-embedding-ada-002"
        )

        clear_output(wait=True)  # Clear output for a fresh display

        if hasattr(result, 'data') and len(result.data) > 0:
            print("API Response:", result)
            return result.data[0].embedding
        else:
            raise ValueError("Invalid response from the OpenAI API. No data returned.")

    except ValueError as ve:
        print(f"ValueError: {ve}")
        return None
    except Exception as e:
        print(f"An error occurred while generating embeddings: {e}")
        return None

# Load your articles from a CSV
df = pd.read_csv('Sample Export File.csv')

# Process each article
for idx, row in df.iterrows():
    try:
        clear_output(wait=True)
        content = row["Content"]
        vector = generate_embeddings(content)

        if vector is None:
            print(f"Skipping article ID {row['ID']} due to empty or invalid embedding.")
            continue

        index.upsert(vectors=[
            (
                row['Permalink'],  # Unique ID
                vector,            # The embedding
                {
                    'title': row['Title'],
                    'category': row['Category'],
                    'type': row['Type'],
                    'publish_date': row['Publish Date'],
                    'publish_year': row['Publish Year']
                }
            )
        ])
    except Exception as e:
        clear_output(wait=True)
        print(f"Error processing article ID {row['ID']}: {str(e)}")

print("Embeddings are successfully stored in the vector database.")

Debe crear un archivo de cuaderno y copiarlo y pegarlo allí, luego cargar el archivo CSV ‘Sample Export File.csv’ en la misma carpeta.

proyecto jupyterProyecto Jupyter.

Una vez hecho esto, haga clic en el botón Ejecutar y comenzará a insertar todos los vectores de incrustación de texto en el índice. article-index-all-ada Creamos en el primer paso.

Ejecutando el guiónEjecutando el guión.

Verá un texto de registro de salida de vectores integrados. Una vez terminado, mostrará el mensaje al final de que se completó correctamente. Ahora ve y revisa tu índice en Pinecone y verás que tus registros están allí.

3. Encontrar un artículo que coincida con una palabra clave

Bien, intentemos encontrar un artículo que coincida con la palabra clave.

Cree un nuevo archivo de cuaderno y copie y pegue este código.

from openai import OpenAI
from pinecone import Pinecone
from IPython.display import clear_output
from tabulate import tabulate  # Import tabulate for table formatting

# Setup your OpenAI and Pinecone API keys
openai_client = OpenAI(api_key='YOUR_OPENAI_API_KEY')  # Instantiate OpenAI client
pinecone = Pinecone(api_key='YOUR_OPENAI_API_KEY')

# Connect to an existing Pinecone index
index_name = "article-index-all-ada"
index = pinecone.Index(index_name)


# Function to generate embeddings using OpenAI's API
def generate_embeddings(text):
    """
    Generates an embedding for a given text using OpenAI's API.

    """
    try:
        if not text or not isinstance(text, str):
            raise ValueError("Input text must be a non-empty string.")

        result = openai_client.embeddings.create(
            input=text,
            model="text-embedding-ada-002"
        )

        # Debugging: Print the response to understand its structure
        clear_output(wait=True)
        #print("API Response:", result)

        if hasattr(result, 'data') and len(result.data) > 0:
            return result.data[0].embedding
        else:
            raise ValueError("Invalid response from the OpenAI API. No data returned.")

    except ValueError as ve:
        print(f"ValueError: {ve}")
        return None

    except Exception as e:
        print(f"An error occurred while generating embeddings: {e}")
        return None

# Function to query the Pinecone index with keywords and metadata
def match_keywords_to_index(keywords):
    """
    Matches a list of keywords to the closest article in the Pinecone index, filtering by metadata dynamically.
    """
    results = []

    for keyword_pair in keywords:
        try:
            clear_output(wait=True)
            # Extract the keyword and category from the sub-array
            keyword = keyword_pair[0]
            category = keyword_pair[1]

            # Generate embedding for the current keyword
            vector = generate_embeddings(keyword)
            if vector is None:
                print(f"Skipping keyword '{keyword}' due to embedding error.")
                continue

            # Query the Pinecone index for the closest vector with metadata filter
            query_results = index.query(
                vector=vector,  # The embedding of the keyword
                top_k=1,  # Retrieve only the closest match
                include_metadata=True,  # Include metadata in the results
                filter={"category": category}  # Filter results by metadata category dynamically
            )

            # Store the closest match
            if query_results['matches']:
                closest_match = query_results['matches'][0]
                results.append({
                    'Keyword': keyword,  # The searched keyword
                    'Category': category,  # The category used for filtering
                    'Match Score': f"{closest_match['score']:.2f}",  # Similarity score (formatted to 2 decimal places)
                    'Title': closest_match['metadata'].get('title', 'N/A'),  # Title of the article
                    'URL': closest_match['id']  # Using 'id' as the URL
                })
           ...

Con información de Search Engine Journal.

Leer la nota Completa > Introducción a las bases de datos vectoriales y cómo utilizar la IA para SEO

LEAVE A REPLY

Please enter your comment!
Please enter your name here