2011-10-26 13 views
58

私は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 
+2

あなたは何を改善したいですか?速度?記憶?統計的収束? (上記のすべて?:))あなたのコードをgrokのように並べ替えることはできますが、解決しようとしている統計的な問題は理解できません。ユーモア私:なぜこれは単純に一般最小二乗回帰ではないでしょうか? 'lm()'はカテゴリ的な要素で大丈夫ですが、(私が間違っていない限り)順序付けされた要素もあります。 – Iterator

+0

@Iterator - 私は500のためにオプション3を取るよ!私が走っている主な問題は、速度とメモリに基づいています。統計的な問題は、もし私がそれをそのように分類しようとしていたとしても、約0.5Mの行を含む行列の80+属性の線形補間を単に実行する必要があるだけです。私が作った2つの簡単な変更はかなり重要であることが判明しました。すなわち、1) 'mdply()'から 'mapply()'に移動します。 2)すべてのdata.framesを行列に変更する。私はまだ全体のアプローチが計算上効率的であると確信していませんが、今は十分です。私が停止地点に達すると – Chase

+0

私は後世のために私自身の質問を更新/答えます。私はあなたに関連する仕事(名前のついたものとすべてのもの)のかなりの量を集めるので、興味があればオフラインでもっと詳しく話すことができます! – Chase

答えて

3

あなたが望むものを得るために、多少型破りな方法は、あなたの10Kは引き分け使用して、すべての製品のグローバルランキングを構築することです。

各ドローを10個の製品間のバイナリコンテストのソースとして使用し、すべてのドローでこれらのコンテストの結果を合計します。

これは、あなたの10製品の最終的な "リーダーボード"を提供します。このことから、すべての消費者の間で相対的な効用が得られます。また、各製品の勝ち数(およびオプションで各コンテストの選択肢の「強さ」)に基づいて絶対値を割り当てることもできます。

異なる属性プロファイルを持つ新しい製品をテストする場合は、他のサンプル製品のベクトル合計としてスパース(st)表現を見つけます。また、コンテストを再度実行することもできます。コンポーネント属性ベクトルの寄与重み。

これは、コンテストのシミュレーションが効率的であることと、グローバルなランキングと既存のデータのスパースベクトル合計としての新製品の表現とを組み合わせることで、結果を熟考して解釈することができるため、競技会の製品属性を打ち負かす。

あなたの新製品の疎な(記述的な)表現を見つけるには、Ax = yここで、Aは既存の製品の行列(属性ベクトルとしての行)、yはあなたの貢献の重み既存の製品。 yのゼロでない項目を最小限にする必要があります。高速ホモトピー法(力の繰り返しのような)に関するDonoho DLの論文を調べて、10-l1の最小化を素早く行い、疎な表現を見つける。

これを(または疎な表現の加重平均をとった場合)、既存の嗜好図で設定されたモデルに基づいて新製品のパフォーマンスを推測することができます。

希少性を表現することの利点は、商品が希薄に表現される可能性が高いため、有用性を増すだけではなく、所有する機能や製品の価値を高めることができます。したがって、大きな行列に拡大し、素早いアルゴリズムで本当に有用な結果を得ることができます。

関連する問題