case-kの備忘録

日々の備忘録です。最近はGCPやデータ分析系のことを呟きます

広告施策効果のt検定をPythonでしてみた

今回は対応のあるt検定について記事を書きたいと思います。対応のあるt検定は因果など調べる際に便利な統計手法です。

広告施策の効果検証を施策前後のアクセス数の変化から判断したいケースがあると思います。
実施してみてWEBサイトのアクセス数が増えているようです。これは偶然ではなく広告施策効果の影響なのか調べたいことがあると思います。
今回は施策前後の効果を検証するための仮説検定手法「対応のあるt検定」で広告施策の効果を検証してみたいと思います。

本記事の目的

本記事は以下を目的としています。
・対応のあるt検定の理解
・因果関係の検定方法を学ぶ
・検定の一連の流れをPythonで動かし理解を深める

対応のあるt検定とは

平均値の差の検定です。2群のデータに対するt検定を行います。
2つの変数の間で平均値に差があるかどうか判断します。
例えば、薬と飲む前と飲んだ後で体温に差がでるか検定したい際に使います。


仮説を立てる

今回広告施策によってWEBサイトのアクセス数が異なることを検定します
帰無仮説:広告施策前後でサイトのアクセス数は変わらない
対立仮説:広告施策前後でサイトのアクセス数が異なる。
有意水準は5%とします。p値が0.05を下回れば、帰無仮説は棄却され
広告施策を行うことで有意な変化が認められると主張することができます。

サンプルデータの準備と可視化

※ jupyter notebookを活用を前提とします。

# ライブラリのimport
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
%matplotlib inline
from scipy import stats

# サンプルデータの作成
columns = np.array(['site','access count before','access count after'])
values = np.array([['A',100,120],
                 ['B',1000,1100],
                 ['C',10,110],
                 ['D',50,59],
                 ['E',60,600],
                 ['F',60,100]])
data = pd.DataFrame(columns=columns,data=values)
print(data)

# out put
  site access count before access count after
0    A                 100                120
1    B                1000               1100
2    C                  10                110
3    D                  50                 59
4    E                  60                600
5    F                  60                100

差分の算出

施策前後の差分」に注目します。
差分の列の平均値が0と異なれば「広告施策前と後でサイトアクセス数が異なる」と主張することが可能です。
対応のあるt検定では、このように差分を取ってから「差分値が0と有意に異なるか」という1群のt検定を行う。

# 差分を追加
diff_lsit = []
for i in range(len(data)):
    diff = float(data.loc[i]['access count after']) - float(data.loc[i]['access count before'])
    diff_lsit.append(diff)
data['diff'] = diff_lsit
data['diff'] = data['diff']
print(data)

# out put
  site access count before access count after   diff
0    A                 100                120   20.0
1    B                1000               1100  100.0
2    C                  10                110  100.0
3    D                  50                 59    9.0
4    E                  60                600  540.0
5    F                  60                100   40.0

標準偏差・標準誤差・自由度・t値算出

# サンプル数
n = len(data)
print("sample count:{}".format(n))
# 自由度
N = n - 1 
print("degree of freedom:{}".format(N))

# 平均
mean_score = data['diff'].mean()
print("diff mean score:{}".format(mean_score))

# 不偏分散
V = np.sum(np.square(data['diff'] - mean_score)) / (n - 1)
print("variance:{:.5f}".format(V))

# 不偏標準偏差
std =  np.sqrt(V)
print("standard division:{:.5f}".format(std))

# 標準誤差
se = std / N
print("standard error:{:.5f}".format(se))

# t値
t_value = (mean_score - 0)/se
print("t value:{}".format(t_value)) 

# out put 
sample count:6
degree of freedom:5
diff mean score:134.83333333333334
variance:40920.16667
standard division:202.28734
standard error:40.45747
t value:3.332718088172629
p value:0.020717136

t値からp値を求める

# p値
alpha = stats.t.cdf(t_value, df = N)
p = (1-alpha)*2
print("p value:{:.9f}".format(p))

# out put 
p value:0.020717136

帰無仮説の棄却を行う

p値が0.020717136なので帰無仮説を棄却します。
広告施策前後でサイトアクセス数は有意に異なると言えそうです。