Newer
Older
TIASDataHub / docs / 04_SPEC / SPEC_03_データセットと受け渡し.md

データセットと受け渡し (Datasets & Delivery)

データセットの定義・版の作成・バンドル(manifest +ファイル)の書き出し・計算サーバへの受け渡し・CLI・出力の規則を定める.表の定義は SPEC_02.

データセットの定義 (Dataset Definition)

datasets/<名前>.toml に置く(リポジトリで管理し,PR で変更する).

name = "tongue_color"
description = "舌色 5 分類+程度(TIASJudgeModel の学習データ)"

[select]
asset_kind = "tongue_crop_masked"      # 集めるファイルの種類
require = ["tongue_color"]             # この所見を持つものだけ(撮影に付いた所見を含む)

[columns]                              # manifest に出す所見の列
tongue_color = ["label", "severity"]
  • 条件は「ファイルの種類」と「必須の所見」から始め,必要になったら所見の値による絞り込み等を足す
  • 1 つのファイル・撮影に同じ種類の有効な所見(訂正されていないもの)が 2 つ以上ある場合は,版の作成を止める(どちらを使うかを黙って決めない)

版の作成 (Creating a Version)

tiasdata dataset freeze <名前> で,その時点の目録に定義を当てはめて新しい版を作る.

  1. 定義を検証し,条件に合うファイルと採用する所見を集める
  2. 直前の版と構成(ファイルと所見)が同じなら,版を作らずにその旨を表示する
  3. 構成・定義の内容・本リポジトリのコミット・manifest.csv の SHA-256 を記録する(以後変更しない)
  • 本リポジトリに未コミットの変更がある状態では版を作らない(定義とコードの版を記録できなくなるため)
  • 行の順序は subject_id・capture_id・sha256 の順に並べる(同じ構成なら同じ manifest.csv になるようにする)
  • 未コミットの変更の確認は,目録を見る前に行う(git status --porcelain --untracked-files=all が空でなければ停止).hub_commit は git rev-parse HEAD
  • 構成の比較: 定義の全文が同じで,かつ採用したファイルと所見(所見の行の ID)の組が同じなら版を作らない.そのため,同じ値への訂正でも所見の行が変わるので新しい版になる(manifest の SHA-256 は直前の版と同じになる).定義は説明だけの変更でも新しい版になる
  • 条件に合うファイルが 0 件なら停止する.撮影にひも付かないファイルが入る場合も停止する(subject_id・capture_id を決められないため)
  • 所見の列は定義の [columns] に書いた順に並べる.値は文字列ならそのまま,無ければ空,それ以外は JSON の表記
  • 定義の description は必須.目録の datasets.description は最初の版のときの値のままにする(版ごとの定義の全文は dataset_versions.definition に残る)
  • 種類との照合(定義の種類・項目が kinds と値の型にあるか)は版を作るときだけ行う.過去の版の manifest の作り直しには使わない(種類の定義が後で変わっても作り直せるようにするため)
  • 版の備考(--note)は dataset show で表示する.備考に患者 ID 等の個人情報を書かない

バンドル (Bundle)

データセットの 1 つの版を,計算サーバ・Python 以外のツールに渡す形にまとめたもの.

<名前>/v<版>/
├── dataset.json          # 名前・版・作成日時・hub_commit・件数・manifest.csv の SHA-256
├── manifest.csv          # 1 行 1 ファイル
├── SHA256SUMS            # files/ の照合用(sha256sum -c で検証できる形式)
└── files/<sha256>.<ext>  # ストアからのコピー

manifest.csv の列

列内容
pathバンドルのルートからの相対パス(files/<sha256>.<ext>.区切りは /)
sha256ファイルの SHA-256
kindファイルの種類
subject_id研究用の症例 ID(分割の単位にする)
capture_id撮影 ID
<所見>.<項目>定義の [columns] で指定した所見の値(例: tongue_color.label・tongue_color.severity)
  • 文字コードは UTF-8(BOM なし),改行は LF
  • 実際の患者 ID・元のファイル名は出さない

TIASJudgeModel との互換 (Compatibility)

TIASJudgeModel の manifest(image_path・patient_id・label・severity・note)は,次の対応で同じ情報を持つ.

TIASJudgeModel本基盤
image_pathpath
patient_idsubject_id
labeltongue_color.label
severitytongue_color.severity
  • TIASJudgeModel 側は tiasdata.load() でバンドルを読み,自分の manifest の形に変換して使う(変換は TIASJudgeModel 側の実装).基盤側は使う側ごとの形式を持たない
  • subject_id は患者単位である.TIASJudgeModel の現行の patient_id は画像 ID(「1 患者 1 枚」という誤った前提)のため,切り替えると分割が患者単位に変わり,交差検証の成績が変わりうる(同じ患者の画像が学習と評価に分かれなくなる)

計算サーバへの受け渡し (Delivery)

tiasdata deliver <名前> --version <版> --to <サーバ名> を研究室 PC で実行する(手元 PC からは ssh labpc 経由.データは手元 PC を通らない).

  1. バンドルを書き出す(bundles/<名前>/v<版>/.既にあれば中身を照合して使う)
  2. tar にまとめ,設定ファイルの鍵で scp する
  3. サーバで <root>/<名前>/v<版>/ に展開し,chmod -R u+rwX,go-rwx で自分だけに絞る(Windows で作った tar は tar --delay-directory-restore -xf で展開する.TIASJudgeModel の ENV_03 の実測)
  4. サーバで sha256sum -c SHA256SUMS を実行して照合する(サーバに tiasdata が無くても検証できる)
  5. tar ファイルを両側で削除し,deliveries に記録する
  • 受け渡し先に同じ版が既にあれば,照合だけ行って記録する(上書きしない)
  • 版は凍結されているため,一度渡した版の中身が変わることはない.新しいデータは新しい版として渡す

ライブラリの API (Library API)

import tiasdata

bundle = tiasdata.load("tongue_color", version=1)   # TIASDATA_BUNDLES/<名前>/v<版>/ を開く
bundle.verify()                                     # ハッシュを照合する(任意.時間がかかる)
for row in bundle.rows:                             # manifest の行(pydantic の型)
    row.path, row.subject_id, row.annotations["tongue_color"]["label"]
bundle.fingerprint                                  # {"name", "version", "manifest_sha256"}.実験記録に残す
  • load() は版の指定を必須にする
  • tiasdata.open_bundle(path) でパスを直接指定して開くこともできる(テスト・Python 以外との突き合わせ用)
  • 読み込み時に manifest.csv の SHA-256 が dataset.json と一致しなければ停止する

CLI (Commands)

研究室 PC で使う.パスは引数に取らず,名前で指定する(SPEC_01「設定ファイル」).

コマンド役割
tiasdata init設定ファイルに従って目録・ストアを作り,マイグレーションを適用する
tiasdata import <取り込み元>取り込み元を読み,ファイルをストアにコピーして症例・撮影・ファイル・所見・由来を登録する(取り込み元の形ごとに importer を用意する.最初は舌色の 9 フォルダ tongue_color_folders).保留リストの番号は飛ばし,件数を報告する
tiasdata dataset list / show <名前>データセットと版の一覧・件数.定義だけあって版の無いものは「版なし」,定義ファイルを消したものは「(定義ファイルなし)」.show は版ごとの件数・作成日時・hub_commit・manifest の SHA-256・備考
tiasdata dataset freeze <名前> [--note TEXT]新しい版を作る(作った版の番号と件数,または「構成・定義が同じなので版を作らなかった」)
tiasdata export <名前> --version <版>バンドルを bundles/ に書き出す
tiasdata deliver <名前> --version <版> --to <サーバ名>計算サーバへ渡す
tiasdata check点検: ストアのファイルのハッシュの照合,目録にあってストアに無いファイル・その逆,所見の参照切れ,凍結した版の構成の欠け,凍結した版の manifest の不一致(全版について記録した定義と構成から manifest を作り直し,記録した SHA-256 と照合する.ファイルの種類や撮影の症例が書き換えられた場合に見つかる),読み取り専用が外れたストアのファイル,書きかけの一時ファイル(.tmp-),ストアの想定外のファイル・フォルダ.件数だけを表示し,問題が 1 件以上なら終了コード 1.対応表は開かない
tiasdata stats症例数(撮影が 2 つ以上の症例数を含む)・撮影数,種類ごとのファイル数,訂正されていない所見の項目ごと・組み合わせごとの件数,訂正された所見の数.対応表は開かない
tiasdata backup目録を backups/catalog-<日時>.sqlite に複製する(SQLite のバックアップ API を使う)
  • 取り込みは何度実行しても同じ結果になるようにする(既に登録済みのファイルは飛ばす)
  • 登録・版の作成は 1 つのトランザクションで行い,途中で失敗したら目録・対応表に何も残さない(取り込みでは対応表を目録の接続に ATTACH して 1 つのトランザクションにする).ストアへのコピーはトランザクションの外なので,失敗時にコピー済みのファイルはストアに残る.これは次に取り込みが成功するまで check が「ストアにあって目録に無いファイル」として報告し,次の取り込みで再利用される
  • 取り込みは,書き込む前に取り込み元の構成・保留リスト・対応表・同じ中身の画像が複数の番号に無いかをすべて検証する
  • import の出力: 取り込み元の画像の件数,保留で飛ばした件数,対応表で使わない行の件数,登録済みで飛ばした件数,登録した件数(症例・撮影・ファイル・所見・由来),ストアにコピーした件数
  • --show-source-names(import)を付けたときだけ,問題のあったファイルの元の名前・番号と,対応表で使わない行の行番号を最大 20 件まで表示する.患者 ID はどの場合も表示しない
  • 取り込みはリポジトリの clone から実行する(保留リスト holds/ をパッケージの位置からリポジトリのルートを辿って読むため).openpyxl が要る(研究室 PC では uv sync --no-dev --extra import)
  • 問題を見つけたら黙って飛ばさず,件数と理由を表示して停止する(check・stats は止めずに件数を報告する)

保留リスト (Hold List)

取り込み元のデータに,基盤では正解を決められない問題(同じ写真の重複・患者 ID やラベルの食い違い等)があるとき,確かめられるまで取り込まずに保留にする.推測で片方を選んで版に固定しないため.

  • holds/<取り込み元の名前>.toml に置く(リポジトリで管理し,PR で変更する).患者 ID は書かない
  • 1 件ごとに number(取り込み元での番号)・reason(理由)・resolve(確かめる方法)・since(保留にした日)を書く
  • tiasdata import は保留の番号を飛ばし,保留の件数を報告する(黙って外さない).保留リストにあるのに取り込み元に無い番号は停止する(リストの誤りを見逃さないため)
  • 保留リストのファイルが無い取り込み元は停止する(設定で取り込み元の名前を誤ったときに保留が効かずに取り込まれるのを防ぐため.2026-10-06 のユーザー判断).保留が無い取り込み元には,空の保留リスト([[hold]] が 0 件)を PR で置く
  • 形の誤り(未知のキー・必須キーの欠落・番号が 1 未満・番号の重複・since が日付でない)は停止する
  • 確かめ終わったら行を消して取り込み直し,データセットの新しい版を作る.過去の版は変わらない
  • 最初の保留リストは holds/tiasjudgemodel.toml(舌色データセットの重複 5 組のうち 9 枚.PLAN_02「舌色データセットの重複 5 組の扱い」)

出力の規則 (Output Rules)

CLI の出力・ログ・エラーメッセージに出してよいもの・出さないもの.Claude が SSH 経由で CLI を実行し,その出力を読むことを前提にする.

出してよい出さない
件数・割合・サイズの合計実際の患者 ID・対応表の中身
研究用 ID(S…・C…)・SHA-256画像の画素値・画像そのもの
種類名・所見の値(舌色の slug 等)・版取り込み元のファイルの中身
設定ファイルで付けた名前(取り込み元・サーバ)—
  • 元のファイル名(source_name)は個人をたどれる情報を含まないが,既定では表示しない(エラーの特定に必要な場合だけ表示する)
  • 目録・ストア・対応表・取り込み元のパスは表示しない.例外として,「設定ファイルが見つからない」エラーでは設定ファイル自身のパスを表示する(データの場所ではなく,原因の特定に必要なため)
  • 設定ファイルの検証エラーは「キーの位置: 理由」だけを 1 行で示し,入力された値(パス等)は表示しない
  • 出力は常に UTF-8 で書き出す(Windows でパイプ・SSH 越しに cp932 で書き出されて手元で文字化けするのを防ぐため)