海老ノート

Google Earth Engine 苦闘の記録

GEEで分布推定モデル1:できるらしい

できるんだろうなと思っていたら

この間のランダムフォレスト回帰で思ったのが、分布推定モデル(SDM)できそう。で、検索したらありました。

Crego, R. D., Stabach, J. A., & Connette, G. (2022). Implementation of species distribution models in Google Earth Engine. Diversity and Distributions.

スクリプトとその解説も公開されています。 データクリーニングから始まるかなり長くてがっちりしたスクリプトです。

smithsonian.github.io

で、この論文はランダムフォレストで分布推定してます。すごいなあと思ったところはたくさんあるんだけど、特にGoogleEarthEngineでは手間な交差検証をスクリプトの中で仕上げてるのがすごい。調査範囲に配置したグリッドを10グループに分割して交差検証してます。

分布推定モデル(SDM)がGoogleEarthEngineでできたらいいとは思う

GEE上でSDMが動かせるメリットっていくつも思いつく。Crego et al. (2022)でも書いてある通り、NDVIとかの衛星由来のデータをモデルに簡単にぶち込めるのは大きい。あとは複数年や多くの種など沢山のモデルを走らせて、それらの出力結果をつかって考察するような仕事(分布適地の経年変化とか、潜在的ホットスポット解析とか)だといい。

なんだかんだのMaxEnt

生態学分野のSDMといえば、MaxEnt。乱用慎むべし的な話も聞くけれども、それでも何年も多くの人が使っているってことはそれなりに納得感のある結果が得られてるってことなんでしょう、たぶん。で、GoogleEarthEngineのドキュメントを見てたら、ClassifierにそのMaxEntがあった。

developers.google.com

正直よくわかっていない

MaxEnt触ったことがある方はご存じの通り、調整できるパラメータが大量にある。

ee.Classifier.amnhMaxent(categoricalNames, outputFormat, autoFeature, linear, quadratic, product, threshold, hinge, hingeThreshold, l2lqThreshold, lq2lqptThreshold, addSamplesToBackground, addAllSamplesToBackground, betaMultiplier, betaHinge, betaLqp, betaCategorical, betaThreshold, extrapolate, doClamp, writeClampGrid, randomTestPoints, seed)

で、わかんないから、とりあえずオートでやってみてAUCみてこんなもんなのかなと(ということをやるから、MaxEntについていろいろ言われるのは知ってる)。で不安で人に聞く/任せるまでが流れ。

というように理解が浅くていので、ここでは動くスクリプトの書き方を記録するにとどめます。レビューも解説論文も出てるので気になる方はそちらを見ていただいたうえ、ご自身の責任でどうぞ。

肝の部分はシンプル

コードの書き方は他のee.Classifilerと似ている。autoFeatureをtrueにしておけば、さらっと動かせる。しかも結構早い。

// モデル作成
// 教師データ(FeatureCollection)をtraining、環境データ(マルチバンドのImage)をenvLayerとした場合
var classifier = ee.Classifier.amnhMaxent({
                                categoricalNames: ['ecoreg'],  // カテゴリカルデータのバンド名を指定
                                autoFeature: true,      // 設定はオートで
                                randomTestPoints: 20        // 分布データの20%をランダムに選んでテストデータにする
                            })
                             .train({
                              features: training,
                              classProperty: 'presence',
                              inputProperties: envLayer.bandNames()
                            });

//  MaxEnt で推定
var imageClassified = envLayer.classify(classifier); // 予測結果がImageで出力される
print(classifier.explain()) //モデルの内容をコンソールに出力

というわけで、次回以降忘備録をつけ足します。