<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>AI &gt; データ設計の再考 on M1KE BL0G</title><link>https://www.m1ke.org/categories/ai_rethink/</link><description>Recent content in AI &gt; データ設計の再考 on M1KE BL0G</description><generator>Hugo -- gohugo.io</generator><language>ja-jp</language><copyright>mike</copyright><atom:link href="https://www.m1ke.org/categories/ai_rethink/index.xml" rel="self" type="application/rss+xml"/><item><title>機械学習におけるデータセットの分割の再考</title><link>https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BB%E3%83%83%E3%83%88%E3%81%AE%E5%88%86%E5%89%B2%E3%81%AE%E5%86%8D%E8%80%83/</link><pubDate>Sat, 05 Sep 2026 12:00:00 +0900</pubDate><guid>https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BB%E3%83%83%E3%83%88%E3%81%AE%E5%88%86%E5%89%B2%E3%81%AE%E5%86%8D%E8%80%83/</guid><description>&lt;img src="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BB%E3%83%83%E3%83%88%E3%81%AE%E5%88%86%E5%89%B2%E3%81%AE%E5%86%8D%E8%80%83/split.jpg" alt="Featured image of post 機械学習におけるデータセットの分割の再考" /&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;機械学習では、データをTrain・Validation・Testの3つに分けるのが定石とされている&lt;/li&gt;
&lt;li&gt;Trainでモデルを学習し、ValidationでハイパーパラメータやEarly Stoppingを決め、最後にTestで未知データに対する性能を測るという構造&lt;/li&gt;
&lt;li&gt;しかし実際にシステムを開発していると、この3分割だけでは説明できない問題にぶつかることがある&lt;/li&gt;
&lt;li&gt;特に「Testで失敗している理由を知りたいが、Testを見て改善した瞬間、そのTestはもはやTestではなくなる」という問題がある&lt;/li&gt;
&lt;li&gt;ここでは、Train・Val・Testという古典的な3分割に、Diagを加えたメインsplitと、Challengeのようなサブsplitを加えて整理する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="メインsplitとサブsplit"&gt;メインsplitとサブsplit&lt;/h2&gt;
&lt;p&gt;splitには2つの種類があると整理できる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;メインsplit: Train・Val・Diag・Test。いずれも「何らかの分布を代表する」ことが目的で、共通のデータプールからのholdout・stratified split、または独立したソースからのサンプリングという形で作られる。スコープや汎化性能そのものを定義・推定するためのsplit&lt;/li&gt;
&lt;li&gt;サブsplit: Challengeのように、診断・分析という前段のステップを経て、事後的に目的を絞って作るsplit。メインsplitと違い、分布を代表する必要がない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;まとめると、以下のようになる。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dataset / Split&lt;/th&gt;
&lt;th&gt;主目的&lt;/th&gt;
&lt;th style="text-align: right"&gt;開発者が見るか&lt;/th&gt;
&lt;th&gt;分布の代表性&lt;/th&gt;
&lt;th&gt;分類&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Train&lt;/td&gt;
&lt;td&gt;Parameter Learning&lt;/td&gt;
&lt;td style="text-align: right"&gt;Yes&lt;/td&gt;
&lt;td&gt;必要&lt;/td&gt;
&lt;td&gt;メイン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Val&lt;/td&gt;
&lt;td&gt;Model Selection&lt;/td&gt;
&lt;td style="text-align: right"&gt;Yes&lt;/td&gt;
&lt;td&gt;必要&lt;/td&gt;
&lt;td&gt;メイン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diag&lt;/td&gt;
&lt;td&gt;Error Analysis&lt;/td&gt;
&lt;td style="text-align: right"&gt;Yes&lt;/td&gt;
&lt;td&gt;必要&lt;/td&gt;
&lt;td&gt;メイン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test&lt;/td&gt;
&lt;td&gt;Final Generalization Estimate&lt;/td&gt;
&lt;td style="text-align: right"&gt;No&lt;/td&gt;
&lt;td&gt;必要&lt;/td&gt;
&lt;td&gt;メイン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Challenge&lt;/td&gt;
&lt;td&gt;Failure-mode / Capability Evaluation&lt;/td&gt;
&lt;td style="text-align: right"&gt;Yes&lt;/td&gt;
&lt;td&gt;不要&lt;/td&gt;
&lt;td&gt;サブ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;処方箋split&lt;/td&gt;
&lt;td&gt;弱点の直接修正&lt;/td&gt;
&lt;td style="text-align: right"&gt;Yes&lt;/td&gt;
&lt;td&gt;不要&lt;/td&gt;
&lt;td&gt;サブ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;err split&lt;/td&gt;
&lt;td&gt;エラーの回帰テスト&lt;/td&gt;
&lt;td style="text-align: right"&gt;Yes&lt;/td&gt;
&lt;td&gt;不要&lt;/td&gt;
&lt;td&gt;サブ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;重要なのは「データを機械的に何分割せよ」という数の話ではなく、それぞれの役割・分類を分離すること&lt;/li&gt;
&lt;li&gt;サブsplitはChallenge以外にも2種類ある&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="処方箋split"&gt;処方箋split&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Diagやエラーアナリシスで見つかった特定の弱点（hard case・OOD・クラス境界の混同など）を、直接修正するために作るデータ&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E3%83%A9%E3%83%99%E3%83%AB%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるクラスとラベルの再考&lt;/a&gt;のhard case mining手法（shifted positive・adversarial negatives・Truncated Negative・Hidden Negativeなど）や、境界専用データセットの作り方がそのまま使える&lt;/li&gt;
&lt;li&gt;作った処方箋splitはTrainに戻し、次のTrain・Val・Diagサイクルで効果を確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="err-split"&gt;err split&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;エラーアナリシスで見つかった実際のエラー事例そのものを、固定化して保存しておくデータ&lt;/li&gt;
&lt;li&gt;同じ間違いが再発していないかを継続的に確認する回帰テストとして使う&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E5%93%81%E8%B3%AAqa%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータ品質QAの再考&lt;/a&gt;で触れた「過去に見つかったデータバグを回帰テストとして固定化する」という考え方と同じ&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="trainvalの役割"&gt;Train・Valの役割&lt;/h2&gt;
&lt;h3 id="train学習データセット"&gt;Train（学習データセット）&lt;/h3&gt;
&lt;p&gt;モデルのパラメータを学習するためのデータ。以下の式で表される、学習データ上での損失を最小化するパラメータ$\theta^*$を求めるために使う。&lt;/p&gt;
$$
\theta^* = \arg\min_\theta \hat{R}_{\text{train}}(\theta)
$$&lt;h3 id="validation検証データセット"&gt;Validation（検証データセット）&lt;/h3&gt;
&lt;p&gt;モデルそのものではなく、学習方法を選択するためのデータ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Learning Rate&lt;/li&gt;
&lt;li&gt;モデルサイズ&lt;/li&gt;
&lt;li&gt;正則化係数&lt;/li&gt;
&lt;li&gt;Data Augmentation&lt;/li&gt;
&lt;li&gt;Early Stopping&lt;/li&gt;
&lt;li&gt;モデルアーキテクチャ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらを選ぶために使う。つまりValidationも、広い意味では学習プロセスの一部といえる。&lt;/p&gt;
&lt;h3 id="train-valの違い"&gt;train, valの違い&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;train data：重み更新に使う&lt;/li&gt;
&lt;li&gt;validation data：学習中のモデル選択、early stopping、ハイパーパラメータ調整に使う&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="train分布と本番分布が違うという問題"&gt;Train分布と本番分布が違うという問題&lt;/h2&gt;
&lt;p&gt;古典的なTrain・Val・Testの説明には、以下のような暗黙の仮定がある。&lt;/p&gt;
$$
P_{\text{train}} \approx P_{\text{val}} \approx P_{\text{test}} \approx P_{\text{deployment}}
$$&lt;p&gt;しかし、実運用ではこの仮定は頻繁に崩れる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TrainはWeb画像だが、本番はスマートフォン画像&lt;/li&gt;
&lt;li&gt;Trainは過去のユーザーだが、本番は将来のユーザー&lt;/li&gt;
&lt;li&gt;Trainはある病院のデータだが、本番は別の病院&lt;/li&gt;
&lt;li&gt;Trainはある国のデータだが、本番は別地域&lt;/li&gt;
&lt;li&gt;Train時とDeployment時で商品の構成が変わる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;WILDSベンチマークは、病院・撮影場所・時間・地域など、実世界で自然に発生するDistribution Shiftによって、In-distribution性能とOut-of-distribution性能の間に大きな差が生じることを示している。つまり、以下の不等式で表される状況は例外ではなく、実世界ではかなり普通に起きる。&lt;/p&gt;
$$
P_{\text{source}} \neq P_{\text{target}}
$$&lt;h2 id="diagの役割"&gt;Diagの役割&lt;/h2&gt;
&lt;p&gt;ここで自然な解決策として、Source側だけでなくTarget側も分割するという発想が出てくる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Source側: Train、Val&lt;/li&gt;
&lt;li&gt;Target側: Diag、Test&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;という構造になる。DiagはTarget distributionを理解するためのデータで、開発者が見てよい。サンプルを直接確認し、以下のような分析をする。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Failure Mode&lt;/li&gt;
&lt;li&gt;Slice別性能&lt;/li&gt;
&lt;li&gt;分布差&lt;/li&gt;
&lt;li&gt;ラベル問題&lt;/li&gt;
&lt;li&gt;Spurious Correlation&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Diagから得られた知見は、Trainへ戻して改善に使う。&lt;/p&gt;
&lt;p&gt;Diagで特に重要なのは、意図的にOODなサンプルも含めておくこと。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Trainがカバーしようとしているスコープ内のサンプルだけでなく、そのスコープの外（OOD）にあたるサンプルもDiagに混ぜておく&lt;/li&gt;
&lt;li&gt;こうすることで、単に「今のスコープ内でどれだけ性能が出ているか」だけでなく、「スコープの境界がどこにあり、境界を越えるとどう性能が崩れるか」を観察できる&lt;/li&gt;
&lt;li&gt;つまりDiagは、Target distributionの理解に加えて、スコープの境界そのものに対する試験という役割も持つ&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="valとdiagの違い"&gt;ValとDiagの違い&lt;/h3&gt;
&lt;p&gt;一見するとValとDiagは同じものに見え、実際に多くの文献ではValidation Setと開発用データセットがほぼ同義語として使われる。ここではあえて分離して考える。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Val: どのモデルを選ぶかを決めるためのデータ&lt;/li&gt;
&lt;li&gt;Diag: なぜ本番で失敗するのかを理解するためのデータ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例えば、Val AccuracyでModel Aが91.2%、Model Bが92.1%ならModel Bを選ぶ。これがModel Selection。一方Diagでは、「Model Bは平均では良いが、夜間画像ではModel Aより悪い」といった分析をする。これがError Analysis。つまり、ValとDiagは役割が異なる。&lt;/p&gt;
&lt;h3 id="diagだけでも足りない理由"&gt;Diagだけでも足りない理由&lt;/h3&gt;
&lt;p&gt;平均的なDiag performanceだけでは、モデルが持っている重要な弱点を発見できないことがある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;例えば自動運転モデルで、全体のAccuracyが99.5%だったとする&lt;/li&gt;
&lt;li&gt;夜間・豪雨・逆光・工事現場・子どもの飛び出しといった状況だけで極端に性能が低ければ、実運用では重大な問題になる&lt;/li&gt;
&lt;li&gt;しかし、これらが通常データの0.1%しか存在しなければ、平均Accuracyではほとんど見えない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そこで必要になるのがChallenge Set。&lt;/p&gt;
&lt;h2 id="testの役割"&gt;Testの役割&lt;/h2&gt;
&lt;p&gt;Target distributionから採取するが、最後までBlindにするデータ。最終的に、「Diagを見ながら作った開発プロセスが、別のTargetサンプルにもGeneralizeしたか」を確認する。つまり、Train→Val→Diag→Error Analysis→Trainという改善ループと、Model→Blind Testという最終評価を分離する構造になる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Testを見て意思決定してはいけないという原則が重要&lt;/li&gt;
&lt;li&gt;Testを見ながらモデルを改善すると、モデルの重みを直接学習していなくても、開発者自身がTestに適応してしまう&lt;/li&gt;
&lt;li&gt;結果として、Testへの「開発プロセス全体の過学習」が起きる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="testのパラドックス"&gt;Testのパラドックス&lt;/h3&gt;
&lt;p&gt;例えば、最終Testで性能が大きく低下したとする。Val Accuracyが94%なのに、Test Accuracyが72%だったとすると、開発者は当然「なぜ22ポイントも落ちたのか」を知りたくなる。そこでTestデータを見ると、以下のようなことが分かる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;暗い画像で失敗している&lt;/li&gt;
&lt;li&gt;特定の端末だけ性能が低い&lt;/li&gt;
&lt;li&gt;特定カテゴリのRecallが悪い&lt;/li&gt;
&lt;li&gt;Trainに存在しない背景が多い&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これがError Analysis。この分析結果を元に、暗所画像をTrainに追加する、Augmentationを変更する、ラベル設計を変更する、モデル構造を変更する、といった改善を行う。&lt;/p&gt;
&lt;p&gt;しかし、この瞬間に問題が起きる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Testから得られた情報でモデルを改善した以上、そのTestはもう完全なBlind Testではない&lt;/li&gt;
&lt;li&gt;形式的にモデルパラメータへTestを入力していなくても、Test→人間→モデル設計という情報経路が成立している&lt;/li&gt;
&lt;li&gt;つまりTestは、実質的に開発用データセットになってしまう&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="なぜ問題なのか-条件付き確率になってしまう"&gt;なぜ問題なのか: 条件付き確率になってしまう&lt;/h3&gt;
&lt;p&gt;この問題を、もう少し形式的に表すと分かりやすい。本来知りたいのは、モデル$f$のデプロイ分布上での汎化性能である。&lt;/p&gt;
$$
R_{\text{true}}(f) = \mathbb{E}_{(x,y)\sim P_{\text{deployment}}}\left[\ell(f(x), y)\right]
$$&lt;p&gt;Testでの性能$\hat{R}_{\text{test}}(f)$がこの$R_{\text{true}}(f)$の妥当な推定値になるのは、$f$が$D_{\text{test}}$と独立している場合に限る。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ところが、Testを覗いて開発プロセス（モデル構造・データ・ハイパーパラメータなど）を調整すると、$f$は$D_{\text{test}}$の関数になってしまう&lt;/li&gt;
&lt;li&gt;このとき実際に測っているのは、以下のような、その特定の$D_{\text{test}}$に条件付けられた量になる&lt;/li&gt;
&lt;/ul&gt;
$$
\mathbb{E}\left[\ell(f(D_{\text{test}})(x), y) \mid (x,y) \in D_{\text{test}}\right]
$$&lt;ul&gt;
&lt;li&gt;これは、知りたかった無条件の汎化性能$R_{\text{true}}(f)$とは別物で、その一回限りのTestサンプルに対して有利になるよう調整された、条件付きの当てはまりの良さに過ぎない&lt;/li&gt;
&lt;li&gt;カンニングが問題なのは、倫理的な話である以上に、推定量として何を測っているかが変わってしまうという統計的な理由による&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="testも多角的に評価する"&gt;Testも多角的に評価する&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Testは一度きり・Blindという性質上、1回の測定・1つの指標に全てを委ねるのはリスクが高い&lt;/li&gt;
&lt;li&gt;単一のTestセット・単一のしきい値・単一の指標だけで「汎化した」と判断すると、そのTestセットの偏りやしきい値の選び方自体が結論を左右してしまう&lt;/li&gt;
&lt;li&gt;そのため、Testそのものも複数の観点から評価するべき
&lt;ul&gt;
&lt;li&gt;複数種類のTestセットを用意する（外部データソース由来・grade別など）。&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E3%83%A9%E3%83%99%E3%83%AB%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるクラスとラベルの再考&lt;/a&gt;の「holdoutだけに頼らない」を参照&lt;/li&gt;
&lt;li&gt;複数のしきい値・複数の指標（ROC-AUCとPR-AUCなど）で評価する。&lt;a class="link" href="https://www.m1ke.org/p/%E5%88%86%E5%B8%83%E5%A4%96%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%90%AB%E3%82%80%E5%88%86%E9%A1%9E%E3%81%A7false-positive%E3%82%92%E6%8A%91%E3%81%88%E3%82%8B%E6%96%B9%E6%B3%95/" &gt;分布外データの対処方法&lt;/a&gt;の評価セクションを参照&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ここでの「複数」は、Testを何度も覗いて調整するという意味ではない点に注意。あらかじめ複数のTest・複数の評価軸を用意しておき、それぞれ一度だけBlindに測定するという話であり、Testのパラドックスとは矛盾しない&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="challengeの役割"&gt;Challengeの役割&lt;/h2&gt;
&lt;p&gt;Challenge Setは、通常のTestとは目的が違う。Testは、以下のようにdeployment分布を代表することを目指す。&lt;/p&gt;
$$
P_{\text{test}} \approx P_{\text{deployment}}
$$&lt;p&gt;一方Challengeは、必ずしもDeployment distributionを代表しなくてよい。むしろ意図的に難しいケースを集める。目的が違うため、以下のように分布が一致していなくても構わない。&lt;/p&gt;
$$
P_{\text{challenge}} \neq P_{\text{deployment}}
$$&lt;p&gt;Challengeの目的は、平均性能を推定することではなく、特定の能力・弱点を診断すること。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ImageNet-Aのような研究はこの発想の典型例&lt;/li&gt;
&lt;li&gt;通常のImageNetとは異なり、既存モデルが失敗しやすい自然画像を意図的に集めることで、平均的なテストセットでは見えにくいモデルの弱点を明らかにする&lt;/li&gt;
&lt;li&gt;Challengeは1つである必要もなく、Failure Modeごとに複数持ってもよい
&lt;ul&gt;
&lt;li&gt;Challenge（低照度）&lt;/li&gt;
&lt;li&gt;Challenge（レアクラス）&lt;/li&gt;
&lt;li&gt;Challenge（OOD）&lt;/li&gt;
&lt;li&gt;Challenge（ロングテール）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="challengeとdiagの違い"&gt;ChallengeとDiagの違い&lt;/h3&gt;
&lt;p&gt;Diagは、Target distributionをなるべく代表する。一方Challengeは、意図的に分布を歪める。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;例えば本番データで、通常画像98%・夜間1%・豪雨0.5%・逆光0.5%だったとする&lt;/li&gt;
&lt;li&gt;Diagではこの比率をある程度維持する&lt;/li&gt;
&lt;li&gt;しかしChallengeでは、夜間33%・豪雨33%・逆光34%のように歪めてもよい&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;なぜならChallengeはPopulation Performanceではなく、Capabilityを測っているため。&lt;/p&gt;
&lt;h2 id="sourceとtargetによる分類"&gt;SourceとTargetによる分類&lt;/h2&gt;
&lt;p&gt;以下のような定義になる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Train・Val:
&lt;ul&gt;
&lt;li&gt;Source distributionからサンプリング&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Diag・Test:
&lt;ul&gt;
&lt;li&gt;Target distributionからサンプリング（Diagは見てよい、Testは見てはいけない）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Challenge:
&lt;ul&gt;
&lt;li&gt;Target（デプロイ環境）に関連するが、意図的に分布を歪めて集める&lt;/li&gt;
&lt;li&gt;「独立」というより「Target寄りだが非代表的」という位置づけ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="本質はinformation-boundary"&gt;本質はInformation Boundary&lt;/h2&gt;
&lt;p&gt;ここで一番重要なのは、Train・Val・Diag・Challenge・Testという名前ではない。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本質は、どの評価情報を開発プロセスへフィードバックしてよいのかというInformation Boundary&lt;/li&gt;
&lt;li&gt;モデル開発は、Data-&amp;gt;Metric-&amp;gt;Human-&amp;gt;Decision-&amp;gt;Modelというループで進む&lt;/li&gt;
&lt;li&gt;そのため、「モデルのWeight Optimizerに渡していないからTest leakageではない」とは限らない&lt;/li&gt;
&lt;li&gt;人間がTest結果を見てArchitectureを変更すれば、それも立派な情報伝達になる&lt;/li&gt;
&lt;li&gt;したがって評価セットは、まず開発に利用してよいデータと、開発から完全に隔離するデータに分ける必要がある&lt;/li&gt;
&lt;li&gt;その上で開発側を、Parameter Learning・Model Selection・Error Analysisに分けると、メインsplitであるTrain・Val・Diagが生まれる&lt;/li&gt;
&lt;li&gt;さらにCapability Analysisのように事後的に目的を絞る分析からは、サブsplitであるChallengeが生まれる&lt;/li&gt;
&lt;li&gt;最後にBlind Testを置く、という構造になる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="既存研究との関係"&gt;既存研究との関係&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ここで整理したメインsplit・サブsplitという構造そのものが、機械学習の標準規格として確立されているわけではなかった&lt;/li&gt;
&lt;li&gt;むしろ、既存研究で別々に議論されてきた問題を、1つの開発フローとして整理したものと考える方が正確&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;先行研究のTopics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;分布シフト（WILDS）
&lt;ul&gt;
&lt;li&gt;Koh et al.のWILDSは、現実世界ではTraining distributionとDeploymentに近いTest distributionが異なることを明示的に扱っている&lt;/li&gt;
&lt;li&gt;病院、地域、時刻、カメラなどによる実世界のDistribution Shiftをベンチマーク化しており、Source/Targetを分けて考える必要性を示している&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Target performanceの推定（Mandoline）
&lt;ul&gt;
&lt;li&gt;Chen et al.のMandolineは、SourceとTargetの分布差を、実務者が定義したSliceを利用してTarget上の性能推定に利用する&lt;/li&gt;
&lt;li&gt;「Target distributionを単一のAccuracyだけではなく、その構造を見ながら評価する」という、Diag的な発想に近い&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;分布シフトに対するStress Test
&lt;ul&gt;
&lt;li&gt;Subbaswamy et al.は、単一の評価分布で平均性能を見るだけでなく、分布を変化させた際のモデルのRobustness・Stabilityを評価する枠組みを提案している&lt;/li&gt;
&lt;li&gt;Challenge SetやStress Testingの考え方と接続する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Challenge Set（ImageNet-A）
&lt;ul&gt;
&lt;li&gt;Hendrycks et al.のImageNet-Aは、既存モデルが失敗しやすい自然画像を意図的に集めることで、通常のTest Accuracyでは見えにくい弱点を評価した、Challenge evaluationの分かりやすい例&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Testから学習してしまう問題
&lt;ul&gt;
&lt;li&gt;Hernández-Orallo et al.は、AI evaluationを単一のAggregate Metricに潰すことの問題を指摘している&lt;/li&gt;
&lt;li&gt;つまり、SystemとProblemの組み合わせに対するより詳細な評価情報を利用する考え方を議論している&lt;/li&gt;
&lt;li&gt;タイトル自体が「Training on the Test Set」であり、評価データからどこまで情報を抽出してよいかという問題を正面から扱っている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;サンプルが持つ属性（クラス・Positive/Negativeなど）をどう区分・管理するかについては、&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E3%83%A9%E3%83%99%E3%83%AB%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるクラスとラベルの再考&lt;/a&gt;で詳しく扱っている。&lt;/p&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;機械学習ではTrain・Val・Testの3分割が基本とされているが、実運用では学習分布と本番分布が一致しないことが珍しくない&lt;/li&gt;
&lt;li&gt;Testで性能が低下した理由を知るにはTarget側のデータを観察する必要があるが、Testを観察して改善に利用すると、そのTestはもはや完全なTestではなくなる&lt;/li&gt;
&lt;li&gt;Train・Val・Diag・Testは分布を代表するメインsplitであり、Challenge・処方箋split・err splitは診断や分析を経て事後的に作るサブsplitであり、分布を代表する必要がない
&lt;ul&gt;
&lt;li&gt;Train: モデルを学習する（メイン）&lt;/li&gt;
&lt;li&gt;Val: モデルを選択する（メイン）&lt;/li&gt;
&lt;li&gt;Diag: 本番分布での失敗を理解する診断データセット（メイン）&lt;/li&gt;
&lt;li&gt;Test: 最後までBlindにして最終性能を測る（メイン）&lt;/li&gt;
&lt;li&gt;Challenge: 重要なFailure Modeを集中的に診断する（サブ）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Source側からTrainとVal、TargetからTest、それと独立したDiagとChallenge&lt;/li&gt;
&lt;li&gt;スコープという軸で見ると、Trainはスコープ内、Diagはスコープ内外の境界、Testはスコープを問わない未知のサンプルという整理もできる&lt;/li&gt;
&lt;li&gt;Testを覗いて開発プロセスを調整すると、測っている量が無条件の汎化性能から、その特定のTestサンプルに条件付けられた量にすり替わってしまう&lt;/li&gt;
&lt;li&gt;単一のTest・単一の指標に頼るとその偏りに結論が左右されるため、あらかじめ複数のTest・複数の評価軸を用意し、それぞれ一度だけBlindに測定するのがよい&lt;/li&gt;
&lt;li&gt;これはデータ分割のテクニックというより、機械学習開発における情報の流れを設計する問題&lt;/li&gt;
&lt;li&gt;本当に守りたいのは、モデル改善に使った情報と最終評価に使う情報を分離すること&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://proceedings.mlr.press/v139/koh21a.html" target="_blank" rel="noopener"
&gt;WILDS: A Benchmark of in-the-Wild Distribution Shifts&lt;/a&gt;（Koh et al., ICML 2021）&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://proceedings.mlr.press/v139/chen21i.html" target="_blank" rel="noopener"
&gt;Mandoline: Model Evaluation under Distribution Shift&lt;/a&gt;（Chen et al., ICML 2021）&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://proceedings.mlr.press/v130/subbaswamy21a.html" target="_blank" rel="noopener"
&gt;Evaluating Model Robustness and Stability to Dataset Shift&lt;/a&gt;（Subbaswamy et al., AISTATS 2021）&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://arxiv.org/abs/1907.07174" target="_blank" rel="noopener"
&gt;Natural Adversarial Examples&lt;/a&gt;（Hendrycks et al., CVPR 2021, ImageNet-A）&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://doi.org/10.1609/aaai.v36i11.21487" target="_blank" rel="noopener"
&gt;Training on the Test Set: Mapping the System-Problem Space in AI&lt;/a&gt;（Hernández-Orallo et al., AAAI 2022）&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://proceedings.mlr.press/v119/miller20a.html" target="_blank" rel="noopener"
&gt;The Effect of Natural Distribution Shift on Question Answering Models&lt;/a&gt;（Miller et al., ICML 2020）&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>機械学習におけるデータとデータソースの再考</title><link>https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E5%86%8D%E8%80%83/</link><pubDate>Sat, 05 Sep 2026 12:00:00 +0900</pubDate><guid>https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E5%86%8D%E8%80%83/</guid><description>&lt;img src="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E5%86%8D%E8%80%83/dataset.jpg" alt="Featured image of post 機械学習におけるデータとデータソースの再考" /&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BB%E3%83%83%E3%83%88%E3%81%AE%E5%88%86%E5%89%B2%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータセットの分割の再考&lt;/a&gt;で、Train・Val・Diag・Testというメインsplitと、Challengeのようなサブsplitにデータを整理した&lt;/li&gt;
&lt;li&gt;今回は、それぞれのsplitを担うデータを実際にどう作るか、という作成方法の観点から再整理する&lt;/li&gt;
&lt;li&gt;特に、どれを自動生成してよく、どれを手動で作るべきか、そしてその理由を明確にする&lt;/li&gt;
&lt;li&gt;ここではデータそのもの（データソース・収集方法・品質）を扱う。タクソノミー・クラス設計・ラベルの信頼度といった、ラベル・クラス側の設計は&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E3%83%A9%E3%83%99%E3%83%AB%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるクラスとラベルの再考&lt;/a&gt;で扱う&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="前回のおさらい-メインsplitとサブsplit"&gt;前回のおさらい: メインsplitとサブsplit&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dataset / Split&lt;/th&gt;
&lt;th&gt;主目的&lt;/th&gt;
&lt;th style="text-align: right"&gt;開発者が見るか&lt;/th&gt;
&lt;th&gt;分類&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Train&lt;/td&gt;
&lt;td&gt;Parameter Learning&lt;/td&gt;
&lt;td style="text-align: right"&gt;Yes&lt;/td&gt;
&lt;td&gt;メイン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Val&lt;/td&gt;
&lt;td&gt;Model Selection&lt;/td&gt;
&lt;td style="text-align: right"&gt;Yes&lt;/td&gt;
&lt;td&gt;メイン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diag&lt;/td&gt;
&lt;td&gt;Error Analysis&lt;/td&gt;
&lt;td style="text-align: right"&gt;Yes&lt;/td&gt;
&lt;td&gt;メイン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test&lt;/td&gt;
&lt;td&gt;Final Generalization Estimate&lt;/td&gt;
&lt;td style="text-align: right"&gt;No&lt;/td&gt;
&lt;td&gt;メイン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Challenge&lt;/td&gt;
&lt;td&gt;Failure-mode / Capability Evaluation&lt;/td&gt;
&lt;td style="text-align: right"&gt;Yes&lt;/td&gt;
&lt;td&gt;サブ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="trainvalの作り方"&gt;Train・Valの作り方&lt;/h2&gt;
&lt;h3 id="自動生成してよい"&gt;自動生成してよい&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Trainは自動生成（合成データ生成など）で作ってよい&lt;/li&gt;
&lt;li&gt;Trainは「モデルに学習させたい範囲＝スコープ」を定義するデータであり、生成プロセス自体がそのままスコープの定義になる&lt;/li&gt;
&lt;li&gt;生成プロセスをコントロールできるからこそ、狙った分布・狙ったカバレッジのデータを効率よく用意できる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="データソースの多様性"&gt;データソースの多様性&lt;/h3&gt;
&lt;p&gt;「自動生成」といっても、その元になるデータをどこから集めるかには、いくつか毛色の異なるアプローチがある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;辞書などの硬いデータソース: 辞書・法令・規格表のような、構造が明確で信頼性の高いデータソース。カバレッジや多様性には限界があるが、ラベルの正確さは高い&lt;/li&gt;
&lt;li&gt;関連するデータソース（間接的な転用）: 本来別の目的で作られたデータが、副産物として目的のラベル・構造を含んでいることがある。本来の作成目的とは別の切り口でデータを転用する発想&lt;/li&gt;
&lt;li&gt;ネットからのキュレーション: Web上の大量のテキスト・画像などから、パターンマッチングやフィルタリングで目的のデータを抽出する。スケールは出しやすい一方、ノイズが多く、前述のデータクレンジングが特に重要になる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらは互いに独立したソースになりやすいという利点もある。複数のアプローチでTrainを集めておくと、データの多様性が増すだけでなく、前述の「トレイン系と診断系で元データソースを分ける」という要求にも応えやすくなる。&lt;/p&gt;
&lt;p&gt;具体的な収集アイデアの実例は、&lt;a class="link" href="https://www.m1ke.org/p/g2p%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%82%92%E4%BD%9C%E3%82%8B%E6%99%82%E3%81%AB%E8%AA%BF%E6%9F%BB%E3%81%97%E3%81%9F%E5%85%88%E8%A1%8C%E6%96%87%E7%8C%AE%E3%81%AA%E3%81%A9%E3%81%AE%E3%83%A1%E3%83%A2/" &gt;G2Pライブラリを作る時に調査した先行文献などのメモ&lt;/a&gt;のデータ収集のアイデアで詳しくまとめている。&lt;/p&gt;
&lt;h3 id="収集時の実践"&gt;収集時の実践&lt;/h3&gt;
&lt;p&gt;データを集める段階そのものにも、気をつけるべき実践がいくつかある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PositiveだけでなくNegativeも意図して集める: Negativeの収集を疎かにすると、実運用でどんな入力が来るか分からないままモデルを評価することになる。特にhard negativeやOODになりうる入力は、Positiveと同じくらい丁寧に設計して集めるべき
&lt;ul&gt;
&lt;li&gt;Positiveがa・b・cという特徴を持っていて本当はaだけを学習させたい場合、b・cは持つがaは持たないNegativeがないと、モデルが間違った特徴を学習してしまう（例: 音声からある単語を学習させたかったのに、Negativeが不足していたため単語ではなく話者の喋り方を学習してしまった、というケース）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;中間データも保存する: 最終的に使う加工済みデータだけでなく、加工前の中間データも保存しておく。後から加工方法自体を見直したくなった時に、収集からやり直さずに済む&lt;/li&gt;
&lt;li&gt;ダブルチェックをする: ラベル付けや収集作業は、1人だけでなく複数人でダブルチェックする。特にAIやクラウドソーシングで生成・収集したデータは、人の目でのダブルチェックが必須&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ホールドアウトでtrainvalに分ける"&gt;ホールドアウトでTrain/Valに分ける&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;生成したデータプールを、ホールドアウトでTrainとValに分割する&lt;/li&gt;
&lt;li&gt;つまりTrainとValは、どちらも同じ生成プロセスに由来する「スコープ内（in-scope）」のデータという位置づけになる&lt;/li&gt;
&lt;li&gt;Valはモデル選択に使うため、Trainと同じ分布から取れていれば十分で、独立性の要求はDiag・Testほど厳しくない&lt;/li&gt;
&lt;li&gt;分割の際は、元データのクラス比率（経験的な事前確率$P(Y)$）をなるべく維持したstratified splitで行う&lt;/li&gt;
&lt;li&gt;例えば元データがA:70%, B:20%, C:10%なら、Train/Val/Testもそれぞれ概ね70/20/10になるように分割する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="diagの作り方"&gt;Diagの作り方&lt;/h2&gt;
&lt;h3 id="自動生成を避け手動で作る"&gt;自動生成を避け、手動で作る&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Diagは基本的に自動生成を避け、人手で作ることが望ましい&lt;/li&gt;
&lt;li&gt;理由は、統計的な優位性（有意性）を主張するために、サンプルの独立性が必要だから&lt;/li&gt;
&lt;li&gt;Trainと同じ生成プロセス（同じモデル・同じテンプレート・同じ乱数源など）でDiagも自動生成すると、TrainとDiagのサンプルが統計的に独立でなくなる&lt;/li&gt;
&lt;li&gt;独立性が崩れると、Diagで良い結果が出たとしても、それが本当の汎化性能なのか、単に生成プロセスの癖への過学習を反映しているだけなのかを区別できなくなる&lt;/li&gt;
&lt;li&gt;少ないサンプルサイズでも意味のある信頼区間を持たせるには、まずサンプル同士の独立性という前提を満たしておく必要がある&lt;/li&gt;
&lt;/ul&gt;
$$
\hat{p} = \frac{x}{n}
$$&lt;ul&gt;
&lt;li&gt;上記のような単純な比率推定であっても、信頼区間の妥当性は$n$個のサンプルが独立であることを前提にしている&lt;/li&gt;
&lt;li&gt;独立性が崩れていると、見かけの$n$より実質的な情報量は少なく、信頼区間は実態より狭く（楽観的に）出てしまう&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="スコープ内スコープ外oodを含める"&gt;スコープ内・スコープ外・OODを含める&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Diagには、in-scopeのデータだけでなく、out-of-scopeのデータ、そしてOOD（Out-of-Distribution）のデータも意図的に含める&lt;/li&gt;
&lt;li&gt;理由は、モデルの能力の幅を測れるようにするため&lt;/li&gt;
&lt;li&gt;in-scopeのデータだけでは「スコープ内でどれだけうまくいっているか」しか分からず、スコープの境界がどこにあり、境界を越えるとどう崩れるかが見えない&lt;/li&gt;
&lt;li&gt;スコープ内・スコープ外・OODを横断的に含めることで、Diag1つで「境界の内側の性能」と「境界そのものの位置」の両方を診断できる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="testの作り方"&gt;Testの作り方&lt;/h2&gt;
&lt;h3 id="外部データソースをなるべく使う"&gt;外部データソースをなるべく使う&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;評価データセット（Test）は、基本的に外部のデータソースをなるべく利用する&lt;/li&gt;
&lt;li&gt;理由は、自分でデータを生成すると、事前確率（prior）が変わってしまうから&lt;/li&gt;
&lt;li&gt;自分の生成プロセスには、無意識のうちにクラス比率・パターンの偏りが入り込みやすく、その偏った事前確率のもとで測った性能は、現実の事前確率のもとでの性能とズレる&lt;/li&gt;
&lt;li&gt;外部のデータソースを使うことで、こうした自己言及的な偏りを避け、より現実の事前確率に近い状態で評価できる&lt;/li&gt;
&lt;li&gt;さらに一歩進めて、自前データを一切混ぜず、出来合いの公開データセットのみ100%でテストセットを作るという手もある。生成過程が完全に独立したデータで評価できるため、自前データの収集過程に共通する癖への過学習を検知しやすくなる
&lt;ul&gt;
&lt;li&gt;これは精度を追求する本番用ではなく、あくまで評価のための物差しとして使う位置づけ&lt;/li&gt;
&lt;li&gt;他人の作ったデータセットや手法を再現しようとすると、特徴量の計算方法など自分では気づかなかった変えられる点が色々見つかるため、学びや改善幅も大きい&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="エラーアナリシス禁止"&gt;エラーアナリシス禁止&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;評価データセットに対するエラーアナリシスは禁止&lt;/li&gt;
&lt;li&gt;集計されたスコア以外の目的で、中身を見ること自体も禁止&lt;/li&gt;
&lt;li&gt;これは前回の記事で扱った「Testを覗いた瞬間、測っている量が無条件の汎化性能から、そのTestに条件付けられた量にすり替わる」という問題への対策そのもの&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="データソースの分離"&gt;データソースの分離&lt;/h2&gt;
&lt;h3 id="トレイン系と診断系は元データソースを分ける"&gt;トレイン系と診断系は元データソースを分ける&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;データセットを作る際、元となる生データソース自体を、トレインデータ系（Train・Val）と診断データセット（Diag）とで必ず分ける&lt;/li&gt;
&lt;li&gt;同じ生データプールからランダムに分割するだけでは、独立性の担保として不十分になりうる&lt;/li&gt;
&lt;li&gt;完全に別のデータソース（別の収集経路、別の収集時期、別の生成方法など）を用意することで、より確実な独立性を担保する&lt;/li&gt;
&lt;li&gt;Testについても同様に、Train・Valはもちろん、Diagとも別のソースであることが望ましい&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="データの量"&gt;データの量&lt;/h2&gt;
&lt;h3 id="サンプル数そのものが必要"&gt;サンプル数そのものが必要&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;seedを固定して実験がべき等に実行でき、2回同じ実験をして全く同じ結果が返ってきたとしても、サンプルサイズは別問題として必要&lt;/li&gt;
&lt;li&gt;サンプル数が極端に少ないと、実験の比較としては再現できても、実際にはドメインシフトが起きている可能性を検知できない&lt;/li&gt;
&lt;li&gt;評価データは結局は注ぎ足し継ぎ足しで増やしていくものなので、最終的には数そのものが重要になる&lt;/li&gt;
&lt;li&gt;経験則として、1クラスあたりのサンプルサイズが50以下のholdoutでは、統計的に優位な数値が出ないことが多い&lt;/li&gt;
&lt;li&gt;学習時にべき等であっても、評価時にべき等とは限らないため、評価方法自体にも注意が必要&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="相対的な量にも注意する"&gt;相対的な量にも注意する&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;クラス間の相対的なサンプル量にも注意が必要&lt;/li&gt;
&lt;li&gt;例えば、AクラスとBクラスがある評価データで、Bクラスのデータ（holdoutも含む）だけを増やすと、全体の指標がBクラス過多の影響を受けてしまう&lt;/li&gt;
&lt;li&gt;ミクロ指標（全体の精度）はBクラスに引っ張られ、平等な精度の指標ではなくなる&lt;/li&gt;
&lt;li&gt;Aクラスは相対的に量が少なくなり、学習側の注力もBクラスに大きく振られている可能性が出てくる&lt;/li&gt;
&lt;li&gt;つまり、もともと学習できていたAクラスの特徴を、モデル容量不足のために上書きしてしまっている可能性がある&lt;/li&gt;
&lt;li&gt;この場合、モグラたたき的にデータを直すのではなく、モデル容量の不足自体を疑うべき&lt;/li&gt;
&lt;li&gt;データ量を増やす際は、モデルのパラメータも合わせて増やす必要がないかを検討する&lt;/li&gt;
&lt;li&gt;精度を報告する際も、1教科で90点なのか10教科で90点なのかで意味が全く違うように、分母（サンプルサイズ・クラス数）を必ず加味する&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="学習曲線分析でデータ量を判断する"&gt;学習曲線分析でデータ量を判断する&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;「データを増やすべきか、それともモデルを変えるべきか」を判断する古典的な手法として、学習曲線分析（Learning Curve Analysis）がある&lt;/li&gt;
&lt;li&gt;横軸に訓練データのサンプル数、縦軸にTrain誤差とVal誤差を取り、サンプル数を段階的に増やしながらそれぞれを記録してプロットする&lt;/li&gt;
&lt;li&gt;曲線の形から、次の2パターンを見分けられる
&lt;ul&gt;
&lt;li&gt;Train誤差・Val誤差がどちらも高く、両者が近い値に収束している場合: High Bias（underfitting）。データを増やしても誤差はほとんど下がらないため、データ収集よりモデルの表現力を上げる方が効く&lt;/li&gt;
&lt;li&gt;Train誤差は低いがVal誤差が高く、両者に大きな差がある場合: High Variance（overfitting）。この場合はデータを増やす、または正則化を強めることで差が縮まりやすい&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;つまり、データを追加する前に、まず小規模なサンプルサイズでこの学習曲線を描き、追加データが本当に効くパターンかどうかを確認しておくと、無駄なデータ収集を避けられる&lt;/li&gt;
&lt;li&gt;これは前述の「相対的な量にも注意する」で触れた、モデル容量の不足を疑うべきケース（High Bias側）と、単純にデータが足りないケース（High Variance側）を、事前に切り分けるための手法とも言える&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="データ品質qa"&gt;データ品質QA&lt;/h2&gt;
&lt;p&gt;ここまでの役割分担・独立性の設計を正しく行っても、データそのものにバグがあれば意味がない。何よりも大切なのは、データの品質QAである。最小構成でのミニテスト、バグの発見方法、パイプラインのテスト、重複除去などは、&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E5%93%81%E8%B3%AAqa%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータ品質QAの再考&lt;/a&gt;で独立して扱う。&lt;/p&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Train・Valは自動生成でよく、同じ生成プロセスからstratified splitでホールドアウトして分割する、スコープ内のデータ&lt;/li&gt;
&lt;li&gt;データソースには、辞書などの硬いデータソース・関連するデータソースの転用・ネットからのキュレーションという毛色の異なるアプローチがあり、複数使うことで多様性とソース分離の両方に貢献する&lt;/li&gt;
&lt;li&gt;Diagは自動生成を避け、独立性を保つために手動で作る。さらにin-scope・out-of-scope・OODを横断的に含めることで、能力の境界そのものを診断できるようにする&lt;/li&gt;
&lt;li&gt;Testはなるべく外部データソースを使い、事前確率のズレを避ける。エラーアナリシスや中身の閲覧は禁止&lt;/li&gt;
&lt;li&gt;元データソース自体を、トレイン系と診断系で分けておくことが、統計的な独立性を担保する土台になる&lt;/li&gt;
&lt;li&gt;サンプル数は絶対量（1クラスあたり最低限の目安）と相対量（クラス間バランス）の両方に注意し、精度を報告する際は分母を必ず加味する&lt;/li&gt;
&lt;li&gt;データを増やす前に、小規模サンプルで学習曲線分析（Train/Val誤差 vs サンプル数）を描き、High Bias（モデルを変えるべき）かHigh Variance（データを増やすべき）かを切り分けるとよい&lt;/li&gt;
&lt;li&gt;役割分担・独立性を正しく設計しても、データ自体にバグがあれば意味が無い。品質QAの具体的な方法は&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E5%93%81%E8%B3%AAqa%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータ品質QAの再考&lt;/a&gt;で扱う&lt;/li&gt;
&lt;li&gt;タクソノミー・クラス設計・Grade・ラベルの信頼度（Gold/Silver）といった、ラベル・クラス側の設計は&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E3%83%A9%E3%83%99%E3%83%AB%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるクラスとラベルの再考&lt;/a&gt;で扱う&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BB%E3%83%83%E3%83%88%E3%81%AE%E5%88%86%E5%89%B2%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータセットの分割の再考&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E3%83%A9%E3%83%99%E3%83%AB%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるクラスとラベルの再考&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E5%93%81%E8%B3%AAqa%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータ品質QAの再考&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/g2p%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%82%92%E4%BD%9C%E3%82%8B%E6%99%82%E3%81%AB%E8%AA%BF%E6%9F%BB%E3%81%97%E3%81%9F%E5%85%88%E8%A1%8C%E6%96%87%E7%8C%AE%E3%81%AA%E3%81%A9%E3%81%AE%E3%83%A1%E3%83%A2/" &gt;G2Pライブラリを作る時に調査した先行文献などのメモ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E5%88%86%E5%B8%83%E5%A4%96%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%90%AB%E3%82%80%E5%88%86%E9%A1%9E%E3%81%A7false-positive%E3%82%92%E6%8A%91%E3%81%88%E3%82%8B%E6%96%B9%E6%B3%95/" &gt;分布外データの対処方法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.geeksforgeeks.org/machine-learning/top-machine-learning-dataset-find-open-datasets/" target="_blank" rel="noopener"
&gt;Top Machine Learning Dataset: Find Open Datasets - GeeksforGeeks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>機械学習におけるデータ品質QAの再考</title><link>https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E5%93%81%E8%B3%AAqa%E3%81%AE%E5%86%8D%E8%80%83/</link><pubDate>Sat, 05 Sep 2026 12:00:00 +0900</pubDate><guid>https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E5%93%81%E8%B3%AAqa%E3%81%AE%E5%86%8D%E8%80%83/</guid><description>&lt;img src="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E5%93%81%E8%B3%AAqa%E3%81%AE%E5%86%8D%E8%80%83/data.png" alt="Featured image of post 機械学習におけるデータ品質QAの再考" /&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータとデータソースの再考&lt;/a&gt;でTrain・Val・Diag・Testの役割分担や独立性の設計を扱ったが、その設計を正しく行っても、データそのものにバグがあれば意味がない&lt;/li&gt;
&lt;li&gt;データ品質QAはそれ単体で1つのテーマとして扱うだけの重みがあるため、この記事として独立させる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="データ品質の6つの次元"&gt;データ品質の6つの次元&lt;/h2&gt;
&lt;p&gt;DMBOK2（データマネジメント知識体系第2版）では、データ品質を以下の6つの独立した次元で評価する。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;次元&lt;/th&gt;
&lt;th&gt;英語&lt;/th&gt;
&lt;th&gt;定義&lt;/th&gt;
&lt;th&gt;チェック例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;正確性&lt;/td&gt;
&lt;td&gt;Accuracy&lt;/td&gt;
&lt;td&gt;データが現実の実体や事実を正しく表しているか&lt;/td&gt;
&lt;td&gt;住所が実際の郵便番号・都道府県と一致しているか&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;完全性&lt;/td&gt;
&lt;td&gt;Completeness&lt;/td&gt;
&lt;td&gt;必要なデータが欠損なく揃っているか&lt;/td&gt;
&lt;td&gt;顧客レコードの必須項目（氏名・メール・電話）が空欄でないか&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;一貫性&lt;/td&gt;
&lt;td&gt;Consistency&lt;/td&gt;
&lt;td&gt;複数のデータソース間・同一テーブル内で矛盾がないか&lt;/td&gt;
&lt;td&gt;CRMと基幹システムで同一顧客の名称表記が一致しているか&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;適時性&lt;/td&gt;
&lt;td&gt;Timeliness&lt;/td&gt;
&lt;td&gt;データが必要なタイミングで最新の状態にあるか&lt;/td&gt;
&lt;td&gt;在庫数が当日の出荷・入荷を反映しているか&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;有効性&lt;/td&gt;
&lt;td&gt;Validity&lt;/td&gt;
&lt;td&gt;データが定義されたドメイン・フォーマット・ルールに従っているか&lt;/td&gt;
&lt;td&gt;メールアドレスが「@」を含む正規形式であるか&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;一意性&lt;/td&gt;
&lt;td&gt;Uniqueness&lt;/td&gt;
&lt;td&gt;重複したレコードが存在しないか&lt;/td&gt;
&lt;td&gt;同一顧客が2件登録されていないか&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;正確性と有効性は紛らわしいが、問うている対象が違う。正確性は「現実との一致」、有効性は「定義（フォーマット・ルール）との一致」を問う&lt;/li&gt;
&lt;li&gt;例えば、存在しない郵便番号を入力した場合、フォーマットとしては正しい（有効性はOK）が、現実の郵便番号ではない（正確性はNG）、という食い違いが起こりうる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="品質管理の4フェーズ"&gt;品質管理の4フェーズ&lt;/h2&gt;
&lt;p&gt;品質問題への対応は、プロファイリング→検出・分類→修正→検証という4つのフェーズで回す。&lt;/p&gt;
&lt;h3 id="フェーズ1-プロファイリング"&gt;フェーズ1: プロファイリング&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;現状把握として、データの統計分析を行う&lt;/li&gt;
&lt;li&gt;列プロファイリング（データ型・NULL率の確認）、パターン分析、関係プロファイリング、重複分析などを行い、データ品質の現状レポートを作る&lt;/li&gt;
&lt;li&gt;本記事の&lt;a class="link" href="#%e3%83%87%e3%83%bc%e3%82%bf%e3%83%93%e3%83%a5%e3%82%a2%e3%83%bc%e3%82%92%e4%bd%9c%e3%82%8b" &gt;データビュアーを作る&lt;/a&gt;・&lt;a class="link" href="#%e3%81%9d%e3%82%82%e3%81%9d%e3%82%82%e3%83%87%e3%83%bc%e3%82%bf%e3%82%bb%e3%83%83%e3%83%88%e3%81%ae%e7%a2%ba%e8%aa%8d%e3%82%92%e5%85%88%e3%81%ab%e3%81%99%e3%82%8b" &gt;そもそもデータセットの確認を先にする&lt;/a&gt;が、このフェーズに相当する&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="フェーズ2-検出分類"&gt;フェーズ2: 検出・分類&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;プロファイリング結果をもとに、品質問題を上記の6次元で分類する&lt;/li&gt;
&lt;li&gt;各問題の影響度（ビジネス・モデル性能への影響）と件数を掛け合わせて、対応の優先度を決定する&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;品質問題の種類&lt;/th&gt;
&lt;th&gt;対応する次元&lt;/th&gt;
&lt;th&gt;例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;欠損値・NULL&lt;/td&gt;
&lt;td&gt;完全性&lt;/td&gt;
&lt;td&gt;必須の電話番号が空欄&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;形式エラー&lt;/td&gt;
&lt;td&gt;有効性&lt;/td&gt;
&lt;td&gt;「2026/13/01」のような不正日付&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;範囲逸脱&lt;/td&gt;
&lt;td&gt;有効性・正確性&lt;/td&gt;
&lt;td&gt;年齢が「-5」や「200」&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;重複レコード&lt;/td&gt;
&lt;td&gt;一意性&lt;/td&gt;
&lt;td&gt;同一顧客が2件登録されている&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;システム間の不整合&lt;/td&gt;
&lt;td&gt;一貫性&lt;/td&gt;
&lt;td&gt;CRMと請求システムで住所が異なる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;更新遅延&lt;/td&gt;
&lt;td&gt;適時性&lt;/td&gt;
&lt;td&gt;退職者情報がシステムに残存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;現実との乖離&lt;/td&gt;
&lt;td&gt;正確性&lt;/td&gt;
&lt;td&gt;引越し後も旧住所のまま&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;本記事の&lt;a class="link" href="#%e3%83%87%e3%83%bc%e3%82%bf%e3%81%ae%e3%83%90%e3%82%b0%e3%82%92%e7%99%ba%e8%a6%8b%e3%81%99%e3%82%8b%e3%81%9f%e3%82%81%e3%81%ae%e3%82%b3%e3%83%bc%e3%83%89" &gt;データのバグを発見するためのコード&lt;/a&gt;・&lt;a class="link" href="#%e6%97%a2%e7%9f%a5%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3%e3%81%af%e3%83%95%e3%82%a3%e3%83%ab%e3%82%bf%e3%83%bc%e6%9c%aa%e7%9f%a5%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3%e3%81%af%e3%83%a9%e3%83%b3%e3%83%80%e3%83%a0%e3%82%b5%e3%83%b3%e3%83%97%e3%83%aa%e3%83%b3%e3%82%b0" &gt;既知パターンはフィルター、未知パターンはランダムサンプリング&lt;/a&gt;が、このフェーズに相当する&lt;/li&gt;
&lt;li&gt;内部矛盾スキャン（&lt;code&gt;find_label_conflicts&lt;/code&gt;）は一貫性、重複除去は一意性、スキーマ検証は有効性の検出に対応する&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="フェーズ3-修正"&gt;フェーズ3: 修正&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;欠損値補完、形式標準化、重複レコードの名寄せ、参照データとの照合、削除などを行う&lt;/li&gt;
&lt;li&gt;修正前のバックアップ取得は必須。一括訂正は効率が良い一方、本来正しかったケースまで巻き込んで壊すリスクがあるため、修正範囲は慎重に見極める&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="フェーズ4-検証"&gt;フェーズ4: 検証&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;修正後、品質基準を達成しているかを再チェックする&lt;/li&gt;
&lt;li&gt;一度きりの検証で終わらせず、継続的なモニタリングパイプラインを構築するのが理想&lt;/li&gt;
&lt;li&gt;本記事の&lt;a class="link" href="#%e3%83%87%e3%83%bc%e3%82%bf%e3%83%91%e3%82%a4%e3%83%97%e3%83%a9%e3%82%a4%e3%83%b3%e3%81%ae%e3%83%86%e3%82%b9%e3%83%88%e3%82%b3%e3%83%bc%e3%83%89" &gt;データパイプラインのテストコード&lt;/a&gt;の回帰テスト・盲検サンプリングとWilson信頼区間による定期監視が、このフェーズに相当する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="品質チェックの基本動作"&gt;品質チェックの基本動作&lt;/h2&gt;
&lt;h3 id="最小構成でのミニテスト"&gt;最小構成でのミニテスト&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;数百万パターンにもなるような大きな予測対象を扱う場合、いきなり全件で学習・評価するのではなく、まず1件だけを使ってデータ生成・学習・テストを一通り試すのも有効&lt;/li&gt;
&lt;li&gt;パイプライン全体（データ生成→学習→推論）を最小構成で一度通してみて、勘所を掴むのが目的&lt;/li&gt;
&lt;li&gt;1件だけの学習すら成功しない（lossが下がりきらない）なら、パターン数を増やす前にやり方自体を疑うべき&lt;/li&gt;
&lt;li&gt;逆に1件で学習できるなら、そのまま件数を横展開していけばよい&lt;/li&gt;
&lt;li&gt;機械学習分野では一般に「overfit a single batch」と呼ばれる、学習パイプラインのsanity checkの定番手法&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="データビュアーを作る"&gt;データビュアーを作る&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;seedデータのデータビュアーは作っておくとよい&lt;/li&gt;
&lt;li&gt;大量データの品質チェックを高速化するのが目的で、データが多くなるほどチェックの負担が大きくなるため、ビュアーの有無で作業効率が大きく変わる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="そもそもデータセットの確認を先にする"&gt;そもそもデータセットの確認を先にする&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ゴミを入れたらゴミが出るだけなので、モデル改善の前にまずデータそのものをチェックするべき&lt;/li&gt;
&lt;li&gt;Trainデータが一部間違っていた結果、精度が出ていないだけという初歩的なミスもある&lt;/li&gt;
&lt;li&gt;そもそも分母のデータは正常か、評価のサンプルサイズは足りているか、エラーの例は妥当かをチェックしたうえで、モデルのパラメータを増やすなどの改善フローに入るべき&lt;/li&gt;
&lt;li&gt;特にAIによって生成されたデータは、確実にチェックが必要&lt;/li&gt;
&lt;li&gt;可視化した結果、現実的に高精度な分類が厳しいと分かることもある。その場合は、モデルを大きくする以外に、前提の制約自体を変えて境界線がはっきり出るように要件とデータセットを見直すという選択肢もある&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="バグの発見方法"&gt;バグの発見方法&lt;/h2&gt;
&lt;h3 id="データのバグを発見するためのコード"&gt;データのバグを発見するためのコード&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;内部矛盾スキャン: 同じ入力に対して異なるラベルが記録されているケースを機械的に全件抽出し、その組だけをレビューする。ランダムサンプリングよりずっと高い効率で誤りを見つけられる&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_label_conflicts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;seen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conflicts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conflicts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;label&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;conflicts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;スキーマ検証: 必須フィールドの欠落・型の不一致・値域の逸脱などを機械的にチェックする&lt;/li&gt;
&lt;li&gt;統計的な外れ値検出: 文字数・トークン数・クラス比率などの分布を可視化し、極端な外れ値を確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="既知パターンはフィルター未知パターンはランダムサンプリング"&gt;既知パターンはフィルター、未知パターンはランダムサンプリング&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;問題を発見する方法は、大きく2つに分かれる&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;既知パターン（過去に見つかったバグの型など） → フィルター・シグネチャスキャンで全件検出
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;未知パターン（まだ気づいていない種類の問題） → ランダムサンプリングで無作為に見つける
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;フィルターは、既に分かっている不具合の型に一致するものを漏れなく拾うのが得意だが、そもそも想定していないパターンの不具合は検出できない&lt;/li&gt;
&lt;li&gt;ランダムサンプリングは、未知のパターンに気づける可能性がある一方、件数を絞ると見逃しも多く、網羅性では劣る&lt;/li&gt;
&lt;li&gt;どちらか一方では不十分で、両方を役割分担として使い分ける必要がある。詳しくは&lt;a class="link" href="https://www.m1ke.org/p/%E3%83%95%E3%83%AA%E3%82%AC%E3%83%8A%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E3%82%AF%E3%83%AC%E3%83%B3%E3%82%B8%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B%E6%99%82%E3%81%AB%E7%9B%B4%E3%81%97%E3%81%9F%E9%A0%85%E7%9B%AE%E3%81%AE%E3%83%A1%E3%83%A2/" &gt;フリガナデータをクレンジングする時に直した項目のメモ&lt;/a&gt;でも扱っている&lt;/li&gt;
&lt;li&gt;ランダムサンプリングで見つかった未知パターンは、原因を特定した時点で「既知パターン」に変わる。そうなれば、次はフィルターの側に組み込み、以降は全件検出できるようにする&lt;/li&gt;
&lt;li&gt;つまり、ランダムサンプリングで見つけた不具合を、フィルターとして恒久化し、さらに後述のパイプラインの修正・回帰テストへ反映するというサイクルが、データ品質QAの基本的な回し方になる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="層化監査抽出stratified-audit-sampling"&gt;層化監査抽出（Stratified Audit Sampling）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;会計・監査分野で使われる統計手法で、母集団を層（strata）に分け、層ごとに個別のサンプル抽出・信頼区間の推定を行う&lt;/li&gt;
&lt;li&gt;これは、データ品質QAにも同じ考え方を適用できる&lt;/li&gt;
&lt;li&gt;例えば、Filter v1のような分類関数群でデータをGold/Silverに層化し、さらにSilverの内側をサブ区分に層化する、という階層的な層分けを行う&lt;/li&gt;
&lt;li&gt;構成比の集計: 全体のうちGoldが何%、Silverが何%か、さらにSilverの内側で、サブ区分Aが何%、Bが何%か、という階層的な比率を集計する&lt;/li&gt;
&lt;li&gt;層ごとの信頼度の推定: 全体で1つの信頼区間を出すのではなく、各層から独立にサンプリングし、その層の分類自体がどれくらい正しいかを、層ごとに別々の信頼区間として推定する&lt;/li&gt;
&lt;/ul&gt;
$$
\hat{p}_{\text{層}} = \frac{x_{\text{層}}}{n_{\text{層}}}
$$&lt;ul&gt;
&lt;li&gt;層ごとに精度が大きく違う場合（例えばGoldは99%正しいが、Silverのサブ区分Bは70%しか正しくない、など）、全体を混ぜた1つの信頼区間ではこの差が見えなくなる。前述の「既知パターンはフィルター、未知パターンはランダムサンプリング」で触れた通り、量の多い層に埋もれて、量の少ない層の汚染を見落とすのと同じ構造&lt;/li&gt;
&lt;li&gt;層ごとに分けることで、どの層（どのフィルターのルール）が実際には信頼できないかを特定でき、改善の優先順位（影響度×件数）をつけやすくなる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="修正とその反映"&gt;修正とその反映&lt;/h2&gt;
&lt;h3 id="データパイプラインのテストコード"&gt;データパイプラインのテストコード&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;データを生成・変換するパイプライン自体にもバグが入り込むため、通常のソフトウェアと同様にテストが必要&lt;/li&gt;
&lt;li&gt;過去に見つかったデータバグは、回帰テストとして固定化しておく&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_known_bug_regression&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 過去に発見された特定の変換バグの再発を防ぐ&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;raw_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expected_output&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;盲検サンプリングとWilson信頼区間を使い、パイプライン適用後のデータのエラー率を定期的に監視する&lt;/li&gt;
&lt;/ul&gt;
$$
\hat{p} = \frac{x}{n}, \qquad \text{95\%CIはサンプル数}n\text{が小さいほど広くなる}
$$&lt;h3 id="重複除去dedupe"&gt;重複除去（Dedupe）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;データセットは基本的に複数のデータソースから集めることが多く、その過程で同じサンプルが重複して混入する可能性がある&lt;/li&gt;
&lt;li&gt;重複データは単なる水増しになるだけでなく、見かけ上のサンプルサイズを実態以上に大きく見せ、独立性の前提も崩してしまう&lt;/li&gt;
&lt;li&gt;重複チェックには、少なくとも以下の軸がある
&lt;ul&gt;
&lt;li&gt;元データ・データソース間の重複: 複数の生データソースをマージする際、同じサンプルが重複して入り込むのを防ぐ&lt;/li&gt;
&lt;li&gt;単一データセット内の重複: 同じサンプルがTrainなどの中で複数回カウントされていないか&lt;/li&gt;
&lt;li&gt;データセット間の重複: 元データソースを分ける設計をしていても、実際にTrain・Val・Diag・Test間で重複が混入していないかを機械的に確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_duplicates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;seen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;duplicates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;input&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;duplicates&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;seen&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;duplicates&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;完全一致だけでなく、表記ゆれなどによる「ほぼ重複」も見逃しやすいため、正規化してから比較する、あるいは類似度ベースの重複検出も併用するとよい&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="データクレンジング"&gt;データクレンジング&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;実際に遭遇したデータクレンジングの具体的な問題・方法論は、別記事&lt;a class="link" href="https://www.m1ke.org/p/%E3%83%95%E3%83%AA%E3%82%AC%E3%83%8A%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E3%82%AF%E3%83%AC%E3%83%B3%E3%82%B8%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B%E6%99%82%E3%81%AB%E7%9B%B4%E3%81%97%E3%81%9F%E9%A0%85%E7%9B%AE%E3%81%AE%E3%83%A1%E3%83%A2/" &gt;フリガナデータをクレンジングする時に直した項目のメモ&lt;/a&gt;で詳しくまとめている&lt;/li&gt;
&lt;li&gt;大きく分けると、文字・表記レベル、読み表記レベル、意味・文脈レベル、分割・アライメントレベル、ソース・アノテーション品質レベル、分布・統計レベル、実装・インフラレベルという複数のレベルで問題が起こりうる&lt;/li&gt;
&lt;li&gt;個別のバグ分類以上に汎用性が高いのは、盲検サンプリング・独立クロスチェック・ノイズフロアの計測といった、データを直す際の方法論そのもの&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;データ品質は、正確性・完全性・一貫性・適時性・有効性・一意性という6つの独立した次元で評価できる。正確性（現実との一致）と有効性（定義との一致）は特に混同しやすい&lt;/li&gt;
&lt;li&gt;品質問題への対応は、プロファイリング（現状把握）→検出・分類（6次元への分類と優先度づけ）→修正（補完・標準化・名寄せ）→検証（再チェックと継続的モニタリング）という4フェーズのサイクルで回す&lt;/li&gt;
&lt;li&gt;役割分担・独立性を正しく設計しても、データ自体にバグがあれば意味がない。最小構成でのミニテストやデータビュアーなど、品質チェックの基本動作から始め、まずデータそのものを確認する&lt;/li&gt;
&lt;li&gt;問題を発見する方法は、既知パターンに対するフィルター・シグネチャスキャンと、未知パターンに対するランダムサンプリングという役割分担で使い分ける&lt;/li&gt;
&lt;li&gt;ランダムサンプリングで見つけた不具合は、原因が分かればフィルターとして恒久化し、パイプラインの回帰テストへ反映するというサイクルが、品質QAの基本的な回し方&lt;/li&gt;
&lt;li&gt;層化監査抽出を使うと、Gold/Silverやそのサブ区分といった層ごとに、構成比と分類自体の信頼度を別々の信頼区間として推定でき、全体を混ぜた1つの指標では見えない層ごとの汚染を検出できる&lt;/li&gt;
&lt;li&gt;複数のデータソースから集める以上、重複データの混入は避けられないため、データセット内・データセット間の両方で重複チェックが必要&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータとデータソースの再考&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E3%83%A9%E3%83%99%E3%83%AB%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるクラスとラベルの再考&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E3%83%95%E3%83%AA%E3%82%AC%E3%83%8A%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E3%82%AF%E3%83%AC%E3%83%B3%E3%82%B8%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B%E6%99%82%E3%81%AB%E7%9B%B4%E3%81%97%E3%81%9F%E9%A0%85%E7%9B%AE%E3%81%AE%E3%83%A1%E3%83%A2/" &gt;フリガナデータをクレンジングする時に直した項目のメモ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval" target="_blank" rel="noopener"
&gt;Binomial proportion confidence interval - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://passdojo.jp/ipa/data-management/articles/data-quality-management-guide/" target="_blank" rel="noopener"
&gt;データ品質管理ガイド | IPAデータマネジメント&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>機械学習におけるクラスとラベルの再考</title><link>https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E3%83%A9%E3%83%99%E3%83%AB%E3%81%AE%E5%86%8D%E8%80%83/</link><pubDate>Sat, 05 Sep 2026 12:00:00 +0900</pubDate><guid>https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E3%83%A9%E3%83%99%E3%83%AB%E3%81%AE%E5%86%8D%E8%80%83/</guid><description>&lt;img src="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E3%83%A9%E3%83%99%E3%83%AB%E3%81%AE%E5%86%8D%E8%80%83/classification.png" alt="Featured image of post 機械学習におけるクラスとラベルの再考" /&gt;&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E5%88%86%E5%B8%83%E5%A4%96%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%90%AB%E3%82%80%E5%88%86%E9%A1%9E%E3%81%A7false-positive%E3%82%92%E6%8A%91%E3%81%88%E3%82%8B%E6%96%B9%E6%B3%95/" &gt;分布外データの対処方法&lt;/a&gt;や&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータとデータソースの再考&lt;/a&gt;では、データそのものの収集・分割・品質管理という観点を扱った&lt;/li&gt;
&lt;li&gt;分類タスクには、それとは別に「クラス・ラベルそのものをどう設計・管理するか」という固有の問題がある&lt;/li&gt;
&lt;li&gt;クラスの境界をどこに引くか、似ているクラス同士をどう切り分けるか、負例をどう定義するか、ラベルの信頼度をどう管理するかによって、同じデータ量でも学習・評価の質が大きく変わる&lt;/li&gt;
&lt;li&gt;今回は、このクラス・ラベル設計という観点から再整理する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="クラス設計の原則"&gt;クラス設計の原則&lt;/h2&gt;
&lt;h3 id="完全性と無矛盾性"&gt;完全性と無矛盾性&lt;/h3&gt;
&lt;p&gt;データセットが間違っていれば、モデルも間違える。では、不完全性のない完璧なデータセットは作れるのか。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;完全性: 不可能。入力空間は無限であり、網羅はできない。現実的なユースケースを定義し、目標とするスコープを絞るしかない&lt;/li&gt;
&lt;li&gt;無矛盾性: 可能。タクソノミーを定義し、運用でカバーすることで、無矛盾なデータセットを作ることはできる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これはゲーデルの不完全性定理に近い構図で、完全性と無矛盾性の両方を同時に満たすことはできないが、無矛盾性だけであれば設計次第で達成できるという整理になる。ただし、ソリテスパラドックスのように、境界の定義自体には曖昧さが残ることには注意する。&lt;/p&gt;
&lt;h3 id="seedとタクソノミーというデータ仮説"&gt;seedとタクソノミーというデータ仮説&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;seedとは、データを収録・生成・収集する上で基本となるデータの設計書&lt;/li&gt;
&lt;li&gt;Data-Centric AIの観点では、seedがデータの分解能の基本であり、実験における最も重要な仮説になる&lt;/li&gt;
&lt;li&gt;人間が対象世界をどの粒度・軸・関係性で分解するかという「データ仮説」を設計することが、知識空間（Knowledge Space）からデータ空間（Data Space）への射影規則を決めることに相当する&lt;/li&gt;
&lt;li&gt;この仮説を先に言語化したものがタクソノミーであり、タクソノミーを先に定義してからデータを集めることで、無矛盾性を担保しやすくなる&lt;/li&gt;
&lt;li&gt;タクソノミーに漏れがあると、学習・評価どちらでもカバーできない領域が生まれ、それがOODの一因にもなる&lt;/li&gt;
&lt;li&gt;ただし、実験計画法の要因実験のように、軸・粒度をすべてマニュアルで組み合わせて定義しようとすると、組み合わせ爆発でパターン数が破綻しやすい&lt;/li&gt;
&lt;li&gt;そのため、全パターンを人手で列挙するのではなく、実データから頻出パターンを抽出してタクソノミーを組み立てる方が現実的&lt;/li&gt;
&lt;li&gt;例
&lt;ul&gt;
&lt;li&gt;文字レベルで扱う場合は、先にタクソノミーを定義してから分類する&lt;/li&gt;
&lt;li&gt;音声データの場合は、音声学（Phonetics）のIPA（国際音声記号）をベースにデータの定義を行う&lt;/li&gt;
&lt;li&gt;難しい課題では、失敗を見越してgrade（難易度）の定義をあらかじめ行う&lt;/li&gt;
&lt;li&gt;クラスが二値分類でも、あえてnegativeを多クラス化し、エラーパターンごとに学習させる&lt;/li&gt;
&lt;li&gt;難しいクラスにはsubclassを定義してMECEに列挙する&lt;/li&gt;
&lt;li&gt;精度が上がらないサブクラスには、対となるDyadのpairを作って対照学習する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;これが仮説となり、人によるデータレベルのinductive biasになる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="タクソノミーとサブデータセットによる分割統治"&gt;タクソノミーとサブデータセットによる分割統治&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;困難は分割せよ、ではないが、サブデータセットを作って対処するのも有効&lt;/li&gt;
&lt;li&gt;サブデータセットは「grade（難易度）× クラス数」のように定義し、それぞれにタクソノミーとdefinitionを与える&lt;/li&gt;
&lt;li&gt;大量の矛盾するデータよりも、少量の無矛盾なデータを作るイメージ&lt;/li&gt;
&lt;li&gt;特に、意味の近いクラス同士を分類するinner-class classificationのようなケースで有効&lt;/li&gt;
&lt;li&gt;実務上は、gradeでフォルダを切り、クラスでフォルダを切り、その中でさらにタクソノミーを分析してseedを生成するという流れになる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="小さな範囲での学習可能性テスト"&gt;小さな範囲での学習可能性テスト&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;データセットが無矛盾かつ完全であれば、gradeの低いものは学習できるはずである&lt;/li&gt;
&lt;li&gt;最初に作ったseedデータをベースに、データ生成やaugmentationをする前に、素の状態でまずテストするとよい&lt;/li&gt;
&lt;li&gt;小さく試して、どのgradeまで学習できるかを確認してから拡張する方が安全&lt;/li&gt;
&lt;li&gt;精度が上がらない原因はモデルの容量や学習データの量ではなく、学習データそのものが矛盾していることも多い&lt;/li&gt;
&lt;li&gt;ただし、小さく多様性のない範囲での実験になるため、そのまま汎化性能を保証するとは言えない&lt;/li&gt;
&lt;li&gt;基本を確認してから応用を学習させるという考え方&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gradeによる難易度設計"&gt;Gradeによる難易度設計&lt;/h2&gt;
&lt;h3 id="なぜgradeが有効か-最小条件での分離可能性の検査"&gt;なぜGradeが有効か: 最小条件での分離可能性の検査&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Gradeを設計する最大の利点は、「最小の条件でタスクが本当に解けるか」を検査できること&lt;/li&gt;
&lt;li&gt;直感的には、grade1（最も易しい設定）は当然解けるはず、と思い込みやすい&lt;/li&gt;
&lt;li&gt;しかし、論理的に最低かつ最小の条件（それ以上削れない、必要最小限の情報だけを残した条件）では、実はクラスの分離が難しいことがある&lt;/li&gt;
&lt;li&gt;理由は、grade2以降で加わる文脈・特徴量が、実は意図せずクラスの分離を助けていた可能性があるから&lt;/li&gt;
&lt;li&gt;例えば「太郎」という単語の検出タスクで、grade1を「音声的な文脈を一切含まない、最短の音素列だけ」と定義したとする
&lt;ul&gt;
&lt;li&gt;この最小条件では、「太郎」の音素列が、別の単語の一部分（例えば別の名前の頭部分）と酷似しており、論理的に区別できない場合がある&lt;/li&gt;
&lt;li&gt;grade3・grade4で加える文脈情報（前後の音・イントネーションなど）があって初めて分離できていたのだとすれば、grade1で解けないのは当然であり、モデルの性能不足ではない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;つまりgrade1が解けないという結果は、モデルの問題ではなく、タスクの定義・クラス設計そのものに問題があることを示すシグナルになる&lt;/li&gt;
&lt;li&gt;これは&lt;code&gt;小さな範囲での学習可能性テスト&lt;/code&gt;で触れた「精度が上がらない原因は、学習データそのものが矛盾していることも多い」という話と直結し、grade1の失敗を「タクソノミー自体を見直すべきサイン」として使える&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="評価用データをgrade別に用意する"&gt;評価用データをgrade別に用意する&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Diag・Challengeのような評価用データは、難易度別に複数用意するとよい&lt;/li&gt;
&lt;li&gt;たとえTrainにデータを追加しても、それが基礎能力に悪影響を及ぼしている可能性もある&lt;/li&gt;
&lt;li&gt;そのため、学校の学年のように6段階程度でgrade別のholdoutデータセットを用意し、評価するとよい&lt;/li&gt;
&lt;li&gt;「grade1は通っているから、その使い方に限定する」といった逃げ道を作れるようにする意味もある&lt;/li&gt;
&lt;li&gt;例えば、paraphraseやreasonを付けたもの、否定形を混ぜたものはgradeを1段上げる、といった基準を決めておく
&lt;ul&gt;
&lt;li&gt;paraphraseの例: 同義語への置き換え、受動態と能動態の変換、品詞の変更、文の統合・分割&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="グレード別のラダー表を作る"&gt;グレード別のラダー表を作る&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;gradeの基準を頭の中だけで管理せず、ラダー表（各gradeで何が加わるかを1段ずつ積み上げた表）として明文化しておくとよい&lt;/li&gt;
&lt;li&gt;例えば、「明日の天気を教えて」という問い合わせを起点にすると、以下のようなラダー表になる&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Grade&lt;/th&gt;
&lt;th&gt;加わる変換&lt;/th&gt;
&lt;th&gt;例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Grade1&lt;/td&gt;
&lt;td&gt;なし（素のケース）&lt;/td&gt;
&lt;td&gt;明日の天気を教えて&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grade2&lt;/td&gt;
&lt;td&gt;同義語への置き換え&lt;/td&gt;
&lt;td&gt;明日の気象を教えて&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grade3&lt;/td&gt;
&lt;td&gt;受動態・能動態の変換や語順の変化&lt;/td&gt;
&lt;td&gt;明日の天気について教えてほしい&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grade4&lt;/td&gt;
&lt;td&gt;否定形の混入&lt;/td&gt;
&lt;td&gt;明日雨が降らないか教えて&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grade5&lt;/td&gt;
&lt;td&gt;文の統合・分割、複数意図の混在&lt;/td&gt;
&lt;td&gt;明日の天気と、傘が必要か教えて&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grade6&lt;/td&gt;
&lt;td&gt;上記の複合&lt;/td&gt;
&lt;td&gt;雨が降らなければ、明日の予定はどうなる？&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;各gradeは前段のgradeに対して「1段だけ変換を加える」ように設計し、どこで精度が崩れたかを1段単位で特定できるようにする&lt;/li&gt;
&lt;li&gt;このラダー表があると、「Grade3までは安定して動く」のように、開発者以外にもスコープの限界を説明しやすくなる&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gradeによる精度の精緻化&lt;/code&gt;で触れた「GradeXまでは80%で解ける」という報告も、このラダー表があって初めて意味を持つ&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="holdoutだけに頼らない"&gt;holdoutだけに頼らない&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;holdout・heldoutだけでは、学習ができたこと以外の証明にならない&lt;/li&gt;
&lt;li&gt;そのため、difficultケースや、生成プロセスから全く別に作ったデータをベースにした評価も併用するべき&lt;/li&gt;
&lt;li&gt;つまり、複数種類のDiag・Testを用意しておくのがよい&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="gradeによる精度の精緻化"&gt;gradeによる精度の精緻化&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;仮にグレードを作っていないと、学習がうまくイカない場合は、低スコアになってしまう&lt;/li&gt;
&lt;li&gt;その場合は使えないモデルを作ったということで、採用されなくなる&lt;/li&gt;
&lt;li&gt;他方、グレードを作った場合は、GradeXまでは80%で解けるのようにスコアがよく見える&lt;/li&gt;
&lt;li&gt;これは仮にうまくいかなかった時に、逃げ道としてどこまでは行けるかを明示する事ができる&lt;/li&gt;
&lt;li&gt;gradeXで80%までは行けるなら、次のグレードからアンサンブルにしようなどのような考え方も可能&lt;/li&gt;
&lt;li&gt;すなわち、Gradeやスコープは有用ということ&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="スコープの選び方-バギーとリライアブル"&gt;スコープの選び方: バギーとリライアブル&lt;/h3&gt;
&lt;p&gt;Gradeを積む・積まないという選択は、結局「スコープをどこまで広げるか」という選択に帰着する。ここには2つの極がある。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;アプローチ&lt;/th&gt;
&lt;th&gt;意味&lt;/th&gt;
&lt;th&gt;特徴&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;なんでもできる（バギー）&lt;/td&gt;
&lt;td&gt;スコープを最初から広げ、全gradeを一気に狙う&lt;/td&gt;
&lt;td&gt;対応範囲は理想的だが、Edge Caseが爆発的に増え、完全性・無矛盾性を確保できず不安定になりやすい&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;少しはできる（リライアブル）&lt;/td&gt;
&lt;td&gt;スコープを絞り、狭いgradeだけを確実に狙う&lt;/td&gt;
&lt;td&gt;対応範囲は狭いが、無矛盾性を保ちやすく、安定して動く&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;「なんでもできる」は理想的な最終形ではあるが、そこへ直接到達しようとするのは修羅の道になりやすい&lt;/li&gt;
&lt;li&gt;スコープが広いほど、&lt;code&gt;クラス設計の原則&lt;/code&gt;で触れた無矛盾性の担保が難しくなり、バグや矛盾したデータが混入する余地も増える&lt;/li&gt;
&lt;li&gt;そのため、まずは狭いスコープ（低いgrade）でリライアブルに動くものを確立し、&lt;code&gt;小さな範囲での学習可能性テスト&lt;/code&gt;のように段階的にgradeを上げてスコープを広げていく方が、結果的に「なんでもできる」に近づく近道になる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="クラスの幾何学的デザインgeometric-class-design"&gt;クラスの幾何学的デザイン（Geometric Class Design）&lt;/h2&gt;
&lt;h3 id="クラスの定義を絞る"&gt;クラスの定義を絞る&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;精度が低いクラスに対して、データ量を増やして曖昧な境界を学習させるのではなく、クラス自体の範囲を狭める方法も有効&lt;/li&gt;
&lt;li&gt;クラスの判定対象を狭め、クラス間の境界が太くなるようにモデルを設計する&lt;/li&gt;
&lt;li&gt;国土を広げて（データを増やして）国境線の太さ（クラスの境界の太さ）を確保するより、国土自体を小さくして境界を太くするという考え方&lt;/li&gt;
&lt;li&gt;もちろん、モデルの性能自体が原因の場合もある&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="コアとサーフェス"&gt;コアとサーフェス&lt;/h3&gt;
&lt;p&gt;分類する空間は、大きく2種類に分けて考えられる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コア: 意味軸。人間が定義したseedで作成するか、実データをサンプリングして得る&lt;/li&gt;
&lt;li&gt;サーフェス: 表現軸。AIによってseedからaugmentationする（パラフレーズの生成など）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例えば文字ベースの分類では、あるクラスを決定する特徴的な属性を属性1、次点で優位な属性を属性2とし、これらの軸を掛け合わせてタクソノミーを作り、データをsubcat（サブカテゴリー）で分類する。クラス内の特徴を抽出してサンプルを生成するレシピを網羅することで、クラスの幾何学的な領域を設計できるようになる。&lt;/p&gt;
&lt;h3 id="inner-classとinter-classでの一貫性"&gt;inner-classとinter-classでの一貫性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;意味の近いクラスを分類する場合は、ラベルの矛盾が発生しやすい&lt;/li&gt;
&lt;li&gt;AというクラスとBというクラスのそれぞれのサンプルの中で、教師信号が一貫していないケースがある&lt;/li&gt;
&lt;li&gt;そのため、クラス間で矛盾がないかのチェックが必要&lt;/li&gt;
&lt;li&gt;そうでないと、モデルが安易な結論に陥りやすくなる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="中間クラスの必要性"&gt;中間クラスの必要性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;クラスAとクラスBの境界を狭め、境界専用データセットを用意するのは有効な対処法だが、それでも解決しないケースがある&lt;/li&gt;
&lt;li&gt;例えば、NoneクラスとReadクラス（知識を要すると判断した場合に割り当てるクラス）があるとする。多くのサンプルは迷わず振り分けられるが、一定数、両者を継続的に取り違えるサンプルが残ることがある&lt;/li&gt;
&lt;li&gt;こうした取り違えは、アノテーションのミスや境界の甘さではなく、AとBの設計そのものに原因があることがある&lt;/li&gt;
&lt;li&gt;AとBは本来「どちらか一方（OR）」という排他的な関係として設計されているはずだが、実際にはAとBの性質を両方あわせ持つ、ANDの領域のサンプルが存在している、ということ&lt;/li&gt;
&lt;li&gt;これは&lt;a class="link" href="https://www.m1ke.org/p/22%E3%81%AE%E4%B8%AD%E3%81%AB%E6%BD%9C%E3%82%80%E9%83%A8%E5%88%86%E3%81%A8%E5%85%A8%E4%BD%93%E3%81%AE%E6%A7%8B%E9%80%A0/" &gt;2×2の中に潜む部分と全体の構造&lt;/a&gt;で触れた、非排他的な領域を無理に排他的な区分に押し込めようとする問題と同じ構造&lt;/li&gt;
&lt;li&gt;AND領域のサンプルを無理にAかBかに押し込めようとすると、どちらのクラスの境界も歪み、inner-class・inter-classの一貫性が崩れ続ける&lt;/li&gt;
&lt;li&gt;対処法は、無理に既存のクラスへ押し込めるのではなく、そのAND領域専用の中間クラスを新設すること&lt;/li&gt;
&lt;li&gt;例えるなら、どちらの国にも属さない集団を無理にどちらかの国籍に割り当てるのではなく、独立した居場所を用意して保護するようなもの&lt;/li&gt;
&lt;li&gt;中間クラスを作ることで、AとBそれぞれの境界は再びクリーンなOR（排他的）の関係に戻り、無矛盾性を回復できる&lt;/li&gt;
&lt;li&gt;中間クラス自体も、Noneクラスと同様に1つのメタクラスとして扱い、必要であればさらにサブクラス化できないかを検討する&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="離散ラベルかマルチラベルか"&gt;離散ラベルかマルチラベルか&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;AND領域を持つサンプルへの対処は、中間クラスを新設する以外にも、そもそものラベルの表現方法を変えるという選択肢がある&lt;/li&gt;
&lt;li&gt;離散値（single-label）: 各サンプルに1つだけラベルを割り当てる方式。モデル側はsoftmax・多クラス分類として学習し、クラス同士が真に排他的（OR関係）である前提に立つ&lt;/li&gt;
&lt;li&gt;マルチラベル（logit形式）: クラスごとに独立した0/1の値を持たせ、複数のクラスが同時に成立してよいとする方式。モデル側はクラスごとに独立したsigmoid出力・二値分類として学習する&lt;/li&gt;
&lt;li&gt;AND領域のサンプルがある場合、中間クラスを新設する（クラスの数を増やして排他性を保つ）代わりに、そのサンプルにAとBの両方のラベルを立てる（そもそも排他性を前提にしない）という対処もできる&lt;/li&gt;
&lt;li&gt;どちらを選ぶかは、AとBの共起が意味的に自然かどうかによる
&lt;ul&gt;
&lt;li&gt;共起が例外的・境界的なものであれば、中間クラスとして明示的に切り出す方が、タクソノミーの見通しが良くなる&lt;/li&gt;
&lt;li&gt;共起が本質的に珍しくない（多くのサンプルがAとBを両方持ちうる）なら、最初からマルチラベルとして設計する方が自然&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;中間的な手法として、0/1の代わりに確率値（0.7、0.3など）を持たせるソフトラベル・ラベルスムージングもある。&lt;code&gt;ラベルの信頼度: GoldとSilver&lt;/code&gt;で触れたラベルの確信度を、ラベル自体の値に埋め込む手段としても使える&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="境界専用データセットを作る"&gt;境界専用データセットを作る&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;クラスの範囲を狭めて境界を太くしても、間違いは起こりうる&lt;/li&gt;
&lt;li&gt;特に、物理的に意味が近い複数のクラスがある場合、その境界は間違いやすい&lt;/li&gt;
&lt;li&gt;そのため、クラスの際（きわ）専用のデータセットを作るのが有効&lt;/li&gt;
&lt;li&gt;例えば12クラス分類の場合、2つを選ぶ組み合わせは&lt;/li&gt;
&lt;/ul&gt;
$$
\binom{12}{2} = 66
$$&lt;ul&gt;
&lt;li&gt;通りあり、境界の両側にそれぞれデータを用意する必要があるため&lt;/li&gt;
&lt;/ul&gt;
$$
66 \times 2 = 132
$$&lt;ul&gt;
&lt;li&gt;通りが、原理的には必要な境界クラス用データの数になる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="境界データセットのためのクラスの選び方"&gt;境界データセットのためのクラスの選び方&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;66通りすべてを対象にするのは大変なので、ターゲットを絞った方がよい&lt;/li&gt;
&lt;li&gt;混同行列から誤爆ランキングを出し、優先度の高い境界を判断する方法がある&lt;/li&gt;
&lt;li&gt;他の指標との相関を見て判断する方法も考えられるが、同じデータを使った相関係数はトートロジーになるため注意が必要&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="hard-caseの作り方"&gt;Hard Caseの作り方&lt;/h2&gt;
&lt;h3 id="注意点"&gt;注意点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;特徴の変化のかけ方によって、有益にも有害にもなるため注意が必要&lt;/li&gt;
&lt;li&gt;例えば画像系では、特徴の一部を0でマスクして消す手法がよく使われる&lt;/li&gt;
&lt;li&gt;同じ手法を音のデータに適用すると、うまくいかないことが多い&lt;/li&gt;
&lt;li&gt;理由は、音の場合はマスクによる不自然さそのものを学習してしまうから&lt;/li&gt;
&lt;li&gt;そのため、単調なマスクだけでなく、ノイズによるマスクなど複数の手法を試す必要がある&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="shifted-positive"&gt;shifted positive&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;例えば「太郎」を対象にする場合、最低でも「〜太郎」「〜太郎〜」「太郎〜」の3パターンを作れる&lt;/li&gt;
&lt;li&gt;時系列的なずらしによってpositiveケースを増やす例で、データのかさ増しにも使える&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="adversarial-negatives"&gt;adversarial negatives&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;いわゆるhard negativeの一種&lt;/li&gt;
&lt;li&gt;例えば「太郎」に対して、音的に似ている「tara」や「soro」のような、一部を変更した特徴量をnegativeとして用意する&lt;/li&gt;
&lt;li&gt;意図的に似た音のケースを増やす例&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="truncated-negative"&gt;Truncated Negative&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Positiveケースの一部を含むデータを、あえてNegativeとして用意する手法&lt;/li&gt;
&lt;li&gt;例えば「太郎」という名前を分類したい場合、前半の「〜太」と後半の「郎〜」を、それぞれTruncated Negativeとして用意できる&lt;/li&gt;
&lt;li&gt;全体を学習させたいが、部分だけで安易に分類させたくない場合に有効&lt;/li&gt;
&lt;li&gt;部分切り出しによってデータ自体も増えるため、かさ増しにも有効&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="hidden-negative"&gt;Hidden Negative&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;画像のFine-grained Classificationなどでは、特徴をマスクで隠して学習させる手法が有効とされている&lt;/li&gt;
&lt;li&gt;Hard NegativeをPositiveケースの一部を隠して作る手法&lt;/li&gt;
&lt;li&gt;特徴的な部分をベースに学習が進んでしまうのを避け、あえて大局的な特徴を隠すことで、局所特徴を学習させる&lt;/li&gt;
&lt;li&gt;こちらもデータのかさ増しに有効&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="組み合わせ数を数える"&gt;組み合わせ数を数える&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;上記のpositive/negativeのパターンは、特徴量の要素ごとにさらに増やせる&lt;/li&gt;
&lt;li&gt;例えば「たろう」を対象にHidden Negativeを適用する場合、3文字なので3要素（A・B・C）とすると、正解はABCのみになる&lt;/li&gt;
&lt;li&gt;計算すると、Hidden Negativeだけでも次のパターンが考えられる&lt;/li&gt;
&lt;/ul&gt;
$$
\binom{3}{2} + \binom{3}{1} + \binom{3}{0} = 3 + 3 + 1 = 7
$$&lt;ul&gt;
&lt;li&gt;2つ選ぶ: AB・AC・BC（3通り）&lt;/li&gt;
&lt;li&gt;1つ選ぶ: A・B・C（3通り）&lt;/li&gt;
&lt;li&gt;0個選ぶ: 選ばない（1通り）&lt;/li&gt;
&lt;li&gt;つまり、順番と要素が固定であれば、7パターンのHidden Negativeを作れる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="メタクラス"&gt;メタクラス&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;メタクラスとは、個々の意味クラス（何であるかを表すクラス）とは異なる階層で、データセット全体の構造上の役割を担うクラスのこと&lt;/li&gt;
&lt;li&gt;代表的なものに、None（負例メタクラス）・OOD（分布外であることを示すクラス）・Impossible（そもそも分類が不可能であることを示すクラス）の3種類がある&lt;/li&gt;
&lt;li&gt;OODについては&lt;a class="link" href="https://www.m1ke.org/p/%E5%88%86%E5%B8%83%E5%A4%96%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%90%AB%E3%82%80%E5%88%86%E9%A1%9E%E3%81%A7false-positive%E3%82%92%E6%8A%91%E3%81%88%E3%82%8B%E6%96%B9%E6%B3%95/" &gt;分布外データの対処方法&lt;/a&gt;で扱っているため、ここではNoneとImpossibleを、メタクラスという共通の観点から整理する&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="noneメタクラス"&gt;Noneメタクラス&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Noneは、既知のどの意味クラスにも当てはまらないサンプルを受け止める、負例用のメタクラス&lt;/li&gt;
&lt;li&gt;個々の意味クラスと同じ階層に並べるのではなく、全体を覆うメタクラスとして位置づけることで、Noneの1-Recallが実質的なFPRに対応するなど、通常のクラスとは異なる評価軸を持つことが明確になる&lt;/li&gt;
&lt;li&gt;具体的な設計・評価方法は、次の&lt;code&gt;Noneクラス（負例クラス）を追加する&lt;/code&gt;で詳しく扱う&lt;/li&gt;
&lt;li&gt;このNoneメタクラスの設計は、哲学のtruthmaker理論における否定的事実の問題と同じ構造を持つ。詳しくは&lt;a class="link" href="https://www.m1ke.org/p/truthmaker%E7%90%86%E8%AB%96%E3%81%A8%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8Bnone%E3%82%AF%E3%83%A9%E3%82%B9%E8%A8%AD%E8%A8%88/" &gt;Truthmaker理論と機械学習におけるNoneクラス設計&lt;/a&gt;で扱っている&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="impossibleクラス"&gt;Impossibleクラス&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;与えられた入力そのものから、原理的に分類が不可能であることを示すためのメタクラス&lt;/li&gt;
&lt;li&gt;Noneが「既知のどのクラスにも当てはまらない」という分類結果を表すのに対し、Impossibleは「そもそも判断材料が足りない・入力が壊れている」という入力の状態についての判断であり、役割が異なる
&lt;ul&gt;
&lt;li&gt;None: 意味のある入力に対して、既知のpositiveクラスのいずれでもないと判定した結果&lt;/li&gt;
&lt;li&gt;Impossible: 音声が途中で切れている、画像が全面ノイズで判別不能、テキストが文字化けしているなど、そもそも人間が見ても判断できない入力&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;NoneとImpossibleを混同すると、Noneクラスの中に「本来は分類不能なだけのサンプル」が紛れ込み、Noneクラスの一貫性が崩れる&lt;/li&gt;
&lt;li&gt;Impossibleを明示的なメタクラスとして切り出しておくことで、モデルの性能低下の原因が「クラス設計の問題」なのか「そもそも判断不能な壊れた入力が混ざっているだけ」なのかを切り分けられる&lt;/li&gt;
&lt;li&gt;特に評価データにImpossibleサンプルが混ざっていると、モデル本来の性能を過小評価してしまうため、事前にImpossibleクラスとして分離しておく価値がある&lt;/li&gt;
&lt;li&gt;Impossibleかどうかの判定自体の難しさに注意する。「判断できないことを判断する」タスクになるため、人手でのダブルチェックが必要になりやすい&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="noneクラスnegationクラスの設計"&gt;Noneクラス・Negationクラスの設計&lt;/h2&gt;
&lt;h3 id="noneクラス負例クラスを追加する"&gt;Noneクラス（負例クラス）を追加する&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;低い確信度を単純に棄却するだけでなく、明示的なNoneまたはOtherクラスを追加する&lt;/li&gt;
&lt;li&gt;これにより、モデルは既知のpositiveクラスだけでなく、学習時に与えた負例をNoneとして識別できるようになる&lt;/li&gt;
&lt;li&gt;ただし、Noneクラスを追加しても、あらゆる未知入力を識別できるわけではない&lt;/li&gt;
&lt;li&gt;学習に使用した負例や、それに近いOODには有効だが、まったく異なる未知入力に対して誤って高い確信度を出す可能性は残る&lt;/li&gt;
&lt;li&gt;Noneは全体の負例クラス用のメタクラスであるため、実質的にはNoneの1-Recallこそが本来のFPRになる&lt;/li&gt;
&lt;li&gt;Noneクラスのrecall（Noneを見逃さなかった割合）は、そのまま通常クラスのprecisionに対応する&lt;/li&gt;
&lt;li&gt;つまり、見逃さずに正確に処理できた通常クラスの評価につながる&lt;/li&gt;
&lt;li&gt;Noneクラスの性能が下がれば、当然通常クラスの性能にも影響が出る&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="既知の弱点をあらかじめ加味する"&gt;既知の弱点をあらかじめ加味する&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;例えばNLPでは、否定表現において精度が下がりやすいという既知の弱点がある&lt;/li&gt;
&lt;li&gt;特徴が似ているにもかかわらず、クラス領域が外れてしまうことが原因&lt;/li&gt;
&lt;li&gt;こうした既知の弱点については、あらかじめデータセットのバランスを調整して対処できる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="negationの明確化"&gt;Negationの明確化&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;特にnegationが絡む場合に有効な手法&lt;/li&gt;
&lt;li&gt;例えば、Moveクラスの反対がDon&amp;rsquo;t MoveなのかStopクラスなのか、AIが迷うケースがある&lt;/li&gt;
&lt;li&gt;その場合は、意味を明確化するために、MoveクラスのスロットにNegationを持たせ、Move(negated=True)のように表現する&lt;/li&gt;
&lt;li&gt;すると、メタクラスであるNone以外の否定表現は、Negationスロットで対応できるようになる&lt;/li&gt;
&lt;li&gt;結果として「動かない」と「Stop」が同一視されなくなり、精度が上がる&lt;/li&gt;
&lt;li&gt;これはデータセットの無矛盾性とも関連する&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ラベルの信頼度-goldとsilver"&gt;ラベルの信頼度: GoldとSilver&lt;/h2&gt;
&lt;p&gt;データセットのラベルは、どうやって付与されたかによって信頼度が異なる。この信頼度をGold・Silverという段階で区別して管理しておくことも重要。&lt;/p&gt;
&lt;h3 id="goldゴールドラベル"&gt;Gold（ゴールド）ラベル&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;人の手で検証・確認されたラベル&lt;/li&gt;
&lt;li&gt;品質は高いが、作成コストが高く量を確保しにくい&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="silverシルバーラベル"&gt;Silver（シルバー）ラベル&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;モデルやルールベース処理などで自動生成されたラベル&lt;/li&gt;
&lt;li&gt;量は確保しやすいが、ゴールドに比べてノイズが混ざりやすい&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="段階的なティア管理"&gt;段階的なティア管理&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;単純な二値の区分だけでは不十分なことも多く、信頼度をさらに細かい段階に分けて管理すると扱いやすい&lt;/li&gt;
&lt;li&gt;例: 読みが一意で人手検証済み（gold_verified）、人手検証済みだが本質的に複数の正解がありうる（gold_free_variation）、まだ判断がついていない自動生成ラベル（silver_ambiguous）&lt;/li&gt;
&lt;li&gt;ティアごとに、機械的なクロスチェックを先に流し、意見が割れたものを優先的に人手レビュー（Silver→Goldへの昇格）に回す、という段階的な運用と組み合わせるとよい&lt;/li&gt;
&lt;li&gt;詳しくは&lt;a class="link" href="https://www.m1ke.org/p/%E3%83%95%E3%83%AA%E3%82%AC%E3%83%8A%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E3%82%AF%E3%83%AC%E3%83%B3%E3%82%B8%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B%E6%99%82%E3%81%AB%E7%9B%B4%E3%81%97%E3%81%9F%E9%A0%85%E7%9B%AE%E3%81%AE%E3%83%A1%E3%83%A2/" &gt;フリガナデータをクレンジングする時に直した項目のメモ&lt;/a&gt;や&lt;a class="link" href="https://www.m1ke.org/p/%E5%88%86%E5%B8%83%E5%A4%96%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%90%AB%E3%82%80%E5%88%86%E9%A1%9E%E3%81%A7false-positive%E3%82%92%E6%8A%91%E3%81%88%E3%82%8B%E6%96%B9%E6%B3%95/" &gt;分布外データの対処方法&lt;/a&gt;でも扱っている&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="用途による使い分け"&gt;用途による使い分け&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Trainには、SilverをGoldと混ぜて量を確保しつつ使うことが多い。多少のラベルノイズは学習の過程である程度吸収されやすい&lt;/li&gt;
&lt;li&gt;Diag・Testのような、性能を正しく測定するためのデータには、なるべくGoldを使うべき&lt;/li&gt;
&lt;li&gt;ラベル自体にノイズがあると、性能の低さがモデルの問題なのかラベルのノイズなのかを区別できなくなり、&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E5%93%81%E8%B3%AAqa%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータ品質QAの再考&lt;/a&gt;の意味が薄れてしまう&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ラベル属性の管理方法"&gt;ラベル・属性の管理方法&lt;/h2&gt;
&lt;p&gt;データセット、特にTrainデータセットを作る際には、サンプルが持つ属性をどう区分・管理するかという問題もある。属性の性質によって、適した管理方法が異なる。&lt;/p&gt;
&lt;h3 id="直交する属性-フォルダ管理"&gt;直交する属性: フォルダ管理&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;クラス・サブクラス・カテゴリー・ID/OOD・Positive/Negative・Easy/Hardのような属性は、互いに直交する（1サンプルにつき各軸で1つの値だけを持ち、軸同士も独立している）&lt;/li&gt;
&lt;li&gt;こうした属性は、フォルダ階層でそのまま表現できる&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;class_A/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; id/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; positive/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; easy/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hard/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; negative/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; easy/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hard/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ood/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; positive/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; easy/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hard/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; negative/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; easy/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hard/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;ディレクトリ構造自体がそのままデータの分類を表すため、追加のマスターファイルが無くても直感的に管理できる&lt;/li&gt;
&lt;li&gt;特にID（In-Distribution）とOOD（Out-of-Distribution）は、&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータとデータソースの再考&lt;/a&gt;のDiagで扱う「スコープの境界」を直接反映する軸でもあり、他の軸と同様にきちんと分けて管理しておくことが重要&lt;/li&gt;
&lt;li&gt;他にも、以下のような軸がフォルダ管理に向いている
&lt;ul&gt;
&lt;li&gt;spec/seed（データを生成・収集する前提となる設計書やtaxonomy）&lt;/li&gt;
&lt;li&gt;self/others（自分で作ったデータか、他所のデータか）&lt;/li&gt;
&lt;li&gt;real/generated・third_party（データの出自）&lt;/li&gt;
&lt;li&gt;sampling_weight（学習時のサンプリング重み別）&lt;/li&gt;
&lt;li&gt;case（特定のケース別）&lt;/li&gt;
&lt;li&gt;calibration（確信度キャリブレーション用）&lt;/li&gt;
&lt;li&gt;generalization dataset（いわゆるOOD dataset。汎化性能を客観的に測るために別途用意しておく必要がある）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="直交しない属性-tagjsonでの管理"&gt;直交しない属性: Tag.jsonでの管理&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;UseCase・FailurePatternのような属性は、クラスのように均等に分布せず、1サンプルが複数の値を同時に持つこともある多対多の関係になる&lt;/li&gt;
&lt;li&gt;こうした属性をフォルダで表現しようとすると、同じサンプルを複数の場所に置く必要が出てきて破綻する&lt;/li&gt;
&lt;li&gt;代わりに、&lt;code&gt;Tag.json&lt;/code&gt;のようなマスターファイルで、サンプルIDとタグの対応表として管理する方がよい&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;sample_001&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;use_case:login&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;failure:timeout&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;sample_002&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;use_case:login&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;use_case:logout&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="対称的な属性-pairjsonでの管理"&gt;対称的な属性: Pair.jsonでの管理&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Dyad（対）になるような、表現がわずかに違うだけの対応関係を持つサンプルもある&lt;/li&gt;
&lt;li&gt;この対応関係自体が情報を持つため、&lt;code&gt;pair_id&lt;/code&gt;を振り、&lt;code&gt;Pair.json&lt;/code&gt;のようなマスターファイルでどのサンプル同士が対になっているかを管理する&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;pair_001&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sample_010&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;sample_011&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;pair_002&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sample_023&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;sample_024&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="まとめると"&gt;まとめると&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;属性の性質&lt;/th&gt;
&lt;th&gt;例&lt;/th&gt;
&lt;th&gt;管理方法&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;直交する&lt;/td&gt;
&lt;td&gt;クラス・カテゴリー・Positive/Negative・Easy/Hard&lt;/td&gt;
&lt;td&gt;フォルダ階層&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;直交しない&lt;/td&gt;
&lt;td&gt;UseCase・FailurePattern&lt;/td&gt;
&lt;td&gt;Tag.json（多対多のマスター管理）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;対称的&lt;/td&gt;
&lt;td&gt;Dyad・minimal pair&lt;/td&gt;
&lt;td&gt;Pair.json（pair_idによる対応管理）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="具体的なデータセット定義例"&gt;具体的なデータセット定義例&lt;/h2&gt;
&lt;h3 id="多クラス分類の例"&gt;多クラス分類の例&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;まずdataについて、種となるデータ（seeds）と生成されたデータ（generated）を分ける&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data/{seeds, generated}&lt;/code&gt;のような形にする&lt;/li&gt;
&lt;li&gt;さらに&lt;code&gt;data/seeds/grade1/class_name/{positive,negative}/subclass_name/{def.md, seed.csv}&lt;/code&gt;のように切る&lt;/li&gt;
&lt;li&gt;gradeは難易度を表し、grade1からgrade6程度まで定義する&lt;/li&gt;
&lt;li&gt;gradeを定義する理由は、うまくいかなかった時に、どこまでうまくいっているのかを測れるようにするため&lt;/li&gt;
&lt;li&gt;それぞれの$\text{grade} \times \text{class} \times \text{subclass}$について、分割統治法のように解いていくイメージ&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; seed1/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; grade1/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; class1/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; positive/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; subclass1/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; subclass2/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; negative/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; subclass1/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; subclass2/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; class2/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; positive/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; subclass1/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; subclass2/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; negative/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; subclass1/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; subclass2/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; grade2/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; class2/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; positive/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; subclass1/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; subclass2/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; negative/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; subclass1/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; subclass2/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="二値分類の例"&gt;二値分類の例&lt;/h3&gt;
&lt;p&gt;以下は、ある名前を対象にした二値分類のクラス設計の実例。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;グレードをトップで分けるのではなく、まず&lt;code&gt;real/synthetic&lt;/code&gt;という&lt;code&gt;source&lt;/code&gt;の軸で分ける&lt;/li&gt;
&lt;li&gt;その後にgrade分け（難易度分け）をクラスに落とし込み、クラス単位で難易度を教える&lt;/li&gt;
&lt;li&gt;この例では単純な二値分類ではなく、negativeの内訳を細分化して5クラス分類にしている&lt;/li&gt;
&lt;li&gt;対象クラスのフォルダ以外はすべてnegativeケースになる&lt;/li&gt;
&lt;li&gt;最後に、サブクラス単位でさらに分割している&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; synthetic/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; target_voice/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; easy_simple/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; hard_negative_voice/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; wrong_name_with_prefix/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; arbitrary_prefix/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; bare_other_name/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; real_word_fragment/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; invented_syllable/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; no_voice/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; synthetic_noise/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; real/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; target_voice/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; easy_simple/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; negative_voice/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; corpus_a/ corpus_b/ corpus_c/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; no_voice/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; silence_clips/ ambient_noise/ musan_noise/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="まとめ"&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;分類クラスの設計には、完全性は目指さず無矛盾性を目指すという原則があり、seedとタクソノミーというデータ仮説、サブデータセットによる分割統治で実現しやすくなる&lt;/li&gt;
&lt;li&gt;評価用データはgrade別に難易度設計しておくと、基礎能力への悪影響やholdout過信を避けられる&lt;/li&gt;
&lt;li&gt;Gradeの本質的な価値は、最小条件でタスクが本当に解けるかを検査できること。grade1が解けない場合、モデルの問題ではなくタスク定義・クラス設計自体を見直すべきシグナルになる&lt;/li&gt;
&lt;li&gt;スコープは「なんでもできる（バギー）」か「少しはできる（リライアブル）」かの選択で、理想は前者だが直接狙うと修羅の道になりやすく、狭いgradeから段階的に広げる方が近道になる&lt;/li&gt;
&lt;li&gt;grade別のラダー表を作っておくと、各gradeで何が加わるかを1段単位で明文化でき、スコープの限界を開発者以外にも説明しやすくなる&lt;/li&gt;
&lt;li&gt;クラスの範囲を絞り境界を太くするGeometric Class Designや、コア（意味軸）とサーフェス（表現軸）の分離によって、クラスの幾何学的な領域を設計できる&lt;/li&gt;
&lt;li&gt;2つのクラスを継続的に取り違えるサンプルがある場合、それはANDの領域が存在するサインであり、無理に既存クラスへ押し込めず、専用の中間クラスを新設することで無矛盾性を回復できる&lt;/li&gt;
&lt;li&gt;AND領域への対処は、中間クラスの新設以外にも、離散ラベル（排他性を前提にしたsingle-label）かマルチラベル（クラスごとに独立したlogit形式）かというラベル表現自体の選択でも解決できる&lt;/li&gt;
&lt;li&gt;特に意味の近いクラス同士は、inner-class・inter-classでの一貫性チェックと、境界専用データセットが有効&lt;/li&gt;
&lt;li&gt;shifted positive・adversarial negatives・Truncated Negative・Hidden Negativeなど、hard caseの作り方には複数の手法があり、組み合わせ数を数えることでデータのかさ増し効果も見積もれる&lt;/li&gt;
&lt;li&gt;NoneクラスやNegationスロットの設計によって、明示的な負例の識別や否定表現の混同を防げる&lt;/li&gt;
&lt;li&gt;メタクラスという観点では、None（負例）・OOD（分布外）・Impossible（分類不能な入力）の3種類があり、特にImpossibleを切り出しておくと、性能低下の原因がクラス設計の問題か壊れた入力かを切り分けられる&lt;/li&gt;
&lt;li&gt;ラベルにはGold（人手検証済み、高品質・高コスト）とSilver（自動生成、大量・ノイズあり）の信頼度差があり、Trainは混ぜて量を確保、Diag・Testはなるべく Goldを使うという使い分けが重要&lt;/li&gt;
&lt;li&gt;クラス・属性の管理は、直交する（フォルダ管理）・直交しない（Tag.json）・対称的（Pair.json）という性質ごとに、適した方法を使い分ける&lt;/li&gt;
&lt;li&gt;実際のフォルダ構成例として、grade×class×subclassの多クラス分類と、source軸を起点にした二値分類の2パターンを示した&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="参考文献"&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E5%88%86%E5%B8%83%E5%A4%96%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%90%AB%E3%82%80%E5%88%86%E9%A1%9E%E3%81%A7false-positive%E3%82%92%E6%8A%91%E3%81%88%E3%82%8B%E6%96%B9%E6%B3%95/" &gt;分布外データの対処方法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%81%A8%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータとデータソースの再考&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%82%BB%E3%83%83%E3%83%88%E3%81%AE%E5%88%86%E5%89%B2%E3%81%AE%E5%86%8D%E8%80%83/" &gt;機械学習におけるデータセットの分割の再考&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/%E3%83%95%E3%83%AA%E3%82%AC%E3%83%8A%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E3%82%AF%E3%83%AC%E3%83%B3%E3%82%B8%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B%E6%99%82%E3%81%AB%E7%9B%B4%E3%81%97%E3%81%9F%E9%A0%85%E7%9B%AE%E3%81%AE%E3%83%A1%E3%83%A2/" &gt;フリガナデータをクレンジングする時に直した項目のメモ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://www.m1ke.org/p/22%E3%81%AE%E4%B8%AD%E3%81%AB%E6%BD%9C%E3%82%80%E9%83%A8%E5%88%86%E3%81%A8%E5%85%A8%E4%BD%93%E3%81%AE%E6%A7%8B%E9%80%A0/" &gt;2×2の中に潜む部分と全体の構造&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://en.wikipedia.org/wiki/G%C3%B6del%27s_incompleteness_theorems" target="_blank" rel="noopener"
&gt;Gödel&amp;rsquo;s incompleteness theorems - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://en.wikipedia.org/wiki/Sorites_paradox" target="_blank" rel="noopener"
&gt;Sorites paradox - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>