spo*_*234 2 r predict mixture-model
我将一些数据拟合为两个高斯分布的混合分布flexmix:
data("NPreg", package = "flexmix")
mod <- flexmix(yn ~ x, data = NPreg, k = 2,
model = list(FLXMRglm(yn ~ x, family= "gaussian"),
FLXMRglm(yn ~ x, family = "gaussian")))
Run Code Online (Sandbox Code Playgroud)
模型拟合如下:
> mod
Call:
flexmix(formula = yn ~ x, data = NPreg, k = 2, model = list(FLXMRglm(yn ~ x, family = "gaussian"),
FLXMRglm(yn ~ x, family = "gaussian")))
Cluster sizes:
1 2
74 126
convergence after 31 iterations
Run Code Online (Sandbox Code Playgroud)
但是我如何从这个模型中实际预测呢?
当我做
pred <- predict(mod, NPreg)
Run Code Online (Sandbox Code Playgroud)
我得到一个列表,其中包含两个组件中的每个组件的预测
要获得单个预测,我是否必须添加像这样的群集大小?
single <- (74/200)* pred$Comp.1[,1] + (126/200)*pred$Comp.2[,2]
Run Code Online (Sandbox Code Playgroud)
我用flexmix以下方式进行预测:
pred = predict(mod, NPreg)
clust = clusters(mod,NPreg)
result = cbind(NPreg,data.frame(pred),data.frame(clust))
plot(result$yn,col = c("red","blue")[result$clust],pch = 16,ylab = "yn")
Run Code Online (Sandbox Code Playgroud)
和混乱矩阵:
table(result$class,result$clust)
Run Code Online (Sandbox Code Playgroud)
为了获得预测值yn,我选择数据点所属的集群的组件值.
for(i in 1:nrow(result)){
result$pred_model1[i] = result[,paste0("Comp.",result$clust[i],".1")][i]
result$pred_model2[i] = result[,paste0("Comp.",result$clust[i],".2")][i]
}
Run Code Online (Sandbox Code Playgroud)
实际与预测结果显示拟合(在这里只添加其中一个,因为两个模型都相同,您将pred_model2用于第二个模型).
qplot(result$yn, result$pred_model1,xlab="Actual",ylab="Predicted") + geom_abline()
Run Code Online (Sandbox Code Playgroud)
RMSE = sqrt(mean((result$yn-result$pred_model1)^2))
Run Code Online (Sandbox Code Playgroud)
给出均方根误差5.54.
这个答案是基于我在工作时读到的许多SO答案flexmix.它适用于我的问题.
您可能也有兴趣可视化这两个发行版.我的模型如下,它显示了一些重叠,因为组件的比例不接近1.
Call:
flexmix(formula = yn ~ x, data = NPreg, k = 2,
model = list(FLXMRglm(yn ~ x, family = "gaussian"),
FLXMRglm(yn ~ x, family = "gaussian")))
prior size post>0 ratio
Comp.1 0.481 102 129 0.791
Comp.2 0.519 98 171 0.573
'log Lik.' -1312.127 (df=13)
AIC: 2650.255 BIC: 2693.133
Run Code Online (Sandbox Code Playgroud)
我还使用直方图生成密度分布,以对两个组件进行可视化.这是受到维护者的回答的启发betareg.
a = subset(result, clust == 1)
b = subset(result, clust == 2)
hist(a$yn, col = hcl(0, 50, 80), main = "",xlab = "", freq = FALSE, ylim = c(0,0.06))
hist(b$yn, col = hcl(240, 50, 80), add = TRUE,main = "", xlab = "", freq = FALSE, ylim = c(0,0.06))
ys = seq(0, 50, by = 0.1)
lines(ys, dnorm(ys, mean = mean(a$yn), sd = sd(a$yn)), col = hcl(0, 80, 50), lwd = 2)
lines(ys, dnorm(ys, mean = mean(b$yn), sd = sd(b$yn)), col = hcl(240, 80, 50), lwd = 2)
Run Code Online (Sandbox Code Playgroud)
# Joint Histogram
p <- prior(mod)
hist(result$yn, freq = FALSE,main = "", xlab = "",ylim = c(0,0.06))
lines(ys, p[1] * dnorm(ys, mean = mean(a$yn), sd = sd(a$yn)) +
p[2] * dnorm(ys, mean = mean(b$yn), sd = sd(b$yn)))
Run Code Online (Sandbox Code Playgroud)