Мультивариантне (Multivariate) тестування на веб-сайтах
Мультивариантне тестування (MVT) дозволяє одночасно перевірити кілька змін на сторінці та визначити найефективнішу комбінацію. На відміну від A/B-тестування, MVT виявляє взаємодію між елементами.
A/B vs Мультивариантне
| Критерій | A/B-тест | MVT |
|---|---|---|
| Кількість змін | 1 (2 варіанти) | 2+ елементи × N варіантів |
| Обсяг трафіку | Менший | Значно більший |
| Швидкість | Швидше | Повільніше |
| Взаємодія елементів | Не виявляє | Виявляє |
| Мета | Один переможець | Найкраща комбінація |
Використовуйте MVT, коли: зміни взаємозалежні, трафіку достатньо, і вам потрібно розуміти взаємодію між заголовком + CTA + зображенням.
Планування експерименту MVT
Приклад: тестування на сторінці товару
- Заголовок: 2 варіанти (A, B)
- Зображення: 3 варіанти (A, B, C)
- CTA-кнопка: 2 варіанти (A, B)
Усього: 2 × 3 × 2 = 12 комбінацій. Кожна комбінація — це окремий варіант.
Розрахунок необхідного трафіку
def mvt_sample_size(n_combinations, baseline_cr, mde=0.05, alpha=0.05, power=0.8):
"""Кожна комбінація вимагає такого ж трафіку, як A/B-тест"""
from scipy import stats
import math
p1 = baseline_cr
p2 = baseline_cr * (1 + mde)
p_avg = (p1 + p2) / 2
z_a = stats.norm.ppf(1 - alpha / 2)
z_b = stats.norm.ppf(power)
n_per_combo = ((z_a * math.sqrt(2 * p_avg * (1-p_avg)) +
z_b * math.sqrt(p1*(1-p1) + p2*(1-p2))) / (p2-p1)) ** 2
total = n_per_combo * n_combinations
print(f"Per combination: {math.ceil(n_per_combo):,}")
print(f"Total needed: {math.ceil(total):,}")
print(f"At 1000 daily visitors: {math.ceil(total/1000)} days")
mvt_sample_size(n_combinations=12, baseline_cr=0.04, mde=0.15)
# Per combination: 4,519
# Total needed: 54,228
# At 1000 daily visitors: 55 days
Якщо трафіку недостатньо для повного MVT — використовуйте fractional factorial design (тестуйте підмножину комбінацій).
Реалізація через Optimizely
// Optimizely Snippet (додайте в <head>)
<script src="https://cdn.optimizely.com/js/PROJECT_ID.js"></script>
// Програмний підхід
const optimizely = window.optimizely || []
// Отримайте варіацію для конкретного експерименту
const variationKey = optimizely.get('state').getVariationMap()['mvt_homepage_elements']
// variationKey = "headline_B_image_C_cta_A"
// Реалізація без Optimizely
function getMVTVariant(userId, elements) {
const variants = {}
for (const [element, options] of Object.entries(elements)) {
const hash = cyrb53(`${userId}_${element}`)
variants[element] = options[hash % options.length]
}
return variants
}
const elements = {
headline: ['Купіть сьогодні', 'Знижка 20% для нових клієнтів'],
image: ['lifestyle', 'product-white', 'product-action'],
cta: ['Додати в кошик', 'Купити зараз'],
}
const variants = getMVTVariant(userId, elements)
// variants = { headline: 'Купіть сьогодні', image: 'product-action', cta: 'Купити зараз' }
// Застосуйте варіанти до DOM
applyVariants(variants)
// Зафіксуйте в аналітиці
gtag('event', 'mvt_assignment', {
experiment: 'product_page_mvt',
headline: variants.headline,
image: variants.image,
cta: variants.cta,
combination: Object.values(variants).join('_')
})
Аналіз результатів MVT
import pandas as pd
from scipy import stats
def analyze_mvt(data):
"""data: DataFrame з колонками combination, visitors, conversions"""
data['cvr'] = data['conversions'] / data['visitors']
data = data.sort_values('cvr', ascending=False)
# Знайти найкращу комбінацію
best = data.iloc[0]
control = data[data['combination'] == 'baseline'].iloc[0]
print(f"\nTop combinations:")
print(data.head(5).to_string())
# Статистична значущість найкращої vs контроль
from scipy.stats import proportions_ztest
_, p_value = proportions_ztest(
[best['conversions'], control['conversions']],
[best['visitors'], control['visitors']]
)
print(f"\nBest: {best['combination']} CVR={best['cvr']:.2%}")
print(f"Control: CVR={control['cvr']:.2%}")
print(f"P-value: {p_value:.4f}")
# Аналіз головних ефектів (main effects)
# Наскільки кожен елемент окремо впливає на конверсію
for element in ['headline', 'image', 'cta']:
effect = data.groupby(element)['cvr'].mean()
print(f"\nMain effect of {element}:")
print(effect.sort_values(ascending=False))
Дробовий факторний дизайн
Якщо ви не можете тестувати всі 12 комбінацій:
# Використовуйте Latin Square або метод Taguchi
# Тестуйте 4 комбінації замість 12, покриваючи взаємодії
combinations_to_test = [
{'headline': 'A', 'image': 'A', 'cta': 'A'}, # контроль
{'headline': 'A', 'image': 'B', 'cta': 'B'},
{'headline': 'B', 'image': 'A', 'cta': 'B'},
{'headline': 'B', 'image': 'B', 'cta': 'A'},
]
# Зменшує трафік в 3 рази, але втрачає деякі взаємодії
Час виконання
Планування та реалізація MVT з аналізом головних ефектів — 5–7 робочих днів.







