Ders 23 / 24
A/B ve Çok Değişkenli Test
Örneklem büyüklüğünün saptanmak istenen farkla ilişkisi, oran farkının güven aralığı, erken durdurmanın yanlış pozitif oranını şişirmesi ve çok değişkenli testte çoklu karşılaştırma düzeltmesi.
İçindekiler
Önceki ders ödünç alma akışının en zayıf adımını buldu: ödünç onayına geçiş, yüzde 55.2. Sıradaki iş bir değişiklik denemektir. Ama değişiklikten sonra ölçülen oranın farklı çıkması, değişikliğin işe yaradığı anlamına gelmez — huni oranları hiçbir şey değişmeden de haftadan haftaya oynar.
A/B testi (A/B test), kullanıcıları rastgele iki gruba ayırıp birine mevcut arayüzü, diğerine değiştirilmiş arayüzü göstererek farkı ölçen deneydir. Bu ders deneyin dört sorusunu ele alır: kaç kullanıcı gerekir, ölçülen fark ne zaman gerçektir, deney niçin erken durdurulmaz ve birkaç değişiklik aynı anda nasıl sınanır?
Dört Hesap
// deney.mjs — ornekleme buyuklugu, guven araligi, erken durdurma ve coklu karsilastirma function uretec(tohum) { let s = tohum >>> 0; return () => { s = (s * 1664525 + 1013904223) >>> 0; return s / 4294967296; }; } // Normal dagilim islevleri (Abramowitz-Stegun yaklasimi + ikili arama ile ters alma) function normalDagilim(x) { const t = 1 / (1 + 0.2316419 * Math.abs(x)); const d = 0.3989422804014327 * Math.exp(-x * x / 2); const p = d * t * (0.319381530 + t * (-0.356563782 + t * (1.781477937 + t * (-1.821255978 + t * 1.330274429)))); return x >= 0 ? 1 - p : p; } function z(p) { let alt = -10, ust = 10; for (let i = 0; i < 200; i++) { const orta = (alt + ust) / 2; if (normalDagilim(orta) < p) alt = orta; else ust = orta; } return (alt + ust) / 2; } // ---- 1) Ornekleme buyuklugu: iki oran arasindaki farki saptamak icin ---- // Huni dersinden: odunc onayi adiminin mevcut orani 0.552. const TEMEL = 0.552; function ornekBuyuklugu(p1, p2, alfa = 0.05, guc = 0.80) { const za = z(1 - alfa / 2), zb = z(guc); const ort = (p1 + p2) / 2; const pay = za * Math.sqrt(2 * ort * (1 - ort)) + zb * Math.sqrt(p1 * (1 - p1) + p2 * (1 - p2)); return Math.ceil((pay * pay) / ((p1 - p2) ** 2)); } console.log("saptanmak istenen fark hedef oran grup basina kullanici toplam"); for (const fark of [0.01, 0.02, 0.03, 0.05, 0.08]) { const n = ornekBuyuklugu(TEMEL, TEMEL + fark); console.log( `${((fark * 100).toFixed(0) + " puan").padStart(22)} ${((TEMEL + fark).toFixed(3)).padStart(11)}` + ` ${String(n).padStart(22)} ${String(2 * n).padStart(7)}` ); } console.log(`(temel oran ${TEMEL}, alfa 0.05 cift yonlu, guc 0.80)`); // ---- 2) Oran farkinin guven araligi ---- console.log("\nA grubu B grubu fark %95 guven araligi sonuc"); const DENEYLER = [ { na: 2000, ka: 1104, nb: 2000, kb: 1160 }, { na: 2000, ka: 1104, nb: 2000, kb: 1260 }, { na: 8000, ka: 4416, nb: 8000, kb: 4640 }, ]; for (const d of DENEYLER) { const pa = d.ka / d.na, pb = d.kb / d.nb, fark = pb - pa; const se = Math.sqrt(pa * (1 - pa) / d.na + pb * (1 - pb) / d.nb); const [alt, ust] = [fark - 1.96 * se, fark + 1.96 * se]; console.log( `${(d.ka + "/" + d.na).padEnd(14)} ${(d.kb + "/" + d.nb).padEnd(14)} ${((fark * 100).toFixed(2) + " p").padStart(8)}` + ` [${(alt * 100).toFixed(2)}, ${(ust * 100).toFixed(2)}] puan ${alt > 0 || ust < 0 ? "fark var" : "belirsiz"}` ); } // ---- 3) Erken durdurma: gercekte fark yokken kac kez "fark var" denir ---- const KOSU = 2000, GRUP = 8000, ARA = 500; function aaDenemesi(rnd, kontrolNoktalari) { let ka = 0, kb = 0, sinyal = false; for (let i = 1; i <= GRUP; i++) { if (rnd() < TEMEL) ka++; if (rnd() < TEMEL) kb++; if (kontrolNoktalari && i % ARA === 0 && i >= ARA * 2) { if (Math.abs(zDegeri(ka, i, kb, i)) > 1.96) { sinyal = true; break; } } } if (!kontrolNoktalari) sinyal = Math.abs(zDegeri(ka, GRUP, kb, GRUP)) > 1.96; return sinyal; } function zDegeri(ka, na, kb, nb) { const pa = ka / na, pb = kb / nb, ort = (ka + kb) / (na + nb); const se = Math.sqrt(ort * (1 - ort) * (1 / na + 1 / nb)); return se === 0 ? 0 : (pb - pa) / se; } console.log("\nA/A deneyi (iki grup da ayni arayuz, gercek fark sifir)"); for (const ara of [false, true]) { const rnd = uretec(20260909); let sinyalli = 0; for (let k = 0; k < KOSU; k++) if (aaDenemesi(rnd, ara)) sinyalli++; console.log( `${(ara ? `her ${ARA} kullanicida bakilirsa` : "yalniz sonda bakilirsa").padEnd(32)}` + ` yanlis "fark var": ${(sinyalli / KOSU * 100).toFixed(1)} % (${sinyalli}/${KOSU})` ); } // ---- 4) Coklu karsilastirma: cok degiskenli testte aile duzeyi hata ---- console.log("\nkarsilastirma duzeltmesiz aile hatasi Bonferroni alfa Sidak alfa"); for (const k of [1, 3, 7, 15]) { const aile = 1 - Math.pow(0.95, k); console.log( `${String(k).padStart(13)} ${((aile * 100).toFixed(1) + " %").padStart(23)}` + ` ${(0.05 / k).toFixed(4).padStart(16)} ${(1 - Math.pow(0.95, 1 / k)).toFixed(4).padStart(11)}` ); } // 2x2x2 cok degiskenli test: 8 birlesim, kontrole karsi 7 karsilastirma const K = 7, DUZELTILMIS = 0.05 / K; console.log(`\n2x2x2 cok degiskenli test: 8 birlesim, ${K} karsilastirma`); console.log(`duzeltmesiz aile hatasi ${((1 - Math.pow(0.95, K)) * 100).toFixed(1)} %, Bonferroni alfa ${DUZELTILMIS.toFixed(4)}`); console.log(`duzeltilmis alfa ile 2 puanlik farki saptamak icin grup basina ${ornekBuyuklugu(TEMEL, TEMEL + 0.02, DUZELTILMIS)} kullanici`); console.log(`8 birlesim icin toplam ${8 * ornekBuyuklugu(TEMEL, TEMEL + 0.02, DUZELTILMIS)} kullanici`); console.log(`duzeltmesiz ve tek karsilastirmali A/B testinde toplam ${2 * ornekBuyuklugu(TEMEL, TEMEL + 0.02)} kullanici`);
saptanmak istenen fark hedef oran grup basina kullanici toplam
1 puan 0.562 38734 77468
2 puan 0.572 9660 19320
3 puan 0.582 4282 8564
5 puan 0.602 1532 3064
8 puan 0.632 592 1184
(temel oran 0.552, alfa 0.05 cift yonlu, guc 0.80)
A grubu B grubu fark %95 guven araligi sonuc
1104/2000 1160/2000 2.80 p [-0.27, 5.87] puan belirsiz
1104/2000 1260/2000 7.80 p [4.76, 10.84] puan fark var
4416/8000 4640/8000 2.80 p [1.26, 4.34] puan fark var
A/A deneyi (iki grup da ayni arayuz, gercek fark sifir)
yalniz sonda bakilirsa yanlis "fark var": 5.7 % (114/2000)
her 500 kullanicida bakilirsa yanlis "fark var": 20.4 % (408/2000)
karsilastirma duzeltmesiz aile hatasi Bonferroni alfa Sidak alfa
1 5.0 % 0.0500 0.0500
3 14.3 % 0.0167 0.0170
7 30.2 % 0.0071 0.0073
15 53.7 % 0.0033 0.0034
2x2x2 cok degiskenli test: 8 birlesim, 7 karsilastirma
duzeltmesiz aile hatasi 30.2 %, Bonferroni alfa 0.0071
duzeltilmis alfa ile 2 puanlik farki saptamak icin grup basina 15351 kullanici
8 birlesim icin toplam 122808 kullanici
duzeltmesiz ve tek karsilastirmali A/B testinde toplam 19320 kullanici
Örneklem Büyüklüğü Deneyden Önce Hesaplanır
İlk tablo, deneyin en çok atlanan adımını veriyor: kaç kullanıcı gerektiği, kullanıcılar gelmeden önce hesaplanır.
Hesap dört girdi ister. Temel oran (0.552, huni dersinden), saptanmak istenen en küçük fark, yanlış pozitif oranı (0.05) ve güç (0.80 — gerçek bir fark varsa onu yakalama olasılığı).
Tablonun taşıdığı asıl bilgi ölçek ilişkisidir: gereken örneklem, saptanmak istenen farkın karesiyle ters orantılıdır. Sekiz puanlık bir farkı yakalamak grup başına 592 kullanıcı ister; bir puanlık farkı yakalamak 38734. Farkı sekizde birine indirmek örneklemi altmış beş katına çıkarıyor.
Bunun pratik karşılığı, deneyin küçük iyileştirmeler için pahalı olmasıdır. Katalog arayüzü haftada beş bin ödünç onayı görüyorsa, iki puanlık bir farkı ölçmek yaklaşık dört hafta sürer; bir puanlık farkı ölçmek on beş hafta. Deneyin süresi, denenmek istenen değişikliğin büyüklüğüne bağlıdır ve bu süre çıkmıyorsa deney yapılmaz — değişiklik başka bir gerekçeyle savunulur ya da savunulmaz.
Aynı Fark, İki Farklı Sonuç
İkinci tablo, “fark var mı” sorusunun neye bağlı olduğunu gösteriyor. Birinci ve üçüncü satırdaki ölçülen fark birebir aynı: 2.80 puan. Birinci satırda 2000’lik gruplarla güven aralığı [-0.27, 5.87] ve sıfırı içeriyor; sonuç belirsiz. Üçüncü satırda 8000’lik gruplarla aralık [1.26, 4.34] ve sıfırı içermiyor; fark var.
Aradaki tek fark örneklem büyüklüğü. “Yüzde 2.8’lik bir iyileşme ölçtük” cümlesi, örneklem yazılmadan hiçbir şey söylemez.
İkinci satır ise karşıt durumu veriyor: 7.80 puanlık büyük bir fark, 2000’lik gruplarla bile aralığın dışında kalıyor. Büyük etkiler küçük örneklemle saptanabilir; ilk tablodaki ilişkinin aynısı.
Güven aralığının genişliği ayrıca bir karar bilgisi taşır. Üçüncü satırda gerçek fark 1.26 ile 4.34 puan arasında; değişikliğin maliyeti yalnızca 4 puanlık bir kazançta karşılanıyorsa aralık bu kararı vermeye yetmez. “İstatistiksel olarak anlamlı” ile “kararı değiştirecek kadar büyük” aynı şey değildir.
Erken Durdurma Yanlış Pozitifi Şişirir
Üçüncü hesap bir A/A deneyi kuruyor: iki grup da aynı arayüzü görüyor, gerçek fark sıfır. Doğru çalışan bir sınama bu durumda kullanıcıların yüzde 5’inde yanlışlıkla “fark var” demelidir.
Yalnızca deneyin sonunda bakıldığında oran yüzde 5.7 çıkıyor — beklenen yüzde 5’e yakın; aradaki fark iki bin koşunun benzetim dalgalanmasıdır. Her 500 kullanıcıda bir bakılıp sınır aşıldığında durulduğunda oran yüzde 20.4’e çıkıyor. Hiçbir gerçek fark yokken, her beş deneyden biri “değişiklik işe yaradı” diyor.
Nedeni şudur: sınama her bakışta yüzde 5 yanılma payı taşır. On dört ayrı bakış, on dört ayrı yanılma fırsatıdır. Rastgele dalgalanan bir fark er ya da geç sınırı bir kez aşar ve o an durulduğunda aşan değer sonuç olarak kaydedilir.
Kural: deney, hesaplanan örneklem büyüklüğüne ulaşana kadar durdurulmaz ve arada karar verilmez. Deney sürerken sayılara bakmak yasak değildir; bakıp durmak yasaktır. Ara kararların gerekli olduğu durumlarda ara bakış sayısına göre sınırı sıkılaştıran ardışık sınama yöntemleri kullanılır; sıradan sınırla ara karar verilmez.
Çok Değişkenli Testin Bedeli
Dördüncü tablo aynı sorunun bir başka biçimini veriyor. Bir deneyde birden çok karşılaştırma yapıldığında, en az birinde yanılma olasılığı — aile düzeyi hata — karşılaştırma sayısıyla birlikte yükselir. Yedi karşılaştırmada yüzde 30.2, on beşte yüzde 53.7.
Çok değişkenli test (multivariate test), birden çok ögeyi aynı deneyde değiştirip birleşimlerini karşılaştırır. İki değerli üç öge birleşim, kontrole karşı yedi karşılaştırma üretir. Düzeltme yapılmazsa deneyin yüzde 30.2 olasılıkla en az bir yanlış “kazanan” bildireceği anlamına gelir.
Düzeltme, her karşılaştırmanın sınırını sıkılaştırır. Bonferroni düzeltmesi ’yı karşılaştırma sayısına böler (0.0071); Šidák düzeltmesi aile hatasını doğrudan 0.05’e sabitler (0.0073) ve biraz daha az sıkıdır.
Son blok bedeli veriyor. Düzeltilmiş sınırla iki puanlık farkı saptamak grup başına 15351 kullanıcı ister; sekiz birleşim için 122808 kullanıcı. Aynı farkı tek bir A/B testiyle ölçmek 19320 kullanıcı ister. Çok değişkenli test, altı kattan fazla trafik istiyor.
Bu, çok değişkenli testin ne zaman seçileceğini belirler. Ögeler arasında bir etkileşim bekleniyorsa — birinin etkisi diğerinin değerine bağlıysa — ayrı ayrı A/B testleri o etkileşimi hiç göremez ve çok değişkenli test gereklidir. Etkileşim beklenmiyorsa ayrı ayrı ve sırayla yapılan A/B testleri hem ucuzdur hem yorumlanması kolaydır.
Deneyin Kuralları
Hipotez ve örneklem deneyden önce yazılır. Hangi ölçütün, hangi yönde, en az ne kadar değişmesinin aranacağı önceden belirlenir. Sonradan seçilen ölçüt, dördüncü tablodaki çoklu karşılaştırma sorununun gizlenmiş biçimidir.
Örneklem hedefine ulaşılmadan karar verilmez. Üçüncü hesap bunun bedelini veriyor.
Fark güven aralığıyla raporlanır. Nokta kestirimi tek başına deneyin belirsizliğini gizler.
Kaç karşılaştırma yapıldığı yazılır. Kesimlere ayrılmış sonuçlar da karşılaştırmadır; “dar ekranda anlamlı çıktı” bulgusu, kesim sayısı kadar karşılaştırma yapıldığı anlamına gelir.
Deney meşruluk ölçütünü değiştirmez. Bir değişikliğin dönüşümü artırdığını göstermek, o değişikliğin Karanlık Kalıplar dersindeki denetimden geçtiğini göstermez. Deney “işe yarıyor mu” sorusunu yanıtlar; “yapılmalı mı” sorusunu yanıtlamaz.
Özet
- Gereken örneklem, saptanmak istenen farkın karesiyle ters orantılıdır: 8 puanlık fark için grup başına 592, 1 puanlık fark için 38734 kullanıcı.
- Aynı ölçülen fark (2.80 puan) 2000’lik gruplarda belirsiz, 8000’lik gruplarda anlamlı çıkar; fark örneklem yazılmadan raporlanamaz.
- Güven aralığının genişliği ayrı bir karar bilgisidir; anlamlı olmak, kararı değiştirecek kadar büyük olmak demek değildir.
- Erken durdurma yanlış pozitifi şişirir: gerçek fark sıfırken sonda bakan sınama yüzde 5.7, her 500 kullanıcıda bakan sınama yüzde 20.4 oranında “fark var” dedi.
- Çok değişkenli testte aile düzeyi hata karşılaştırma sayısıyla yükselir (7 karşılaştırmada yüzde 30.2); Bonferroni ya da Šidák düzeltmesi sınırı sıkılaştırır ve gereken trafiği bu örnekte altı kattan fazlaya çıkarır.
- Deney bir değişikliğin işe yarayıp yaramadığını gösterir; yapılıp yapılmayacağı ayrı bir ölçütle karara bağlanır.
Sonraki Adım
Bu ders bir farkın gerçek olup olmadığını söylemeyi öğretti; farkın niçin olduğunu söylemedi. Ödünç onayı ekranındaki değişiklik oranı 2.8 puan artırdıysa, kullanıcıların neyi farklı yaptığı sayıda görünmez. Kursun son dersi bu boşluğu kapatır: aynı huni adımındaki terk oranıyla o adımda yapılan görüşmelerin kodları yan yana konur, nicel bulgunun hangi nitel gözlemle eşleştiği hesaplanır ve iki kaynağın birbirini yalanladığı durumda ne yapılacağı ele alınır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.