Tant si es tracta de demanda de cerques, d’ingressos o de trànsit procedent de la cerca orgànica, en algun moment de la vostra carrera de SEO, se us demanarà que feu una previsió.
En aquesta columna, aprendreu a fer-ho amb precisió i eficiència, gràcies a Python.
Explorarem com:
- Extraieu i dibuixeu les vostres dades.
- Utilitzeu mètodes automatitzats per estimar els paràmetres del model més adequat.
- Apliqueu el mètode Augmented Dickey-Fuller (ADF) per provar estadísticament una sèrie temporal.
- Calculeu el nombre de paràmetres per a un model SARIMA.
- Posa a prova els teus models i comença a fer previsions.
- Interpretar i exportar les seves previsions.
Abans d’entrar-hi, definim les dades. Independentment del tipus de mètrica, intentem predir que les dades es produiran amb el pas del temps.
En la majoria dels casos, és probable que passi per una sèrie de dates. De manera efectiva, les tècniques que presentem aquí són tècniques de predicció de sèries temporals.
Llavors, per què fer previsions?
Per respondre a una pregunta amb una pregunta, per què no pronostiqueu?
Aquestes tècniques s’han utilitzat durant molt de temps en finances per a preus de les accions, per exemple, i en altres camps. Per què el SEO ha de ser diferent?
Publicitat
Continueu llegint a continuació
Amb múltiples interessos, com el titular del pressupost i altres col·legues (per exemple, el gerent de SEO i el director de màrqueting), hi haurà expectatives sobre què pot oferir el canal de cerca orgànica i si es compliran o no aquestes expectatives.
Les previsions proporcionen una resposta basada en dades.
Informació útil sobre previsions per a professionals de SEO
Utilitzant l’enfocament basat en dades Python, hi ha algunes coses a tenir en compte:
Les previsions funcionen millor quan hi ha moltes dades històriques.
La cadència de les dades determinarà el període de temps necessari per a la vostra previsió.
Per exemple, si teniu dades diàries com les que teniu a les analítiques del lloc web, tindreu més de 720 punts de dades, que estan bé.
Amb Google Trends, que té una cadència setmanal, necessitareu almenys 5 anys per obtenir 250 punts de dades.
En qualsevol cas, hauríeu d’orientar-vos a un període de temps que us proporcionés com a mínim 200 punts de dades (un número arrencat de la meva experiència personal).
Models com la coherència.
Si la vostra tendència de dades té un patró (per exemple, és cíclic perquè hi ha estacionalitat), és probable que les previsions siguin fiables.
Publicitat
Continueu llegint a continuació
Per aquest motiu, les previsions no gestionen molt bé les tendències de ruptura perquè no hi ha dades històriques per basar el futur, com veurem més endavant.
Llavors, com funcionen els models de predicció? Hi ha alguns aspectes que abordaran els models sobre les dades de sèries temporals:
Autocorrelació
L’autocorrelació és la mesura en què el punt de dades és similar al punt de dades anterior.
Això pot donar informació al model quant a l’impacte que té un esdeveniment en el temps sobre el trànsit de cerca i si el patró és estacional.
Estacionalitat
L’estacionalitat informa el model sobre si hi ha un patró cíclic i les propietats del patró, per exemple: quant de temps o la mida de la variació entre els màxims i els mínims.
Estacionarietat
L’estacionarietat és la mesura de com la tendència general canvia amb el pas del temps. Una tendència no estacionària mostraria una tendència general cap amunt o cap avall, malgrat els màxims i mínims dels cicles estacionals.
Tenint en compte l’anterior, els models “faran” coses a les dades perquè siguin més rectes i, per tant, més predicibles.
Amb la teoria del xiulet fora de camí, comencem a predir.
Exploració de les vostres dades
# Import your libraries import pandas as pd from statsmodels.tsa.statespace.sarimax import SARIMAX from statsmodels.graphics.tsaplots import plot_acf, plot_pacf from statsmodels.tsa.seasonal import seasonal_decompose from sklearn.metrics import mean_squared_error from statsmodels.tools.eval_measures import rmse import warnings warnings.filterwarnings("ignore") from pmdarima import auto_arima
Estem utilitzant Google Trends data, que és una exportació CSV.
Aquestes tècniques es poden utilitzar en qualsevol sèrie de dades temporals, ja siguin vostres, clics, ingressos, del vostre client o empresa, etc.
# Import Google Trends Data df = pd.read_csv("exports/keyword_gtrends_df.csv", index_col=0) df.head()
Com esperaríem, les dades de Google Trends són una sèrie temporal molt senzilla amb data, consulta i visites que abasten un període de cinc anys.
Publicitat
Continueu llegint a continuació
És hora de donar format al marc de dades per passar de llarg a ampli.
Això ens permet veure les dades amb cada consulta de cerca com a columnes:
df_unstacked = ps_trends.set_index(["date", "query"]).unstack(level=-1) df_unstacked.columns.set_names(['hits', 'query'], inplace=True) ps_unstacked = df_unstacked.droplevel('hits', axis=1) ps_unstacked.columns = [c.replace(' ', '_') for c in ps_unstacked.columns] ps_unstacked = ps_unstacked.reset_index() ps_unstacked.head()
Ja no tenim cap columna de visites, ja que aquests són els valors de les consultes a les seves respectives columnes.
Aquest format no només és útil per a SARIMA (que explorarem aquí), sinó també per a xarxes neuronals com la memòria a curt termini (LSTM).
Publicitat
Continueu llegint a continuació
Representem les dades:
ps_unstacked.plot(figsize=(10,5))
A la trama (a sobre), es nota que els perfils de “PS4” i “PS5” són diferents. Per a aquells que no són jugadors, “PS4” és la quarta generació de la consola Sony Playstation i “PS5” la cinquena.
Les cerques “PS4” són molt estacionals, ja que són un producte consolidat i tenen un patró regular a part del final quan apareix el “PS5”.
Publicitat
Continueu llegint a continuació
El “PS5” no existia fa 5 anys, cosa que explicaria l’absència de tendència en els primers 4 anys de la trama anterior.
He escollit aquestes dues consultes per ajudar a il·lustrar la diferència en la previsió d’eficàcia de les dues característiques molt diferents.
Descomposició de la tendència
Descomposem ara les característiques estacionals (o no estacionals) de cada tendència:
ps_unstacked.set_index("date", inplace=True) ps_unstacked.index = pd.to_datetime(ps_unstacked.index)
query_col="ps5" a = seasonal_decompose(ps_unstacked[query_col], model = "add") a.plot();
L’anterior mostra les dades de les sèries temporals i la tendència general suavitzada que es produeix a partir del 2020.
Publicitat
Continueu llegint a continuació
El quadre de tendències estacionals mostra pics repetits, cosa que indica que hi ha estacionalitat a partir del 2016. Tot i això, no sembla particularment fiable tenint en compte la planitud de les sèries temporals des del 2016 fins al 2020.
També és sospitosa la manca de soroll, ja que la trama estacional mostra un patró pràcticament uniforme que es repeteix periòdicament.
El Resid (que significa “Residual”) mostra qualsevol patró del que queda de les dades de les sèries temporals després de tenir en compte l’estacionalitat i la tendència, que efectivament no és fins al 2020, ja que la majoria de vegades és zero.
Per a “ps4”:
Podem veure fluctuacions a curt termini (estacionalitat) i a llarg termini (tendència), amb una mica de soroll (Resid).
Publicitat
Continueu llegint a continuació
El següent pas és utilitzar el mètode Augmented Dickey-Fuller (ADF) per provar estadísticament si una sèrie temporal determinada és estacionària o no.
from pmdarima.arima import ADFTest adf_test = ADFTest(alpha=0.05) adf_test.should_diff(ps_unstacked[query_col]) PS4: (0.09760939899434763, True) PS5: (0.01, False)
Podem veure que el valor p de “PS5” que es mostra anteriorment és superior a 0,05, cosa que significa que les dades de la sèrie temporal no són estacionàries i, per tant, necessiten diferències.
“PS4”, en canvi, és inferior a 0,05 a 0,01; és estacionari i no requereix diferències.
L’objectiu de tot plegat és entendre els paràmetres que s’utilitzarien si construíssim manualment un model per predir les cerques a Google.
Adaptació del vostre model SARIMA
Com que farem servir mètodes automatitzats per estimar els paràmetres del millor model d’ajust (més endavant), ara estimarem el nombre de paràmetres per al nostre model SARIMA.
He escollit SARIMA perquè és fàcil d’instal·lar. Tot i que el Profeta de Facebook és elegant matemàticament parlant (utilitza mètodes de Monte Carlo), no es manté prou i és possible que molts usuaris tinguin problemes per intentar instal·lar-lo.
Publicitat
Continueu llegint a continuació
En qualsevol cas, SARIMA es compara bastant bé amb el Profeta en termes de precisió.
Per estimar els paràmetres del nostre model SARIMA, tingueu en compte que establim m a 52, ja que hi ha 52 setmanes a l’any, que és la manera en què els períodes s’espaien a Google Trends.
També establim tots els paràmetres perquè comencin a 0, de manera que puguem deixar que l’auto_arima faci pes i buscar els valors que millor s’ajusten a les dades per a la previsió.
ps5_s = auto_arima(ps_unstacked['ps4'], trace=True, m=52, # there are 52 periods per season (weekly data) start_p=0, start_d=0, start_q=0, seasonal=False)
Resposta a l’anterior:
Performing stepwise search to minimize aic ARIMA(3,0,3)(0,0,0)[0] : AIC=1842.301, Time=0.26 sec ARIMA(0,0,0)(0,0,0)[0] : AIC=2651.089, Time=0.01 sec ... ARIMA(5,0,4)(0,0,0)[0] intercept : AIC=1829.109, Time=0.51 sec Best model: ARIMA(4,0,3)(0,0,0)[0] intercept Total fit time: 6.601 seconds
La impressió anterior mostra que els paràmetres que obtenen els millors resultats són:
PS4: ARIMA(4,0,3)(0,0,0) PS5: ARIMA(3,1,3)(0,0,0)
L’estimació de PS5 es detalla a l’hora d’imprimir el resum del model:
ps5_s.summary()
El que passa és això: La funció busca minimitzar la probabilitat d’error mesurada tant pel criteri d’informació d’Akaike (AIC) com pel criteri d’informació bayesià.
Publicitat
Continueu llegint a continuació
AIC = -2Log(L) + 2(p + q + k + 1)
Tal que L és la probabilitat de les dades, k = 1 si c ≠ 0 i k = 0 si c = 0
BIC = AIC + [log(T) - 2] + (p + q + k + 1)
En minimitzar AIC i BIC, obtenim els paràmetres millor estimats per a p i q.
Proveu el model
Ara que tenim els paràmetres, podem començar a fer previsions. En primer lloc, veurem el rendiment del model respecte a les dades anteriors. Això ens dóna algunes indicacions sobre el rendiment del model en períodes futurs.
ps4_order = ps4_s.get_params()['order'] ps4_seasorder = ps4_s.get_params()['seasonal_order'] ps5_order = ps5_s.get_params()['order'] ps5_seasorder = ps5_s.get_params()['seasonal_order'] params = { "ps4": {"order": ps4_order, "seasonal_order": ps4_seasorder}, "ps5": {"order": ps5_order, "seasonal_order": ps5_seasorder} } results = [] fig, axs = plt.subplots(len(X.columns), 1, figsize=(24, 12)) for i, col in enumerate(X.columns): #Fit best model for each column arima_model = SARIMAX(train_data[col], order = params[col]["order"], seasonal_order = params[col]["seasonal_order"]) arima_result = arima_model.fit() #Predict arima_pred = arima_result.predict(start = len(train_data), end = len(X)-1, typ="levels") .rename("ARIMA Predictions") #Plot predictions test_data[col].plot(figsize = (8,4), legend=True, ax=axs[i]) arima_pred.plot(legend = True, ax=axs[i]) arima_rmse_error = rmse(test_data[col], arima_pred) mean_value = X[col].mean() results.append((col, arima_pred, arima_rmse_error, mean_value)) print(f'Column: {col} --> RMSE Error: {arima_rmse_error} - Mean: {mean_value}n') Column: ps4 --> RMSE Error: 8.626764032898576 - Mean: 37.83461538461538 Column: ps5 --> RMSE Error: 27.552818032476257 - Mean: 3.973076923076923
Les previsions mostren que els models són bons quan hi ha prou història fins que canvien de sobte, tal com ho fan per a PS4 a partir del març.
Per a PS5, els models són pràcticament desesperats des del primer moment.
Ho sabem perquè el Root Mean Squared Error (RMSE) és de 8,62 per a PS4, que és més d’un terç de la PS5 RMSE de 27,5. Com que Google Trends varia de 0 a 100, es tracta d’un marge d’error del 27%.
Previsió del futur
Arribats a aquest punt, farem ara l’intent absurd de predir el futur a partir de les dades que tenim fins ara:
Publicitat
Continueu llegint a continuació
oos_train_data = ps_unstacked oos_train_data.tail()
Com podeu veure a l’extracte de la taula anterior, ara estem utilitzant totes les dades disponibles.
Ara predirem els propers 6 mesos (definits com a 26 setmanes) al codi següent:
oos_results = [] weeks_to_predict = 26 fig, axs = plt.subplots(len(ps_unstacked.columns), 1, figsize=(24, 12)) for i, col in enumerate(ps_unstacked.columns): #Fit best model for each column s = auto_arima(oos_train_data[col], trace=True) oos_arima_model = SARIMAX(oos_train_data[col], order = s.get_params()['order'], seasonal_order = s.get_params()['seasonal_order']) oos_arima_result = oos_arima_model.fit()
#Predict oos_arima_pred = oos_arima_result.predict(start = len(oos_train_data), end = len(oos_train_data) + weeks_to_predict, typ="levels").rename("ARIMA Predictions") #Plot predictions oos_arima_pred.plot(legend = True, ax=axs[i]) axs[i].legend([col]); mean_value = ps_unstacked[col].mean() oos_results.append((col, oos_arima_pred, mean_value)) print(f'Column: {col} - Mean: {mean_value}n')
La sortida:
Performing stepwise search to minimize aic ARIMA(2,0,2)(0,0,0)[0] intercept : AIC=1829.734, Time=0.21 sec ARIMA(0,0,0)(0,0,0)[0] intercept : AIC=1999.661, Time=0.01 sec ... ARIMA(1,0,0)(0,0,0)[0] : AIC=1865.936, Time=0.02 sec Best model: ARIMA(1,0,0)(0,0,0)[0] intercept Total fit time: 0.722 seconds Column: ps4 - Mean: 37.83461538461538
Performing stepwise search to minimize aic ARIMA(2,1,2)(0,0,0)[0] intercept : AIC=1657.990, Time=0.19 sec ARIMA(0,1,0)(0,0,0)[0] intercept : AIC=1696.958, Time=0.01 sec ... ARIMA(4,1,4)(0,0,0)[0] : AIC=1645.756, Time=0.56 sec Best model: ARIMA(3,1,3)(0,0,0)[0] Total fit time: 7.954 seconds Column: ps5 - Mean: 3.973076923076923
Aquesta vegada, hem automatitzat la cerca dels millors paràmetres d’ajust i els hem introduït directament al model.
Hi ha hagut molts canvis en les darreres setmanes de les dades. Tot i que les tendències previstes semblen probables, no semblen molt precises, com es mostra a continuació:
Això és en el cas d’aquestes dues paraules clau; si proveu el codi de les vostres altres dades basant-vos en consultes més establertes, probablement proporcionaran previsions més precises sobre les vostres pròpies dades.
Publicitat
Continueu llegint a continuació
La qualitat de la previsió dependrà de l’estabilitat dels patrons històrics i, òbviament, no tindrà en compte esdeveniments imprevisibles com COVID-19.
Inicieu la previsió de SEO
Si no us ha emocionat l’eina de visualització de dades de trama matriu de Python, no us temeu. Podeu exportar les dades i les previsions a Excel, Tableau o a un altre frontal del tauler per fer-los més agradables.
Per exportar les previsions:
df_pred = pd.concat([pd.Series(res[1]) for res in oos_results], axis=1) df_pred.columns = [x + str('_preds') for x in ps_unstacked.columns] df_pred.to_csv('your_forecast_data.csv')
El que hem après aquí és on la previsió mitjançant models estadístics és útil o és probable que aporti valor per a la predicció, sobretot en sistemes automatitzats com els taulers, és a dir, quan hi ha dades històriques i no quan es produeix un repunt sobtat, com PS5.
Més recursos:
Imatge destacada: ImageFlow / Shutterstock