多変数における最小二乗クロスバリデーション評価関数を最小にするhを決定する - Seeking for my unique color.の最適化関数の付近。
mapply(に相当するもの)が3つくらいネストしたりしていますが、怖がってはいけません。
gkbrです。。。
optim(par=c(1,0.1),function(h){ h1 <- h[1] h2 <- h[2] sum(mapply(function(X1i,X2i,Yi){ (Yi - (Reduce("+",Map(function(f){outer(X1i,X2i,f)},mapply(function(X1,X2,Y){y.exp(X1,X2,Y,h1,h2)},X1,X2,Y))) - 1/sqrt(2*pi)) / (Reduce("+",Map(function(f){outer(X1i,X2i,f)},mapply(function(X1,X2){gauusian(X1,X2,h1,h2)},X1,X2))) - 1/sqrt(2*pi)) )^2 },X1,X2,Y)) })
卒論ではとりあえずplotとかを考えて2変数でしかやらないから上みたいなのでよかったんだけど、3変数以上だととりあえずouter関数が動かなくなる。根本な部分なこの辺か。
(Reduce("+",Map(function(f){outer(X1i,X2i,f)},mapply(function(X1,X2,Y){y.exp(X1,X2,Y,h1,h2)},X1,X2,Y))) - 1/sqrt(2*pi))
Reduceは足し込んでいく(今回の場合はinitは与えていない)だけなんだけど、何を足し込んでいるのかを見る必要がある。
Map(function(f){outer(X1i,X2i,f)},mapply(function(X1,X2,Y){y.exp(X1,X2,Y,h1,h2)},X1,X2,Y))
Map関数は第一引数に関数を取る関数。第二引数がデータ。第一引数の関数に第二引数のデータを適用していって、その結果をベクトルとかで返す。
第二引数のデータは普通はただの数値が入ったベクトルだったりするんだけど、今回のy.expとかgauusian関数は関数を返す関数になっているので、第二引数は関数リストが入っているリストが返ってくるという結果になっている。
そうなるとMap関数の第一引数の関数を見てやればよいのだが、ただのouter関数になっている。
function(f){outer(X1i,X2i,f)}
X1iとX2iの全ての組み合わせをfに適用させる。
追記
説明していたらここが間違いであるっぽいことに気がついてきた。outerさせないでX1i、X2iをそのまま関数に適用してやればいいだけじゃないか。X1iもX2iもスカラーであるから(Rでは1つの要素でもベクトルだが)outerでも間違いとは言えないが(やっている操作は同じ)、読めない原因となっているというか意図とは違うコードになっているという意味でよくない。
function(f){f(X1i,X2i)}
だからこれでよい。たぶんpersp関数でplotさせるところでouterを使っていたからここでも使ってしまっていたんだろう。
- 1/sqrt(2*pi)
とかある部分はleave-one outの付近を表わしている。ここコードでやっているのは全部足して最後に引くというような手順になっている。カーネルに0を入れた時に値になっている。