Teil des intern verwendeten Data Mining Boards ist das Keyword-Clustering, das auf dem Levenshtein-Algorithmus basiert. Was sich im Zuge eines SEO-Audits als einmalige Fleißarbeit betiteln lässt, wird bei der Analyse von wöchentlichen und anders getakteten Reportings zu einer zeitaufwendigen Herausforderung. Der Levenshtein-Algorithmus kann ein grobes, aber automatisiertes Keyword-Clustering im Vorfeld erzeugen, sodass bei drei- bis fünfstelligen Keyword-Listen zumindest eine annehmbare Keyword-Sortierung stattgefunden hat. Per Hand wäre dies undenkbar. In der Praxis erzeugen die Code-Schnipsel unterhalb bei ca. 800 Keywords 80-90 Cluster. Die Präzision dieses Algorithmus ist natürlich auch erheblich von der Gestalt der vorliegenden Keywords abhängig.
Keywords der Vorwoche und der aktuellen
Zunächst einmal benötigen wir für zwei Listen (verlorene und gewonnene Keywords) zwei Abfragen der Google Search Analytics API. Dafür benötigen wir zwei zusätzliche Zeitschranken. Für zwei gegebene Zeitpunkte wird eine zweite Anfrage vorbereitet, die Suchanfragen im Zeitraum zwei Wochen davor abfragt. So können wir verlorene und gewonnene Keywords gewinnen.
schrankeOben = datetime.strptime(flags.start_date, '%Y-%m-%d') - timedelta(days=14) schrankeUnten = datetime.strptime(flags.end_date, '%Y-%m-%d') - timedelta(days=14)
Der Prozess sehr minimalistisch grafisch dargestellt.
Auf beide Listen wird jeweils die Differenz der Menge in die eine und in die andere Richtung gebildet.
newKeywordsListe = list(set(new_keywords) - set(old_keywords))
lostKeywordsListe = list(set(old_keywords) - set(new_keywords))
Die Queries dabei unterscheiden sich lediglich in den Request-Parametern startDate und endDate.
QUERY_REQUEST = { 'startDate': flags.start_date, 'endDate': flags.end_date, 'dimensions': ['query'], 'searchType': 'web', 'dimensionFilterGroups': [{ 'filters': [{ 'dimension': 'country', 'expression': 'DEU' }] }], 'rowLimit': 5000 } QUERY_PREWEEK_REQUEST = { 'startDate': schrankeOben.strftime("%Y-%m-%d"), 'endDate': schrankeUnten.strftime("%Y-%m-%d"), 'dimensions': ['query'], 'searchType': 'web', 'dimensionFilterGroups': [{ 'filters': [{ 'dimension': 'country', 'expression': 'DEU' }] }], 'rowLimit': 5000 }
Auf die beiden Listen wird dann die Funktion levensthein aufgerufen. Die Werte werden entsprechend in separate csv-Dateien abgelegt. Der Parameter y ist optional und hat per se einen Existenzgrund, der nur im Gesamtzusammenhang des gesamten SEO-Reporting-Skripts zu verstehen ist. Benötigt man lediglich das Cluster, so kann die Funktion auch abstrahiert und y sowie die if-Bedingungen entfernt werden.
# CLUSTER-ALGORTIHMUS def levenshtein(x,y='gewonnen'): words = np.asarray(sorted(x)) lev_similarity = -5*np.array([[distance.levenshtein(w1,w2) for w1 in words] for w2 in words]) affprop = sklearn.cluster.AffinityPropagation(affinity="precomputed", damping=0.5) affprop.fit(lev_similarity) for cluster_id in np.unique(affprop.labels_): exemplar = words[affprop.cluster_centers_indices_[cluster_id]] cluster = np.unique(words[np.nonzero(affprop.labels_==cluster_id)]) cluster_str = ", ".join(cluster) neues_cluster = "%s: %s" % (exemplar, cluster_str) if (y == 'gewonnen'): with open('gewonnene-keywords-' + start_zeitpunkt.strftime('%Y-%M-%d') + '-' + end_zeitpunkt.strftime('%Y-%M-%d') + '.csv', 'a', newline='') as csvfile: der_writer = csv.writer(csvfile, delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL) der_writer.writerow([neues_cluster,","]) if (y == 'verloren'): with open('verlorene-keywords-' + start_zeitpunkt.strftime('%Y-%M-%d') + '-' + end_zeitpunkt.strftime('%Y-%M-%d') + '.csv', 'a', newline='') as csvfile: der_writer = csv.writer(csvfile, delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL) der_writer.writerow([neues_cluster,","])
Hier kann man experimentierfreudig sein. Das Gewicht (hier 5) erzeugt plausible Ergebnisse.
lev_similarity = -5*np.array([[distance.levenshtein(w1,w2) for w1 in words] for w2 in words])
Zusätzlich zum Keyword-Clustering sind Anwendungen zur Bereinigung von Fehlschreibweisen, Brand-Filter und ähnliche Methoden denkbar.
Weiterführende Informationen
Bereits mit 14 Jahren absolvierte Jörs sein erstes Schulpraktikum bei der Deutschen Telekom mit Aspekten aus der Suchmaschinenoptimierung. Seitdem erfolgten mehrere berufliche Stationen sowie Aktivitäten als freiberuflicher Webdesigner. Er hat an der Technischen Universität in Darmstadt einen B.Sc. in Wirtschaftsinformatik abgeschlossen. Seit 2019 ist Jörs Lehrbeauftragter für Online-Marketing an der Hochschule Darmstadt sowie Honorardozent für Marketing Automation & Datenintegration an der Hochschule Fresenius. Marvin Jörs ist Gründer und geschäftsführender Gesellschafter der Skyscraper Marketing GmbH.
Wo bin ich?