Categories
GoogleAnalytics

Google Website Optimizer用 行動ターゲティングスクリプト作りました2

行動ターゲティングJSの仕様

説明はココココ

■仕込み
リダイレクトを出し分けする対象のページにスプリット用のJSを仕込みます。
ページ内の行動でターゲティングする場合は、対象のページ全てに、
ターゲティング用のJSを仕込みます。
それぞれ色々設定は必要です。

■セグメント軸
<出し分け対象ページ内>
・リファラー
・検索キーワード
<ターゲティングページ>
・総滞在時間
・特定ページ(グループ)のPV数
・再訪問間隔

訪問回数はまだつけていません。
ちょっとめんどくさい上に、定義がGAとどうしても変わってしまいます。
JSなので、ジオターゲティングはできません。
検索キーワードによる出し分けは一応実装しています。
ほぼ全ての検索エンジンに対応していると思います。
エンコード周りはecl.jsというライブラリを使っちゃいました。
ライセンスがどこにも書いていなかったので、商用で使ってよいのかどうかは微妙です。

■セグメント化のロジックについて
これだけたくさん変数があると、いくらでも組み合わせができてしまい、
ロジックが複雑になります。
なので、あえてロジックを簡単に設定できるような機能を実装していません。
都度都度、JSを手書きするイメージです。

■動くけど。。。
素人が作ったものなので、これはプロトタイプというイメージです。
実際に使う前には、専門家の人に確認してもらった方が良いと思います。
作っておいて、あれですけど、そこまでしてターゲティングにこだわる必要ないかもってちょっと思ってきました。
あと、リダイレクト先にパラメータ付けて、パラメータ読み込むライブラリを使えば、GAでトラッキングすることができるので、セグメント別のCVRとか出すことができます。

Categories
GoogleAnalytics

Google Website Optimizer用 行動ターゲティングスクリプト作りました1

と、いうことでGWOと組み合わせて使えるような行動ターゲティングのJSを書きました。
GWO専用ではなく、独立したJSにしています。単体でも使えるし、他のツールと組み合わせても使えると思います。

かなり設定が必要ですが、ベースのソースコードだけココに置いておきます。

behavior_t.zip

■GWO専用にしなかった理由
前の投稿にも書いたとおり、GWOはASPではなく、JSファイルでのみスプリットテストを行うので、A/BテストでもMVTでも全データをHTMLファイル上に記載する必要があります。
・GWOのタグを出し分ける
という発想もできたのですが、かなり複雑になります。
アクティブコアのようなASPサービスでは、scriptタグを2~3行入れれば良いだけなので、作りやすいんですけど、GWOの場合はあまりにも、設定が複雑になりすぎてしまいます。
それと、テストを実行する前に、Google様にバリデーションをしてもらう必要があります。
タグを出し分ける場合だとデフォルトではHTML上に記載していない状態なので、Google様に怒られてしまいます。なので、一回Google様のご指示通り記載してからバリデーション通ってから、変更するという形になり、かなり面倒です。

■ GWOを動かす前にリダイレクト
なので、ユーザー誘導用のページを作って、セグメント別にリダイレクト先を変えるという方法を採っています。
セグメント1のユーザーがページに訪れると、セグメント1用のページへとリダイレクトさせ、リダイレクト先でGWOを実施してくれという考えです。
つまり、セグメント分の「ページ」とセグメント分の「テスト」が必要になります。
GWOでA/Bテストをしてしまうと、人によっては2回リダイレクトすることになるので、あんまりよろしくないかもしれないです。するならMVTの方が良いと思います。

仕様については、次の投稿

Categories
GoogleAnalytics

Google Website Optimizerの概要

行動ターゲティング用のJSを作成したのですが、
その前にGWOにテスト方法ついて、ごく簡単に説明したいと思います。

■2つのテスト方法
GWOには
・A/Bテスト
・多変量テスト(MVT)
という2種類のテスト方法があります。
普通のA/Bテスト、MVTと同じと言えば同じなんですけど
定義が少し変です。
Googleの公式サイトによると

A/B テストと多変量テストの 2 種類を提供します。 A/B テストは、2 つのまったく異なるページのコンバージョン率を比較するテストです。レイアウトを変更したり、ページ内のセクションの位置を変更したり、ページの全体的なデザインを変更して、テストを実施できます。 これらのテストは比較的単純で、短期間で結果が得られます。 これに対して、多変量テストはより柔軟性が高く強力なテストです。 多変量テストでは、ページ内の複数のセクションのコンテンツ パターンを同時にテストできます。 たとえば、2 つの異なる見出し、3 つの異なる画像、2 つの異なる製品説明をテストできます。

つまり、A/BテストとMVTというよりも、
・全体テスト
・部分テスト
と言った方が良さそうな感じです。
ちなみに、A/Bテストでも3パターン以上テストすることができます。

■GWOの動作イメージ
ということで、A/BテストとMVTでGWOの動作は異なります。
・A/Bテスト
オリジナルページのHTMLとバリエーションページのHTMLを用意します。
ユーザーが対象のページ(オリジナルページ)を開こうとしたときに、
– オリジナルページを表示
– バリエーションページへリダイレクト
のいずれかが起こります。
表示割合はどのページもほぼイコールになります。
例)2パターン:オリジナル50%、バリエーション50%、
3パターン:オリジナル33.3%、バリエーション33.3%ずつ

・MVT
MVTではA/Bテストと異なり、用意するページは「1ページのみ」です。
ページ内に全てのパターンを記載します。
ユーザーが対象ページを開くと、ページ内に記載したパターンのうち、
どれか一つが表示されます。
もちろん、表示される割合は均等です。

当然、タグチメソッド的な方法は用意されていません。
直行表作って頑張って手動でタグチメソッドをすることはできます。
分析は結構めんどくさいです。
(一般線形モデルが必要)

Categories
GoogleAnalytics

GoogleAnalyticsプラグイン JSファイル

jsフォルダ内に2つのjsファイルを置いて、
HTMLのGAコードスニペットを書くところに↓と書いてください。

あ、うまく動かなかったら、ごめんなさい。

<script type="”text/javascript”">// <![CDATA[
var gaJsHost = ((“https:== document.location.protocol) ? “https://ssl.” : “http://www.”);
document.write(unescape(%3Cscript src=’” + gaJsHost + “google-analytics.com/ga.js’ type=’text/javascript’%3E%3C/script%3E”));
// ]]></script>
<script src="”/js/gaPlugin.js”" type="”text/javascript”"></script> <script src="”/js/gaConf.js”" type="”text/javascript”"></script>

プラグインファイル

//GA用のプラグイン
//gaGroup : コンテンツグループ設定コンフィグ
//getGroup : コンテンツグループをカスタム変数へ
//getQueryParam : パラメータをカスタム変数へ
//gaEvent : 外部リンク、DLリンクをカスタムリンクへ
//gaConv : コンバージョンのアリのユーザーをカスタム変数へ

//コンテンツグループ設定
var gaGroup = {
//グループ設定。上から順に評価される。
//正規表現でコンテンツグループを設定する

//1つ目
groupA : {
groupA : /.+sampling.+/,
groupB : /ga_test.html$/,
topPage : /^/$|^/index.html$/
},
confA : {
//スロットの設定
slot : 1,
//カテゴリ名の設定
category : "group",
//スコープはレベル3:ページレベル
scope : 3
},

//2つ目
groupB : {
test : /ga_test.html$/,
sample : /.+sampling.+/,
TopPage : /^/$|^/index.html$/
},
confB : {
//スロットの設定
slot : 2,
//カテゴリ名の設定
category : "bigGroup",
//スコープはレベル3:ページレベル
scope : 3
}

//end of gaGroup
}

//コンテンツグループを正規表現で設定して
//マルチカスタム変数へ入れる
//使用時はpageTrackerの前でnewして、set();
//_setCustomVar(index, name, value, opt_scope)
var getGroup = function(group, conf){
//コンストラクタ
this.group = group;
this.conf = conf;
}
getGroup.prototype = {
//パス名からグループを判断
get : function(){
var path = location.pathname;
var cVal = "";
for(var i in this.group){
if(path.match(this.group[i])){
cVal = i;
break;
}
}
//当てはまるものが無かった場合はotherを追加
if(cVal==""){
cVal = "others";
}
return cVal;
},

//カスタム変数にいれる
makeCVar : function(cVal){
pageTracker._setCustomVar(
this.conf.slot,
this.conf.category,
cVal,
this.conf.scope
);
},

//通常のPV取得用
set : function(){
var cVal = this.get();
this.makeCVar(cVal);
}
}

//end of getGroup

//getQueryParam
//GETクエリを見てパラメータに入れる
//コンストラクタ
var getQueryParam = function(slot, category, param, scope){
this.param = param;
this.slot = slot;
this.category = category;
this.scope = scope;
}

getQueryParam.prototype = {
//nameのクエリを返す
getQuery : function(name){
if(location.search){
var query = location.search;
query = query.substring(1,query.length);
var qArray = [];
qArray = query.split("&amp;");
for(var i=0;i
var param = qArray[i].split("=");
if(param[0] == name){
return param[1];
}
}
}
},

//カスタム変数にいれる
set : function(){
var arr = [];
var param = this.getQuery(this.param);
arr = [this.slot, this.category, param, this.scope]
pageTracker._setCustomVar(
arr[0],
arr[1],
arr[2],
arr[3]
);
}
}
//end of getQueryParam

//gaEvent
//aタグクリック時にトラックイベントへ入れる
//onloadイベント中にgaEvent.adding()でスタート
var gaEvent = {
//設定
conf : {
domain : "tanakanakana.happy888.net",       //domain名
down : {        //ダウンロード対象ファイル
pdf: /.pdf$/,
zip: /.zip$/
},
//カスタム変数を使っている場合はスロット番号を記載
customSlot : [1,2]
},

//wait関数
loopWait : function(timeWait) {
var timeStart = new Date().getTime();
var timeNow = new Date().getTime();
while( timeNow &lt; (timeStart + timeWait ) )
{
timeNow = new Date().getTime();
}
return;
},

//カスタム変数を消去
delCvar : function(){
for(var i = 0; i &lt; gaEvent.conf.customSlot.length ; i++){
pageTracker._deleteCustomVar(gaEvent.conf.customSlot[i]);
}
},

//クロスブラウザ対応のaddListenr
addListener : function(el, type, func) {
if(! el) { return false; }
if(el.addEventListener) {
el.addEventListener(type, func, false);
} else if(el.attachEvent) {
el.attachEvent('on'+type, func);
} else {
return false;
}
return true;
},

//_trackEvent(category, action, optional_label, optional_value)
tracking: function(category, action, optional_label){
pageTracker._trackEvent(category, action, optional_label);
},

//イベントバインド
bindFunc : function (bind, func){
return function(){
func.apply(bind, arguments);
//return false;
};
},

//aタグにイベント追加
adding : function(){
//aタグを取得
var atag = document.getElementsByTagName('a');
//それぞれにイベントリスナーを付ける
for(var i=0; i &lt; atag.length; i++){
var ref = atag[i].href;
//サイト外へのリンクの時
if(ref.indexOf(gaEvent.conf.domain) == -1){
gaEvent.addListener(atag[i], "click", gaEvent.bindFunc(atag[i], gaEvent.getOffsite));

//サイト内へのリンクの時
}else{
gaEvent.addListener(atag[i], "click", gaEvent.bindFunc(atag[i], gaEvent. getOnsite));
}

}

},

//サイト内リンク場合
getOnsite : function(){
var path = this.pathname;
path = gaEvent.delSla(path);
var cVar = [];
for (var j in gaEvent.conf.down){
if(path.match(gaEvent.conf.down[j])){
cVar = [j, "download",  path];
}
}
gaEvent.delCvar();
gaEvent.tracking(cVar[0], cVar[1], cVar[2]);
gaEvent.loopWait(100);
},

//オフサイトリンクの場合
getOffsite : function(){
var path = this.hostname + this.pathname;
path = gaEvent.delSla(path);
//変数名を設定 : _trackEvent(category, action, optional_label, optional_value)
var cVar = ["offsite", "offsite",  "offsite:" + path,];
gaEvent.delCvar();
gaEvent.tracking(cVar[0], cVar[1], cVar[2]);
gaEvent.loopWait(100);
},

//最初と最後に/があったら、削除
delSla : function(str){
if (str == "/"){
return "/";
}else{
str = str.replace(/^//, "");
str = str.replace(//$/, "");
return str;
}
}

//end of gaEvent
}

//gaConv
//カスタム変数に
//コンバージョンしたユーザーをTrue
//してないユーザーをFalse で設定
//_setCustomVar(index, name, value, opt_scope)
//slot,nameは任意で設定
//scopeは基本1(visitor)
var gaConv = function(slot, name, scope){
//コンバージョンのパス名を設定
this.path = ["/sampling/sample.html", "/sampling/conf.html"];
this.slot = slot;
this.name = name;
this.value = "";
this.scope = scope;
}

gaConv.prototype = {
set : function(){
for(var i = 0; i &lt; this.path.length; i++){
if(location.pathname==this.path[i]){
this.value = "true";
var val = [this.slot, this.name, this.value, this.scope];
pageTracker._setCustomVar(
val[0],
val[1],
val[2],
val[3]
);
}
}
}
}
//end of gaConv

設定用ファイル

try {
var pageTracker = _gat._getTracker("UA-XXXXX-X");

//set contents groupA
var groupA = new getGroup(gaGroup.groupA, gaGroup.confA);
groupA.set();
//set contents groupB
var groupB = new getGroup(gaGroup.groupB, gaGroup.confB);
groupB.set();
//set getQueryParam
var gq = new getQueryParam(3, "cid", "cid", 2);
gq.set();

//set get conversion
var gaC = new gaConv(4, "conv", 1);
gaC.set();

pageTracker._trackPageview();
} catch(err) {}

//get offsite, download link
window.onload = function(){
gaEvent.adding();
}
Categories
GoogleAnalytics

GoogleAnalyticsプラグイン作りました

GAはよく出来ていますけど、機能的に不満な点も多々あります。
ただし、こないだローンチしたマルチカスタム変数によって、
JavaScriptを書けば、かなりのことまで出来るようになりました。

ということで、js書いちゃいました。
使用頻度が高いだろうと考えられる機能を
できるだけ汎用的に書いています。

マルチカスタム変数が5個まで(+カスタムリンク)しか
使えないのですが、クロス集計の自由度が非常に高いので、
5個だけでも十分に使えます。
(おすすめしませんが、ちょっとした技を使えば5個以上もいけます)

現時点で下記の機能が使えます。

1.コンテンツグループの設定
正規表現でコンテンツグループを設定できるプラグインです。
違う変数に違う方法でのグルーピングも出来るようにしています。
(複数の単位のグループ分けができる)

2.外部リンク・DLリンクの取得
機能をONにするだけで、自動的にリンク(aタグ)を監視して、
全ての外部リンク、設定したDLリンク(pdf、zipなど設定可)が
押されると、カスタムリンクに変数を格納します。
onclickイベントにjsを書かなくても、クリックイベントを取得できます。

3.GETパラメータを取得
GAにもキャンペーン分析の機能があるので、必要ないと言えば、
ないんですけど、設定面倒なので、GETパラメータを取れるような
機能を付けました。
パラメータでクロス集計したい時にどうぞ。

4.コンバージョンした人を識別
コンバージョンページへ到達したユーザーを識別します。
これで、CVユーザーの特徴や、CVしていないユーザーとの違いが
集計できるようになります。
セッションレベルでの識別と、半永続的な識別の両方共設定可能です。

もうちょっと機能を拡大していくつもりですが、
これだけあれば、一般的なコーポレイトサイトでは、
SCいらないんじゃないくらいな感じになると思います。
パス系の機能弱いですけど。

この機能欲しいって言うのがあれば、ぜひお寄せください。
僕の気まぐれで実装するかもしれないです。

ファイルは次の投稿で。