Saltar al contenido principal

Ciencia de datos para Search Engine Marketing (SEM)

En este tutorial, la ciencia de datos se une al Search Engine Marketing: aprende a crear campañas de Google AdWords generando palabras clave y plantillas de anuncios con Python.
· 15 min leer

Explora con IA

Como usuario intensivo de DataCamp desde hace dos años, he aprendido muchísimo. Mi actividad principal es el marketing online y me he beneficiado mucho de las habilidades de ciencia de datos que he adquirido. Ahora puedo gestionar campañas mucho más grandes y complejas, y mantenerlas de forma eficiente. Como ya estoy bastante familiarizado con el contenido, los distintos temas y los packages de R y Python, pensé en cómo podría crear campañas de búsqueda para DataCamp, simplemente como ejercicio.

En este tutorial, abordarás los siguientes temas:

  • Primero aprenderás más sobre el Search Engine Marketing (SEM) y las campañas de búsqueda;
  • Después, analizarás con más detalle el caso de negocio;
  • A continuación, generarás palabras clave para el profesorado, las tecnologías, los cursos y los temas de DataCamp.
  • Con las palabras clave en la mano, podrás empezar a generar tus anuncios. Primero definirás una estrategia y luego crearás plantillas de anuncios.

Search Engine Marketing (SEM) y campañas

¿Qué es el SEM?

El SEM es una de las formas más efectivas de hacer crecer tu negocio en un mercado cada vez más competitivo. Consiste en atraer tráfico a tu web comprando anuncios en los motores de búsqueda. Google AdWords es una de las formas más populares de publicidad online: pujas por aparecer en los enlaces patrocinados del buscador para palabras clave relacionadas con tu negocio y pagas una tarifa por cada clic.

Pagar por clic puede suponer un coste importante, por lo que es clave planificar y agrupar bien tus palabras clave y anuncios para controlar el gasto y, con suerte, lograr campañas rentables.

Aunque el proceso exacto para determinar el precio por clic es un secreto bien guardado y depende de muchos factores, la idea principal es que cuanto más relevantes sean tus anuncios, menor será tu coste por clic.

Cómo configurar una campaña de búsqueda

Antes de montar una campaña, normalmente defines un presupuesto, eliges palabras clave y estudias a la competencia. Además, te aseguras de que tu landing page esté preparada. Luego ya puedes configurar la campaña: redactas tu primer anuncio, ajustas sus detalles y configuras el seguimiento de conversiones. Este tutorial se centra sobre todo en el proceso de generar un gran volumen de palabras clave y anuncios en función de las distintas páginas de destino que tengamos.

Pero antes de empezar, ¡veamos exactamente qué son estas campañas de búsqueda!

Grupos de anuncios

Para empezar con una campaña de búsqueda, primero necesitas definir un plan para tus grupos de anuncios. Este es el elemento básico de organización donde asignas palabras clave, anuncios y páginas de destino. ¿Qué son exactamente estos tres componentes?

  1. Palabras clave: la intención del usuario, lo que está buscando.
  2. Anuncios: tu promesa al usuario para esa intención.
  3. Páginas de destino: el cumplimiento de esa promesa.

Mapear correctamente estos tres elementos es alrededor del 70-80% del trabajo. Si lo haces bien, el mantenimiento y los cambios serán mucho más sencillos.

Esto implica que, para ser específico y relevante para los usuarios, debes promocionar el producto que tienes y centrarte en llevar a la persona adecuada a la página adecuada con el mensaje o la expectativa adecuados. Una buena estructura de campaña refleja y sigue la estructura del sitio web, que en el fondo refleja la estrategia de negocio.

Nota: cada grupo de anuncios debe formar parte de una campaña. A nivel de campaña tienes ajustes que afectan a todos los grupos de anuncios, como la segmentación por idioma, ubicaciones, dispositivos, franja horaria, etc.

Campaña de búsqueda, paso a paso

En la sección anterior viste las campañas de búsqueda a alto nivel: palabras clave, anuncios y páginas de destino forman un grupo de anuncios, y necesitas un plan para esta unidad básica donde asignas esos tres componentes de forma que reflejen tu estrategia. En esta sección, profundizarás en cómo configurar una campaña, centrándote en los pasos que recorrerás en este tutorial.

Search Engine Marketing Campaigns Data Science

Como ves arriba, este es el mapeo que quieres conseguir. Como salida, querrás terminar con dos DataFrames principales: uno para palabras clave y otro para anuncios. Abajo puedes ver un ejemplo de cómo se verían.

CampaignAd GroupKeyword
campaign 1adgroup 1keyword 1
campaign 1adgroup 2keyword 2
campaign 2adgroup 1keyword 3
campaign 2adgroup 1keyword 4
campaign 2adgroup 2keyword 5
CampaignAd GroupDisplay URLFinal URLHeadline 1Headline 2
campaign 1adgroup 1datacamp.comdatacamp.com/aHeadline 1Headline 1a
campaign 1adgroup 2datacamp.comdatacamp.com/bHeadline 1Headline 1a
campaign 2adgroup 1datacamp.comdatacamp.com/cHeadline 1Headline 1a
campaign 2adgroup 2datacamp.comdatacamp.com/dHeadline 2Headline 2a
campaign 2adgroup 3datacamp.comdatacamp.com/eHeadline 3Headline 1a

Una vez listo, podrás subirlos como archivos CSV (valores separados por comas) a Google AdWords o incluso a otras plataformas que funcionan de forma muy similar. Google AdWords es, con diferencia, la plataforma de búsqueda de pago más popular entre los especialistas en search, además de Bing Ads, Yandex, Baidu, y otras.

Nota: si quieres importar tus datos a otras plataformas y no a Google Adwords o Bing Ads, ¡tendrás que hacer pequeños ajustes!

El caso de negocio: DataCamp

Como leíste en la introducción, quieres crear campañas de búsqueda para DataCamp. Si analizas las distintas formas en que alguien puede mostrar interés por el producto que ofrece esta empresa, es decir, formación en ciencia de datos, puedes elaborar fácilmente una lista inicial de posibilidades:

  1. Instructores: "curso de Hadley Wickham", "cursos de Garrett Grolemund", etc.
  2. Tecnologías: "curso de python", "cursos de r", "curso de sql para ciencia de datos", etc.
  3. Cursos: nombres de cursos específicos que tenemos; "unsupervised learning in python", "deep learning in python", etc.
  4. Temas: "cursos de machine learning", "curso de visualización de datos", etc.
  5. Packages/librerías: "aprender ggplot", "tutorial de matplotlib", etc.

En este tutorial no pasarás por la fase tradicional de investigación de palabras clave porque tienes el poder del lenguaje de programación para generar todas las combinaciones posibles y agruparlas en sus respectivas campañas y grupos de anuncios.

Por tanto, necesitas dos cosas principales para hacer esta configuración:

  • Conocimiento del producto: saber qué cursos y temas tiene DataCamp, cómo se organizan en la web y cómo se agrupan. Puedes descubrirlo navegando por el sitio y, sin duda, obtener mejores insights con información interna (¡especialmente si hay cambios previstos!).
  • Palabras clave relevantes: todas las posibles formas en que alguien puede expresar deseo por lo que ofreces. En el caso de DataCamp: "curso", "aprender", "formación", "tutorial", etc. Puedes hacerlo con lluvia de ideas, usando herramientas de keywords y otros métodos.

Generación de palabras clave para tu campaña de SEM

¡Empecemos generando las palabras clave!

1. Generar palabras clave de instructores

Esta campaña se dirigirá a personas que busquen cursos de cualquiera de los instructores de DataCamp.

Puedes restringir las palabras clave a "course by <instructor name>" o apostar por un conjunto amplio que apunte solo al nombre del instructor. Al principio es mejor orientar los nombres con "course" o "courses" y ver el efecto.

También tendrás que comprobar si alguno de los nombres coincide con el de otra persona famosa o es muy común; en ese caso, tendrás que restringir las palabras clave para ese instructor.

Empiezas obteniendo los nombres de los instructores y las URLs de cada uno:

import requests
from bs4 import BeautifulSoup


instructors_page = 'https://www.datacamp.com/instructors?all=true'
instructor_link_selector = '.instructor-block__description .instructor-block__link' # CSS class of the link
instructor_name_selector = '.mb-sm'  # CSS class of the name

instructor_resp = requests.get(instructors_page)
soup = BeautifulSoup(instructor_resp.text, 'lxml')

instructor_urls = [url['href'] for url in soup.select(instructor_link_selector)]
instructor_names = [name.text.strip() for name in soup.select(instructor_name_selector)]
instructor_urls = ['https://www.datacamp.com' + url for url in instructor_urls]

Los guardas en un DataFrame para usarlos más adelante. Las URLs se usarán después para generar los anuncios.

instructor_df = pd.DataFrame({
    'name': instructor_names,
    'url': instructor_urls
})
print(instructor_df.shape)
instructor_df.head()
(72, 2)
 nameurl
0Filip Schouwenaarshttps://www.datacamp.com/instructors/filipsch
1Jonathan Cornelissenhttps://www.datacamp.com/instructors/jonathana...
2Hugo Bowne-Andersonhttps://www.datacamp.com/instructors/hugobowne
3Greg Wilsonhttps://www.datacamp.com/instructors/greg48f64...
4Nick Carchedihttps://www.datacamp.com/instructors/nickyc


Ahora que ya tienes los nombres de los instructores, usarás una plantilla en la que combinas cada nombre con un conjunto de palabras clave relacionadas con tu tema, que en esencia son cursos del instructor.

Variables usadas en el siguiente código:

col_names: lista de nombres de cabecera de la tabla que subiremos a Google AdWords.
words: palabras que combinarás con los nombres de los instructores para generar palabras/frases clave completas.
match_types: puedes ver más detalles en el Centro de ayuda de AdWords, pero aquí tienes lo básico.
[data science course], "data science course" y data science course son técnicamente tres palabras clave distintas.

  • exact match (entre corchetes) solo mostrará anuncios si el usuario busca exactamente esa palabra clave, por ejemplo, 'data science course', escrita tal cual.
  • phrase match (con comillas) mostrará tus anuncios si el usuario busca la cadena exacta junto con cualquier cosa antes o después. Por tanto, "best data science course" o "data science course online" activarían tus anuncios.
  • broad match (sin signos) activará tus anuncios si alguien busca algo similar o relacionado con 'data science course'. Esto depende de los algoritmos de Google y hay que tener cuidado, porque podría activar anuncios con búsquedas como 'data science platform', que no es exactamente lo que queremos promocionar. A mí me gusta más el broad match modificado, porque restringe un poco más la segmentación. Básicamente activa los anuncios si alguien busca cualquier derivado de la palabra, no sinónimos en significado. Se indica con un signo '+' al principio de la palabra. Así, '+game' activaría anuncios con 'gaming', 'gamers', pero no con 'play'.
col_names = ['Campaign', 'Ad Group', 'Keyword', 'Criterion Type']
instructor_keywords = []

words = ['course', 'courses', 'learn', 'data science', 'data camp', 'datacamp']
match_types = ['Exact', 'Phrase', 'Broad']
for instructor in instructor_df['name']:
    for word in words:
        for match in match_types:
            if match == 'Broad':
                keyword = '+' + ' +'.join([instructor.replace(' ', ' +').lower(), word])  # modified broach match
            else:
                keyword = instructor.lower() + ' ' + word
            row = ['SEM_Instructors',  # campaign name
                   instructor,  # ad group name
                   keyword, # instructor <keyword>
                   match]  # keyword match type
            instructor_keywords.append(row)

# do the same by having the keywords come before the instructor name
for instructor in instructor_df['name']:
    for word in words:
        for match in match_types:
            if match == 'Broad':
                keyword = '+' + ' +'.join([word, instructor.replace(' ', ' +').lower()])
            else:
                keyword = word + ' ' + instructor.lower() 
            row = ['SEM_Instructors',  # campaign name
                   instructor,  # ad group name
                   keyword, # <keyword> instructor 
                   match]  # keyword match type
            instructor_keywords.append(row)


instructor_keywords_df = pd.DataFrame.from_records(instructor_keywords, 
                                                   columns=col_names)
print('total keywords:', instructor_keywords_df.shape[0])
instructor_keywords_df.head()
total keywords: 2592
 CampaignAd GroupKeywordCriterion Type
0SEM_InstructorsFilip Schouwenaarsfilip schouwenaars courseExact
1SEM_InstructorsFilip Schouwenaarsfilip schouwenaars coursePhrase
2SEM_InstructorsFilip Schouwenaars+filip +schouwenaars +courseBroad
3SEM_InstructorsFilip Schouwenaarsfilip schouwenaars coursesExact
4SEM_InstructorsFilip Schouwenaarsfilip schouwenaars coursesPhrase


Básicamente, estás iterando sobre los nombres de los instructores, todas las palabras clave y todos los tipos de concordancia para obtener todas las combinaciones posibles. Lo hacemos dos veces: una con la plantilla 'nombre del instructor + palabra clave' y otra con 'palabra clave + nombre del instructor'.

Ahora simplemente repites lo mismo para todos nuestros segmentos con pequeñas modificaciones en las palabras clave y en cómo extraemos los datos.

Una buena regla que aprendí de R for Data Science es que si vas a copiar y pegar más de dos veces, ¡es hora de escribir una función!

def generate_keywords(topics, keywords, match_types=['Exact', 'Phrase', 'Broad'],
                     campaign='SEM_Campaign'):
    col_names = ['Campaign', 'Ad Group', 'Keyword', 'Criterion Type']
    campaign_keywords = []

    for topic in topics:
        for word in keywords:
            for match in match_types:
                if match == 'Broad':
                    keyword = '+' + ' +'.join([topic.lower().replace(' ', ' +'), word.replace(' ', ' +')])
                else:
                    keyword = topic.lower() + ' ' + word
                row = [campaign,  # campaign name
                       topic,  # ad group name
                       keyword, # instructor <keyword>
                       match]  # keyword match type
                campaign_keywords.append(row)

    # I said more than twice! :)             
    for topic in topics:
        for word in keywords:
            for match in match_types:
                if match == 'Broad':
                    keyword = '+' + ' +'.join([word.replace(' ', ' +'), topic.lower().replace(' ', ' +')])
                else:
                    keyword = word + ' ' + topic.lower()
                row = [campaign,  # campaign name
                       topic,  # ad group name
                       keyword, # <keyword> instructor
                       match]  # keyword match type
                campaign_keywords.append(row)

    return pd.DataFrame.from_records(campaign_keywords, columns=col_names)

Probémosla:

topics = ['Data Science', 'Machine Learning']
keywords = ['course', 'tutorial']
generate_keywords(topics, keywords).head(10)
 CampaignAd GroupKeywordCriterion Type
0SEM_CampaignData Sciencedata science courseExact
1SEM_CampaignData Sciencedata science coursePhrase
2SEM_CampaignData Science+data +science +courseBroad
3SEM_CampaignData Sciencedata science tutorialExact
4SEM_CampaignData Sciencedata science tutorialPhrase
5SEM_CampaignData Science+data +science +tutorialBroad
6SEM_CampaignMachine Learningmachine learning courseExact
7SEM_CampaignMachine Learningmachine learning coursePhrase
8SEM_CampaignMachine Learning+machine +learning +courseBroad
9SEM_CampaignMachine Learningmachine learning tutorialExact


Tiene buena pinta. ¡Ahora generemos los temas y palabras clave relevantes para cada segmento!

2. Palabras clave de tecnologías

topics = ['R', 'Python', 'SQL', 'Git', 'Shell']  # listed on the /courses page
keywords = ['data science', 'programming', 'analytics', 'data analysis', 'machine learning',
            'deep learning', 'financial analysis', 'data viz', 'visualization', 'data visualization',
            'learn', 'course', 'courses', 'education', 'data import', 'data cleaning', 
            'data manipulation', 'probability', 'stats', 'statistics', 'course', 'courses',
           'learn', 'education', 'tutorial']  # @marketing_team: this list can / should be refined or 
                                              # expanded based on the strategy and how specific the 
                                              # targeting needs to be
tech_keywords = generate_keywords(topics, keywords, campaign='SEM_Technologies')
print('total keywords:', tech_keywords.shape[0])
tech_keywords.head()
total keywords: 750
 CampaignAd GroupKeywordCriterion Type
0SEM_TechnologiesRr data scienceExact
1SEM_TechnologiesRr data sciencePhrase
2SEM_TechnologiesR+r +data +scienceBroad
3SEM_TechnologiesRr programmingExact
4SEM_TechnologiesRr programmingPhrase

3. Generar palabras clave de cursos

Probablemente sea el segmento más específico y, por tanto, el más relevante para llegar a la gente. Si alguien busca "data visualization with r" y DataCamp tiene ese curso, el anuncio será extremadamente relevante porque tendrás la landing page exacta que satisface esa necesidad.

Hay un pequeño problema. Algunos nombres de cursos no coinciden con lo que un usuario buscaría típicamente: "Machine Learning with the Experts: School Budgets", "Sentiment Analysis in R: The Tidy Way". No son malos nombres, pero habrá que prestar atención para seleccionar las palabras clave adecuadas que la gente podría usar para encontrarlos.

De nuevo, puedes hacer scraping de los nombres y sus URLs como hiciste con la campaña de instructores:

courses_page = 'https://www.datacamp.com/courses/all'
course_link_selector = '.courses__explore-list .course-block'

course_resp = requests.get(courses_page)
soup = BeautifulSoup(course_resp.text, 'lxml')

course_urls = [link.contents[1]['href'] for link in soup.select(course_link_selector)] 
course_urls = ['https://www.datacamp.com' + url for url in course_urls]
course_names = [link.h4.text for link in soup.select(course_link_selector)]
course_df = pd.DataFrame({
    'name': course_names,
    'url': course_urls
})
course_df['name_clean'] = course_df.name.str.replace('\(.*\)', '').str.strip()  # remove (part x)
print('total keywords:', course_df.shape[0])
course_df.head()
total keywords: 104
 nameurlname_clean
0Intro to Python for Data Sciencehttps://www.datacamp.com/courses/intro-to-python-for-data-science...Intro to Python for Data Science
1Introduction to Rhttps://www.datacamp.com/courses/free-introduction-to-r...Introduction to R
2Intermediate Python for Data Sciencehttps://www.datacamp.com/courses/intermediate-python...Intermediate Python for Data Science
3Introduction to Git for Data Sciencehttps://www.datacamp.com/courses/introduction-to-git...Introduction to Git for Data Science
4Intermediate Rhttps://www.datacamp.com/courses/intermediate-rIntermediate R


Harás lo mismo (usar la función generate_keywords()) para los cursos, pero con cuidado, porque hay que revisarlos: como se dijo arriba, algunos nombres no son realmente lo que la gente buscaría, y tendrás que tratarlos caso por caso. Lo siguiente es un buen punto de partida; luego podrás ver los datos y decidir.

Ten en cuenta que usar el carácter vacío abajo no es un error. Los nombres de los cursos son lo suficientemente largos y específicos como para funcionar como palabras clave en sí mismos, sin añadir calificadores como 'learn' o 'course'. Así que usarás los nombres solos y también junto con palabras calificadoras.

keywords = ['', 'learn', 'course', 'courses', 'tutorial', 'education']
course_keywords = generate_keywords(course_df['name_clean'], keywords, campaign='SEM_Courses')
print('total keywords:', course_keywords.shape[0])
course_keywords.head(10)
total keywords: 3744
 CampaignAd GroupKeywordCriterion Type
0SEM_CoursesIntro to Python for Data Scienceintro to python for data scienceExact
1SEM_CoursesIntro to Python for Data Scienceintro to python for data sciencePhrase
2SEM_CoursesIntro to Python for Data Science+intro +to +python +for +data +science +Broad
3SEM_CoursesIntro to Python for Data Scienceintro to python for data science learnExact
4SEM_CoursesIntro to Python for Data Scienceintro to python for data science learnPhrase
5SEM_CoursesIntro to Python for Data Science+intro +to +python +for +data +science +learnBroad
6SEM_CoursesIntro to Python for Data Scienceintro to python for data science courseExact
7SEM_CoursesIntro to Python for Data Scienceintro to python for data science coursePhrase
8SEM_CoursesIntro to Python for Data Science+intro +to +python +for +data +science +courseBroad
9SEM_CoursesIntro to Python for Data Scienceintro to python for data science coursesExact

4. Palabras clave por temas

Son temas genéricos que la gente puede buscar. Los cubre la sección de "tracks", con skills y career como subsecciones. Para tu propósito, puedes agruparlos en la misma campaña. El proceso es el mismo que en secciones anteriores.

Skills

skills_page = 'https://www.datacamp.com/tracks/skill'
skills_link_selector = '#all .shim'

skills_resp = requests.get(skills_page)
skill_soup = BeautifulSoup(skills_resp.text, 'lxml')

skills_urls = [link['href'] for link in skill_soup.select(skills_link_selector)] 
skills_names = [skill.replace('/tracks/', '').replace('-', ' ') for skill in skills_urls]
skills_urls = ['https://www.datacamp.com' + url for url in skills_urls]

Careers

career_page = 'https://www.datacamp.com/tracks/career'
career_link_selector = '#all .shim'

career_resp = requests.get(career_page)
career_soup = BeautifulSoup(career_resp.text, 'lxml')

career_urls = [link['href'] for link in career_soup.select(career_link_selector)] 

career_names = [career.replace('/tracks/', '').replace('-', ' ') for career in career_urls]
career_urls = ['https://www.datacamp.com' + url for url in career_urls]
tracks_df = pd.DataFrame({
    'name': skills_names + career_names,
    'url': skills_urls + career_urls
})
tracks_df['name'] = [x.title() for x in tracks_df['name']]
tracks_df.head()
tracks_keywords = generate_keywords(tracks_df['name'], keywords, campaign='SEM_Tracks')
print('total keywords:', tracks_keywords.shape[0])
tracks_keywords.head()
total keywords: 720
 CampaignAd GroupKeywordCriterion Type
0SEM_TracksR Programmingr programmingExact
1SEM_TracksR Programmingr programmingPhrase
2SEM_TracksR Programming+r +programming +Broad
3SEM_TracksR Programmingr programming learnExact
4SEM_TracksR Programmingr programming learnPhrase

Por último, concatena todas las palabras clave listadas en instructor_keywords, tech_keywords, course_keywords y tracks_keywords para tenerlo todo en un único DataFrame:

full_keywords_df = pd.concat([instructor_keywords_df, tech_keywords, course_keywords, tracks_keywords])
print('total keywords:', full_keywords_df.shape[0])
print('total campaigns:', len(set(full_keywords_df['Campaign'])))
print('total ad groups:', len(set(full_keywords_df['Ad Group'])))
full_keywords_df.to_csv('keywords.csv', index=False)
full_keywords_df.head()
total keywords: 7806
total campaigns: 4
total ad groups: 191
 CampaignAd GroupKeywordCriterion Type
0SEM_InstructorsFilip Schouwenaarsfilip schouwenaars courseExact
1SEM_InstructorsFilip Schouwenaarsfilip schouwenaars coursePhrase
2SEM_InstructorsFilip Schouwenaars+filip +schouwenaars +courseBroad
3SEM_InstructorsFilip Schouwenaarsfilip schouwenaars coursesExact
4SEM_InstructorsFilip Schouwenaarsfilip schouwenaars coursesPhrase

¡Ya estás listo con tus palabras clave! Si quieres ver el conjunto de datos completo, descárgalo aquí. Después, necesitas generar anuncios para cada grupo de anuncios.

Vamos a generar los anuncios.

Generación de anuncios y copywriting

Actualmente tienes lo siguiente:

  • Campañas y nombres de grupos de anuncios correctamente mapeados entre sí en el DataFrame full_keywords_df
  • El nombre del grupo de anuncios y la URL correspondiente del scraping previo (cursos, instructores y tracks), y necesitas generar uno para tecnologías.

Con esto, puedes seguir este plan:

  1. Crea plantillas de anuncios (con 2-3 para empezar es suficiente)
  2. Crea una columna Campaign y añádela a los DataFrames ('name', 'url')
  3. Une todos los DataFrames ('name', 'url') en uno solo
  4. Genera todos los anuncios para todos los grupos de anuncios; cada anuncio tendrá estos campos (nuevas columnas en el mismo DataFrame):

    • Headline 1: máximo 30 caracteres
    • Headline 2: máximo 30 caracteres
    • Display URL: se infiere automáticamente de la Final URL
    • Final URL: la ruta completa a la que llegará el usuario (debe ser del mismo dominio que la Display URL)
  5. Asegúrate de que el trabajo es coherente con el DataFrame de keywords

  6. ¡Sube y lanza las campañas!

Generar anuncios significa sustituir el nombre del tema (curso, tecnología, instructor, etc.) donde corresponda en la plantilla y crear 2-3 variaciones por cada grupo de anuncios.

Python SEM Campaign

Plantillas de anuncios

Un detalle importante: aunque insertar los nombres de los grupos de anuncios donde toca es sencillo, el problema es que los campos deben respetar los límites de longitud. Y como los nombres de cursos y temas varían bastante, hay que ver cómo manejarlo.

Veamos hasta qué punto es un problema:

%matplotlib inline
import matplotlib.pyplot as plt
adgroup_lengths = pd.Series([len(adgrp) for adgrp in full_keywords_df['Ad Group'].unique()])
long_adgroups = sum(adgroup_lengths > 30)
plt.figure(figsize=(9,6))
plt.hist(adgroup_lengths, rwidth=0.9, bins=50)
plt.vlines(x=30, ymin=0, ymax=10, colors='red')
plt.title(str(long_adgroups) + ' ad group name lenghts > 30 (don\'t fit in a headline)',  fontsize=17)
plt.xlabel('Ad Group Name Lengths', fontsize=15)
plt.ylabel('Count', fontsize=15)
plt.yticks(range(11))
plt.xticks(range(0, 51, 5))
plt.grid(alpha=0.5)
plt.show()

Search Engine Marketing Data Science Python

Parece que no es un problema trivial y no hay una solución directa. Idealmente, nos gustaría que los dos titulares contuvieran el título completo del producto (curso) que estamos promocionando.

Pensé en distintas opciones y decidí escribir un algoritmo sencillo que divide el nombre en dos frases, cada una con un máximo de treinta caracteres.

El algoritmo no es apto para uso general y necesita retoques para generalizarlo, pero funciona suficientemente bien para este conjunto de datos:

def split_string(string, splits=2, max_len=60):
    """Split `string` into `splits` words, each shorter than `max_len` / `splits`"""
    if len(string) < max_len / splits:
        return string, ''
    str_words = string.split(' ')
    result = ''
    for i, word in enumerate(str_words):
        if len(result + ' ' + word) <= max_len / splits:
            result += word + ' '
        else:
            break
    spaces = result.strip().count(' ')
    result2 = string[string[len(result):].index(word) + len(result):]
    return result.strip(), result2
print(split_string('this is a very long course name that needs splitting', 2, 60))
print(split_string('short course name', 2, 60))
('this is a very long course', 'name that needs splitting')
('short course name', '')

No es algo que suela hacer, pero me gusta esta técnica y creo que la usaré al crear otras campañas. ¡Una agradable consecuencia de escribir un tutorial!

Ahora pensemos en las plantillas que quieres redactar.

La plantilla general que uso suele incluir estos elementos (normalmente en este orden).

  • Producto: si busco 'data science course' en Google, necesito ver 'data science course' en los enlaces/anuncios de alguna manera.
  • Beneficios: el impulso emocional/psicológico que la gente busca más allá de completar el curso: "impulsa tu carrera", "destaca frente a los demás".
  • Características: ahora que me has prometido la luna, ¡enséñame cómo vas a llevarme allí! "más de 100 cursos de ciencia de datos", "aprende con los mejores expertos", "recibe feedback instantáneo sobre tu código".
  • Llamada a la acción: bien, ya me has dicho qué ofreces, me has motivado y me has mostrado cómo voy a lograrlo. Me convence. ¿Qué hago ahora? "regístrate y prueba gratis", "prueba los primeros capítulos gratis", "ahorra un 20% en suscripciones anuales"

No es fácil meter todo en un anuncio de la longitud de un tuit, y algunos puntos se solapan. Pero haremos lo posible.

  • Headline 1: siempre contendrá el nombre del curso (o su primera mitad).
  • Headline 2: la segunda mitad del nombre del curso, o una de estas opciones:
    • Boost Your Data Science Career
    • Stand Out From the Crowd
    • Tackle Complex Questions
  • Description: cada grupo de anuncios tendrá estas tres variaciones en rotación.
    • Learn Directly From the Top Experts in the Field. 20% off Annual Subscriptions
    • Get Ahead of the Curve, Master Data Science Skills. $29 / Month. Cancel Anytime
    • Choose From a Wide Variety of Topics Tuaght by the Best in the World. Start Now

Crear columnas Campaign

full_keywords_df.Campaign.unique()  # just to make sure you have consistent naming conventions
array(['SEM_Instructors', 'SEM_Technologies', 'SEM_Courses', 'SEM_Tracks'], dtype=object)
course_df['Campaign'] = 'SEM_Courses'
course_df = course_df.rename(columns={'name_clean': 'name', 'name': 'old_name'})
course_df.head()
 old_nameurlnameCampaign
0Intro to Python for Data Sciencehttps://www.datacamp.com/courses/intro-to-python-for-data-science...Intro to Python for Data ScienceSEM_Courses
1Introduction to Rhttps://www.datacamp.com/courses/free-introduction-to-r...Introduction to RSEM_Courses
2Intermediate Python for Data Sciencehttps://www.datacamp.com/courses/intermediate-python...Intermediate Python for Data ScienceSEM_Courses
3Introduction to Git for Data Sciencehttps://www.datacamp.com/courses/introduction-to-git...Introduction to Git for Data ScienceSEM_Courses
4Intermediate Rhttps://www.datacamp.com/courses/intermediate-rIntermediate RSEM_Courses
instructor_df['Campaign'] = 'SEM_Instructors'
instructor_df.head()
 nameurlCampaign
0Filip Schouwenaarshttps://www.datacamp.com/instructors/filipschSEM_Instructors
1Jonathan Cornelissenhttps://www.datacamp.com/instructors/jonathana...SEM_Instructors
2Hugo Bowne-Andersonhttps://www.datacamp.com/instructors/hugobowneSEM_Instructors
3Greg Wilsonhttps://www.datacamp.com/instructors/greg48f64...SEM_Instructors
4Nick Carchedihttps://www.datacamp.com/instructors/nickycSEM_Instructors
tracks_df['Campaign'] = 'SEM_Tracks'
tracks_df.head()
 nameurlCampaign
0R Programminghttps://www.datacamp.com/tracks/r-programmingSEM_Tracks
1Importing Cleaning Data With Rhttps://www.datacamp.com/tracks/importing-cleaning-data-with-r...SEM_Tracks
2Data Manipulation With Rhttps://www.datacamp.com/tracks/data-manipulation-with-r...SEM_Tracks
3Python Programminghttps://www.datacamp.com/tracks/python-programming...SEM_Tracks
4Importing Cleaning Data With Pythonhttps://www.datacamp.com/tracks/importing-cleaning-data-with-python...SEM_Tracks
tech_domain = 'https://www.datacamp.com/courses/tech:'
tech_domain_list = []
for tech in ['R', 'Python', 'SQL', 'Git', 'Shell']:
    tech_domain_list.append((tech, tech_domain + tech))
tech_df = pd.DataFrame.from_records(tech_domain_list, columns=['name', 'url'])
tech_df['Campaign'] = 'SEM_Technologies'
tech_df

Unir todos los DataFrames ('name', 'url')

full_ads_df = pd.concat([course_df[['Campaign', 'name', 'url']],
                        instructor_df,
                        tracks_df,
                        tech_df], ignore_index=True)
full_ads_df = full_ads_df.rename(columns={'name': 'Ad Group', 'url': 'Final URL'})
print('total rows:', full_ads_df.shape[0])
n_adgroups = full_ads_df.shape[0]
full_ads_df.head()
total rows: 201
 CampaignAd GroupFinal URL
0SEM_CoursesIntro to Python for Data Sciencehttps://www.datacamp.com/courses/intro-to-python-for-data-science...
1SEM_CoursesIntroduction to Rhttps://www.datacamp.com/courses/free-introduction-to-r...
2SEM_CoursesIntermediate Python for Data Sciencehttps://www.datacamp.com/courses/intermediate-python...
3SEM_CoursesIntroduction to Git for Data Sciencehttps://www.datacamp.com/courses/introduction-to-git...
4SEM_CoursesIntermediate Rhttps://www.datacamp.com/courses/intermediate-r

Generar anuncios

Para situarnos: ya tienes el DataFrame de anuncios con las columnas Campaign, Ad Group y Final URL correctamente mapeadas. Falta añadir Headline 1, Headline 2 y Description.

Recuerda que para cada grupo de anuncios añadirás tres variaciones distintas. Es una buena práctica para hacer tests: ver en qué hace clic la gente, qué anuncios convierten mejor, etc. Deberías terminar con un DataFrame con el triple de filas.

Empecemos duplicando cada fila tres veces en full_ads_df:

full_ads_df = full_ads_df.iloc[[x  for x in range(n_adgroups) for i in range(3)], :] 
print('total rows:', full_ads_df.shape[0])
full_ads_df.head(9)
total rows: 603
 CampaignAd GroupFinal URL
0SEM_CoursesIntro to Python for Data Sciencehttps://www.datacamp.com/courses/intro-to-python-for-data-science...
0SEM_CoursesIntro to Python for Data Sciencehttps://www.datacamp.com/courses/intro-to-python-for-data-science...
0SEM_CoursesIntro to Python for Data Sciencehttps://www.datacamp.com/courses/intro-to-python-for-data-science...
1SEM_CoursesIntroduction to Rhttps://www.datacamp.com/courses/free-introduction-to-r...
1SEM_CoursesIntroduction to Rhttps://www.datacamp.com/courses/free-introduction-to-r...
1SEM_CoursesIntroduction to Rhttps://www.datacamp.com/courses/free-introduction-to-r...
2SEM_CoursesIntermediate Python for Data Sciencehttps://www.datacamp.com/courses/intermediate-python...
2SEM_CoursesIntermediate Python for Data Sciencehttps://www.datacamp.com/courses/intermediate-python...
2SEM_CoursesIntermediate Python for Data Sciencehttps://www.datacamp.com/courses/intermediate-python...


Ahora añade las tres descripciones que creaste arriba.

Description = [
    'Learn Directly From the Top Experts in the Field. 20% off Annual Subcriptions',
    'Be Ahead of the Curve, Master Data Science Skills. $29 / Month. Cancel Anytime',
    'Choose From a Wide Variety of Topics Tuaght by the Best in the World. Start Now'   
]
Description = [x for i in range(n_adgroups) for x in Description ]
full_ads_df['Description'] = Description
full_ads_df.head()
 CampaignAd GroupFinal URLDescription
0SEM_CoursesIntro to Python for Data Sciencehttps://www.datacamp.com/courses/intro-to-python-for-data-science...Learn Directly From the Top Experts in the Fie...
0SEM_CoursesIntro to Python for Data Sciencehttps://www.datacamp.com/courses/intro-to-python-for-data-science...Be Ahead of the Curve, Master Data Science Ski...
0SEM_CoursesIntro to Python for Data Sciencehttps://www.datacamp.com/courses/intro-to-python-for-data-science...Choose From a Wide Variety of Topics Tuaght by...
1SEM_CoursesIntroduction to Rhttps://www.datacamp.com/courses/free-introduction-to-r...Learn Directly From the Top Experts in the Fie...
1SEM_CoursesIntroduction to Rhttps://www.datacamp.com/courses/free-introduction-to-r...Be Ahead of the Curve, Master Data Science Ski...


Después, añade Headline 1 y Headline 2 al DataFrame. ¡Ya casi está!

benefits = [
    'Boost Your Data Science Career',
    'Stand Out From the Crowd',
    'Tackle Complex Questions'    
]

Los beneficios se incluirán como Headline 2 cuando la longitud del nombre del grupo de anuncios sea de 30 o menos. En ese caso quedaría un campo vacío que rellenaremos con uno de los beneficios.

benefits = [x for i in range(n_adgroups) for x in benefits]
headlines = [split_string(x) for x in full_ads_df['Ad Group']]
full_ads_df['Headline 1'] = [x[0] for x in headlines]
full_ads_df['Headline 2'] = [x[1] if x[1] else benefits[i] for i, x in enumerate(headlines)]
print('total ads:', full_ads_df.shape[0])
full_ads_df.head(9)
total ads: 603
 CampaignAd GroupFinal URLDescriptionHeadline 1Headline 2
0SEM_CoursesIntro to Python for Data Sciencehttps://www.datacamp.com/courses/intro-to-python-for-data-science...Learn Directly From the Top Experts in the Fie...Intro to Python for DataScience
0SEM_CoursesIntro to Python for Data Sciencehttps://www.datacamp.com/courses/intro-to-python-for-data-science...Be Ahead of the Curve, Master Data Science Ski...Intro to Python for DataScience
0SEM_CoursesIntro to Python for Data Sciencehttps://www.datacamp.com/courses/intro-to-python-for-data-science...Choose From a Wide Variety of Topics Tuaght by...Intro to Python for DataScience
1SEM_CoursesIntroduction to Rhttps://www.datacamp.com/courses/free-introduction-to-r...Learn Directly From the Top Experts in the Fie...Introduction to RBoost Your Data Science Career
1SEM_CoursesIntroduction to Rhttps://www.datacamp.com/courses/free-introduction-to-r...Be Ahead of the Curve, Master Data Science Ski...Introduction to RStand Out From the Crowd
1SEM_CoursesIntroduction to Rhttps://www.datacamp.com/courses/free-introduction-to-r...Choose From a Wide Variety of Topics Tuaght by...Introduction to RTackle Complex Questions
2SEM_CoursesIntermediate Python for Data Sciencehttps://www.datacamp.com/courses/intermediate-python...Learn Directly From the Top Experts in the Fie...Intermediate Python for DataScience
2SEM_CoursesIntermediate Python for Data Sciencehttps://www.datacamp.com/courses/intermediate-python...Be Ahead of the Curve, Master Data Science Ski...Intermediate Python for DataScience
2SEM_CoursesIntermediate Python for Data Sciencehttps://www.datacamp.com/courses/intermediate-python...Choose From a Wide Variety of Topics Tuaght by...Intermediate Python for DataScience


Como ves, "Intro to Python for Data Science" era lo bastante largo como para ocupar dos campos, así que lo dejamos tal cual para mantener la claridad. En el segundo caso, "Introduction to R" cabe en el primer titular, así que insertamos los tres beneficios en Headline 2.

¡Y listo!

Revisa bien los detalles

Una comprobación rápida para asegurarte de que todos los nombres de campaña y de grupo de anuncios en ambos DataFrames coinciden.

ads_check = (full_ads_df[['Campaign', 'Ad Group']]
             .drop_duplicates()
             .sort_values(['Campaign', 'Ad Group'])
             .reset_index(drop=True))
keywords_check = (full_keywords_df[['Campaign', 'Ad Group']]
                  .drop_duplicates()
                  .sort_values(['Campaign', 'Ad Group'])
                  .reset_index(drop=True))

all(ads_check == keywords_check)
True
full_ads_df.to_csv('ads.csv', index=False)

Sube y lanza

Como hemos comentado, este tutorial solo cubre pasos concretos dentro de campañas SEM y por tanto requiere una comprensión básica de cómo funciona el search engine marketing. Si quieres saber más sobre la mecánica y los detalles para subir y lanzar tus grupos de anuncios, puedes consultar la guía de AdWords para empezar. Para acceder a cursos completos en distintas áreas, puedes visitar la Google Academy for Ads.

Ciencia de datos y SEM: ¡queda mucho por descubrir!

Con los dos archivos CSV que tienes ahora, puedes subirlos y empezar a ejecutar tus campañas. Tendrás que definir presupuestos diarios, geosegmentación y algunos otros parámetros, pero en esencia ya lo tienes todo listo.

Si quieres consultar los CSV, los encontrarás aquí:

Espero que te haya resultado útil. Gracias por leerlo y, si quieres compartir algún proyecto de crecimiento que hayas hecho con Python, no dudes en escribirme en Twitter @eliasdabbas.

Temas

Relacionado