Cómo automatizar la agrupación de palabras clave de SEO por intención de búsqueda con Python


Nota del editor: Al final de 2021, lo celebramos con una cuenta regresiva de 12 días de Navidad de los artículos de expertos más populares y útiles de Search Engine Journal de este año.

Esta colección fue seleccionada por nuestro equipo editorial en función del rendimiento, la utilidad, la calidad y el valor creado para ustedes, nuestros lectores, de cada artículo.

Todos los días hasta el 24 de diciembre, volveremos a publicar una de las mejores columnas del año, comenzando en el número 12 y contando hacia debajo hasta el número 1. Hoy es el número 11, publicado originalmente el 28 de julio de 2021.

Andreas Voniatis hizo un trabajo fantástico al explicar cómo crear grupos de palabras clave por intención de búsqueda usando Python. Las imágenes y capturas de pantalla facilitan el seguimiento, camino a camino, para que incluso el usuario de Python más principiante pueda seguirlo. ¡Bien hecho, Andreas!

Anuncio publicitario

Continuar leyendo a continuación

Gracias por contribuir a Search Engine Journal y compartir su sabiduría con los lectores.

¡Que disfruten todos!


Hay mucho que saber sobre la intención de búsqueda, al usar aprendizaje profundo para inferir la intención de búsqueda clasificando texto y desglosar los títulos SERP utilizando el procesamiento del lenguaje natural (NLP) técnicas, para agrupamiento basado en relevancia semántica con los beneficios explicados.

No solo conocemos los beneficios de descifrar la intención de búsqueda, también tenemos una serie de técnicas a nuestra disposición para escalar y automatizar.

Pero a menudo, esos implican la construcción de su propia IA. ¿Qué pasa si no tienes el tiempo ni el conocimiento para eso?

Anuncio publicitario

Continuar leyendo a continuación

En esta columna, aprenderá un proceso camino a camino para automatizar la agrupación de palabras clave por intención de búsqueda usando Python.

Las SERP contienen información para la intención de búsqueda

Algunos métodos requieren que obtenga toda la copia de los títulos del contenido de clasificación para una palabra clave determinada, luego lo ingrese en un modelo de red neuronal (que luego debe construir y probar), o tal vez esté utilizando NLP para agrupar palabras clave .

Existe otro método que le permite usar la propia IA de Google para hacer el trabajo por usted, sin tener que raspar todo el contenido de las SERP y construir un modelo de IA.

Supongamos que Google clasifica las URL del sitio según la probabilidad de que el contenido satisfaga la consulta del usuario en orden descendente. De ello se deduce que si la intención de dos palabras clave es la misma, es probable que las SERP sean similares.

Durante años, muchos profesionales de SEO compararon los resultados de SERP para palabras clave para inferir la intención de búsqueda compartida (o compartida) para mantenerse al tanto de las actualizaciones principales, por lo que esto no es nada nuevo.

El valor agregado aquí es la automatización y el escalado de esta comparación, que ofrece tanto velocidad como mayor precisión.

Cómo agrupar palabras clave por intención de búsqueda a escala usando Python (con código)

Comience con los resultados de su SERP en una descarga de CSV.

Anuncio publicitario

Continuar leyendo a continuación

1. Importe la lista a su cuaderno de Python.

import pandas as pd
import numpy as np

serps_input = pd.read_csv('data/sej_serps_input.csv')
serps_input

A continuación se muestra el archivo SERPs ahora importado a un marco de datos de Pandas.

Archivo SERPs importado a un marco de datos de Pandas.

2. Filtrar datos para la página 1

Queremos comparar los resultados de la página 1 de cada SERP entre palabras clave.

Anuncio publicitario

Continuar leyendo a continuación

Dividiremos el marco de datos en mini marcos de datos de palabras clave para ejecutar la función de filtrado antes de volver a combinarlos en un solo marco de datos, porque queremos filtrar a nivel de palabra clave:

# Split 
serps_grpby_keyword = serps_input.groupby("keyword")
k_urls = 15

# Apply Combine
def filter_k_urls(group_df):
    filtered_df = group_df.loc[group_df['url'].notnull()]
    filtered_df = filtered_df.loc[filtered_df['rank'] <= k_urls]
    return filtered_df
filtered_serps = serps_grpby_keyword.apply(filter_k_urls)

# Combine
## Add prefix to column names
#normed = normed.add_prefix('normed_')

# Concatenate with initial data frame
filtered_serps_df = pd.concat([filtered_serps],axis=0)
del filtered_serps_df['keyword']
filtered_serps_df = filtered_serps_df.reset_index()
del filtered_serps_df['level_1']
filtered_serps_df

3. Convierta las URL de clasificación en una cadena

Debido a que hay más URL de resultado de SERP que palabras clave, necesitamos comprimir esas URL en una sola línea para representar el SERP de la palabra clave.

Así es cómo:

# convert results to strings using Split Apply Combine
filtserps_grpby_keyword = filtered_serps_df.groupby("keyword")
def string_serps(df):
    df['serp_string'] = ''.join(df['url'])
    return df    

# Combine
strung_serps = filtserps_grpby_keyword.apply(string_serps)

# Concatenate with initial data frame and clean
strung_serps = pd.concat([strung_serps],axis=0)
strung_serps = strung_serps[['keyword', 'serp_string']]#.head(30)
strung_serps = strung_serps.drop_duplicates()
strung_serps

A continuación se muestra el SERP comprimido en una sola línea para cada palabra clave.
SERP comprimido en una sola línea para cada palabra clave.

4. Compare la similitud de SERP

Para realizar la comparación, ahora necesitamos cada combinación de SERP de palabras clave emparejadas con otros pares:

Anuncio publicitario

Continuar leyendo a continuación

# align serps
def serps_align(k, df):
    prime_df = df.loc[df.keyword == k]
    prime_df = prime_df.rename(columns = {"serp_string" : "serp_string_a", 'keyword': 'keyword_a'})
    comp_df = df.loc[df.keyword != k].reset_index(drop=True)
    prime_df = prime_df.loc[prime_df.index.repeat(len(comp_df.index))].reset_index(drop=True)
    prime_df = pd.concat([prime_df, comp_df], axis=1)
    prime_df = prime_df.rename(columns = {"serp_string" : "serp_string_b", 'keyword': 'keyword_b', "serp_string_a" : "serp_string", 'keyword_a': 'keyword'})
    return prime_df

columns = ['keyword', 'serp_string', 'keyword_b', 'serp_string_b']
matched_serps = pd.DataFrame(columns=columns)
matched_serps = matched_serps.fillna(0)
queries = strung_serps.keyword.to_list()

for q in queries:
    temp_df = serps_align(q, strung_serps)
    matched_serps = matched_serps.append(temp_df)

matched_serps

Compare la similitud de SERP.

Lo anterior muestra todas las combinaciones de pares SERP de palabras clave, lo que lo prepara para la comparación de cadenas SERP.

No existe una biblioteca de código abierto que compare los objetos de la lista por orden, por lo que la función se ha escrito para usted a continuación.

Anuncio publicitario

Continuar leyendo a continuación

La función ‘serp_compare’ compara la superposición de sitios y el orden de esos sitios entre SERP.

import py_stringmatching as sm
ws_tok = sm.WhitespaceTokenizer()

# Only compare the top k_urls results 
def serps_similarity(serps_str1, serps_str2, k=15):
    denom = k+1
    norm = sum([2*(1/i - 1.0/(denom)) for i in range(1, denom)])

    ws_tok = sm.WhitespaceTokenizer()

    serps_1 = ws_tok.tokenize(serps_str1)[:k]
    serps_2 = ws_tok.tokenize(serps_str2)[:k]

    match = lambda a, b: [b.index(x)+1 if x in b else None for x in a]

    pos_intersections = [(i+1,j) for i,j in enumerate(match(serps_1, serps_2)) if j is not None] 
    pos_in1_not_in2 = [i+1 for i,j in enumerate(match(serps_1, serps_2)) if j is None]
    pos_in2_not_in1 = [i+1 for i,j in enumerate(match(serps_2, serps_1)) if j is None]
    a_sum = sum([abs(1/i -1/j) for i,j in pos_intersections])
    b_sum = sum([abs(1/i -1/denom) for i in pos_in1_not_in2])
    c_sum = sum([abs(1/i -1/denom) for i in pos_in2_not_in1])

    intent_prime = a_sum + b_sum + c_sum
    intent_dist = 1 - (intent_prime/norm)
    return intent_dist
# Apply the function
matched_serps['si_simi'] = matched_serps.apply(lambda x: serps_similarity(x.serp_string, x.serp_string_b), axis=1)
serps_compared = matched_serps[['keyword', 'keyword_b', 'si_simi']]
serps_compared

Superposición de sitios y el orden de esos sitios entre SERP.

Ahora que se han ejecutado las comparaciones, podemos comenzar a agrupar las palabras clave.

Anuncio publicitario

Continuar leyendo a continuación

Trataremos cualquier palabra clave que tenga una similitud ponderada del 40% o más.

# group keywords by search intent
simi_lim = 0.4

# join search volume
keysv_df = serps_input[['keyword', 'search_volume']].drop_duplicates()
keysv_df.head()

# append topic vols
keywords_crossed_vols = serps_compared.merge(keysv_df, on = 'keyword', how = 'left')
keywords_crossed_vols = keywords_crossed_vols.rename(columns = {'keyword': 'topic', 'keyword_b': 'keyword',
                                                                'search_volume': 'topic_volume'})

# sim si_simi
keywords_crossed_vols.sort_values('topic_volume', ascending = False)


# strip NANs
keywords_filtered_nonnan = keywords_crossed_vols.dropna()
keywords_filtered_nonnan

Ahora tenemos el nombre del tema potencial, la similitud de las SERP de las palabras clave y los volúmenes de búsqueda de cada uno.
Agrupación de palabras clave.

Observará que se ha cambiado el nombre de keyword y keyword_b a tema y palabra clave, respectivamente.

Anuncio publicitario

Continuar leyendo a continuación

Ahora vamos a iterar sobre las columnas en el marco de datos usando la técnica lamdas.

La técnica lamdas es una forma eficiente de iterar sobre filas en un marco de datos Pandas porque convierte filas en una lista en lugar de la función .iterrows ().

Aquí va:

queries_in_df = list(set(keywords_filtered_nonnan.topic.to_list()))
topic_groups_numbered = {}
topics_added = []

def find_topics(si, keyw, topc):
    i = 0
    if (si >= simi_lim) and (not keyw in topics_added) and (not topc in topics_added): 
        i += 1     
        topics_added.append(keyw)
        topics_added.append(topc)
        topic_groups_numbered[i] = [keyw, topc]          
    elif si >= simi_lim and (keyw in topics_added) and (not topc in topics_added):  
        j = [key for key, value in topic_groups_numbered.items() if keyw in value]
        topics_added.append(topc)
        topic_groups_numbered[j[0]].append(topc)

    elif si >= simi_lim and (not keyw in topics_added) and (topc in topics_added):
        j = [key for key, value in topic_groups_numbered.items() if topc in value]        
        topics_added.append(keyw)
        topic_groups_numbered[j[0]].append(keyw) 

def apply_impl_ft(df):
  return df.apply(
      lambda row:
        find_topics(row.si_simi, row.keyword, row.topic), axis=1)

apply_impl_ft(keywords_filtered_nonnan)

topic_groups_numbered = {k:list(set(v)) for k, v in topic_groups_numbered.items()}

topic_groups_numbered

A continuación, se muestra un diccionario que contiene todas las palabras clave agrupadas por intención de búsqueda en grupos numerados:

{1: ['fixed rate isa',
  'isa rates',
  'isa interest rates',
  'best isa rates',
  'cash isa',
  'cash isa rates'],
 2: ['child savings account', 'kids savings account'],
 3: ['savings account',
  'savings account interest rate',
  'savings rates',
  'fixed rate savings',
  'easy access savings',
  'fixed rate bonds',
  'online savings account',
  'easy access savings account',
  'savings accounts uk'],
 4: ['isa account', 'isa', 'isa savings']}

Peguemos eso en un marco de datos:

topic_groups_lst = []

for k, l in topic_groups_numbered.items():
    for v in l:
        topic_groups_lst.append([k, v])

topic_groups_dictdf = pd.DataFrame(topic_groups_lst, columns=['topic_group_no', 'keyword'])
                                
topic_groups_dictdf

Marco de datos del grupo de temas.

Los grupos de intención de búsqueda anteriores muestran una buena aproximación de las palabras clave dentro de ellos, algo que probablemente lograría un experto en SEO.

Anuncio publicitario

Continuar leyendo a continuación

Aunque solo usamos un pequeño conjunto de palabras clave, el método obviamente se puede escalar a miles (si no más).

Activando las salidas para mejorar su búsqueda

Por supuesto, lo anterior podría llevarse más lejos utilizando redes neuronales que procesen el contenido de clasificación para clústeres y nombres de grupos de clústeres más precisos, como ya lo hacen algunos de los productos comerciales.

Por ahora, con esta salida puede:

  • Incorpore esto en sus propios sistemas de paneles de SEO para hacer sus tendencias y Informes de SEO más significativo.
  • Construir mejor campañas de búsqueda pagas estructurando sus cuentas de Google Ads por intención de búsqueda para obtener un Nivel de calidad más alto.
  • Fusionar URL de búsqueda de comercio electrónico de facetas redundantes.
  • Estructurar la taxonomía de un sitio de compras según la intención de búsqueda en lugar de un catálogo de productos típico.

Anuncio publicitario

Continuar leyendo a continuación

Estoy seguro de que hay más aplicaciones que no he mencionado; siéntase libre de comentar sobre las importantes que aún no he mencionado.

En cualquier caso, ¡su investigación de palabras clave de SEO se volvió un poco más escalable, precisa y rápida!


2021 SEJ Christmas Countdown:

Imagen destacada: Astibuag / Shutterstock.com

Anuncio publicitario

Continuar leyendo a continuación





Consultar el artículo en la publicación original

Cómo automatizar la agrupación de palabras clave de SEO por intención de búsqueda con Python