編集:私はもともとOPはどの観察がどの種から来たのか知っていると思っていました。OPの編集により、私の元のアプローチが実行可能でないことが明らかになりました。後世のために残しておきますが、他の答えははるかに優れています。慰めとして、私はスタンの混合モデルをコーディングしました。この場合、ベイジアンのアプローチが特に良いと言っているわけではありませんが、それは私が貢献できる素晴らしいものです。
スタンコード
data{
//Number of data points
int N;
real y[N];
real x[N];
}
parameters{
//mixing parameter
real<lower=0, upper =1> theta;
//Regression intercepts
real beta_0[2];
//Regression slopes.
ordered[2] beta_1;
//Regression noise
real<lower=0> sigma[2];
}
model{
//priors
theta ~ beta(5,5);
beta_0 ~ normal(0,1);
beta_1 ~ normal(0,1);
sigma ~ cauchy(0,2.5);
//mixture likelihood
for (n in 1:N){
target+=log_mix(theta,
normal_lpdf(y[n] | beta_0[1] + beta_1[1]*x[n], sigma[1]),
normal_lpdf(y[n] | beta_0[2] + beta_1[2]*x[n], sigma[2]));
}
}
generated quantities {
//posterior predictive distribution
//will allow us to see what points belong are assigned
//to which mixture
matrix[N,2] p;
matrix[N,2] ps;
for (n in 1:N){
p[n,1] = log_mix(theta,
normal_lpdf(y[n] | beta_0[1] + beta_1[1]*x[n], sigma[1]),
normal_lpdf(y[n] | beta_0[2] + beta_1[2]*x[n], sigma[2]));
p[n,2]= log_mix(1-theta,
normal_lpdf(y[n] | beta_0[1] + beta_1[1]*x[n], sigma[1]),
normal_lpdf(y[n] | beta_0[2] + beta_1[2]*x[n], sigma[2]));
ps[n,]= p[n,]/sum(p[n,]);
}
}
Rからスタンモデルを実行する
library(tidyverse)
library(rstan)
#Simulate the data
N = 100
x = rnorm(N, 0, 3)
group = factor(sample(c('a','b'),size = N, replace = T))
y = model.matrix(~x*group)%*% c(0,1,0,2)
y = as.numeric(y) + rnorm(N)
d = data_frame(x = x, y = y)
d %>%
ggplot(aes(x,y))+
geom_point()
#Fit the model
N = length(x)
x = as.numeric(x)
y = y
fit = stan('mixmodel.stan',
data = list(N= N, x = x, y = y),
chains = 8,
iter = 4000)
結果
破線はグラウンドトゥルース、実線は推定値です。
元の回答
どのサンプルがどの種類の水仙に由来するかがわかっている場合、品種と土壌PHの相互作用を推定できます。
モデルは次のようになります
y= β0+ β1多様性+ β2PH + β3様々な⋅ PH
Rの例を次に示します。次のようなデータを生成しました。
明らかに2つの異なる線、および線は2つの種に対応しています。線形回帰を使用してラインを推定する方法は次のとおりです。
library(tidyverse)
#Simulate the data
N = 1000
ph = runif(N,5,8)
species = rbinom(N,1,0.5)
y = model.matrix(~ph*species)%*% c(20,1,20,-3) + rnorm(N, 0, 0.5)
y = as.numeric(y)
d = data_frame(ph = ph, species = species, y = y)
#Estimate the model
model = lm(y~species*ph, data = d)
summary(model)
そして結果は
> summary(model)
Call:
lm(formula = y ~ species * ph, data = d)
Residuals:
Min 1Q Median 3Q Max
-1.61884 -0.31976 -0.00226 0.33521 1.46428
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 19.85850 0.17484 113.58 <2e-16 ***
species 20.31363 0.24626 82.49 <2e-16 ***
ph 1.01599 0.02671 38.04 <2e-16 ***
species:ph -3.03174 0.03756 -80.72 <2e-16 ***
---
Signif. codes:
0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.4997 on 996 degrees of freedom
Multiple R-squared: 0.8844, Adjusted R-squared: 0.8841
F-statistic: 2541 on 3 and 996 DF, p-value: < 2.2e-16
0というラベルが付けられた種の場合、線はおよそ
y= 19 + 1 ⋅ PH
1というラベルが付けられた種の場合、線はおよそ
y= 40 - 2 ⋅ PH