假设我必须在回归中估计系数a,b:
y=a*x+b*z+c
我事先知道y总是在y> = 0和y< = x的范围内,但回归模型有时会产生y在此范围之外。
示例数据:
mydata<-data.frame(y=c(0,1,3,4,9,11),x=c(1,3,4,7,10,11),z=c(1,1,1,9,6,7))
round(predict(lm(y~x+z,data=mydata)),2)
1 2 3 4 5 6
-0.87 1.79 3.12 4.30 9.34 10.32
第一预测值<0。
我尝试了没有拦截的模型:所有预测都是> 0,但y的第三次预测是&gt; x(4.03> 3)
round(predict(lm(y~x+z-1,data=mydata)),2)
1 2 3 4 5 6
0.76 2.94 4.03 4.67 8.92 9.68
我还考虑建模比例 y / x而不是y:
mydata$y2x<-mydata$y/mydata$x
round(predict(lm(y2x~x+z,data=mydata)),2)
1 2 3 4 5 6
0.15 0.39 0.50 0.49 0.97 1.04
round(predict(lm(y2x~x+z-1,data=mydata)),2)
1 2 3 4 5 6
0.08 0.33 0.46 0.47 0.99 1.07
但现在第六次预测> 1,但比例应该在[0,1]范围内。
我还尝试应用glm
与offset
选项一起使用的方法:Regression for a Rate variable in R
和
http://en.wikipedia.org/wiki/Poisson_regression#.22Exposure.22_and_offset
但这不成功。
请注意,在我的数据因变量中:比例 y / x 既是零膨胀又是一次膨胀。 任何想法,在R('glm','lm')中建立模型的合适方法是什么?
答案 0 :(得分:4)
你走在正确的轨道上:如果0≤y≤x则0≤(y / x)≤1。这表明y/x
符合glm(...)
中的逻辑模型。详情如下,但考虑到你只得到6分,这是一个非常合适的选择。
主要关注的是该模型无效,除非(y/x)
中的误差为常态且方差不变(或等效地,y中的误差随x增加)。如果这是真的那么我们应该得到(或多或少)线性Q-Q图,我们这样做。
一个细微差别:glm逻辑模型的接口需要两列y:“成功次数(S)”和“失败次数(F)”。然后计算概率为S /(S + F)。所以我们必须提供两个模仿这个的列:y和x-y。然后glm(...)
将计算y/(y+(x-y)) = y/x
。
最后,拟合总结表明x很重要,z可能是也可能不是。您可能想尝试排除z的模型,看看是否可以改善AIC。
fit = glm(cbind(y,x-y)~x+z, data=mydata, family=binomial(logit))
summary(fit)
# Call:
# glm(formula = cbind(y, x - y) ~ x + z, family = binomial(logit),
# data = mydata)
# Deviance Residuals:
# 1 2 3 4 5 6
# -0.59942 -0.35394 0.62705 0.08405 -0.75590 0.81160
# Coefficients:
# Estimate Std. Error z value Pr(>|z|)
# (Intercept) -2.0264 1.2177 -1.664 0.0961 .
# x 0.6786 0.2695 2.518 0.0118 *
# z -0.2778 0.1933 -1.437 0.1507
# ---
# Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
# (Dispersion parameter for binomial family taken to be 1)
# Null deviance: 13.7587 on 5 degrees of freedom
# Residual deviance: 2.1149 on 3 degrees of freedom
# AIC: 15.809
par(mfrow=c(2,2))
plot(fit) # residuals, Q-Q, Scale-Location, and Leverage Plots
mydata$pred <- predict(fit, type="response")
par(mfrow=c(1,1))
plot(mydata$y/mydata$x,mydata$pred,xlim=c(0,1),ylim=c(0,1), xlab="Actual", ylab="Predicted")
abline(0,1, lty=2, col="blue")