2013-03-15 49 views
3

背景模型公式與GLM迴歸用戶指定的家庭

我試圖預測用於產品線的銷售(在樣品中y_test末)。它的一段時間內的銷售額是基於以前所有其他產品的銷售額(x_test),以及之前有多少銷售額仍在使用中。直接測量仍然在使用的那些以前銷售的產品的數量是不可能的,因此需要推斷存活曲線。

例如,如果您爲特定智能手機型號生產配件,配件銷售至少部分基於仍在使用的智能手機的數量。 (這不是功課,順便說一句。)

詳細

我有一些時間序列數據,並想以適應使用glm或類似的東西迴歸模型。因變量和自變量之間的關係是這樣的: regression formula

其中P是時間段,Y p是因變量,X p是自變量,C 和c 是迴歸係數,F t是累積分佈函數(如pgamma),e p是殘差。

通過前三個時間段,該功能將擴展到這樣的事情:

#y[1] = c0 + c1*(x[1]*(1-integrate(function(q) {pgamma(q, c2, c2/c3)}, 0, 1)$value)) 
#y[2] = c0 + c1*(x[1]*(1-integrate(function(q) {pgamma(q, c2, c2/c3)}, 1, 2)$value) + x[2]*(1-integrate(function(q) {pgamma(q, c2, c2/c3)}, 0, 1)$value)) 
#y[3] = c0 + c1*(x[1]*(1-integrate(function(q) {pgamma(q, c2, c2/c3)}, 2, 3)$value) + x[2]*(1-integrate(function(q) {pgamma(q, c2, c2/c3)}, 1, 2)$value) + x[3]*(1-integrate(function(q) {pgamma(q, c2, c2/c3)}, 0, 1)$value)) 

所以,我有X p和y p歷史數據,我想使殘差最小化的係數/​​參數c ,c ,c 和c 的值。

我認爲解決方案是使用glm並創建一個自定義系列,但我不知道該怎麼做。我查看了Gamma家族的代碼,但並沒有走得很遠。我已經能夠使用nlminb「手動」進行優化,但我更喜歡glm或類似功能提供的簡單性和實用性(即predict等)。

下面是一些示例數據:

# Survival function (the integral part): 
fsurv<-function(q, par) { 
    l<-length(q) 
    out<-vapply(1:l, function(i) {1-integrate(function(x) {pgamma(x, par[1], par[1]/par[2])}, q[i]-1, q[i])$value}, FUN.VALUE=0) 
    return(out)} 

# Sum up the products: 
frevsumprod <- function(x,y) { 
    l <- length(y) 
    out <- vapply(1:l, function(i) sum(x[1:i]*rev(y[1:i])), FUN.VALUE=0) 
    return(out)} 

# Sample data: 
p<-1:24 # Number of periods 
x_test<-c(1188, 2742, 4132) # Sample data 
y_test<-c(82520, 308910, 749395, 801905, 852310, 713935, 624170, 603960, 640660, 553600, 497775, 444140) # Sample data 
c<-c(-50.161147,128.787437,0.817085,13.845487) # Coefficients and parameters, from another method that fit the data 

# Pad the data to the correct length: 
pad<-function(p,v,padval=0) { 
    l<-length(p) 
    padv<-l-length(v) 
    if(padv>0) (v<-c(v,rep(padval,padv))) 
    return(v) 
} 
x_test<-pad(p,x_test) 
y_test<-pad(p,y_test,NA) 

y_fitted<-c[0+1]+c[1+1]*frevsumprod(x_test,fsurv(p,c[(2:3)+1])) # Fitted values from regression 

library(ggplot2) 
ggplot(data.frame(p,y_test,y_fitted))+geom_point(aes(p,y_test))+geom_line(aes(p,y_fitted)) # Plot actual and fit 
+0

您應該備份幾個步驟並描述問題......不僅僅是您解決它的失敗努力。 (我想這可能是作業?)請不要做評論中迴應的SO-newb。請編輯該問題。 – 2013-03-15 18:30:57

+0

謝謝@DWin。我編輯了這個問題,但還沒有嘗試回答它。你有更好的提出這個問題的其他建議嗎?順便說一句,我認爲幾乎所有的問題陳述都與任何潛在的答案有關,而不僅僅是對我的「失敗的努力」的敘述。 – dnlbrky 2013-04-16 18:27:53

+0

我建議你用遷移到CrossValidated的請求標記這個。 (......或者你可以在那裏交叉發佈它,並注意它沒有得到SO的迴應。) – 2013-04-16 19:15:58

回答

0

這不能與glm來完成。 glm中的family指定線性預測器如何與y的平均值相關聯。見?familywiki。特別是,你需要能夠寫一個family清單,(一些)之類的功能:

> fam <- poisson() 
> str(fam) 
List of 12 
$ family : chr "poisson" 
$ link  : chr "log" 
$ linkfun :function (mu) 
$ linkinv :function (eta) 
$ variance :function (mu) 
$ dev.resids:function (y, mu, wt) 
$ aic  :function (y, n, mu, wt, dev) 
$ mu.eta :function (eta) 
$ initialize: expression({ if (any(y < 0)) stop("negative values not allowed for the 'Poisson' family") n <- rep.int(1, nobs| __truncated__ 
$ validmu :function (mu) 
$ valideta :function (eta) 
$ simulate :function (object, nsim) 
- attr(*, "class")= chr "family" 
> 
> fam <- Gamma() 
> str(fam) 
List of 12 
$ family : chr "Gamma" 
$ link  : chr "inverse" 
$ linkfun :function (mu) 
$ linkinv :function (eta) 
$ variance :function (mu) 
$ dev.resids:function (y, mu, wt) 
$ aic  :function (y, n, mu, wt, dev) 
$ mu.eta :function (eta) 
$ initialize: expression({ if (any(y <= 0)) stop("non-positive values not allowed for the 'gamma' family") n <- rep.int(1, n| __truncated__ 
$ validmu :function (mu) 
$ valideta :function (eta) 
$ simulate :function (object, nsim) 
- attr(*, "class")= chr "family" 

其中eta指線性預測。即至少您需要指定一個反向鏈接函數linkinv,其中只有取決於通過參數和協變量之間的點積的協變量。你的不是因爲它以非線性方式依賴於c_2和c_3。