読者です 読者をやめる 読者になる 読者になる

Rを通じて統計学を学ぶ備忘録ブログ

SPSSからRに移行したい私のような人向けのR解説ブログ兼学習用備忘録。

大学の時にもっと勉強しておけばよかったマーケティング・リサーチ〜その9〜

マーケティング

大学の時にもっと勉強しておけばよかったマーケティング・リサーチの9話目です。今回は、コンジョイント分析です。

コンジョイント分析(Conjoint Analysis)

コンジョイント分析は、1980年頃にアメリカで導入され始めた分析手法で、ユーザーが好むであろう商品のコンセプトや特徴を探し出すための手法です。つまり、どれくらい好きなのか、どの程度購入したいのかを尋ねることによって、商品を構成している色、デザイン、特徴の効果を推定することで、最適な商品要素の組み合わせを探る手法です。従い、商品の好き嫌いや商品の購入意向を目的変数にし、説明変数は、各要因の効果を表すようなモデルになります。 商品の企画・開発者は、商品の価格、機能、デザインを市場のターゲットに合わせて組み合わせて商品を開発する必要があります。その際に、最も売れるであろう組み合わせが探ることによって新商品の売上を伸ばそうと試みるわけですね。

コンジョイント分析の仕組み

コンジョイント分析では、ユーザーが享受する効用を、「部分効用」と「全体効用」の2つに分解して考えます。つまり、「全体効用は部分効用の組み合わせにって構築されている」と考えて分析します。その中で、色や形状などの個別の要素を「属性」といい、色でも「赤」「青」「黄」というように属性が取りうる値を「水準」といいます。したがって、コンジョイント分析では、属性を組み合わせた仮想の商品を「属性プロファイルカード(コンジョイントカード)」にまとめ、回答者に順位付けしてもらうことになります。 たとえば、1属性3水準、1属性2水準ある商品の場合は以下のようなモデルになり、組み合わせ自体は18通りを表現します。yは順位、xは部分効用を表すダミー変数を含めたモデルです。 daum_equation_1484369708499 ここでは、属性Aは3水準、属性Cは2水準と仮定しているので、属性Aはx_1とx_2があれば3水準表現できます。 属性Aのa,b,cの3水準の場合・・・ daum_equation_1484369855125 このような感じで6個の組み合わせを表現することになります。最後の式については、属性のそれぞれで最も部分効用が低い水準の組み合わせ=全体効用を表していることがわかります。そして、順位変数のyについては6の組み合わせについて順位(z)を決定してもらうので、そのまま使用すると順位が高いものが数値としては低くなってしますので、変換をする必要があります。y=7-zとしておけばz=1の場合、y=7-z→y=6になりますし、z=6の場合、y=7-z→y=1となり数値をうまく逆転させることができます。

実験計画法

ここまではコンジョイント分析について見てきましたが、属性の水準が多くなると組み合わせ爆発が起こってしまいます。その爆発を防ぐために開発されたのが「直交表」です。例えば2つの水準をもつ属性が4つある場合、組み合わせ数は16になります。まだ16組ならば、実験してデータを集めれそうですが、3つの水準をもつ属性が8つある場合、どうでしょうか。6561組となり、回答者の順位付けにかかるストレスは半端ないものになってしまいますし、仮に回答してもらってもそれは信頼できるデータといえるでしょうか・・・。そこで、このような問題を避けるために利用するのが直交表です。 例えば、2つの属性間を独立しているのものと仮定するなら、各属性の水準の組み合わせを省略することができるため、組み合わせ数を減らすことができるのです。この手法を「直交計画」といいます。直交の由来は、列属性の効用が他属性の効用には影響されず、独立している状態で相関係数が0であることを意味するため、直交計画と言われます。以下は直交表の例で、左はL18型と呼ばれるもので、水準が2つある要因が1つ、水準が3つある要因が7つの場合直交表です。本来であれば4374組の実験が必要ですが、直交表を用いれば18組で済みます。 %e7%9b%b4%e4%ba%a4%e8%a1%a8 理由は、No9までの行を見るとC1の列では「1」だけが割付られ、他の列(2-8)を見ると、すべての水準が3回づつ均等に含まれています。No10からは、No10からの行を見るとC1の列では「2」だけが割付られ、同様に、他の列(2-8)を見ると、すべての水準が3回づつ均等に含まれています。このように割り付けを行うことによって、他の影響は完全に平均化されているので、公平に比較できる、というカラクリがあります。 がしかし、直交表は万能ではないく、画像右側のL8型は目的に沿って割り付けパターンを決定する必要があり、L18型は決まった割り付けパターンがない代わりに、交互作用が検討できないなどの問題もあります。従い、直交表は属性数、水準数が少ない場合に非常に有効な手法ですが、多い場合には結局実験数は多くなってしまいます。

コンジョイント分析の実践

スマートフォンの開発を例にコンジョイント分析を行っていきます。もちろん、仮想データなので、結果に意味はありません。新しいスマートフォンは、インカメラをつけるどうかの2水準、バッテリは満タンで2時間、4時間、6時間の3水準、色はグレー、シルバー、ブラックの3水準で検討しようとしています。直交表を用いて9つ組み合わせに減らし、回答者は20人に順位づけをしてもらいました。切片含め6つの偏回帰係数、つまり部分効用を求めることになります。

> Dataset <- read.csv("CJ002.csv")
> head(Dataset, 10);head(Dataset, 10)

   ID ConjointCard Incamera X6time X4time black silver Rank
1   1            1        1      1      0     1      0    9
2   1            2        1      0      1     0      1    7
3   1            3        1      0      0     0      0    3
4   1            4        0      1      0     0      1    5
5   1            5        0      0      1     0      0    2
6   1            6        0      0      0     1      0    4
7   1            7        1      1      0     0      0    1
8   1            8        1      0      1     1      0    8
9   1            9        1      0      0     0      1    6
10  2            1        1      1      0     1      0    9
   ID ConjointCard Incamera X6time X4time black silver Rank
1   1            1        1      1      0     1      0    9
2   1            2        1      0      1     0      1    7
3   1            3        1      0      0     0      0    3
4   1            4        0      1      0     0      1    5
5   1            5        0      0      1     0      0    2
6   1            6        0      0      0     1      0    4
7   1            7        1      1      0     0      0    1
8   1            8        1      0      1     1      0    8
9   1            9        1      0      0     0      1    6
10  2            1        1      1      0     1      0    9

> ConjointAnalysis <- lm(Rank ~ Incamera + X6time + X4time + black + silver, data = Dataset)
> summary(ConjointAnalysis)

Call:
lm(formula = Rank ~ Incamera + X6time + X4time + black + silver, 
    data = Dataset)

Residuals:
    Min      1Q  Median      3Q     Max 
-5.1417 -0.6000 -0.1417  0.5917  3.0417 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   0.1333     0.2380   0.560   0.5760    
Incamera      2.2750     0.1908  11.924  < 2e-16 ***
X6time        0.5500     0.2203   2.497   0.0135 *  
X4time        1.3000     0.2203   5.901 1.84e-08 ***
black         4.4667     0.2203  20.275  < 2e-16 ***
silver        3.7333     0.2203  16.946  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.207 on 174 degrees of freedom
Multiple R-squared:  0.7889,    Adjusted R-squared:  0.7828 
F-statistic:   130 on 5 and 174 DF,  p-value: < 2.2e-16

結果を見てみると、調整済みR2は「78%」なので順位付けの78%は3つの変数で説明されていることがわかります。また、「インカメラ付き」「バッテリは4時間」「色はブラック」の組み合わせが一番評価が高くなる組み合わせのようです。

コンジョイント分析でwebマーケティング

コンジョイント分析は組み合わせの最適化を探るための手法でもあるため、webマーケティングでは、ランディングページのABテストを実施するために用いられることもあります。 ABテストとは、分野によって内容は異なりますが、複数の何かを比較していいものを決めるという点では同じです。ここでは、複数のランディングページのCVRの良し悪しをもとに、最もCVRが高いランディングページを決定するためのABテストになります。基本的には、単純にCVRを比較するのではなく、カイ二乗検定を行ったり、多変量解析を行って各要素の影響力を分析したりします。

カイ二乗検定

なぜカイ二乗検定を行う必要があるのでしょうか。それは「誤差」というものがあるためです。その誤差が発生するため、誤差というものを持っても差があるのか、それとも偶然の差なのかを判断する必要があるので検定が必要なのです。以下のCVRを同じにしてシュミレーションしてみましょう。

> A.CVR <- 0.01
> B.CVR <- 0.01
> n <- 1000
> ABtest <- data.frame(Pattern = c(rep("A", n), rep("B", n)),CV = c(rbinom(n, 1, A.CVR), rbinom(n, 1, B.CVR)))
> ddply(ABtest, .(Pattern), summarize, CVR = mean(CV))

  Pattern   CVR
1       A 0.013
2       B 0.009

  Pattern   CVR
1       A 0.010
2       B 0.016

> chisq.test(table(ABtest))

Pearson's Chi-squared test with Yates' continuity correction

data:  table(ABtest)
X-squared = 0.28582, df = 1, p-value = 0.5929

> fisher.test(table(ABtest))

Fisher's Exact Test for Count Data

data:  table(ABtest)
p-value = 0.1079
alternative hypothesis: two.sided

上記の結果を見てわかるように、CVRは1%でシュミレーションしていますが、1度目はランディングページAの方がCVRが高くなっており、2度目はランディングページBの方がCVRが高くなっています。このように本当は差がないのに、偶然によって差があるように見えたりするので、検定をする必要があるのです。検定の結果を見てみると、p-valueは59%となっており、同じCVRにもかかわらず、59%の確率で違いがあるような結果が出ることがわかります。フィッシャーの正確性検定においても有意な差はないという結果がでており、AでもBでも特に差はない、という結論を受け入れることになります。以下の例は、無理矢理に適当な差があるデータを作った例です。

> x <- matrix(c(2892, 608, 2522, 978), ncol = 2, byrow = TRUE)
> rownames(x) <- c("before", "after")
> colnames(x) <- c("0", "1")
> x
          0   1
before 2892 608
after  2522 978

> chisq.test(x)

    Pearson's Chi-squared test with Yates' continuity correction

data:  x
X-squared = 111, df = 1, p-value < 2.2e-16

fisher.test(x)

    Fisher's Exact Test for Count Data

data:  x
p-value < 2.2e-16
alternative hypothesis: true odds ratio is not equal to 1
95 percent confidence interval:
 1.642562 2.071985
sample estimates:
odds ratio 
  1.844407 

コンジョイント分析を用いたウェブページの改善

仮想のデータを用いて、多変量解析の手法であるコンジョイント分析、ロジスティック回帰分析を用いたwebページの改善を行っていきます。ECであれば、webページの構成は、CVするかどうかに関わる重要な要素ですので、どのようなパーツを組み合わせ、webページを構成するかが重要です。しかし、パーツが増えれば増えるほど、パーツの組み合わせは膨大になりますので、ここまでに学んだ直交表を用いて、組み合わせ数をへらし、最適な組み合わせを探ることになります。 仮想データの内容は、webページのヘッダー属性には、「動画」「画像」の2水準、ヘッダー下部に配置するテキストを2種類用意しているとします。

> library(conjoint)
> library(epicalc)

> test <- expand.grid(Top = c("Movie", "Picture"),
                       Text = c("Text1", "Text2"))

> design.ort <- caFactorialDesign(data = test, type = "orthogonal")
> design.ort

      Top  Text
1   Movie Text1
2 Picture Text1
3   Movie Text2
4 Picture Text2

今回のデータでは、組み合わせ自体は少ないですが、頭でも簡単に組み合わせを算出できますが、caFactorialDesign()関数を使うことで直交表を得ることができます。直交表を計算してくれるフリーソフトがウェブにも幾つかあります。そして、この結果を用いて、webページの出しわけを行い、CVするかどうかを見ていきます。

> webpage.dat <- read.csv("webpage.csv", header = TRUE)
> head(webpage.dat)

   Header  Text CV
1   Movie Text1  1
2   Movie Text2  1
3 Picture Text1  0
4 Picture Text2  0
5   Movie Text1  1
6   Movie Text2  1

> fit <- glm(CV ~ Header + Text, data = webpage.dat, family = binomial)
summary(fit)

Call:
glm(formula = CV ~ Header + Text, family = binomial, data = webpage.dat)

Deviance Residuals: 
   Min      1Q  Median      3Q     Max  
-1.152  -1.135  -1.039   1.220   1.323  

Coefficients:
              Estimate Std. Error z value Pr(>|z|)  
(Intercept)   -0.05979    0.10982  -0.544   0.5862  
HeaderPicture -0.23455    0.12733  -1.842   0.0655 .
TextText2     -0.04053    0.12733  -0.318   0.7503  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 1376.7  on 999  degrees of freedom
Residual deviance: 1373.2  on 997  degrees of freedom
AIC: 1379.2

Number of Fisher Scoring iterations: 4

> exp(fit$coefficients)

  (Intercept) HeaderPicture     TextText2 
    0.9419647     0.7909270     0.9602833

logistic.display(fit, simplified = TRUE)

                     OR lower95ci upper95ci   Pr(>|Z|)
HeaderPicture 0.7909270 0.6162390  1.015134 0.06547533
TextText2     0.9602833 0.7482025  1.232479 0.75026293

> 1/0.7909270
[1] 1.264339

> 1/0.9602833
[1] 1.041359

分析の結果をみると、10%でヘッダーが有意になっています。そして、「HeaderPicture 」「TextText2 」の変数が共にマイナスになっていますので、「動画 」「テキスト1 」のほうがCVしやすいと言えます。また、オッズ比を計算してみると、「動画」は「画像」よりも1.26倍(=1/0.79)CVしやすく、「テキスト1」は「テキスト2」よりも1.04倍(=1/0.96)CVしやすいことがわかります。 したがって、ヘッダーには動画を用いて、テキスト1を組み合わせるのが最適な組合せということがわかります。logistic.display()関数を使えば、Expを取らなくてもオッズ比を算出できます。