Com s’utilitza Python per pronosticar la demanda, el trànsit i molt més per a SEO


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()
Dades d’exemple de Google Trends.Captura de pantalla de Google Trends, setembre de 2021

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()
Marc de dades formatat.Captura de pantalla de Google Trends, setembre de 2021

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))
Representació de les dades.Captura de pantalla de Google Trends, setembre de 2021

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();
Dades de sèries temporals.Captura de pantalla de Google Trends, setembre de 2021

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”:

Dades de sèries temporals.Captura de pantalla de Google Trends, setembre de 2021

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()
Resultats SARIMAX.Captura de pantalla de SARIMA, setembre de 2021

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()
Dades per fer previsions.Captura de pantalla de Google Trends, setembre de 2021

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ó:

Gràfic de previsions a partir de les dades.Captura de pantalla de Google Trends, setembre de 2021

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





Source link

Com s’utilitza Python per pronosticar la demanda, el trànsit i molt més per a SEO