Python ile arama niyetiyle SEO anahtar kelime kümelenme nasıl otomatikleştirilir

Derin öğrenmeyi kullanmaktan, metni sınıflandırarak ve doğal dil işleme (NLP) tekniklerini kullanarak SERP başlıklarını parçalayarak arama niyetini kullanmaktan, semantik alaka düzeyine dayalı kümelemeye kadar açıklanan faydalarla birlikte arama niyeti hakkında bilecek çok şey var.

Sadece arama niyetinin deşifre edilmesinin faydalarını bilmekle kalmıyor, aynı zamanda ölçek ve otomasyon için elimizde bir dizi teknik de var.

Peki, arama amacını otomatikleştirmek için neden başka bir makaleye ihtiyacımız var?

AI araması geldiğine göre arama niyeti artık daha önemli.

Daha fazlası genellikle 10 mavi bağlantı arama döneminde olsa da, AI arama teknolojisi ile tam tersi geçerlidir, çünkü bu platformlar genellikle hizmeti sunmak için bilgi işlem maliyetlerini (flop başına) en aza indirmeye çalışır.

SERP'ler hala arama niyeti için en iyi bilgileri içerir

Şimdiye kadar teknikler kendi yapay zekanızı yapmayı, yani belirli bir anahtar kelime için sıralama içeriğinin başlıklarından tüm kopyayı almayı ve daha sonra bir sinir ağ modeline (daha sonra oluşturmanız ve test etmeniz gerekir) veya küme anahtar kelimelerini kullanmayı içerir.

Ya kendi yapay zekanızı oluşturacak veya açık AI API'sını çağırmak için zamanınız veya bilginiz yoksa ne olur?

Kosinüs benzerliği, SEO profesyonellerinin taksonomi ve site yapıları için konuların sınırlandırılmasına yardımcı olmanın cevabı olarak lanse edilmiş olsa da, hala SERP sonuçlarıyla arama kümelemesinin çok üstün bir yöntem olduğunu savunuyorum.

Bunun nedeni, AI'nın sonuçlarını SERP'lere ve iyi bir nedenle topraklamak için çok istekli olmasıdır – kullanıcı davranışları üzerinde modellenmiştir.

Tüm SERPS içeriğini kazımak ve bir AI modeli oluşturmak zorunda kalmadan Google'ın kendi yapay zekasını sizin için yapmak için kullanan başka bir yol daha var.

Google'ın, kullanıcı sorgusunu azalan sırayla karşılama olasılığına göre site URL'lerini sıraladığını varsayalım. İki anahtar kelimenin amacı aynısa, SERP'lerin benzer olması muhtemeldir.

Yıllarca, birçok SEO uzmanı, temel güncellemelerin üstünde kalmak için paylaşılan (veya paylaşılan) arama niyetini çıkarmak için anahtar kelimeler için SERP sonuçlarını karşılaştırdı, bu yüzden bu yeni bir şey değil.

Buradaki katma değer, hem hız hem de daha fazla hassasiyet sunan bu karşılaştırmanın otomasyonu ve ölçeklendirilmesidir.

Python kullanarak ölçekte arama niyetiyle anahtar kelimeler nasıl kümelenir (kodla)

SERPS sonuçlarınızın bir CSV indirmesinde olduğunu varsayarsak, Python Notebook'unuza aktaralım.

1. Listeyi Python Notebook'unuza aktarın

import pandas as pd
import numpy as np

serps_input = pd.read_csv('data/sej_serps_input.csv')
del serps_input['Unnamed: 0']
serps_input

Aşağıda SERPS dosyası artık bir Pandas veri çerçevesine aktarılmıştır.

Yazardan Resim, Nisan 2025

2. Sayfa 1 için filtre verileri

Anahtar kelimeler arasındaki her bir SERP'nin sayfa 1 sonuçlarını karşılaştırmak istiyoruz.

Tek bir veri çerçevesinde yeniden birleştirmeden önce filtreleme işlevini çalıştırmak için veri çerçevesini mini anahtar kelime veri çerçevelerine ayıracağız, çünkü anahtar kelime düzeyinde filtrelemek istiyoruz:

# 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
Yazardan Resim, Nisan 2025

3. Convert Ranking URLs To A String

Because there are more SERP result URLs than keywords, we need to compress those URLs into a single line to represent the keyword’s SERP.

Here’s how:


# 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şağıda SERP, her anahtar kelime için tek bir satır halinde sıkıştırılmıştır.

Yazardan Resim, Nisan 2025

4. SERP mesafesini karşılaştırın

Karşılaştırmayı gerçekleştirmek için, artık diğer çiftlerle eşleştirilmiş SERP anahtar kelimesinin her kombinasyonuna ihtiyacımız var:


# 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

The above shows all of the keyword SERP pair combinations, making it ready for SERP string comparison.

There is no open-source library that compares list objects by order, so the function has been written for you below.

The function “serp_compare” compares the overlap of sites and the order of those sites between SERPs.


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)])
    #use to tokenize the URLs
    ws_tok = sm.WhitespaceTokenizer()
    #keep only first k URLs
    serps_1 = ws_tok.tokenize(serps_str1)[:k]
    serps_2 = ws_tok.tokenize(serps_str2)[:k]
    #get positions of matches 
    match = lambda a, b: [b.index(x)+1 if x in b else None for x in a]
    #positions intersections of form [(pos_1, pos_2), ...]
    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)

# This is what you get
matched_serps[['keyword', 'keyword_b', 'si_simi']]

Now that the comparisons have been executed, we can start clustering keywords.

We will be treating any keywords that have a weighted similarity of 40% or more.


# 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 NAN
keywords_filtered_nonnan = keywords_crossed_vols.dropna()
keywords_filtered_nonnan

Artık her birinin potansiyel konu adına, anahtar kelimeleri SERP benzerliği ve arama hacimlerine sahibiz.

Anahtar Kelime ve Key Word_B'nin sırasıyla konu ve anahtar kelime olarak yeniden adlandırıldığını not edersiniz.

Şimdi Lambda tekniğini kullanarak veri çerçevesindeki sütunları yineleyeceğiz.

Lambda tekniği, bir Pandas veri çerçevesindeki satırları yinelemenin etkili bir yoludur, çünkü .Terrows () işlevinin aksine satırları bir listeye dönüştürür.

İşte gidiyor:


queries_in_df = list(set(matched_serps['keyword'].to_list()))
topic_groups = {}

def dict_key(dicto, keyo):
    return keyo in dicto

def dict_values(dicto, vala):
    return any(vala in val for val in dicto.values())

def what_key(dicto, vala):
    for k, v in dicto.items():
            if vala in v:
                return k

def find_topics(si, keyw, topc):
    if (si >= simi_lim):

        if (not dict_key(sim_topic_groups, keyw)) and (not dict_key(sim_topic_groups, topc)): 

            if (not dict_values(sim_topic_groups, keyw)) and (not dict_values(sim_topic_groups, topc)): 
                sim_topic_groups[keyw] = [keyw] 
                sim_topic_groups[keyw] = [topc] 
                if dict_key(non_sim_topic_groups, keyw):
                    non_sim_topic_groups.pop(keyw)
                if dict_key(non_sim_topic_groups, topc): 
                    non_sim_topic_groups.pop(topc)
            if (dict_values(sim_topic_groups, keyw)) and (not dict_values(sim_topic_groups, topc)): 
                d_key = what_key(sim_topic_groups, keyw)
                sim_topic_groups[d_key].append(topc)
                if dict_key(non_sim_topic_groups, keyw):
                    non_sim_topic_groups.pop(keyw)
                if dict_key(non_sim_topic_groups, topc): 
                    non_sim_topic_groups.pop(topc)
            if (not dict_values(sim_topic_groups, keyw)) and (dict_values(sim_topic_groups, topc)): 
                d_key = what_key(sim_topic_groups, topc)
                sim_topic_groups[d_key].append(keyw)
                if dict_key(non_sim_topic_groups, keyw):
                    non_sim_topic_groups.pop(keyw)
                if dict_key(non_sim_topic_groups, topc): 
                    non_sim_topic_groups.pop(topc) 

        elif (keyw in sim_topic_groups) and (not topc in sim_topic_groups): 
            sim_topic_groups[keyw].append(topc)
            sim_topic_groups[keyw].append(keyw)
            if keyw in non_sim_topic_groups:
                non_sim_topic_groups.pop(keyw)
            if topc in non_sim_topic_groups: 
                non_sim_topic_groups.pop(topc)
        elif (not keyw in sim_topic_groups) and (topc in sim_topic_groups):
            sim_topic_groups[topc].append(keyw)
            sim_topic_groups[topc].append(topc)
            if keyw in non_sim_topic_groups:
                non_sim_topic_groups.pop(keyw)
            if topc in non_sim_topic_groups: 
                non_sim_topic_groups.pop(topc)
        elif (keyw in sim_topic_groups) and (topc in sim_topic_groups):
            if len(sim_topic_groups[keyw]) > len(sim_topic_groups[topc]):
                sim_topic_groups[keyw].append(topc) 
                [sim_topic_groups[keyw].append(x) for x in sim_topic_groups.get(topc)] 
                sim_topic_groups.pop(topc)

        elif len(sim_topic_groups[keyw]) < len(sim_topic_groups[topc]):
            sim_topic_groups[topc].append(keyw) 
            [sim_topic_groups[topc].append(x) for x in sim_topic_groups.get(keyw)]
            sim_topic_groups.pop(keyw) 
        elif len(sim_topic_groups[keyw]) == len(sim_topic_groups[topc]):
            if sim_topic_groups[keyw] == topc and sim_topic_groups[topc] == keyw:
            sim_topic_groups.pop(keyw)

    elif si < simi_lim:
  
        if (not dict_key(non_sim_topic_groups, keyw)) and (not dict_key(sim_topic_groups, keyw)) and (not dict_values(sim_topic_groups,keyw)): 
            non_sim_topic_groups[keyw] = [keyw]
        if (not dict_key(non_sim_topic_groups, topc)) and (not dict_key(sim_topic_groups, topc)) and (not dict_values(sim_topic_groups,topc)): 
            non_sim_topic_groups[topc] = [topc]

Aşağıda, arama niyetiyle kümelenen tüm anahtar kelimeleri içeren bir sözlük göstermektedir:

{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']}

Bunu bir veri çerçevesine yapıştıralım:


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
Yazardan Resim, Nisan 2025

Yukarıdaki arama niyet grupları, içlerindeki anahtar kelimelerin iyi bir yaklaşımını gösterir, bu da bir SEO uzmanının elde edeceği bir şeydir.

Yalnızca küçük bir anahtar kelime kullansak da, yöntem açık bir şekilde binlerce kişiye (daha fazla değilse) ölçeklendirilebilir.

Aramanızı daha iyi hale getirmek için çıktıları etkinleştirme

Tabii ki, yukarıdakiler sinir ağları kullanılarak daha doğru alınabilir, daha doğru kümeler ve küme grubu adlandırma için sıralama içeriğini işleyebilir, ancak bazı ticari ürünlerin zaten yaptığı gibi.

Şimdilik, bu çıktı ile:

  • Trendlerinizi ve SEO raporlarını daha anlamlı hale getirmek için bunu kendi SEO gösterge panosu sistemlerinize dahil edin.
  • Daha yüksek kalite puanı için arama niyetiyle Google Reklam Hesaplarınızı yapılandırarak daha iyi ücretli arama kampanyaları oluşturun.
  • Gereksiz faset e -ticaret arama URL'lerini birleştirin.
  • Tipik bir ürün kataloğu yerine arama amacına göre bir alışveriş sitesinin taksonomisini yapılandırın.

Bahsetmediğim daha fazla uygulama var – daha önce bahsetmediğim önemli olanlar hakkında yorum yapmaktan çekinmeyin.

Her durumda, SEO anahtar kelime araştırmanız biraz daha ölçeklenebilir, doğru ve daha hızlı oldu!

Kendi kullanımınız için tam kodu buradan indirin.

Daha fazla kaynak:


Öne Çıkan Resim: Buch ve Bee/Shutterstock


Yayımlandı

kategorisi

yazarı:

Etiketler:

Yorumlar

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir