ダブルスだけの結果から個人のレーティングとペアの相性を推定する

前回の続きで、卓球などで試合はダブルスばかりだったり、シングルと統合したい場合に使えると思う。 核はペアの場合のrateを rate[x]+rate[y]+rate_two[x,y] と分けて、rate_two(x<yの順序集合)はプラスマイナス200程度になる希望を事前分布に押し込んだ事。 使わない(x,x)や(3,1)などをゼロにする事前分布はなぜか全くうまくいかなかった。つねにx側が勝つ(=inv_logit[p]もほぼ1)なのに、何故か五分五分になりたがるみたいな。

library(rstan)

scode="
data{
  int N;
  int M;
  int x[N,2];
  int y[N,2];
  int one[N];
}

parameters {
  real rate[M];
  real rate_two[M,M];
}

transformed parameters {
    real p[N];
    real tmp1;
    real tmp2;
    real b=0.00575364;
    for(i in 1:N){
      tmp1=rate[x[i,1]]+rate[x[i,2]]+rate_two[x[i,1],x[i,2]];
      tmp2=rate[y[i,1]]+rate[y[i,2]]+rate_two[y[i,1],y[i,2]];
      p[i]=inv_logit(b*(tmp1-tmp2));
      //print(rate_two[1,1])
      print(p[i])
    }
}

model{
  
  rate~normal(1500,500);
  //rate~normal(0,0.0001);
  //b=0.00575364;
  for(i in 1:M){
    for(j in 1:M){
      if(i<j){
        rate_two[i,j]~normal(0,500);
      }else{
        //rate_two[i,j]~normal(1500,500);
        rate_two[i,j]~normal(0,500);
      }
    }
  }
      
  //rate_two~normal(0,100);
  //one~berounulli(p);
  
  for(i in 1:N){
    one[i]~bernoulli(inv_logit(p[i]));
  }
  
}

"

#b=Solve[1/(1 + Exp[-x*100]) == 0.64, x]

d=c(1,2,3,4,
    1,4,2,3,
    2,3,4,5,
    2,3,1,5,
    1,3,2,5,
    2,3,1,4,
    1,5,2,4
    )

d2=c(1,2,3,4,
    1,4,2,3,
    2,3,4,5,
    2,3,1,5,
    1,3,2,5,
    1,2,4,5,
    1,3,4,5
)

#12が強いが14だと弱くなるペア
d3=c(1,2,3,4,
     1,2,3,4,
     1,3,2,4,
     1,3,2,5,
     1,2,3,5,
     1,2,3,4,
     2,3,4,5,
     2,3,1,4
     )
#あえてシングル
dsingle=c(1,1,2,2,
          1,1,3,3,
          2,2,3,3,
          2,2,4,4,
          3,3,4,4,
          1,1,2,2,
          1,1,3,3,
          2,2,3,3,
          2,2,4,4,
          3,3,4,4
          )

df=matrix(d3,ncol=4,byrow = T)

x=df[,1:2]
y=df[,3:4]
M=max(df)
#rtinit=matrix(1500,M,M)

lst=list(N=nrow(x),x=x,y=y,M=max(df),one=rep(1,nrow(x)))
fit=stan(model_code = scode,data=lst,
         #init = function(){list(rate_two=rtinit,rate=rep(1500,M))},
         chain=1,iter=500,warmup = 80)

la=extract(fit)

rate=apply(la$rate,2,mean)
M=max(df)
rate_two=matrix(0,M,M)
for(i in 1:M){
  for(j in 1:M){
    rate_two[i,j]=mean(la$rate_two[,i,j])
  }
}

print(rate_two)
   [,1]       [,2]       [,3]       [,4]      [,5]
[1,] -12.471779 113.325409  84.967680 -35.935146  30.57404
[2,] -15.944763  28.629781  33.380074  -8.663292 -28.67175
[3,] -28.933494 -57.394162 -31.988833 -91.035994 -41.68916
[4,]  11.050791  -9.301574  -6.932745  17.611705 -14.15838
[5,]   6.273119   3.523987  32.405800  -8.521642 -32.16282

print(rate)
[1] 1629.242 1578.852 1507.623 1329.176 1386.851

基本的に1が1番強いようにつくり、d3は(1,2)のペアが最強だが1は4と組んだときに弱くなるのが出ていると思う。

同じノリで対戦相手の相性はaisho[xa,xb,ya,yb]とすれば良いと思う。