
Yra daug ką žinoti apie paieškos ketinimus, pradedant nuo giluminio mokymosi ir baigiant paieškos ketinimais, klasifikuojant tekstą ir suskaidžius SERP pavadinimus, naudojant natūralių kalbų apdorojimo (NLP) metodus, iki grupavimo pagal semantinį svarbą, paaiškinant pranašumus.
Mes ne tik žinome paieškos ketinimų iššifravimo pranašumus, bet ir turime daugybę metodų, turinčių mastą ir automatizavimą.
Taigi, kodėl mums reikia kito straipsnio apie paieškos ketinimo automatizavimą?
Paieškos ketinimas yra vis svarbesnis dabar, kai atėjo AI paieška.
Nors daugiau buvo 10 „Blue Links“ paieškos eroje, priešingai – AI paieškos technologija, nes šios platformos paprastai siekia sumažinti skaičiavimo išlaidas (už FLOP), kad galėtų teikti paslaugą.
SERP vis dar yra geriausios įžvalgos ieškant paieškos
Iki šiol metodai apima savo AI atlikimą, tai yra, visas kopijas iš tam tikro raktinio žodžio reitingo turinio pavadinimų ir tada padedant jį į neuroninio tinklo modelį (kurį turite tada sukurti ir išbandyti) arba naudoti NLP, kad suskirstytumėte raktinius žodžius.
Ką daryti, jei neturite laiko ar žinių, kaip sukurti savo AI ar iškviesti atvirą AI API?
Nors kosinuso panašumas buvo nurodytas kaip atsakymas į pagalbą SEO profesionalams naršyti taksonomijos ir teritorijos struktūrų temų demarkaciją, aš vis tiek manau, kad paieškos grupavimas pagal SERP rezultatus yra daug pranašesnis metodas.
Taip yra todėl, kad AI labai nori pagrįsti savo rezultatus SERP ir dėl rimtos priežasties – tai modeliuojama pagal vartotojo elgesį.
Yra dar vienas būdas, kuriuo naudojamas pats „Google“ AI, kad atliktumėte darbą jums, nereikia nuvalyti viso SERP turinio ir sukurti AI modelį.
Tarkime, kad „Google“ įvertina svetainės URL pagal tikimybę, kad turinys patenkina vartotojo užklausą mažėjančia tvarka. Iš to išplaukia, kad jei dviejų raktinių žodžių ketinimas yra tas pats, tada SERP greičiausiai bus panašūs.
Ilgus metus daugelis SEO profesionalų palygino raktinių žodžių SERP rezultatus, kad būtų galima daryti išvadą apie bendrą (arba dalijantis) paieškos ketinimą išlikti pagrindinių atnaujinimų viršuje, taigi tai nėra nieko naujo.
Pridedama vertė yra šio palyginimo automatizavimas ir mastas, siūlantis tiek greitį, tiek didesnį tikslumą.
Kaip sugrupuoti raktinius žodžius, naudojant „Payctent“ mastelio būdu, naudojant „Python“ (su kodu)
Darant prielaidą, kad turite SERP rezultatus CSV atsisiunčiant, importuosime jį į savo „Python“ nešiojamąjį kompiuterį.
1. Importuokite sąrašą į savo „Python“ nešiojamąjį kompiuterį
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
Žemiau yra SERP failas, dabar importuotas į „Pandas“ duomenų rėmelį.

2. 1 puslapio filtrų duomenys
Mes norime palyginti kiekvieno SERP 1 puslapio rezultatus tarp raktinių žodžių.
Mes padalinsime „DataFrame“ į mini raktinių žodžių duomenų rėmus, kad atliktume filtravimo funkciją prieš rekombinant į vieną „DataFrame“, nes norime filtruoti raktinių žodžių lygyje:
# Split
serps_grpby_keyword = serps_input.groupby("keyword")
k_urls = 15
# Apply Combine
def filter_k_urls(group_df):
filtered_df = group_df.loc(group_df('url').notnull())
filtered_df = filtered_df.loc(filtered_df('rank') <= k_urls)
return filtered_df
filtered_serps = serps_grpby_keyword.apply(filter_k_urls)
# Combine
## Add prefix to column names
#normed = normed.add_prefix('normed_')
# Concatenate with initial data frame
filtered_serps_df = pd.concat((filtered_serps),axis=0)
del filtered_serps_df('keyword')
filtered_serps_df = filtered_serps_df.reset_index()
del filtered_serps_df('level_1')
filtered_serps_df

3. 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
Žemiau parodytas SERP, suspaustas į vieną eilutę kiekvienam raktiniam žodžiui.

4. Palyginkite SERP atstumą
Norėdami atlikti palyginimą, mums dabar reikia kiekvieno raktinių žodžių SERP derinio, suporuoto su kitomis poromis:
# 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
Dabar turime galimą temos pavadinimą, raktinių žodžių SERP panašumą ir kiekvieno paieškos tomus.
Atkreipsite dėmesį, kad raktiniai žodžiai ir raktiniai žodžiai buvo pervadinti atitinkamai pagal temą ir raktinį žodį.
Dabar mes pakartosime duomenų rėmo stulpelius, naudodami „Lambda“ techniką.
„Lambda“ technika yra efektyvus būdas pakartoti „Pandas“ duomenų įrišimo eilutes, nes ji konvertuoja eiles į sąrašą, o ne. ITERROWS () funkciją.
Štai:
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)
Žemiau pateiktas žodynas, kuriame yra visi raktiniai žodžiai, suskirstyti į paieškos ketinimus sunumeruotose grupėse:
{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')}
Įklijuokime tai į duomenų rė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

Aukščiau pateiktos paieškos ketinimų grupės parodo gerą raktinių žodžių apytikslį jų viduje – to, ko greičiausiai pasieks SEO ekspertas.
Nors mes panaudojome tik nedidelį raktinių žodžių rinkinį, metodas akivaizdžiai gali būti sumažintas tūkstančiais (jei ne daugiau).
Suaktyvinkite išėjimus, kad jūsų paieška būtų geresnė
Žinoma, tai, kas išdėstyta aukščiau, būtų galima dar labiau panaudoti naudojant neuroninius tinklus, tvarkant tikslesnių grupių ir klasterių grupės pavadinimų reitingo turinį, kaip kai kurie iš jų jau yra komerciniai produktai.
Kol kas, naudodamiesi šia išvestimi, galite:
- Įtraukite tai į savo SEO prietaisų skydelio sistemas, kad jūsų tendencijos ir SEO būtų prasmingesnės.
- Sukurkite geriau apmokamas paieškos kampanijas, struktūrizuodami „Google“ skelbimų paskyras, ieškodami aukštesnės kokybės balo.
- Sujungti nereikalingą briaunos elektroninės prekybos paieškos URL.
- Struktūrizuokite apsipirkimo svetainės taksonomiją pagal paieškos ketinimus, o ne tipišką produktų katalogą.
Esu tikras, kad yra daugiau programų, kurių aš nepaminėjau – nedvejodami pakomentuokite svarbius, kurių dar neminėjau.
Bet kokiu atveju, jūsų SEO raktinių žodžių tyrimas tiesiog sulaukė šiek tiek labiau keičiamo, tikslaus ir greitesnio!
Atsisiųskite visą kodą čia savo reikmėms.
Daugiau išteklių:
Teminis vaizdas: „Buch“ ir „Bee/Shutterstock“