Ga naar hoofdinhoud

Data science voor Search Engine Marketing (SEM)

In deze tutorial komt data science samen met Search Engine Marketing: leer Google AdWords-campagnes maken door met Python keywords en advertentietemplates te genereren!
· 15 min lezen

Verken met AI

Als intensieve DataCamp-gebruiker sinds twee jaar heb ik ontzettend veel geleerd. Mijn corebusiness is online marketing en ik profiteer enorm van de data science-vaardigheden die ik heb opgedaan. Ik kan nu veel grotere en complexere campagnes beheren en ze efficiënt onderhouden. Omdat ik inmiddels goed bekend ben met de content, topics en packages in R en Python, vroeg ik me af hoe ik zoekcampagnes voor DataCamp zou kunnen opzetten, gewoon als oefening.

In deze tutorial behandel je het volgende:

  • Je leert eerst meer over Search Engine Marketing (SEM) en zoekcampagnes;
  • Vervolgens kijk je van dichterbij naar de businesscase;
  • Daarna genereer je keywords voor de docenten, technologieën, cursussen en topics van DataCamp.
  • Met de keywords op zak kun je je advertenties gaan genereren. Eerst bedenk je een strategie, daarna maak je advertentietemplates.

Search Engine Marketing (SEM) en campagnes

Wat is SEM?

SEM is een van de meest effectieve manieren om je bedrijf te laten groeien in een steeds competitievere markt. Het is het proces waarbij je websiteverkeer verwerft door advertenties op zoekmachines te kopen. Google AdWords is een van de meest populaire vormen van online adverteren: je biedt op advertentieposities in de gesponsorde links van een zoekmachine voor keywords die gerelateerd zijn aan je bedrijf, en vervolgens betaal je de zoekmachine een vergoeding per klik.

Betalen per klik kan flink in de papieren lopen, dus het is heel belangrijk om je keywords en advertenties zo te plannen en te groeperen dat je de kosten onder controle houdt en hopelijk winstgevende campagnes hebt.

Hoewel het exacte proces om de prijs per klik te bepalen goed bewaard wordt en afhangt van veel factoren, is het belangrijkste idee dat hoe relevanter je advertenties zijn, hoe lager je kosten per klik.

Een zoekcampagne opzetten

Voordat je een campagne opzet, bepaal je meestal een budget, kies je keywords en check je de concurrentie. Ook zorg je dat je landingspagina in orde is. Daarna kun je je campagne opzetten: je schrijft je eerste advertentie, stelt de details in en zet conversietracking op. Deze tutorial behandelt vooral het proces van het genereren van een groot aantal keywords en advertenties, gebaseerd op de verschillende landingspagina’s die we hebben.

Maar voordat je begint, kijken we even wat zoekcampagnes precies zijn!

Advertentiegroepen

Om te starten met een zoekcampagne heb je eerst een plan nodig voor je advertentiegroepen. Dit is de basiseenheid waarin je keywords, advertenties en landingspagina’s aan elkaar koppelt. Maar wat zijn deze drie componenten precies?

  1. Keywords: de intentie van de gebruiker, waar die naar zoekt.
  2. Ads: jouw belofte aan de gebruiker voor die intentie.
  3. Landingspagina’s: jouw inlossing van die belofte.

Deze drie elementen goed mappen is zo’n 70–80% van het werk. Als je dit goed doet, worden onderhoud en wijzigingen veel makkelijker.

Dat betekent dat je, om specifiek en relevant te zijn voor gebruikers, het product dat je hebt moet promoten en vooral moet focussen op het sturen van de juiste persoon naar de juiste pagina, met de juiste boodschap of verwachting. Een goede campagnestructuur weerspiegelt de structuur van de website en daarmee in feite de bedrijfsstrategie.

Let op dat elke advertentiegroep deel moet uitmaken van een campagne. Op campagneniveau heb je instellingen die alle advertentiegroepen in de campagne aansturen, zoals doeltaal, locaties, apparaten, tijdstip van de dag, enzovoort.

Zoekcampagne, stap voor stap

In de vorige sectie bekeek je zoekcampagnes op hoofdlijnen: je zag dat keywords, advertenties en landingspagina’s onderdeel zijn van een advertentiegroep en dat je een plan moet maken voor deze basiseenheid waarin je deze drie componenten zo mapt dat ze je bedrijfsstrategie weerspiegelen. In deze sectie duik je dieper in wat je kunt doen om een campagne op te zetten, met focus op de stappen die je in deze tutorial doorloopt.

Search Engine Marketing Campaigns Data Science

Zoals hierboven te zien is, is dit de mapping die je wilt bereiken. Als output wil je twee hoofd-DataFrames hebben: één voor keywords en één voor advertenties. Hieronder zie je hoe dat eruit kan zien.

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

Als dit klaar is, kun je ze uploaden als comma-separated value (CSV)-bestanden naar Google AdWords of andere platforms die op dezelfde manier werken. Google AdWords is veruit het meest populaire paid search-platform onder searchmarketeers, naast Bing Ads, Yandex, Baidu en andere.

Let op dat je kleine aanpassingen nodig hebt als je je data naar andere platforms wilt importeren en niet naar Google Adwords of Bing Ads!

De businesscase: DataCamp

Zoals je in de introductie las, wil je zoekcampagnes voor DataCamp maken. Kijkend naar de verschillende manieren waarop iemand interesse kan tonen in het product van dit bedrijf, namelijk data science-onderwijs, kun je gemakkelijk een eerste lijst met mogelijke manieren bedenken:

  1. Docenten: ‘Hadley Wickham course’, ‘courses by Garrett Grolemund’, enz.
  2. Technologieën: ‘python course’, ‘r courses’, ‘sql data science course’, enz.
  3. Cursussen: namen van specifieke cursussen die we hebben; ‘unsupervised learning in python’, ‘deep learning in python’, enz.
  4. Topics: ‘machine learning courses’, ‘data visualization course’, enz.
  5. Packages/libraries: ‘learn ggplot’, ‘matplotlib tutorial’, enz.

In deze tutorial doorloop je niet de traditionele keyword research-fase, en dat komt doordat je de kracht van een programmeertaal gebruikt om alle mogelijke combinaties te genereren en ze te groeperen in de bijbehorende campagnes en advertentiegroepen.

Daarom heb je twee hoofdzaken nodig om deze setup te doen:

  • Productkennis: weten welke cursussen en topics DataCamp heeft, hoe ze op de website zijn georganiseerd en hoe ze gegroepeerd zijn. Dit kun je vinden door te browsen, en met interne kennis krijg je zeker betere inzichten (vooral als er wijzigingen gepland zijn!).
  • Relevante keywords: alle mogelijke manieren waarop iemand interesse kan uitdrukken in wat je aanbiedt. In het geval van DataCamp zijn dat ‘course’, ‘learn’, ‘education’, ‘tutorial’, enz. Dit kun je doen door te brainstormen, keywordtools te gebruiken en andere methoden.

Keywordgeneratie voor je SEM-campagne

Laten we beginnen met het genereren van de keywords!

1. Keywords voor docenten genereren

Deze campagne richt zich op mensen die zoeken naar cursussen van een van de docenten van DataCamp.

Je kunt de keywords beperken tot "course by <instructor name>" of je kunt gaan voor een brede set keywords die alleen op de naam van de docent targeten. In het begin is het beter om te targeten op de namen met ‘course’ of ‘courses’ en dan het effect te bekijken.

Je moet ook controleren of een van de namen die je hebt ook de naam is van een andere bekende persoon, of een heel algemene naam; in dat geval zul je de keywords voor die docent moeten beperken.

Je begint met het ophalen van de namen van de docenten en de URL’s voor ieder van hen:

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]

Je zet ze in een DataFrame voor later gebruik. De URL’s worden later gebruikt voor het genereren van advertenties.

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


Nu je de namen van de docenten hebt, gebruik je een template waarbij je elke naam combineert met een set keywords die bij je topic horen, in dit geval vooral cursussen van de docent.

Variabelen die in onderstaande code gebruikt worden:

col_names: Dit is een lijst met de kopnamen van de tabel die we uiteindelijk naar Google AdWords uploaden.
words: De woorden die je met de docentennamen combineert om de volledige keywords/zinnen te genereren.
match_types: Meer details vind je in het AdWords Helpcentrum, maar dit zijn de basics.
[data science course], "data science course" en data science course zijn technisch gezien drie verschillende keywords.

  • exacte overeenkomst (tussen blokhaken), triggert alleen advertenties als een gebruiker precies naar dat keyword zoekt, ‘data science course’ bijvoorbeeld, exact zo geschreven.
  • woordgroep-overeenkomst (met aanhalingstekens), triggert je advertenties als een gebruiker zoekt naar de exacte string met iets ervoor of erna. Dus "best data science course" of "data science course online" zou onze advertenties triggeren.
  • brede overeenkomst (zonder leestekens) zou onze advertenties triggeren als iemand zoekt naar iets dat vergelijkbaar is met of gerelateerd is aan ‘data science course’. Dit is aan Google’s algoritmen en je moet er voorzichtig mee zijn, omdat het bijvoorbeeld ook advertenties kan triggeren bij ‘data science platform’, wat niet precies is wat we promoten. Ik gebruik liever de gemodificeerde broad match, omdat die de targeting iets meer beperkt. Deze triggert advertenties als iemand zoekt naar een afgeleide van het woord, en niet een woord met vergelijkbare betekenis. Dit wordt aangegeven met een ‘+’-teken aan het begin van het woord. Dus ‘+game’ zou advertenties triggeren bij ‘gaming’, ‘gamers’, maar niet bij ‘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


Kort gezegd loop je over de docentennamen, alle verschillende keywords en alle matchtypes die we hebben, zodat we alle mogelijke combinaties krijgen. We doen het twee keer: één keer met de template ‘docentnaam keyword’ en één keer met ‘keyword docentnaam’.

Nu herhaal je hetzelfde voor al onze segmenten met kleine aanpassingen aan de keywords en de manier waarop we de data extraheren.

Een goede vuistregel die ik leerde uit R for Data Science is: als je iets meer dan twee keer gaat kopiëren en plakken, is het tijd om een functie te schrijven!

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)

Laten we het proberen:

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


Dit ziet er goed uit. Laten we nu de relevante topics en keywords genereren voor elk van je segmenten!

2. Technologie-keywords

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. Cursus-keywords genereren

Dit is waarschijnlijk het meest specifieke en dus meest relevante segment om mensen te targeten. Als iemand zoekt naar "data visualization with r" en DataCamp heeft die cursus, dan is de advertentie extreem relevant, omdat je de juiste landingspagina hebt die precies aan de behoefte van die gebruiker voldoet.

Er is echter één klein probleem. Sommige cursustitels komen niet overeen met waar een gebruiker typisch naar zoekt: ‘Machine Learning with the Experts: School Budgets’, ‘Sentiment Analysis in R: The Tidy Way’. Dit zijn geen slechte cursustitels, maar ze vragen wat aandacht bij het selecteren van de juiste keywords die mensen zouden gebruiken om ze te vinden.

Wederom kun je de namen en bijbehorende URL’s scrapen, zoals je deed voor de docenten-campagne:

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


Je doet hetzelfde (gebruik de functie generate_keywords()) voor de cursussen, maar je moet voorzichtig zijn: ze moeten worden beoordeeld, want zoals hierboven vermeld zijn sommige namen niet echt waar mensen naar zoeken, en dat moet je geval per geval meenemen. Het volgende is een prima startpunt; daarna kun je de data bekijken en keuzes maken.

Let op: het gebruik van het lege teken hieronder is geen fout. De cursustitels zijn lang en specifiek genoeg om op zichzelf als keyword te dienen, zonder extra kwalificerende woorden als ‘learn’ of ‘course’. Dus je gebruikt de cursustitels alleen, én in combinatie met kwalificerende keywords.

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. Keywords voor topics

Dit zijn in feite generieke topics waar mensen mogelijk naar zoeken. Ze vallen onder de ‘tracks’-sectie, met ‘skills’ en ‘career’ als subsectoren. Voor jouw doel kunnen ze onder dezelfde campagne worden gegroepeerd. Het proces is weer hetzelfde, zoals je in de vorige secties hebt gedaan!

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

Tot slot concateneer je alle keywords die in instructor_keywords, tech_keywords, course_keywords en tracks_keywords staan zodat ze allemaal in één groot DataFrame terechtkomen:

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

Nu ben je klaar om met je keywords aan de slag te gaan! Wil je de volledige dataset bekijken, haal hem dan hier op. Vervolgens moet je advertenties genereren voor elk van je advertentiegroepen.

Laten we de advertenties genereren.

Advertenties genereren en copywriting

Je hebt momenteel het volgende:

  • Campagnes en advertentiegroepnamen die correct aan elkaar gemapt zijn in het DataFrame full_keywords_df
  • De naam van de advertentiegroep en de bijbehorende URL uit je eerdere scraping (cursussen, docenten en tracks), en je moet er nog één genereren voor technologieën.

Met dit in de hand kun je het volgende plan volgen:

  1. Maak advertentietemplates (2–3 is een goede start)
  2. Maak een kolom Campaign en voeg die toe aan de DataFrames ('name', 'url')
  3. Voeg alle ('name', 'url') DataFrames samen tot één grote
  4. Genereer alle advertenties voor alle advertentiegroepen; dit bestaat uit de volgende velden per advertentie (dit worden nieuwe kolommen in hetzelfde DataFrame waar je mee werkt):

    • Headline 1: maximaal 30 tekens
    • Headline 2: maximaal 30 tekens
    • Display URL: automatisch afgeleid van de final URL
    • Final URL: het volledige pad waar de gebruiker terechtkomt (moet hetzelfde domein hebben als de display URL)
  5. Zorg dat het werk consistent is met het DataFrame keywords

  6. Upload en start campagnes!

Advertenties genereren betekent simpelweg dat je de naam van het topic (cursus, technologie, docent, enz.) op de juiste plek in de template zet en 2–3 advertentievarianten maakt voor elk van de advertentiegroepen die je hebt.

Python SEM Campaign

Advertentietemplates

Een belangrijk punt is dat, hoewel het invullen van de advertentiegroepnamen op de juiste plekken vrij eenvoudig is, je wel moet zorgen dat de lengte van de velden binnen de bovengenoemde limieten blijft. En omdat de namen van je cursussen en topics sterk variëren, moet je bekijken wat je daaraan kunt doen.

Laten we zien hoe groot dat probleem is:

%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

Het lijkt erop dat je probleem niet triviaal is, en er is geen eenduidige manier om het op te lossen. Idealiter wil je dat de twee headlines de volledige titel bevatten van het product (de cursus) die we promoten.

Ik heb over verschillende oplossingen nagedacht en besloten een eenvoudige algoritme te schrijven dat de naam splitst in twee zinsdelen van elk maximaal dertig tekens.

Het algoritme is niet geschikt voor algemeen gebruik en heeft wat tweaks nodig om het generieker te maken, maar het werkt goed genoeg voor deze dataset:

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', '')

Dit is niet iets wat ik meestal doe, maar ik vind deze techniek prettig en ik denk dat ik hem vaker ga gebruiken bij het maken van andere campagnes. Een mooi neveneffect van het schrijven van een tutorial!

Laten we nu nadenken over de templates die je wilt schrijven.

De algemene advertentietemplate die ik gebruik bestaat uit de volgende elementen (meestal in deze volgorde).

  • Product: als ik op Google zoek naar ‘data science course’, wil ik ergens ‘data science course’ in de links/advertenties zien.
  • Voordelen: dit is het emotionele/psychologische aspect waar mensen echt naar op zoek zijn, voorbij het simpelweg afronden van de cursus: ‘boost je carrière’, ‘val op tussen de massa’.
  • Features: nu je me de maan hebt beloofd, laat me zien hoe je me daar gaat krijgen! ‘meer dan 100 data science-cursussen’, ‘leer van top experts’, ‘krijg direct feedback op je codeervaardigheden’.
  • Call-to-action: oké, je hebt verteld wat je aanbiedt, me gemotiveerd om het te kopen en laten zien hoe ik er kom. Ik ben overtuigd. Wat doe ik nu? ‘meld je aan voor een gratis proefperiode’, ‘bekijk de eerste hoofdstukken gratis’, ‘bespaar 20% op jaarabonnementen’

Het is niet makkelijk om dit allemaal in één advertentie te proppen die zo lang is als een tweet, en sommige elementen overlappen. Maar we doen ons best.

  • Headline 1: bevat altijd de naam van de cursus (of de eerste helft).
  • Headline 2: de tweede helft van de cursustitel, of een van de volgende:
    • Boost Your Data Science Career
    • Stand Out From the Crowd
    • Tackle Complex Questions
  • Description: elke advertentiegroep krijgt de drie onderstaande varianten die rouleren.
    • 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

Kolommen Campaign maken

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

Alle DataFrames ('name', 'url') samenvoegen

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

Advertenties genereren

Even checken waar je staat. Je hebt nu het ads-dataframe met de kolommen Campaign, Ad Group en Final URL correct gemapt. Je moet nog de velden Headline 1, Headline 2 en Description toevoegen.

Onthoud dat je voor elke advertentiegroep drie verschillende advertentievarianten toevoegt. Dit is een goede praktijk, vooral voor testdoeleinden: kijken waar mensen op klikken, welke advertenties beter converteren, enz. Je eindigt met een DataFrame dat drie keer zoveel rijen heeft als nu.

Laten we beginnen met elke rij drie keer te dupliceren in 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...


Nu voeg je de drie verschillende descriptions toe die je hierboven hebt gemaakt.

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...


Vervolgens voeg je Headline 1 en Headline 2 toe aan het DataFrame. Je bent bijna klaar!

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

De benefits worden opgenomen als Headline 2 in de gevallen waarin de lengte van de advertentiegroep 30 of minder is. In dat geval heb je een leeg veld, dat je vult met een van de benefits die je hebt.

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


Zoals je ziet was "Intro to Python for Data Science" lang genoeg om twee velden te vullen, dus laten we het zo om het duidelijk te houden. In het tweede geval past "Introduction to R" in de eerste headline, dus voeg je de drie verschillende benefits in bij Headline 2.

En klaar!

Check de details dubbel

Even een snelle check om zeker te zijn dat alle campagne- en advertentiegroepnamen in beide DataFrames hetzelfde zijn.

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)

Uploaden en lanceren

Zoals besproken, behandelt deze tutorial alleen specifieke stappen binnen SEM-campagnes en vereist hij dus een basisbegrip van hoe search engine marketing werkt. Wil je meer weten over de mechaniek en details van het uploaden en lanceren van je advertentiegroepen, bekijk dan de AdWords-gids om te starten. Voor volledige cursussen in verschillende gebieden kun je terecht bij de Google Academy for Ads.

Data science en SEM: er valt nog veel meer te ontdekken!

Met de twee CSV-bestanden die je nu hebt, kun je ze uploaden en je campagnes laten draaien. Je moet dagbudgetten, geotargeting en een paar andere parameters instellen, maar grotendeels ben je klaar om te gaan.

Als je de CSV-bestanden wilt bekijken, vind je ze hier:

Ik hoop dat je deze tutorial nuttig vond. Bedankt voor het lezen en als je groeiprojecten wilt delen die je met behulp van Python hebt gedaan, neem dan gerust contact met me op via Twitter @eliasdabbas.

Onderwerpen

Gerelateerd