Day 151 — NLP系コンペへの応用② — テキスト分類にPseudo Labelingは本当に効くのか

2026-09-10 金 / Phase 6(Grandmaster、総復習後の発展回) 理論→コーディング Pseudo Labeling / 選択バイアス / 仮説が覆った実測

📚 背景知識(読んでから問題へ)

🔁
Day150では画像・数値データ向けのTTAをテキスト分類に応用し、「意味を保つ」SAFE辞書でさえ精度が悪化する(平均acc 0.9244→0.8778)という結果を実測した。今日はDay150の次回予告どおり、別の手法 Pseudo Labeling(疑似ラベル自己学習) をテキスト分類に応用する。Day136-137で表形式データに実装し効果を確認した手法だが、表形式データで効いたテクニックがテキストでも同じように効くのかを実測する。

Pseudo Labelingの基本アイデアは「少量のラベル付きデータでモデルを学習し、そのモデルでラベルなしデータを予測し、確信度が高い予測だけを疑似ラベルとして学習データに追加して再学習する」という半教師あり学習の手法である。Day136-137では表形式データで確信度閾値を適切に設定すれば精度改善につながることを確認済みである。

🧪
検証前の仮説: Day136-137の表形式データと同様に、テキスト分類でもPseudo Labelingはラベル付きデータが少ない(40件)状況で有効に働き、確信度閾値を適切に選べば精度を改善できるだろう。まずは表形式データで使っていた「確信度0.9以上を採用」という定番の閾値を素直に流用して検証する。
用語意味
Pseudo Labeling(自己学習)ラベル付きモデルの予測を、ラベルなしデータの「疑似的な正解」として学習データに追加する半教師あり学習の手法
確信度閾値predict_probaの値がこの閾値を超えた(または下回った)予測だけを疑似ラベルとして採用する基準
選択バイアス「確信度が高い」という基準でデータを選ぶこと自体が、元の分布から偏ったサブセットを切り出してしまう現象。ラベルが全部正解でも生じうる
ラベルノイズ疑似ラベルが実際の正解と異なってしまうこと(モデルの予測ミスによる誤ラベル)

🗂️ データ・分割のスキーマ

変数名型内容
df (n=450)pd.DataFramemake_text_dataset()で生成した合成テキスト全体。Day150と同じ語彙・ロジック
test_df (110件)pd.DataFrame最終評価専用のホールドアウト。全設定で共通に使う
labeled_df (40件)pd.DataFrame「ラベル付きデータが少ない」状況を模したベースライン学習セット
unlabeled_df (約300件)pd.DataFrameラベルを隠した疑似ラベル候補プール(label列は分析専用でモデルには使わせない)
STANDARD_THRESHOLD   = 0.90  # Day136-137(表形式データ)の定番閾値をそのまま流用
MODERATE_THRESHOLD   = 0.60  # 実測したproba分布(0.22〜0.72程度)に合わせて調整
PERMISSIVE_THRESHOLD = 0.55  # ほぼ無選別に近い、意図的に緩すぎる閾値

🎯 問題

タスクA(理論)

以下2点をそれぞれ2〜3文で説明する。

1
Day136-137の表形式データで使っていた「確信度0.9以上を採用」という定番閾値を、そのままテキスト分類(TF-IDF+LogisticRegression、ラベル付き40件)に流用すると何が起こりうるかをpredict_probaの性質から予想する
2
Pseudo Labelingが悪化した場合、「選択バイアス」と「ラベルノイズ」のどちらが主因かを見分けるには、どのような比較実験を設計すればよいかを説明する

タスクB(コーディング→分析)

B1
make_text_dataset(n=450, seed) — Day150と同じ語彙・ロジックで合成テキストを生成する関数を実装する(n=450に拡大)
B2
split_seed(seed) — test_df(110件) / labeled_df(40件) / unlabeled_df(残り約300件)の3分割を作る関数を実装する
B3
train_and_eval(texts, labels, test_df) — TF-IDF+LogisticRegressionを学習しtest精度・loglossを返す共通関数を実装する
B4
select_confident_pseudo_labels(model, vectorizer, unlabeled_df, threshold) — 予測確率が閾値条件を満たす行だけを選ぶ関数を実装する
B5
STANDARD(0.90)/MODERATE(0.60)/PERMISSIVE(0.55)の3閾値で、5シードにわたりPseudo Labelingあり/なしのaccuracyとloglossを比較する
B6
閾値0.60で選ばれた同じサブセットに対し(A)モデル自身の疑似ラベル、(B)正解ラベル(オラクル)、(C)同数のランダム選択+正解ラベル、の3パターンでtest精度を比較する「選択バイアス vs ラベルノイズ」アブレーションを実装する
B7
STANDARD閾値で5シード全て追加件数0件であること/MODERATE・PERMISSIVEどちらもbaselineより悪化すること/ランダム選択がオラクルを明確に上回ることをassert文で確認する
B8
(考察): 「表形式データで効いたテクニックをそのままテキストに持ち込むとどこで壊れるか」について、Day150のTTAの失敗パターンとの共通点・相違点を踏まえ100〜150字程度で述べる

💡 ヒント

ヒント1方向性

タスクAの1.は、Day150で見た「TF-IDFの固定語彙による情報の分岐」とは別角度の問題である。ヒントは「ラベル付きデータがわずか40件しかない状態で学習したLogisticRegressionのpredict_probaは、どれくらい極端な値(0や1に近い値)を出せるか」を考えることである。学習データが少なく特徴量空間が疎なTF-IDFでは、モデルの自信の"天井"がそもそも低い可能性がある。

ヒント2アプローチ
  • select_confident_pseudo_labelsを実装したら、まずthreshold=0.9で実際に何件選ばれるかを1シードだけ試しに確認するとよい。「0件」という結果はバグではなく重要な実測結果である
  • アブレーション(A)(B)(C)は、labeled_dfに「追加する行以外」は固定し、(A)(B)は同じmask(同じ行)を使いラベルだけを疑似/正解で変える。(C)はmaskを使わずmask.sum()と同じ件数をnp.random.RandomState(seed).choiceでランダムに選ぶ
  • 「オラクル」は、モデルには本来見せない正解情報を検証目的だけに使う、という意味。「もし疑似ラベルが100%正しくても、確信度による選び方自体に問題はないか」を確認するために使う
  • 5シードのループをrun_threshold_sweep(seed, threshold)・run_selection_bias_ablation(seed, threshold=0.6)のように関数化しpd.DataFrame([... for s in SEEDS])で集計する
ヒント3コード骨格
def select_confident_pseudo_labels(model, vectorizer, unlabeled_df, threshold):
    X_un = vectorizer.transform(unlabeled_df["text"])
    proba = model.predict_proba(X_un)[:, 1]
    mask = (proba >= threshold) | (proba <= (1 - threshold))
    pseudo_labels = (proba[mask] >= 0.5).astype(int)
    return mask, pseudo_labels

def run_selection_bias_ablation(seed, threshold=0.60):
    labeled_df, unlabeled_df, test_df = split_seed(seed)
    acc_base, ll_base, vectorizer, model = train_and_eval(
        labeled_df["text"].tolist(), labeled_df["label"].tolist(), test_df)

    mask, pseudo_labels = select_confident_pseudo_labels(model, vectorizer, unlabeled_df, threshold)
    true_labels_selected = unlabeled_df.loc[mask, "label"].to_numpy()

    # (A) 疑似ラベル自己学習 / (B) オラクル(同じ選択+正解ラベル) / (C) ランダム(同数+正解ラベル)
    # ... train_and_eval を3パターン呼び出して比較する ...

✅ 模範解答

import random
import numpy as np
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, log_loss

# POSITIVE_WORDS / NEGATIVE_WORDS / NEUTRAL_WORDS / make_text_dataset は Day150と同一(省略)

def train_and_eval(texts, labels, test_df):
    vectorizer = TfidfVectorizer()
    X = vectorizer.fit_transform(texts)
    model = LogisticRegression(max_iter=1000)
    model.fit(X, labels)
    X_test = vectorizer.transform(test_df["text"])
    proba = model.predict_proba(X_test)[:, 1]
    acc = accuracy_score(test_df["label"], (proba >= 0.5).astype(int))
    ll = log_loss(test_df["label"], proba, labels=[0, 1])
    return acc, ll, vectorizer, model


def select_confident_pseudo_labels(model, vectorizer, unlabeled_df, threshold):
    X_un = vectorizer.transform(unlabeled_df["text"])
    proba = model.predict_proba(X_un)[:, 1]
    mask = (proba >= threshold) | (proba <= (1 - threshold))
    pseudo_labels = (proba[mask] >= 0.5).astype(int)
    return mask, pseudo_labels


def split_seed(seed):
    df = make_text_dataset(n=450, seed=seed)
    rest_df, test_df = train_test_split(df, test_size=110, random_state=seed, stratify=df["label"])
    labeled_df, unlabeled_df = train_test_split(rest_df, train_size=40, random_state=seed, stratify=rest_df["label"])
    return labeled_df.reset_index(drop=True), unlabeled_df.reset_index(drop=True), test_df.reset_index(drop=True)


def run_threshold_sweep(seed, threshold):
    labeled_df, unlabeled_df, test_df = split_seed(seed)
    acc_base, ll_base, vectorizer, model = train_and_eval(
        labeled_df["text"].tolist(), labeled_df["label"].tolist(), test_df)

    mask, pseudo_labels = select_confident_pseudo_labels(model, vectorizer, unlabeled_df, threshold)
    n_added = int(mask.sum())
    if n_added == 0:
        acc_st, ll_st, pseudo_acc = acc_base, ll_base, float("nan")
    else:
        true_labels = unlabeled_df.loc[mask, "label"].to_numpy()
        pseudo_acc = float((pseudo_labels == true_labels).mean())
        texts_st = labeled_df["text"].tolist() + unlabeled_df.loc[mask, "text"].tolist()
        labels_st = labeled_df["label"].tolist() + pseudo_labels.tolist()
        acc_st, ll_st, _, _ = train_and_eval(texts_st, labels_st, test_df)

    return {"seed": seed, "n_added": n_added, "pseudo_acc": pseudo_acc,
            "acc_base": acc_base, "acc_st": acc_st, "ll_base": ll_base, "ll_st": ll_st}


def run_selection_bias_ablation(seed, threshold=0.60):
    labeled_df, unlabeled_df, test_df = split_seed(seed)
    acc_base, ll_base, vectorizer, model = train_and_eval(
        labeled_df["text"].tolist(), labeled_df["label"].tolist(), test_df)

    mask, pseudo_labels = select_confident_pseudo_labels(model, vectorizer, unlabeled_df, threshold)
    n_added = int(mask.sum())
    true_labels_selected = unlabeled_df.loc[mask, "label"].to_numpy()

    # (A) 疑似ラベル自己学習: 高確信度サブセット + モデル自身の予測ラベル
    acc_pseudo, ll_pseudo, _, _ = train_and_eval(
        labeled_df["text"].tolist() + unlabeled_df.loc[mask, "text"].tolist(),
        labeled_df["label"].tolist() + pseudo_labels.tolist(), test_df)

    # (B) オラクル: 同じ高確信度サブセット + 正解ラベル(ラベルノイズだけを除去)
    acc_oracle, ll_oracle, _, _ = train_and_eval(
        labeled_df["text"].tolist() + unlabeled_df.loc[mask, "text"].tolist(),
        labeled_df["label"].tolist() + true_labels_selected.tolist(), test_df)

    # (C) ランダム: 同じ件数をランダム選択 + 正解ラベル(選択バイアスだけを除去)
    rng = np.random.RandomState(seed)
    rand_idx = rng.choice(len(unlabeled_df), size=n_added, replace=False)
    rand_texts = unlabeled_df.iloc[rand_idx]["text"].tolist()
    rand_labels = unlabeled_df.iloc[rand_idx]["label"].tolist()
    acc_random, ll_random, _, _ = train_and_eval(
        labeled_df["text"].tolist() + rand_texts,
        labeled_df["label"].tolist() + rand_labels, test_df)

    return {"seed": seed, "n_added": n_added, "acc_base": acc_base,
            "acc_pseudo": acc_pseudo, "acc_oracle": acc_oracle, "acc_random": acc_random}


SEEDS = [0, 1, 2, 3, 4]
df_std = pd.DataFrame([run_threshold_sweep(s, 0.90) for s in SEEDS])
df_mod = pd.DataFrame([run_threshold_sweep(s, 0.60) for s in SEEDS])
df_perm = pd.DataFrame([run_threshold_sweep(s, 0.55) for s in SEEDS])
df_ablation = pd.DataFrame([run_selection_bias_ablation(s, 0.60) for s in SEEDS])

assert (df_std["n_added"] == 0).all(), "STANDARD閾値0.90で疑似ラベルが1件も追加されない、という実測結果が再現しませんでした"
assert df_mod["acc_st"].mean() < df_std["acc_base"].mean(), "MODERATE閾値の自己学習がbaselineを悪化させていません"
assert df_perm["acc_st"].mean() < df_std["acc_base"].mean(), "PERMISSIVE閾値の自己学習がbaselineを悪化させていません"
assert df_ablation["acc_random"].mean() > df_ablation["acc_oracle"].mean() + 0.05, \
    "ランダム選択(正解ラベル)がオラクルを明確に上回っていません"
print("[OK] STANDARDは空振り/MODERATE・PERMISSIVEはbaselineを悪化/悪化の主因は選択バイアス")
# ============ 実測結果(実際にPython 3で実行して確認済み) ============
# ---- Part 1: 閾値スイープ ----
# STANDARD threshold=0.90: 5シード全てで n_added=0(疑似ラベル追加ゼロ、完全に空振り)
# MODERATE threshold=0.60: mean n_added≈91件 mean pseudo_acc=0.8995
#   mean acc_base=0.7418 → mean acc_st=0.6236(悪化)
# PERMISSIVE threshold=0.55: mean n_added≈182件 mean pseudo_acc=0.8122
#   mean acc_base=0.7418 → mean acc_st=0.6527(悪化、だがMODERATEより悪化幅は小さい)
#
# ---- Part 2: 選択バイアス vs ラベルノイズのアブレーション(閾値0.60)----
#   mean acc_base  = 0.7418
#   (A) 疑似ラベル自己学習           mean acc = 0.6236
#   (B) オラクル(同じ選択+正解ラベル) mean acc = 0.7291  ← baselineとほぼ同水準
#   (C) ランダム(同数+正解ラベル)     mean acc = 0.8818  ← 大きく改善
#
# [OK] STANDARDは空振り/MODERATE・PERMISSIVEはbaselineを悪化/悪化の主因は選択バイアス
⚠️
重要な発見1(当初の仮説が外れた): 検証前の仮説は「表形式データと同様、閾値を適切に選べば改善するはず」だった。しかし3閾値すべてでbaseline(0.7418)を下回った。特に「定番」の閾値0.90は、40件学習ではpredict_probaの実測レンジが0.22〜0.72程度に収まり、5シード全てで疑似ラベルが1件も追加されないという完全な空振りに終わった。
🔍
重要な発見2(選択バイアスの正体): 疑似ラベル精度は約90%と高いのに自己学習は悪化した(0.7418→0.6236)。「同じ選択+正解ラベル」のオラクルもbaseline並み(0.7291)にしか届かず、「同数のランダム選択+正解ラベル」だけが大きく改善した(0.8818)。ラベルの正しさと無関係に、確信度で選ぶという選択プロセス自体が多様性を損ない悪化の主因になっていた。

📊 結果の可視化

① 40件でベースライン学習

train_and_eval()でラベル付き40件のみからbaselineを学習

② 閾値スイープで疑似ラベル追加

STANDARD/MODERATE/PERMISSIVEの3閾値でselect_confident_pseudo_labels()を実行

③ 選択バイアスのアブレーション

疑似ラベル・オラクル・ランダムの3パターンでtest精度を比較

閾値別accuracy比較(5シード平均、高いほど良い) baseline(40件のみ) 0.7418 STANDARD(0.90)=baselineと同値 0.7418(追加0件) PERMISSIVE(0.55) 0.6527 MODERATE(0.60) 0.6236 仮説(閾値を選べば改善)に反し、全ての疑似ラベル自己学習がbaselineを下回った STANDARD(0.90)は追加件数0件で"空振り"、それ以外は追加するほど悪化した
選択バイアス vs ラベルノイズ アブレーション(閾値0.60、5シード平均) (C) ランダム選択+正解ラベル 0.8818 baseline(40件のみ) 0.7418 (B) オラクル(同じ選択+正解ラベル) 0.7291 (A) 疑似ラベル自己学習 0.6236 (B)がbaseline並みにしか届かない一方、(C)は大きく改善 → 正解ラベルを与えても 「確信度で選ぶ」という選び方自体が多様性を損ない、悪化の主因になっている
設定平均accuracy解釈
(C) ランダム選択 + 正解ラベル0.8818選択バイアスもラベルノイズも無い理想形
baseline(40件のみ)0.7418追加データなし
(B) オラクル(確信度選択+正解ラベル)0.7291ラベルノイズを除いても改善せず→選択バイアスが主因と判明
(A) 疑似ラベル自己学習(確信度選択+予測ラベル)0.6236選択バイアス+ラベルノイズの二重苦

🪜 Step-by-Step 解説

1なぜ「定番の閾値0.90」がテキスト分類では機能しないのか

mask = (proba >= threshold) | (proba <= (1 - threshold))
# threshold=0.90 のとき、5シード全てで mask.sum() == 0
📋
なぜこうするか: ラベル付きデータが40件、TF-IDFの語彙サイズが数十語という条件では、LogisticRegressionの決定境界を支えるサンプル数が少なすぎて、極端な確率(0.9以上や0.1以下)を出すだけの根拠をモデルが持てない。実測したproba分布の最大値はおよそ0.65〜0.71程度で、Day136-137の表形式データの閾値をそのまま移植すると1件も選ばれずに自己学習が完全な空振りに終わる。新しいデータ形式・データ量に移るたびにproba分布を実測してから閾値を決める必要がある。

2なぜ疑似ラベル精度が90%近くても自己学習は悪化するのか

acc_pseudo = 0.6236   # モデル自身の疑似ラベルを使用
acc_oracle = 0.7291   # 同じサブセット + 正解ラベル
acc_random = 0.8818   # 同数のランダムサブセット + 正解ラベル
🎯
なぜこうするか: 疑似ラベルを正解ラベルに置き換えたオラクル設定(0.7291)でも、ランダムに同じ件数を選んだ場合(0.8818)に遠く及ばなかった。「確信度が高い」という基準で選ばれるサンプルは、初期40件モデルにとって「すでに判断しやすい典型的な」サンプルに偏っており、モデルが不得意とする境界事例(本来学習に有益な多様なサンプル)を排除してしまう。ラベルが仮に100%正しくても、選び方自体が汎化性能を損なうことが、このオラクル比較によって実測で裏付けられた。

3なぜPERMISSIVE閾値(0.55)がMODERATE閾値(0.60)より"マシ"だったのか

# MODERATE(0.60): mean n_added≈91件, mean pseudo_acc=0.8995, mean acc_st=0.6236
# PERMISSIVE(0.55): mean n_added≈182件, mean pseudo_acc=0.8122, mean acc_st=0.6527
🔀
なぜこうするか: 「閾値を緩めるほど質の低い疑似ラベルが混ざるので悪化するはず」という直感に反し、PERMISSIVE(0.55)の方が悪化幅が小さかった。閾値を緩めたことで追加件数が約2倍(91件→182件)に増え、より多様なサンプルが学習データに入った結果、疑似ラベル精度の低下(89.95%→81.22%)という損失よりも、多様性が増えたことによる選択バイアス緩和効果の方が上回った可能性がある。「精度の高い疑似ラベルを厳選する」ことと「多様なサンプルを確保する」ことはトレードオフになりうる。

🧮 数学・統計の補足(文系向け)

📝
「選択バイアス」を「得意な問題だけを解いて自己採点する受験勉強」として理解する:

40件しか勉強していない受験生が、模試の問題集(ラベルなしデータ)の中から「自分が自信を持って解ける問題」だけを選んで自己採点し、その解答を新しい過去問として勉強に追加する場面を想像するとよい。自己採点自体が仮に100%正確だったとしても(今日のオラクル設定に相当)、選んだ問題は「すでに得意な、簡単な問題」に偏っている。これでは本当に苦手な範囲(境界事例)を一切補強できず、模試全体の点数(test精度)はランダムに問題を追加した場合(ランダム設定に相当)ほど伸びない。
📊
「ラベルノイズ」と「選択バイアス」の違いを「誤答の混入」と「偏った出題範囲」として理解する:

ラベルノイズは「自己採点を間違えた(答えを勘違いしたまま覚えてしまった)」ことに相当し、選択バイアスは「そもそも解く問題の範囲が偏っている(得意分野しか復習していない)」ことに相当する。今日の実測(オラクル0.7291 vs ランダム0.8818)は、自己採点の正確さを100%にしても、出題範囲の偏りだけでこれほど点数差が生まれることを示している。

🏆 Kaggleでの実践的な使い方

よく使われるコンペカテゴリ: ☑ 自然言語処理(NLP) / ☑ 表形式データ(半教師あり学習全般に応用可)

原則

🎨 確信度だけでなく「多様性」を考慮する

diversity-aware pseudo labeling

確信度上位を単純に選ぶだけでは選択バイアスが生じる。クラスタリングや埋め込み距離を使って「確信度が高く、かつ既存の学習データと似すぎていない」サンプルを優先的に選ぶ手法が上位解法で使われることがある。

実例

📐 閾値は必ずデータごとに実測してから決める

流用は危険

「他のコンペや他のデータ形式で効いた閾値」をそのまま流用すると、今日のSTANDARD閾値(0.90)のように完全に機能しないことがある。predict_probaのヒストグラムを可視化し、実際の分布範囲を確認してから設計するのが安全である。

実務

🔬 オラクル・ランダムとの比較を検証プロセスに組み込む

原因の切り分け

「疑似ラベルを使ったら精度が下がった」で終わらせず、「同じ選択+正解ラベル」「ランダム選択+正解ラベル」との比較を行うことで、原因がラベルの質か選び方かを切り分けられる。原因が分かれば対策の方向性が変わる。

⚠️ よくある誤解・ミス

誤解・ミスなぜ起こるか正しい理解
「他のデータ・他のコンペで効いた閾値」をそのまま流用できると思い込む「Pseudo Labeling」という同じ名前の手法だから同じパラメータで動くと錯覚するラベル付きデータの量・特徴量空間の性質(表形式 vs TF-IDFの疎な空間)が変わればpredict_probaが出しうる値の範囲も変わる。閾値は毎回実測して設計し直す必要がある
疑似ラベルの精度(正解率)が高ければ自己学習は安全だと考えるラベルノイズが唯一の悪化要因だと無意識に仮定してしまう疑似ラベル精度が約90%と高くても、確信度による選択プロセス自体が学習データの多様性を損ない(選択バイアス)、精度を悪化させることがある。ラベルノイズと選択バイアスは別の問題であり、両方を切り分けて検証する必要がある
閾値を上げるほど(厳しくするほど)安全だと考える「確信度が高い=正しい可能性が高い」という直感を、選択バイアスの影響を考慮せずに適用してしまう今日の実測ではPERMISSIVE(0.55)の方がMODERATE(0.60)より悪化幅が小さかった。閾値を上げることは疑似ラベルの精度を上げる一方で追加サンプルの多様性を減らし選択バイアスを強める可能性があり、単純な一方向の改善にはならない
「疑似ラベルが0件だった」ことをバグだと思い込みコードを疑う期待した挙動(何かしら追加される)と異なる結果が出ると、まず自分の実装ミスを疑ってしまう正しく実装されたコードでも「データの性質上、閾値の条件を満たす予測が存在しない」という結果は普通に起こりうる。まずproba分布を確認し、閾値がそのデータに対して現実的な値かを検証する習慣が必要

🚀 次のステップ

  • 発展: 今日は確信度上位を選ぶ1回だけの自己学習(1ラウンド)を検証したが、複数ラウンドにわたって反復的に自己学習を繰り返すと、モデルが自身の予測に対してますます自信を深め、選択バイアスがラウンドを追うごとに強化される「確証バイアスの雪だるま現象」が起こりうる。予備検証では複数ラウンドの反復自己学習で最終的に未ラベルデータのほぼ全件が学習データに取り込まれ、精度がさらに悪化する傾向が観測された。この「ラウンド数と悪化の関係」を正式に検証することが次の発展候補である
  • 次回予告: 引き続きPhase6の「NLP系コンペへの応用」を深掘りし、次回はback-translationのような文単位のTTA(Day150で保留)、または今日発見した「選択バイアス」を緩和するdiversity-awareな疑似ラベル選択(クラスタリングベースの多様性確保)をテキスト分類に実装して検証することを検討する

Phase 6 の学習マップ(NLP系コンペへの応用フェーズ継続中)

1-23
Phase6主要テーマ6項目・総復習(Day126-149、完了)
発展①②
NLP系コンペへの応用(Day150: TTA→逆効果/Day151: Pseudo Labeling→選択バイアスで逆効果)

Day150に続き、Day151も「表形式・画像で効いた手法をそのままテキストに持ち込むと機能不全になる」というパターンが実測で再現された。TTAは情報の中身が壊れ、Pseudo Labelingは情報の選び方が壊れる、という異なるメカニズムで同じ結論に至った。

📝 自己評価(解いた後に記入)

自分の回答・気づき・メモ: