統計検定の問題を解いていて、単回帰分析が出てきました。
昔習った覚えがありますが、完全に忘れていて外したので、クリック数の予測をすることで思い出し、覚え直したいと思います。


参考

実装の前段階で、単回帰分析とは? がわからなったため、以下記事を読んで学習しました。

前提

  • Google Search Console のデータの取得
    joshcarty/google-searchconsole: A wrapper for the Google Search Console API.使用しています。
    本線にマージされていませんが、branch にある version は、サービスアカウントを使った API 接続ができるようになっていますので、それを使用しています。

  • pandas の Version

    python3 -m pip list | grep pandas
    pandas                            0.21.1
    

  • scikit-learn の Version

    % python3 -m pip list | grep  scikit-learn 
    scikit-learn                      0.19.1    
    

  • bokeh の Version

    % python3 -m pip list | grep  bokeh
    bokeh                             0.12.16    
    


手順

以下の手順で、単回帰直線を引き、未来のクリック数を予測します。

  1. Google Search Console から取得したデータで、時系列グラフを引く。
  2. LinearRegression で、Model を作成する。
  3. 回帰直線を描く。
  4. 回帰直線を区間を延長して、未来の表示回数を予測する。

1. Google Search Console から取得したデータで、時系列グラフを引く。

%matplotlib inline
import pandas as pd
import searchconsole

# Google Search Console のデータを pandas dataframe として取得
account = searchconsole.authenticate(service_account='./client_secrets.json')
web_property = account['https://www.monotalk.xyz/']
report = web_property.query.range('today', days=-90).dimension('date').limit(50000).get()
df = report.to_dataframe()

# 日付と、impressions を取り出す。
df = df.loc[:,['date','impressions']]
# date を 日付型に変換
df['date'] = pd.to_datetime(df['date'])
# 日付をindexにする
df = df.set_index('date')
# julian_date 形式に変換(これは後続処理で数値に変換するために実施)
df.index= df.index.to_julian_date()
# 描画
df.plot()

<matplotlib.axes._subplots.AxesSubplot at 0x111b75208>

時系列グラフ

90日分の表示回数の、時系列グラフが描画できました。
GWは、表示回数が大きく下がっていることがわかります。

2. LinearRegression で、Model を作成する。

日付を説明変数、表示回数を目的変数として、単回帰分析を実施します。
決定係数があまり高くなくて、説明変数が目的変数をあまり説明していなさそうですが、気にせず進めます。

from sklearn import linear_model
clf = linear_model.LinearRegression()

# 説明変数
X = df.index - 2458177
# 2次元配列に変換
X = np.reshape(X.values, (X.size, 1))

# 目的変数
Y =  df['impressions']
# 2次元配列に変換
Y = np.reshape(Y.values, (Y.size, 1))

# 予測モデルを作成
clf.fit(X, Y)

# 回帰係数
print(clf.coef_)
# 切片 (誤差)
print(clf.intercept_)
# 決定係数
print(clf.score(X, Y))

[[ 37.68256666]]
[ 5232.76640044]
0.151442359086

3.回帰直線を描く。

bokeh を使って、元の時系列グラフのデータを散布図で表示、それとともに、回帰直線を引きます。

# matplotlib パッケージを読み込み
from bokeh.plotting import figure
from bokeh.io import output_notebook
from bokeh.io import show
output_notebook()

# figureで新規プロットを作成
p = figure(plot_width=400, plot_height=400)
# 回帰直線を表示
p.line(np.asarray(X).reshape(-1),
         np.asarray(clf.predict(X)).reshape(-1),
         line_width=2)
# 散布図を表示
p.circle(df.index - 2458177,  
         df['impressions'],  
         line_color="navy",# 線の色
         fill_color="blue",# 円の色
         fill_alpha=0.5)   # 透明度

show(p)  # 結果を出力

散布図と<wbr>回帰直線

4.回帰直線を区間を延長して、未来の表示回数を予測する。

# matplotlib パッケージを読み込み
from bokeh.plotting import figure
from bokeh.io import output_notebook
from bokeh.io import show
output_notebook()
# 説明変数
X = df.index - 2458177
# 延長する期間分配列を作成
X_append = range(95, 200, 1)
# 元の配列に足す
X = np.append(X.values, X_append)
X = np.reshape(X, (X.size, 1))
# figureで新規プロットを作成
p = figure(plot_width=400, plot_height=400)
# 回帰直線を引く
p.line(np.asarray(X).reshape(-1),
         np.asarray(clf.predict(X)).reshape(-1),
         line_width=2)
# 散布図を引く
p.circle(df.index - 2458177,  
         df['impressions'],  
         line_color="navy",# 線の色
         fill_color="blue",# 円の色
         fill_alpha=0.5)   # 透明度

show(p)  # 結果を出力

散布図と<wbr>回帰直線 予測

Google Search Console から取得した表示回数の時系列データを元に、単回帰分析を実行し、未来の表示回数を予測しました。
75-80日後くらいには、表示回数が12000回を超えそうな結果がでました。
現状のブログ更新頻度から落ちなければということかと思います。
Webで検索する限りは、時系列データ分析は単回帰分析よりも、statmodel を使って時系列分析したほうが良い予測ができそうに思いました。
統計検定の学習が一段落したら、statmodel での分析も実施してみようかと思います。
以上です。

コメント