python Google Search Console の掲載順位に影響を与える要因を重回帰分析で特定する


Google Analytics で、Google Search Console のデータを連携(調整)すると、Google Analyics 上で、Google Search Console のデータを結合して参照することができます。 結合したデータでは掲載順位と直帰率等のデータの関係が確認できるので、これを元に、python で重回帰分析を実施して、掲載順位に影響を与えるデータ項目を特定してみましたので、結果を記載します。


前提

ライブラリ

python の 以下ライブラリを使用しています。

  • pandas
  • statsmodels

入力データ

Google Analytics の、集客 > Search Console > ランディングページ から取得できるデータです。
期間設定をし、ページ滞在時間に関するコンバージョンの数を選択して、csvエクスポートし、スプレッドシートで不要なデータを除外した結果を再度csvエクスポートしています。


データの読み込んで、散布図を描画、重回帰分析を実施する

相関関係をざっくり知るために、データを読み込んで、散布図に描画します。

import pandas as pd
df = pd.read_csv("acquisition-sc-landingpages.csv")
df.head()
ランディング ページ表示回数クリック数クリック率平均掲載順位セッション直帰率ページ/セッションサイトの滞在時間(目標 2 の完了数)サイトの滞在時間(目標 2 の値)サイトの滞在時間(目標 2 のコンバージョン率)
0/blog/typeerror-builtin_function_or_method-obj...3,5371273.59%15.013294.70%1.085<¥13.79%
1/blog/Try-static-analysis-of-Python-using-Sona...2,360853.60%12.07581.33%1.207<¥19.33%
2/blog/get-single-result-on-django-model-filter/2,3341958.35%8.820388.18%1.1317¥28.37%
3/blog/Use-the-Google-Place-API-as-a-facility-s...2,0681426.87%18.014983.89%1.1411¥17.38%
4/blog/WSGIRequest-object-is-not-subscriptable-...1,845643.47%9.56287.10%1.114<¥16.45%
# クリック数が1回以上あるデータを抽出
df_clicked = df[df["クリック数"] >= 1]
# データを編集する
df_clicked = df_clicked.assign(直帰率=df_clicked['直帰率'].str.rstrip('%').astype('float') / 100.0)
df_clicked = df_clicked.assign(クリック率=df_clicked['クリック率'].str.rstrip('%').astype('float') / 100.0)
# 必要なカラムのみ取り出し
df_clicked = df_clicked.loc[:,['クリック率','直帰率','サイトの滞在時間(目標 2 の完了数)','平均掲載順位']]
%matplotlib inline
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (15, 10)
plt.rcParams['font.family'] = 'IPAexGothic'
ax = df_clicked.plot(kind='scatter', x='サイトの滞在時間(目標 2 の完了数)', y='平均掲載順位',color='RED', label='サイトの滞在時間 2分以上の数',s=10);
# 掲載順位を反転させる
ax.set_ylim([80, 0])
(80, 0)

png

ax = df_clicked.plot(kind='scatter', x='直帰率', y='平均掲載順位',color='BLUE', label='直帰率',s=10);
# 掲載順位を反転させる
ax.set_ylim([80, 0])
(80, 0)

png

ax = df_clicked.plot(kind='scatter', x='クリック率', y='平均掲載順位',color='GREEN', label='クリック率',s=10);
# 掲載順位を反転させる
ax.set_ylim([80, 0])
(80, 0)

png


重回帰分析を実施する

statsmodels.api.OLS を使って、重回帰分析を実行します。
OLS は、Ordinary Least Square の略で、最小二乗法による線型回帰分析になります。

  • Rの数式を使わない
import statsmodels.api as sm
# Fit and summarize OLS model
y = df_clicked['平均掲載順位']
X = df_clicked[['クリック率', '直帰率', 'サイトの滞在時間(目標 2 の完了数)']]
# 切片を追加する
mod = sm.OLS(y, sm.add_constant(X))
res=mod.fit()
print(res.summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                 平均掲載順位   R-squared:                       0.125
Model:                            OLS   Adj. R-squared:                  0.111
Method:                 Least Squares   F-statistic:                     8.501
Date:                Sat, 28 Jul 2018   Prob (F-statistic):           2.62e-05
Time:                        12:14:45   Log-Likelihood:                -701.70
No. Observations:                 182   AIC:                             1411.
Df Residuals:                     178   BIC:                             1424.
Df Model:                           3                                         
Covariance Type:            nonrobust                                         
=======================================================================================
                          coef    std err          t      P>|t|      [0.025      0.975]
---------------------------------------------------------------------------------------
const                  29.6176      3.402      8.706      0.000      22.904      36.331
クリック率                 -37.3386      9.001     -4.148      0.000     -55.100     -19.577
直帰率                    -8.3988      3.635     -2.311      0.022     -15.572      -1.226
サイトの滞在時間(目標 2 の完了数)    -0.8279      0.318     -2.604      0.010      -1.455      -0.200
==============================================================================
Omnibus:                       79.274   Durbin-Watson:                   1.921
Prob(Omnibus):                  0.000   Jarque-Bera (JB):              260.565
Skew:                           1.785   Prob(JB):                     2.62e-57
Kurtosis:                       7.649   Cond. No.                         34.1
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
  • Rの数式を使う
    statsmodels.formula.api.ols を使うと、formula にRの数式を指定でき、出力もRのlm と同様の形式になります。
import statsmodels.formula.api as smf
df2 = df_clicked.copy()
df2['AveragePosition'] = df2['平均掲載順位']
df2['CTR'] = df2['クリック率']
df2['Bouncerate'] = df2['直帰率']
df2['Goal2Completions'] = df2['サイトの滞在時間(目標 2 の完了数)']
mod = smf.ols(formula="AveragePosition ~ CTR + Bouncerate + Goal2Completions", data=df2)
res = mod.fit()
print(res.summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:        AveragePosition   R-squared:                       0.125
Model:                            OLS   Adj. R-squared:                  0.111
Method:                 Least Squares   F-statistic:                     8.501
Date:                Sat, 28 Jul 2018   Prob (F-statistic):           2.62e-05
Time:                        12:14:49   Log-Likelihood:                -701.70
No. Observations:                 182   AIC:                             1411.
Df Residuals:                     178   BIC:                             1424.
Df Model:                           3                                         
Covariance Type:            nonrobust                                         
====================================================================================
                       coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------------
Intercept           29.6176      3.402      8.706      0.000      22.904      36.331
CTR                -37.3386      9.001     -4.148      0.000     -55.100     -19.577
Bouncerate          -8.3988      3.635     -2.311      0.022     -15.572      -1.226
Goal2Completions    -0.8279      0.318     -2.604      0.010      -1.455      -0.200
==============================================================================
Omnibus:                       79.274   Durbin-Watson:                   1.921
Prob(Omnibus):                  0.000   Jarque-Bera (JB):              260.565
Skew:                           1.785   Prob(JB):                     2.62e-57
Kurtosis:                       7.649   Cond. No.                         34.1
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

出力の説明

個人的にあまり内容を理解、出力内容の意味を記載します。

  • 結果上部
項目名説明
Dep. Variable:目的変数名が出力されます。
R-squared決定係数
Model回帰分析のModelの名前が出力されます
Adj. R-squared自由度修正済決定係数
Method分析方法? Model OLS とほぼ同じかもしれません。
F-statisticF 統計量
Date実行した日
Prob (F-statistic)F 統計量のp値
Time:実行した時刻
Log-Likelihood最大化対数尤度
No. Observationsサンプルサイズ
AIC赤池情報量規準
Df Residuals残差の自由度
BICベイズ情報量規準
Df Model説明変数の数
Covariance Type共分散の種類
  • 説明変数の出力部
項目名説明
coef相関係数
std err標準誤差
tt値
P>t両側検定のp値
[0.025 0.975]95%信頼区間
  • 結果下部
    残差に関する、検定の結果が出力されます。
    OmnibusDurbin-Watson等が検定の種類で、その結果が数値として出力されています。
    詳しい意味については少し調べて限りは、ピンとくるものがなく、後日詳細調べてみようかと思います。

結果を分析する

サマリの決定係数は、R-squared: 0.125 あまりうまく説明できていないように思います。
データの単位が違うことが影響しているのではと考え、データを標準化して、再試行してみます。


データの標準化し、1つの散布図に描画する

滞在時間 2分の完了数、直帰率、クリック率 を、説明変数 とします。
データのばらつきがあるので標準化を実施し、標準化したデータを1つのグラフに描画してみます。

from sklearn.preprocessing import StandardScaler
## データの標準化を行う準備
# 標準化を行うモデル
std = StandardScaler()
# モデルにデータを学習させる
std.fit(df_clicked)
# データを標準化する
std_data = pd.DataFrame(std.transform(df_clicked), columns=df_clicked.columns)
std_data.head()
クリック率直帰率サイトの滞在時間(目標 2 の完了数)平均掲載順位
0-0.5330600.5045021.258045-0.261439
1-0.532013-0.0464501.980330-0.506833
2-0.0344410.2358255.591754-0.768587
3-0.1894740.0590433.424900-0.016045
4-0.5456310.1913210.896903-0.711328
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (15, 10)
plt.rcParams['font.family'] = 'IPAexGothic'
ax1 = std_data.plot(kind='scatter', x='サイトの滞在時間(目標 2 の完了数)', y='平均掲載順位',color='RED', label='サイトの滞在時間 2分以上の数',s=10);
ax2 = std_data.plot(kind='scatter', x='直帰率', y='平均掲載順位',color='BLUE', label='直帰率',s=10, ax=ax1);
ax3 = std_data.plot(kind='scatter', x='クリック率', y='平均掲載順位',color='GREEN', label='クリック率',s=10, ax=ax2);
# 掲載順位を反転させる
ax1.set_ylim([10, -10])
ax2.set_ylim([10, -10])
ax3.set_ylim([10, -10])
(10, -10)

png

以下の内容が読み取れるように思います。

  • サイトの滞在時間、クリック率と掲載順位は正の相関、直帰率と掲載順位には負の相関がある。
  • 直帰率は、zスコアは負の方法に広がっている。直帰率 100% に近いデータが多そう。
  • サイトの滞在時間、クリック率 は正の方法に広がっている。 滞在時間の短い(2分を超えない)ページ、クリック率の低いページが多そう。

重回帰分析を実施する

import statsmodels.formula.api as smf
df2 = std_data.copy()
df2['AveragePosition'] = df2['平均掲載順位']
df2['CTR'] = df2['クリック率']
df2['Bouncerate'] = df2['直帰率']
df2['Goal2Completions'] = df2['サイトの滞在時間(目標 2 の完了数)']
mod = smf.ols(formula="AveragePosition ~ CTR + Bouncerate + Goal2Completions", data=df2)
res = mod.fit()
print(res.summary())
                            OLS Regression Results                            
==============================================================================
Dep. Variable:        AveragePosition   R-squared:                       0.125
Model:                            OLS   Adj. R-squared:                  0.111
Method:                 Least Squares   F-statistic:                     8.501
Date:                Sat, 28 Jul 2018   Prob (F-statistic):           2.62e-05
Time:                        12:15:22   Log-Likelihood:                -246.06
No. Observations:                 182   AIC:                             500.1
Df Residuals:                     178   BIC:                             512.9
Df Model:                           3                                         
Covariance Type:            nonrobust                                         
====================================================================================
                       coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------------
Intercept         1.041e-16      0.070   1.48e-15      1.000      -0.138       0.138
CTR                 -0.2916      0.070     -4.148      0.000      -0.430      -0.153
Bouncerate          -0.1667      0.072     -2.311      0.022      -0.309      -0.024
Goal2Completions    -0.1875      0.072     -2.604      0.010      -0.330      -0.045
==============================================================================
Omnibus:                       79.274   Durbin-Watson:                   1.921
Prob(Omnibus):                  0.000   Jarque-Bera (JB):              260.565
Skew:                           1.785   Prob(JB):                     2.62e-57
Kurtosis:                       7.649   Cond. No.                         1.27
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

結果を分析する

以下のことが読み取れるのかと思います。

  • サマリの決定係数は、R-squared: 0.135 で標準化前の、R-squared: 0.125 に比べて少し説明できるようになっている。
  • CTR の、P>t の値は、0.015 で CTR、Bouncerate、Goal2Completions の中では掲載順位に与える影響が最も強そう。
  • Bouncerate の、P>t の値は、0.504 で 掲載順位に与える影響はあまりなさそう。
  • 直帰率が高くても、ページ滞在時間が長いページがあり、そのページの掲載順位が低いとは言えず、掲載順位が高い傾向がありそう。
  • Goal2Completions の、P>t の値は、0.098 であり、CTRほどではないが、掲載順位に与える影響が最も強そう。
  • CTRと掲載順位の関係は、掲載順位が高いから、CTRが上がるとも言える。
  • ページ滞在時間が長いページ(良いコンテンツ)を作ると、その結果として掲載順位が上がり、掲載順位に比例してCTRが上がっていきそう。

参考

分析実施時に参考にした記事になります。

以上です。

コメント