【Gemini CLI活用】クマ出現率予測ロジック追加|クマ共生ハッカソン進捗③
石川県オープンデータ利活用企画のクマ共生ハッカソンにチャレンジしています。
初回参加レポートはこちら。
日々の試行錯誤の状況を報告します。今回はパート3です。
これまでのおさらいと今回やったこと
前回までやったことは以下を参照。
前回はGoogleMap APIを使ってユーザーがクリックした位置のクマ出現確率を表示できるようにしました。
今回は、クマ出没データを使ってクマ出現確率を表示するロジックを組み込んでみました。
結論から言えば、以下のようにユーザーがクリックした位置の半径1kmにおけるクマ出現回数を表示する仕組みは追加できました。(※ただし精度は謎)

具体的な作業は以下のとおりです。
クマ出没データをダウンロード
クマ出没データと地図アプリを組み合わせる
以下ではそれぞれについて紹介します。
①クマ出没データをダウンロード
今回使用するオープンデータはこちらに掲載されています。
6つの視点から分析したクマ出没データをダウンロードして使います。

②クマ出没データと地図アプリを組み合わせる
先ほどダウンロードしたデータを使って今いる地点のクマ出現率を予測したい。
Gemini CLIに無茶振りしてみました。
dataにあるデータは6つの視点からクマの出没分析したデータです。
これを活用してユーザーがクリックした座標のクマ出現率を予測するモデルを作ってバックエンドに追加して 以前と同様にバックエンドのサーバーを起動するところ止まってしまったのでいったん実行を中断しました。

ロジックを見るとCSVのデータをもとに半径1km以内のクマの出現回数を返却するようにしたようです。
モデルの考え方
ユーザーが指定した地点の周辺で、過去にどれだけのクマが目撃されたかを計算し、その密度に応じて出現確率を算出す
る、というシンプルなアプローチで進めます。
開発のステップ
1. データ整形: 緯度・経度が含まれるCSVから、座標データを抽出・統合します。
2. モデル実装: 指定された座標の周辺(例:半径1km以内)の過去の目撃情報をカウントするロジックを実装します。
3. バックエンド組込:
* backendに、prediction.jsという名前でモデル処理用のファイルを作成します。
* index.jsを修正し、/api/v1/bears/probabilityというエンドポイントを追加します。
* このエンドポイントが、prediction.jsのモデルを呼び出し、計算結果をJSON形式で返却するようにします。
せっかくなので仕様と使い方をREADMEファイルに書いてもらいました。
今の仕様とこのアプリの使い方をわかりやすく説明するREADMEファイルを作って個人的にREADMEファイル書くのすごく苦手なので、指示するだけで作ってくれるのはありがたいです。

③いざ実行
できたコードを実行すると、早速エラーになりました。

エラーメッセージは以下。CSVの読み込みに失敗しているようです。
Loading bear sighting data...
Error reading or parsing file 石川県クマ出没分析マップ(R1〜R6)- (3)誘引物が要因の出没(R1-R6).csv: CsvError: Invalid Record Length: columns length is 17, got 9 on line 12
at Object.__onRecord (C:\Work\kuma-hackathon-ishikawa-2025\backend\node_modules\csv-parse\dist\cjs\sync.cjs:1356:15)
at Object.parse (C:\Work\kuma-hackathon-ishikawa-2025\backend\node_modules\csv-parse\dist\cjs\sync.cjs:1183:40)
at parse (C:\Work\kuma-hackathon-ishikawa-2025\backend\node_modules\csv-parse\dist\cjs\sync.cjs:1775:24)
at C:\Work\kuma-hackathon-ishikawa-2025\backend\prediction.js:21:23
at Array.forEach (<anonymous>)
at loadSightingData (C:\Work\kuma-hackathon-ishikawa-2025\backend\prediction.js:17:13)
at Server.<anonymous> (C:\Work\kuma-hackathon-ishikawa-2025\backend\index.js:30:3)
at Server.f (C:\Work\kuma-hackathon-ishikawa-2025\backend\node_modules\once\once.js:25:25)
at Object.onceWrapper (node:events:638:28)
at Server.emit (node:events:536:35) {
code: 'CSV_RECORD_INCONSISTENT_COLUMNS',
bytes: 2911,
comment_lines: 0,
empty_lines: 0,せっかくなので、GeminiCLIに直してもらいます。
指示文は以下。
バックエンドを実行したらCSVの読み込みでInvalid Record Lengthというエラーが出たちゃんとCSVを読み込んでエラーの再現検証をしてくれました。すごい!

どうやらCSVのデータ形式が問題なようです。Gemini CLIに修正してもらいました。

そのあともGemini CLIとやり取りを繰り返し、CSVファイルの修正、エンコードや読み込みオプションの追加などを行いました。
最終的にバックエンドサーバーが起動することを確認しました。

④実行結果
実行すると、クリック位置によって結果は変わることは確認できました。
街中では出現回数0回。

山のほうをクリックすると出現回数変わりました!

確かに3回出てそう……?4回出てる気もする…データ足りてない可能性ありますね。

おまけ:ログ出力機能追加
出現回数の信ぴょう性が分かりにくかったので、ログ機能を追加してみました。
コンソールでヒットした目撃情報を出力する仕様を追加しました。これは自分で作ってしまった…

このあたりも画面に出した方が分かりやすいのかな?それは今後の課題にします。
⑤地図データとマッピング→あってないことが判明
先ほどの地図のデータとマッピングしてみる。
日付と場所が一致したのは以下のデータです。

さきほど予測した結果とあってないことが判明。
そして他の2件はどこのデータ拾ってきているか分からなかったです。
入力データが悪いのか
判定ロジックが悪いのか
もう少し検証が必要そうです…
まとめ
今回はクマ出現データをバックエンドのロジックに組み込んで、ユーザーがクリックした位置のクマ出現回数を表示するロジックを追加しました。
導通はできたものの正しく表示できているかは再検証が必要です。
また、最終的には出現予測にしたいので、ここからどうロジックを変えていくかも課題です。
課題だらけですが少しずつ頑張ります。
最後までお読みいただきありがとうございました。
