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()
.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
ランディング ページ 表示回数 クリック数 クリック率 平均掲載順位 セッション 直帰率 ページ/セッション サイトの滞在時間(目標 2 の完了数) サイトの滞在時間(目標 2 の値) サイトの滞在時間(目標 2 のコンバージョン率)
0 /blog/typeerror-builtin_function_or_method-obj... 3,537 127 3.59% 15.0 132 94.70% 1.08 5 <¥1 3.79%
1 /blog/Try-static-analysis-of-Python-using-Sona... 2,360 85 3.60% 12.0 75 81.33% 1.20 7 <¥1 9.33%
2 /blog/get-single-result-on-django-model-filter/ 2,334 195 8.35% 8.8 203 88.18% 1.13 17 ¥2 8.37%
3 /blog/Use-the-Google-Place-API-as-a-facility-s... 2,068 142 6.87% 18.0 149 83.89% 1.14 11 ¥1 7.38%
4 /blog/WSGIRequest-object-is-not-subscriptable-... 1,845 64 3.47% 9.5 62 87.10% 1.11 4 <¥1 6.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-statistic F 統計量
Date 実行した日
Prob (F-statistic) F 統計量のp値
Time: 実行した時刻
Log-Likelihood 最大化対数尤度
No. Observations サンプルサイズ
AIC 赤池情報量規準
Df Residuals 残差の自由度
BIC ベイズ情報量規準
Df Model説明変数の数
Covariance Type 共分散の種類
  • 説明変数の出力部
項目名 説明
coef 相関係数
std err 標準誤差
t t値
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()
.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
クリック率 直帰率 サイトの滞在時間(目標 2 の完了数) 平均掲載順位
0 -0.533060 0.504502 1.258045 -0.261439
1 -0.532013 -0.046450 1.980330 -0.506833
2 -0.034441 0.235825 5.591754 -0.768587
3 -0.189474 0.059043 3.424900 -0.016045
4 -0.545631 0.191321 0.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が上がっていきそう。

参考

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

以上です。

コメント