私はdiscrete choice tasksのセットから、3つの属性(ブランド、価格、性能)の2つの選択肢を含むデータセットを持っています。このデータから、事後分布から1000回抜きました。それを使って各個人と各ドローの効用と最終的な選好度を計算します。商品属性を補間する
個別のレベル(-.2,0、.2)と(-.25,0,25)でテストしました。私はテストされた属性レベルの間でユーティリティを補間できる必要があります。今のところ線形補間は統計的に行うのが妥当であると仮定しましょう。言い換えれば、@ 10%の価格でシナリオをテストしたければ、ユーティリティを価格に補間する最も効率的な方法は何ですか?私は補間を行うために滑らかで効率的な方法を考えることができませんでした。属性レベルを補間することなく、私が達成しようとしているかについてのコンテキストを提供するために
library(plyr)
#draws from posterior, 2 respondents, 2 draws each
draw <- list(structure(c(-2.403, -2.295, 3.198, 1.378, 0.159, 1.531,
1.567, -1.716, -4.244, 0.819, -1.121, -0.622, 1.519, 1.731, -1.779,
2.84), .Dim = c(2L, 8L), .Dimnames = list(NULL, c("brand_1",
"brand_2", "price_1", "price_2", "price_3", "perf_1", "perf_2",
"perf_3"))), structure(c(-4.794, -2.147, -1.912, 0.241, 0.084,
0.31, 0.093, -0.249, 0.054, -0.042, 0.248, -0.737, -1.775, 1.803,
0.73, -0.505), .Dim = c(2L, 8L), .Dimnames = list(NULL, c("brand_1",
"brand_2", "price_1", "price_2", "price_3", "perf_1", "perf_2",
"perf_3"))))
#define attributes for each brand: brand constant, price, performance
b1 <- c(1, .15, .25)
b2 <- c(2, .1, .2)
#Create data.frame out of attribute lists. Wil use mdply to go through each
interpolateCombos <- data.frame(xout = c(b1,b2),
atts = rep(c("Brand", "Price", "Performance"), 2),
i = rep(1:2, each = 3),
stringsAsFactors = FALSE)
#Find point along line. Tried approx(), but too slow
findInt <- function(x1,x2,y1,y2,reqx) {
range <- x2 - x1
diff <- reqx - x1
out <- y1 + ((y2 - y1)/range) * diff
return(out)
}
calcInterpolate <- function(xout, atts, i){
if (atts == "Brand") {
breaks <- 1:2
cols <- 1:2
} else if (atts == "Price"){
breaks <- c(-.2, 0, .2)
cols <- 3:5
} else {
breaks <- c(-.25, 0, .25)
cols <- 6:8
}
utils <- draw[[i]][, cols]
if (atts == "Brand" | xout %in% breaks){ #Brand can't be interpolated or if level matches a break
out <- data.frame(out = utils[, match(xout, breaks)])
} else{ #Must interpolate
mi <- min(which(breaks <= xout))
ma <- max(which(breaks >= xout))
out <- data.frame(out = findInt(breaks[mi], breaks[ma], utils[, mi], utils[,ma], xout))
}
out$draw <- 1:nrow(utils)
return(out)
}
out <- mdply(interpolateCombos, calcInterpolate)
:私はここにいくつかのデータと私の現在のアプローチだplyr
からmdply機能付きmapply()のアプローチに頼ってきました、私はそれをどうやってやるの?ブランドは列参照の観点から定義されていることに注意してください。 p1 & p2は製品定義を参照し、u1 & u2はユーティリティ、s1、s2はその抽選の優先株式です。
正しい方向に向かってどんな軽微な動きもあります。私の実際の事例では、それぞれ8つの属性を持つ10の製品があります。 10kで引っ張っていくと、私の8GBのラムが壊れていますが、私が掘ったこのウサギの穴から出ることはできません。
p1 <- c(1,2,1)
p2 <- c(2,1,2)
FUN <- function(x, p1, p2) {
bases <- c(0,2,5)
u1 <- rowSums(x[, bases + p1])
u2 <- rowSums(x[, bases + p2])
sumExp <- exp(u1) + exp(u2)
s1 <- exp(u1)/sumExp
s2 <- exp(u2)/sumExp
return(cbind(s1,s2))
}
lapply(draw, FUN, p1 = p1, p2 = p2)
[[1]]
s1 s2
[1,] 0.00107646039 0.9989235
[2,] 0.00009391749 0.9999061
[[2]]
s1 s2
[1,] 0.299432858 0.7005671
[2,] 0.004123175 0.9958768
あなたは何を改善したいですか?速度?記憶?統計的収束? (上記のすべて?:))あなたのコードをgrokのように並べ替えることはできますが、解決しようとしている統計的な問題は理解できません。ユーモア私:なぜこれは単純に一般最小二乗回帰ではないでしょうか? 'lm()'はカテゴリ的な要素で大丈夫ですが、(私が間違っていない限り)順序付けされた要素もあります。 – Iterator
@Iterator - 私は500のためにオプション3を取るよ!私が走っている主な問題は、速度とメモリに基づいています。統計的な問題は、もし私がそれをそのように分類しようとしていたとしても、約0.5Mの行を含む行列の80+属性の線形補間を単に実行する必要があるだけです。私が作った2つの簡単な変更はかなり重要であることが判明しました。すなわち、1) 'mdply()'から 'mapply()'に移動します。 2)すべてのdata.framesを行列に変更する。私はまだ全体のアプローチが計算上効率的であると確信していませんが、今は十分です。私が停止地点に達すると – Chase
私は後世のために私自身の質問を更新/答えます。私はあなたに関連する仕事(名前のついたものとすべてのもの)のかなりの量を集めるので、興味があればオフラインでもっと詳しく話すことができます! – Chase