library(dplyr) # 使っても使わなくても読み込むパッケージ1
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyr) # 使っても使わなくても読み込むパッケージ2
library(ade4) # Factor型をダミー型に変換
library(cjoint)
## Loading required package: sandwich
## Loading required package: lmtest
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: ggplot2
## Loading required package: survey
## Loading required package: grid
##
## Attaching package: 'survey'
## The following object is masked from 'package:graphics':
##
## dotchart
## cjoint: AMCE Estimator for Conjoint Experiments
## Version: 2.0.4
実験の設定は
データ生成過程は
\[Y = \beta_0 + \beta_1 A_2 + \beta_2 B_2 + \beta_3 B_3 + \beta_4 C_2 + \beta_5 C_3 + \beta_6 C_4 + \varepsilon\]
だとする。各係数は以下のように設定する。
母数 | 係数 |
---|---|
\(\beta_0\) | 0 |
\(\beta_1\) | 0.04651905 |
\(\beta_2\) | 0.09523810 |
\(\beta_3\) | 0.14285714 |
\(\beta_4\) | 0.19047619 |
\(\beta_5\) | 0.23809524 |
\(\beta_6\) | 0.28571429 |
\(\sigma_{\varepsilon}\) | 1 |
早速データセットを作ってみる。
n.Respondents <- 10000
n.Task <- 4
n.Profile <- 2
n.Obs <- n.Respondents * n.Task * n.Profile
dgp.df <- data.frame(matrix(rep(NA, n.Obs * 7),
nrow = n.Obs))
names(dgp.df) <- c("ID", "Task", "Profile",
"Attr1", "Attr2", "Attr3", "Selected")
dgp.df$ID <- rep(1:n.Respondents, each = n.Task * n.Profile)
dgp.df$Task <- rep(rep(1:n.Task, each = n.Profile), n.Profile)
dgp.df$Profile <- rep(1:n.Profile, n.Respondents * n.Task)
dgp.df$Attr2 <- sample(c("B1", "B2", "B3"), n.Obs, replace = TRUE)
dgp.df$Attr3 <- sample(c("C1", "C2", "C3", "C4"), n.Obs, replace = TRUE)
Attr1 <- rep(NA, n.Obs)
for(i in seq(1, (n.Obs), by = 2)){
Attr1[i:(i+1)] <- sample(c("A1", "A2"), 2, replace = FALSE)
}
dgp.df$Attr1 <- Attr1
dgp.df$Attr1 <- factor(dgp.df$Attr1)
dgp.df$Attr2 <- factor(dgp.df$Attr2)
dgp.df$Attr3 <- factor(dgp.df$Attr3)
# ここからselectedを計算
beta_vec <- (1:6)/sum(1:6)
temp.df <- acm.disjonctif(dgp.df[, 4:6])[-c(1, 3, 6)]
e <- rnorm(n.Obs, 0, 0.1)
Selected <- rep(NA, n.Obs)
for(i in 1:n.Obs){
Selected[i] <- sum(temp.df[i,] * beta_vec)
}
Selected <- Selected + e
# 今のSelectedは選択確率。
# 別にこのまま計算してもいいが、リアリティーのために
# 選択確率が高い方に1をつける
for(i in seq(1, n.Obs, by = 2)){
if(Selected[i] == Selected[i+1]){
temp.result <- sample(0:1, 1, replace = FALSE)
}else if(Selected[i] > Selected[i+1]){
temp.result <- c(1, 0)
}else{
temp.result <- c(0, 1)
}
Selected[i:(i+1)] <- temp.result
}
dgp.df$Selected <- Selected
# これでデータセット作りは完了。
# 中身を見てみる
head(dgp.df)
## ID Task Profile Attr1 Attr2 Attr3 Selected
## 1 1 1 1 A2 B1 C1 0
## 2 1 1 2 A1 B2 C3 1
## 3 1 2 1 A2 B1 C3 0
## 4 1 2 2 A1 B1 C3 1
## 5 1 3 1 A2 B1 C2 0
## 6 1 3 2 A1 B1 C3 1
tail(dgp.df)
## ID Task Profile Attr1 Attr2 Attr3 Selected
## 79995 10000 2 1 A2 B3 C2 1
## 79996 10000 2 2 A1 B2 C1 0
## 79997 10000 3 1 A1 B1 C3 0
## 79998 10000 3 2 A2 B3 C4 1
## 79999 10000 4 1 A2 B2 C4 1
## 80000 10000 4 2 A1 B2 C1 0
実際にcjoint
パッケージを用いて推定してみる。
Est1 <- amce(Selected ~ Attr1 + Attr2 + Attr3, data = dgp.df,
respondent.id = "ID")
Est2 <- amce(Selected ~ Attr1 + Attr2 + Attr3,
data = filter(dgp.df, Profile == 1),
respondent.id = "ID")
summary(Est1)$amce
## Attribute Level Estimate Std. Err z value Pr(>|z|)
## 1 Attr1 A2 0.1671127 0.004166654 40.10716 0 ***
## 2 Attr2 B2 0.1717942 0.003819910 44.97337 0 ***
## 3 Attr2 B3 0.2550115 0.003758975 67.84069 0 ***
## 4 Attr3 C2 0.3234665 0.004212308 76.79080 0 ***
## 5 Attr3 C3 0.4083121 0.004109691 99.35349 0 ***
## 6 Attr3 C4 0.5032019 0.003952208 127.32169 0 ***
summary(Est2)$amce
## Attribute Level Estimate Std. Err z value Pr(>|z|)
## 1 Attr1 A2 0.1676327 0.004423632 37.89482 0.000000e+00 ***
## 2 Attr2 B2 0.1770276 0.005443581 32.52043 5.484219e-232 ***
## 3 Attr2 B3 0.2536654 0.005395813 47.01152 0.000000e+00 ***
## 4 Attr3 C2 0.3234017 0.006156375 52.53120 0.000000e+00 ***
## 5 Attr3 C3 0.4092543 0.005983901 68.39256 0.000000e+00 ***
## 6 Attr3 C4 0.5030460 0.005918553 84.99475 0.000000e+00 ***
ケースが半減するし、標準誤差を見ても意味がないので、係数だけみる。
属性 | 水準 | プロファイル両方使用 | プロファイル1のみ使用 |
---|---|---|---|
A | |||
A2 | 0.167 | 0.168 | |
B | |||
B2 | 0.172 | 0.177 | |
B3 | 0.255 | 0.254 | |
C | |||
C2 | 0.323 | 0.323 | |
C3 | 0.408 | 0.409 | |
C4 | 0.503 | 0.503 |
どっちも係数はほぼ変わらないことが確認できた。
DGPと係数が異なるのはSelectedの値を選択確率でなく、バイナリー変数へ変換したため。(係数の比較という観点では問題ない)