この記事の目次

海洋データで作った機械学習モデルが、テストでは高い精度を示したのに、次の調査ではうまく機能しないことがあります。原因としてよくあるのが、テストデータと実質的に同じ、あるいは強く関連する情報が学習側に入り込み、実際の運用では得られない手がかりをモデルが使ってしまう「データリーク」です。

海洋・水産のデータは、もともとリークが起きやすい性質を持っています。たとえば、動画の連続したフレームは互いによく似ており、同じArgoフロートが取得したプロファイルも空間的・時間的につながっています。また、同じカメラで撮った画像は照明、撮影高度、背景が似通っているうえ、隣り合う格子点も互いに独立したデータとは言えません。

データを1件ずつランダムに振り分けると、こうしたつながりは考慮されません。この記事では、モデルを実際にどう使うのかという科学的な目的から逆算して、評価用データの分け方を説明します。

データリークとは何か

データリークとは、学習用と評価用を分けた境界を越えて、本来使うべきでない情報がモデル開発に利用されることです。分割方法だけでなく、特徴量の作り方、前処理、ラベル、テスト結果を見ながら繰り返す調整からも生じます。

次の二つに分けると理解しやすくなります。

  • 直接的なリーク:同じ測定値、同じ切り出し画像、重複ファイル、正解から逆算した特徴量が、学習側と評価側の両方に入る。
  • 依存関係によるリーク:別々のファイルではあるが内容が近すぎて、テストデータが「未知のデータへの対応力」を測れていない。同じ動画の隣接フレームが典型例。

海洋分野で見落としやすいのは後者です。プログラムとしては正しくランダム分割できていても、本来評価したかったものとは別の性能を測っていることがあります。

海洋データが互いに関連しやすい理由

水中画像

ROVや曳航カメラは連続した映像を記録します。隣り合うフレームには同じ生物や海底面が写り、色かぶりや機体の影もほとんど変わりません。1秒ごとにフレームを切り出してランダムに分けると、ほとんど同じ画像が学習側とテスト側の両方に入りかねません。

プランクトン・顕微鏡画像

同じ採水ボトル、同じ曳網、同じプレート、同じ測定回、同じ前処理バッチから得た画像は、取得条件がそろっています。モデルが生物そのものではなく、そのバッチ特有の背景を覚えてしまうことがあります。

音響調査

近接するピングや測線は、船、機器、気象、水塊の条件がほぼ同じです。区間をランダムに割り振ると、その航海に固有の特徴が評価側へ漏れることがあります。

プロファイル・格子化海洋データ

一つのArgoフロートが繰り返すサイクルは、連続する水塊をたどる軌跡上に並びます。近接する格子点や日時のあいだには自己相関があります。データを1件ずつランダムに抜き出して評価すると、未知の海域や将来の時点での性能ではなく、すでに観測した条件のあいだを内挿する能力を測ることになりかねません。

地点ごとの値を地図上に予測する研究では、空間的な依存性を無視した通常のランダム交差検証が、性能を過大に見せることがあると報告されています。どの程度偏るかはデータと目的によって変わります。地理的なまとまり単位で分ける方法(空間ブロック分割)は決まり事として使うのではなく、評価地点間の距離を実際の利用場面に合わせるために使います。詳しくは、ランダム交差検証と空間交差検証を分析したNature Communications論文を参照してください。

評価したい利用条件に合わせて分割する

関連するデータを混在させるランダム分割、ミッションや地点を分けるグループ分割、間隔を空けて後半を評価する時間分割の比較図

3種類の分割で測れる性能は、それぞれ異なります。

分割グループの例評価できること
個別データのランダム分割互いに独立した個体同じ母集団と取得工程から得た別のデータに対応できるか
グループ単位のホールドアウト地点、航海、測線、潜航、フロート、動画、曳網、バッチ同じ種類の未知のグループへ汎化できるか
時間順のホールドアウト前半を学習、後半をテスト将来の観測データへ汎化できるか

ランダム分割が常に誤りというわけではありません。個々のデータが十分に独立していて、運用時も同じ取得工程からデータが得られるなら適した方法です。重要なのは、分割方法をむやみに複雑にすることではなく、個々のデータを独立とみなせる根拠を示すことです。

まず「何が未知なのか」を定義する

コードを書く前に、次の文の空欄を埋めます。

このモデルは、学習データに含まれていない ______ に対して使う。

空欄には、たとえば次のようなものが入ります。

  • 同じ固定カメラの、より後のフレーム
  • 同じカメラ装置を使った新しい潜航
  • 新しいサンゴ礁地点
  • 将来の季節
  • 新しい船舶や機器
  • 学習に含まれないフロートや海域

この空欄に入るものが、そのままグループの単位になります。たとえば「新しい潜航」であれば、一回の潜航で撮った全フレームを学習側かテスト側のどちらかにまとめます。一方、「新しい地点」を未知とする場合は、同じ地点で撮った別の動画が境界をまたいでしまうため、動画単位のグループでは不十分です。

未知とみなす条件が二つになることもあります。たとえば、最終テストで将来の期間と未知の地点を同時に取り分ける設計です。評価は厳しくなり、独立したグループの数も減りますが、それだけ広い適用範囲を裏づけられます。

インデックスの配列で済ませず、分割マニフェストを残す

分割結果は、バージョン管理すべき研究記録です。1件につき1行で、次のような項目を残します。

sample_id, source_id, site_id, deployment_id, observed_at, label_version, split

識別子はデータセットごとに変わりますが、重要な性質は共通しています。

  • データIDが途中で変わらない
  • 分割単位に使ったグループがすべて明示されている
  • 同じ一連の実験では、分割を一度だけ生成している
  • 分離したはずのグループが境界を越えていないことを、コードで検証している
  • マニフェストをレビューし、コミットまたは学習・評価の実行結果と一緒に保存している

こうしておけば、後からリークの有無を検証できます。同じ乱数シードを指定した二つの学習スクリプトが、別々の「テストデータ」を作ってしまう事故も防げます。

研究コードの変更履歴と再現性を残す方法:Git・GitHub入門では、Gitだけで大容量データまで管理できるわけではないことを前提に、コードと小さなメタデータファイルを記録する方法を説明しています。

グループ分割を実装する

scikit-learnのGroupKFoldは、各分割で同じグループが学習側とテスト側の両方に現れないようにします。海洋画像なら、潜航をグループの単位にできます。

from sklearn.model_selection import GroupKFold

splitter = GroupKFold(n_splits=5)

for train_index, validation_index in splitter.split(
    samples,
    labels,
    groups=dive_ids,
):
    train_model(samples[train_index], labels[train_index])
    evaluate(samples[validation_index], labels[validation_index])

書き方そのものは難しくありません。重要なのは、dive_idsが目的に合ったグループ単位を表しているかどうかです。同じ地点で何度も潜航していて、新しい地点での利用を想定するなら、地点IDか、地点と期間を組み合わせたグループを使います。

クラスが偏っている場合は、分割の前にグループごとのクラス数を確認します。希少クラスが一つの地点にしか存在しないなら、未知地点でのテストと、そのクラスの信頼できる評価は両立しません。これはデータの収集範囲の限界であって、同じ地点を学習側とテスト側の両方へ入れてよい理由にはなりません。

時間分割を実装する

将来時点の予測や運用を想定するなら、時刻順に並べて最後の期間を取り分けます。scikit-learnのTimeSeriesSplitは時間の順序を保ったまま分割し、学習とテストのあいだにgapを設けられます。

境界の前後のデータが強く関連しているときは、このgapが効きます。ただし、gapだけでは季節性や、長く続くグループの重なりまでは解消できません。同じフロート、同じ地点、同じ個体が両側に残ることもあるため、時間の規則とグループの規則を専用の分割マニフェストで組み合わせる必要が出てきます。

スコアが最も良くなる日付を、結果を見てから選ぶことは避けます。区切る日付は、想定する運用場面か、事前に決めた実験計画から決めます。

空間ブロックの大きさを根拠から決める

空間で分ける場合は、地理格子、緩衝域を設けた区域、調査地点、調査海域全体といった単位でテスト側に取り分けます。ブロックの大きさは、次のような点をもとに決めます。

  • 1回の観測がカバーする範囲と、位置の不確かさ
  • 想定される空間自己相関の距離
  • 実運用で対象になる地点どうしの距離
  • 独立したグループがいくつあり、どのように分布しているか
  • 結論として主張したい空間スケール

何キロメートルが正しいという一律の基準はありません。根拠を説明できるブロックサイズをいくつか試し、結果がどう変わるかを確かめます。そのうえで、使ったブロックサイズを明記し、実際に評価した距離を越える範囲まで性能を主張しないようにします。

漂流するフロートやブイでは、緯度経度の単純な格子で区切ると、一本の軌跡が意味のない位置で分断されることがあります。観測機器、ミッション、期間、海域、またはそれらの組み合わせを単位にした方が、実際の使い方に近いこともあります。

分割後にもリークは起こる

分割マニフェストを適切に作っても、その後の処理が自動的に安全になるわけではありません。

前処理は学習データだけで決める

正規化に使う統計量、欠損補間、特徴選択、次元削減、学習によって決める色補正は、学習データだけから計算します。そこで決まったパラメータを、そのまま検証データとテストデータへ適用します。

データ拡張やパッチ切り出しより先に分ける

切り出し、回転、重なりのあるタイルを先に作って、その派生ファイルを分割するのは避けます。元画像か取得グループの単位で先に分け、データ拡張は学習側の中だけで行います。

最終分割の前に重複を探す

完全に同じファイルは、ハッシュ値で見つけられます。リサイズや再圧縮を経た画像、ほとんど同じフレームは、見た目の特徴を数値化する知覚ハッシュ(perceptual hash)や、モデルが出力する特徴ベクトル(埋め込み表現)で候補を絞れますが、最終的な判断は人が行います。

正解情報を特徴量へ入れない

調査のあとで確定した種名コード、レビュアーの判定、ラベルをそのまま含むファイル名は、正解そのものを漏らします。画像データだけでなく、メタデータとファイルパスも点検します。

最終テストで調整しない

テストの成績を何度も見ながらモデルを変えると、テストデータは実質的に検証データになります。手法が決まるまで、最終テスト用のデータには手を触れません。

適切な単位で結果を報告する

10回の潜航から得た数千枚のフレームは、数千回分の独立した運用テストではありません。画像単位の指標だけでなく、潜航などの意味のあるグループ間でどれだけばらついたかも報告します。

次の情報も報告します。

  • 学習・検証・テストそれぞれに含まれる地点・航海・潜航・動画・フロートの数
  • 日付と空間の範囲
  • グループごとのクラス数
  • グループ分けと緩衝域の正確な規則
  • 全体を集約した指標と、グループごとの分布または信頼区間
  • 濁り、深度、カメラの種類など、重要な条件ごとの性能
  • その分割では評価していないこと

既知の地点で行った未知の潜航で評価したモデルを、「未知の海域で検証済み」と説明してはいけません。

アノテーション時の判断がリークに影響する

リーク対策は、モデルを学習させる前から始まっています。アノテーションのプロジェクトには、元画像、動画、潜航、地点、取得条件のメタデータを残しておきます。画像とマスクだけを書き出すと、後で必要になるグループの情報が失われます。

海洋画像をAIの学習データにする:Label StudioとSAMで始めるアノテーションでは、ラベルとセグメンテーションマスクの作成方法を説明しています。プロジェクトが大きくなる前に、途中で変わらない取得IDを付けておきます。後からファイル名だけで復元しようとしても、正確には戻せません。

評価結果を見直すためのチェックリスト

海洋データの機械学習で得た評価結果を採用する前に、次の点を確認します。どれも唯一の正しい手順というわけではなく、自分の目的に対して分割が妥当かを見直すための観点です。当てはまらない項目があれば、なぜ不要なのかを説明できるようにしておきます。

  • 何を未知とみなすかを1文で書いている
  • 分割前に元の取得グループが分かっている
  • 近似重複や派生した切り出し画像が境界を越えていない
  • 学習専用の変換を、検証・テストデータを使わずに決めている
  • モデル選択前に最終テストを固定している
  • グループ、空間、期間の範囲を報告している
  • 潜航など、意味のある独立グループごとに指標をまとめている
  • 結論を、その分割で評価できた範囲に限定している

自分たちのプロジェクトで分割の設計や検証を進めるのが難しい場合は、下の問い合わせ導線から、評価設計の支援についてもご相談いただけます。

お問い合わせ

構築・実装支援とアノテーション業務

環境構築や設計・実装の支援、アノテーション業務の委託について、ご相談いただけます。

お問い合わせフォームへ

よくある質問

80/20のランダム分割は必ずリークになりますか?

いいえ。運用時と同じ条件で得られた、互いに独立したデータであれば適切です。危険なのは、繰り返し撮影されたデータ、近接したデータ、同じグループに属するデータを独立とみなす場合です。

地点と調査のどちらで分けるべきですか?

運用時に未知となる方の単位で分けます。どちらも未知になるなら、両方を取り分けるテストを設計するか、実際に評価した条件はそれより狭いと明記します。

交差検証があれば最終テストは不要ですか?

グループ交差検証は、手法の選択と不確かさの把握に役立ちます。ただし、繰り返しの判断に影響されない最終的な推定値が必要なら、別に固定したテストデータを用意する意味があります。

グループ数が少ない場合はどうしますか?

まず制約として報告します。グループを考慮した再標本化は慎重に使い、評価目的に必要であればデータの収集範囲を広げます。1件ずつランダムに振り分けても、独立したデータが増えるわけではありません。

参考資料と次に読む記事