LoginSignup
8
7

More than 5 years have passed since last update.

Javascriptで2x2のクロス表の独立性検定(ABテスト)

Last updated at Posted at 2015-09-11

A/Bテストの評価を簡単にブラウザ上でできるようにしたい。ということで実装してみた。
そういえばGoogleスプレッドシートでもカイ2乗検定はできないのね。
これを使えばスプレッドシートから値を持ってきて簡単に検定できるかも。

A/Bテストの技術的整理

A/Bテスト(2群の比率の差の検定)をするとき、比率を扱うので2項分布を使う方法もあるが、クロス表で扱うこともできる。

たとえば

creative imp click
A $x_0$ $x_1$
B $x_2$ $x_3$

において

クリエイティブAとBとでCTRが変わらない

すなわち

クリエイティブの違い(行)とクリックのしやすさ(列)は独立

かどうかを検定したい。一般に検定で用いられるクロス表は

グループ ○○する ○○しない
A
B

という形式になるので、
クリックのしやすさは「クリックする or クリックしない」だから

creative クリックする クリックしない imp(周辺度数)
A $x_0-x_1$ $x_1$ $x_0$
B $x_2-x_3$ $x_3$ $x_2$

というクロス表の独立性の検定をすることになる。

実装

/**
 * Returns p-value of x.
 * @param {Array} x [[nTrial1, nOccurrence1], [nTrial2, nOccurrence2]]
 * @returns {Number} p-value
 */
function getChisq(x){

    if(x !== undefined){

        // Observations
        var o = [
            x[0][0] - x[0][1],
            x[0][1],
            x[1][0] - x[1][1],
            x[1][1],
        ];

        var s = o[0]+o[1]+o[2]+o[3];

        // Expectations
        var e = [
            (o[0]+o[1]) * (o[0]+o[2]) / s,
            (o[0]+o[1]) * (o[1]+o[3]) / s,
            (o[2]+o[3]) * (o[0]+o[2]) / s,
            (o[2]+o[3]) * (o[1]+o[3]) / s,
        ];

        var chisq = 0;
        for (i=0; i<=3; i++){
            chisq += (o[i] - e[i]) * (o[i] - e[i]) / e[i];
        }

    return chisq;

    }
}

// Cumulative distribution function of Normal distribution
// See http://qiita.com/gigamori/items/e17e6f9faffb78822c56
function cdf(x) {

    // constants
    var p  =  0.2316419;
    var b1 =  0.31938153;
    var b2 = -0.356563782;
    var b3 =  1.781477937;
    var b4 = -1.821255978;
    var b5 =  1.330274429;

    var t = 1 / (1 + p * Math.abs(x));
    var Z = Math.exp(-x * x / 2) / Math.sqrt(2 * Math.PI);
    var y = 1 - Z * ((((b5 * t + b4) * t + b3) * t + b2) * t + b1) * t;

    return (x > 0) ? y : 1 - y;
}

// Example
cdf(Math.sqrt(getChisq([[10000,100],[5000,45]])));

cdf()は正規分布の累積分布関数。自由度1のカイ2乗分布は平方根が片側標準正規分布になるのでcdf(Math.sqrt(...)としている。
http://qiita.com/gigamori/items/e17e6f9faffb78822c56

GoogleスプレッドシートでABテスト

2x2のセルを指定して実行すればOK!

var values = SpreadsheetApp.getActiveSheet().getRange('A1:B2').getValues();
var p = cdf(Math.sqrt(getChisq(values)));
Logger.log(p);
8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7