我正在使用Javascript API的谷歌分析内容实验,似乎你有两个选择:
- 一次运行一个实验,并让谷歌分配变化,您可以使用
chooseVariation()
或 获得 - 一次运行多个实验,并使用
setChosenVariation()
自行分配变量
(1)允许Google控制分配给每个变体的用户数量,这是我需要的,但我有几个实验。这看起来很基本。我错过了什么?
我不认为你错过了什么。我的理解是,GA实验API允许您使用选择变化命令将访问者分配到单个a/B/N测试的任何版本:
cxApi.chooseVariation();
但是,只有当你在页面上加载api.js时指定了实验ID,这个函数才可用。
如果你想做的是同时在一个页面上运行几个A/B测试,这真的是多变量测试,不幸的是,这在GA内容实验中是不可用的"开箱即用"(它曾经与Google网站优化器一起可用)。你仍然可以使用你自己的桶来"伪造"它,代码如下:
<!-- 1. Load the Content Experiments JavaScript Client -->
<script src="//www.google-analytics.com/cx/api.js"></script>
<!-- 2. See if the visitor has seen an experiment already -->
<script>
// loop through all active experiments server-side.
cxApi.getChosenVariation(
$experimentId
);
<!-- 3. Bucket the visitor if he isn't bucketed already -->
// loop through your live experiments
cxApi.setChosenVariation(
$chosenVariation, // The index of the variation shown to the visitor
$experimentId // The id of the experiment the user has been exposed to
);
</script>
您需要决定是让访问者一次只查看一个实验还是同时进入多个实验。
第一个选项可能更可靠,但意味着你必须将访问者分成相当多的桶,这意味着你的测试将花费很长时间才能返回结果。
如果您使用第二个选项,您需要小心:如果您的实验不是独立的,您将无法信任来自Google Analytics的测试结果,因为内容实验中使用的统计测试具有独立性。即使你的实验是独立的,你也需要在所有的变异组合中有一个相等的分割。
我希望这对你有帮助!
当同时运行多个实验时,问题是如果您的站点上有来自一个实验的访问者与正在运行的另一个实验的元素交互,那么很难解释这些交互效果。这将扭曲你的数据并导致一些错误的结论。如果您对如何分析多个并发实验有绝对的信心,那么一次只运行一个实验是安全的。
我使用node.js脚本解决了这个问题。
开箱即用的谷歌内容实验让你选择:
- 加载cxApi补丁仅用于1次实验
- 加载cxApi plain,失去调用chooseVariation()函数的能力,让你实现自己的选择算法(这是一个遗憾,因为谷歌的多臂强盗思想真的很聪明)。
所以我做了一些逆向工程谷歌cxApi js是如何修补1个实验,事实证明,它只是捆绑实验信息(变化权重)在文件的中间,我实验触摸捆绑手动添加多个实验,现在我可以调用cxApi.chooseVariation(experimentId)
为每个实验,并很好地工作!
权重每12小时改变一次,所以我自动化了它,我创建了一个node.js小应用程序,它将从google下载cxApi,然后为您指定的每个实验重复下载它,并在其上修补一个包含所有实验的cxApi。
瞧!,在任意页面上进行多个实验。
这里是repo: https://github.com/benjamine/mutagen, fork at will
这个node.js应用程序将为多个实验修补cxApi,并且还将打包(并缩小)您的变量
这个解决方案对我来说非常有效。好处是:
- 不需要node.js
- 不需要更改站点-站点保持完全可缓存
- 使用Google Multi-Armed-Bandit方法,无补丁
- 轻松维护
Javascript模块提供执行多个Google实验的所有功能:
var runExperiment = (function(jQ) {
var apiUrl = '/ga-experiments-api.php?preview=true&experimentId=',
experimentId,
variations;
var chooseAndApplyNewVariation = function() {
if (typeof jQ !== 'undefined') {
jQ.ajax({
type: 'get',
url: apiUrl + experimentId,
success: function(data, status){
var choosenVariation = data.choosenVariation;
if (typeof choosenVariation !== 'undefined' && choosenVariation >= 0) {
cxApi.setChosenVariation(choosenVariation, experimentId);
applyVariation(choosenVariation);
}
}
});
}
};
var applyVariation = function(chosenVariation) {
var variationFunction = (typeof variations[chosenVariation] === 'function') ? variations[chosenVariation] : false;
if (variationFunction) {
variationFunction.apply();
sentGaEvent();
console.log(experimentId, chosenVariation);
}
};
var sentGaEvent = function() {
if (typeof ga !== 'undefined') {
ga('send', 'event', 'experiment', 'view');
}
};
return function(experiment) {
experimentId = experiment.id;
variations = experiment.variations;
if (typeof cxApi !== 'undefined') {
var chosenVariation = cxApi.getChosenVariation(experimentId);
if (chosenVariation >= 0) {
applyVariation(chosenVariation);
} else {
chooseAndApplyNewVariation();
}
}
};
})(jQuery);
用于运行单个实验的Javascript代码片段-可以在页面上多次集成:
(function(jQ) {
var experiment = {
'id': 'RHwa-te2T_WnsuZ_L_VQBw',
'variations': [
function() {},
function() {
jQ('#nav #menu-item-2000927 a').text('Shop + Abo');
}]
};
runExperiment(experiment);
}(jQuery));
PHP (API)通过Google的API生成新的变化,我使用这个类:
https://github.com/thomasbachem/php-gacx<?php
use UnitedPrototypeGoogleAnalytics;
require_once dirname(__FILE__) . '/libs/googleAnalytics/Experiment.php';
$experimentId = (!empty($_GET['experimentId'])) ? $_GET['experimentId'] : null;
$returnData = array(
'experimentId' => $experimentId,
);
try {
$experiment = new GoogleAnalyticsExperiment($experimentId);
$variation = $experiment->chooseNewVariation();
if (is_integer($variation)) {
$returnData['success'] = true;
$returnData['choosenVariation'] = $variation;
}
} catch (Exception $exception) {
$returnData['success'] = false;
$returnData['error'] = $exception;
}
header('Content-Type: application/json');
echo json_encode($returnData);