本リポジトリは、「2025年度卒業生 鍛原大成」の修士論文で使用した実験コードです。
研究内容は研究引き継ぎ資料_鍛原大成を参照してください。
SNS上のヘイトスピーチ検出において、データのラベリングには時間とコストを要します。本プロジェクトでは、大規模言語モデル(LLM)を活用してこのラベリング工程を効率化します。そのために、LLMラベルの精度向上および、人間による高品質なラベルとLLMによる擬似ラベルを最適に組み合わせる手法を確立することを目的としています。
本リポジトリには、ヘイトスピーチ検出モデルの精度向上とラベリングコスト削減に向けた、以下の実験および検証コードが含まれています。
LLMによる自動ラベリングの検証 GPT-4やGPT-4oなどのLLMを用い、few-shotプロンプティングやRAG(検索拡張生成)を組み合わせた際のラベリング精度を評価しています。
LLMラベル vs 人間ラベル それぞれのデータセットで学習したモデルの分類精度を比較しています。
難易度分類モデルの構築 分類が困難な投稿を事前に識別するモデルを構築し、人間が注力すべきデータを切り分ける手法を検討しています。
ハイブリッド学習の検証 人間のラベルとLLMの擬似ラベルを混合して学習させた際のモデル性能の変化を分析し、最適な混合比率を検証しています。
使用技術の概要
モデル: LUKE-base, DeBERTa-v3-base などの事前学習済みモデル
手法: Multi-sample dropout, Layer re-initialization, Zero-shot/Few-shot learning
データ: 日本語ヘイトスピーチ検出用データセット
--> データセットの構築は過去の倉嶋の研究で作成 (構築に使用したコードはこちら)
.
├── .gitignore
├── .python-version
├── pyproject.toml
├── uv.lock
├── README.md
└── src/
├── 000_精度検証/ # 既存の日本語事前学習済みモデル(LUKE, DeBERTa等)の性能評価
│ ├── train_deberta-v3-base.py
│ ├── train_luke-base.py
│ ├── train_luke-base_multi-sample-dropout.py
│ ├── train_luke-base_multi-sample-dropout_layer-re-initialization.py
│ ├── training_arguments.json
│ ├── validation.ipynb
│ └── models/ # 各実験手法ごとのテスト結果(CSV)を格納
│ ├── result.csv
│ ├── Baseline(9000)_LUKE-base/test.csv
│ ├── Baseline(9000)_LUKE-base_Multi-sample-dropout/test.csv
│ ├── Baseline(9000)_LUKE-base_Multi-sample-dropout_Layer-re-initialization/test.csv
│ └── Baseline(9000)_deberta-v3-base/test.csv
├── 001_前処理/ # 生データのクリーニングおよび学習用フォーマットへの変換
│ └── preprocess.ipynb
├── 002_難易度分類モデル&LLMラベル/ # LLMによるラベリング実行と「難しさ」の判定モデル
│ ├── ラベリングの性能比較.ipynb
│ ├── LLM_labeling/ # GPT-4oを用いた様々なプロンプト手法(RAG, Few-shot等)の実験
│ │ ├── gpt-4o_cover15shot.ipynb
│ │ ├── gpt-4o_cover3shot.ipynb
│ │ ├── gpt-4o_rag15shot.ipynb
│ │ ├── gpt-4o_rag3shot.ipynb
│ │ ├── gpt-4o_rag3shot_normal.ipynb
│ │ ├── gpt-4o_rag3shot_hate.ipynb
│ │ ├── gpt-4o_rand15shot.ipynb
│ │ ├── gpt-4o_rand3shot.ipynb
│ │ ├── gpt-4o_zero-shot.ipynb
│ │ └── labeled_data/
│ │ ├── result_with_gpt-4.csv
│ │ ├── result_with_gpt-4o.csv
│ │ ├── result_with_gpt-4o_all_3_rag.csv
│ │ ├── result_with_gpt-4o_all_3_random.csv
│ │ ├── result_with_gpt-4o_all_3_sample.csv
│ │ ├── result_with_gpt-4o_all_15_rag.csv
│ │ ├── result_with_gpt-4o_all_15_random.csv
│ │ ├── result_with_gpt-4o_all_15_sample.csv
│ │ ├── result_with_gpt-4o_hate.csv
│ │ └── result_with_gpt-4o_normal.csv
│ └── difficulty_model/ # 投稿がヘイト判定困難かどうかを予測する難易度分類モデル
│ ├── difficulty.ipynb
│ ├── train_difficulty.py
│ ├── training_arguments.json
│ └── fold_0-4_difficulty_LUKE-base_Multi-sample-dropout/test.csv
├── 003_LLM+人間で学習したモデル/ # 人間とLLMのラベルを混合したハイブリッド学習の検証
│ ├── train_cross.py
│ ├── train_cross_add.py
│ ├── train_cross_add_gpt4.py
│ ├── training_arguments.json
│ ├── verification.ipynb
│ ├── verification_add.ipynb
│ ├── 結果の分析.ipynb
│ ├── LLM_labeling/
│ │ ├── result_with_gpt-4.csv
│ │ ├── result_with_gpt-4o_all.csv
│ │ ├── result_with_gpt-4o_all_15_rag.csv
│ │ ├── result_with_gpt-4o_hate.csv
│ │ └── result_with_gpt-4o_normal.csv
│ ├── results_verification/
│ │ ├── gpt4o_0.0716/test.csv
│ │ ├── gpt4o_0.0752/test.csv
│ │ ├── gpt4o_0.0831/test.csv
│ │ ├── gpt4o_0.1207/test.csv
│ │ ├── gpt4o_0.73/test.csv
│ │ ├── gpt4o_1/test.csv
│ │ └── human/test.csv
│ └── results_verification_add/
│ ├── gpt4/test.csv
│ ├── gpt4/test_sample.csv
│ ├── gpt4o_0.0716/test.csv
│ ├── gpt4o_0.0752/test.csv
│ ├── gpt4o_0.0831/test.csv
│ ├── gpt4o_0.1207/test.csv
│ ├── gpt4o_0.73/test.csv
│ ├── gpt4o_1/test.csv
│ └── human/test.csv
├── 004_LLMのみで学習したモデル/ # LLMの擬似ラベルのみで学習した際の性能限界を検証
│ ├── train.ipynb
│ ├── train_label.py
│ ├── training_arguments.json
│ ├── labeled_data/
│ │ ├── result_with_gpt-4.csv
│ │ ├── result_with_gpt-4o_all.csv
│ │ ├── result_with_gpt-4o_all_15_rag.csv
│ │ ├── result_with_gpt-4o_hate.csv
│ │ └── result_with_gpt-4o_normal.csv
│ └── results_model/
│ ├── gpt-4/test.csv
│ ├── gpt-4o_best/test.csv
│ └── human/test.csv
├── 005_人間ラベルの分析/ # データセット自体の傾向や、LLMと人間の判断の乖離を分析
│ ├── analysis_dataset.ipynb
│ └── data/
│ ├── hate_speech_dataset_preprocessed.csv
│ ├── llm_vs_human_label.csv
│ ├── llm_vs_human_noun_analysis.csv
│ └── result_with_gpt-4o_all_15_rag.csv
└── data/ # 元データおよび前処理済みデータセット
├── hate_speech_dataset.csv
├── hate_speech_dataset_preprocessed.csv
└── tweet_annotate_data_cleaned_10000.csv
本リポジトリでは Python パッケージ管理に uv を使用しています。
# リポジトリのクローン
git clone https://github.com/sakurai-lab/taisei_kajiwara_research2025.git
cd taisei_kajiwara_research2025
# uvのインストール(未導入の場合)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 仮想環境の作成と依存関係の同期
uv sync
# 仮想環境の有効化
source .venv/bin/activate # macOS/Linux
.venv\Scripts\activate # Windows
OPENAI_API_KEY = your_api_key_here各工程は src 下の番号順に実行することを想定しています。
既存モデル(LUKE, DeBERTa)のベースライン精度を計測します。
学習済みの結果比較は validation.ipynb で確認できます。
生データから不要な文字列を除去し、学習用のデータセットを作成します。
LLMによる自動ラベリングと、投稿の「ヘイト判定難易度」を予測するモデルの構築を行います。
LLMラベリング: LLM_labeling/ 内の各ノートブック(例: gpt-4o_rag15shot.ipynb)を実行し、擬似ラベルを生成します。
難易度分類モデルの学習:difficulty.ipynb で学習を行います。
本研究のメインとなる、人間ラベルとLLMラベルを混合したハイブリッドデータセットの精度検証です。
交差検証の実行 verification.ipynb で単体での学習を行います。 verification_add.ipynb で人間ラベルデータで学習したモデルに追加学習を行います。
実験結果の可視化 結果の分析.ipynb で行います。
人間によるラベルを一切使わず、LLMの擬似ラベルのみで学習した際の性能を検証します。
データセットの質的な分析や、誤分類の傾向を品詞単位で分析します。
本リポジトリのモデル学習(LUKE, DeBERTa-v3 等)で使用されている標準的な設定は以下の通りです。
ハイパーパラメータの詳細な設定値は、各実行ディレクトリの training_arguments.json を参照してください。
| 項目 | 設定値 | 備考 |
|---|---|---|
| Base Model | studio-ousia/luke-base または microsoft/deberta-v3-base | |
| Epochs | 5 | データセットサイズにより調整 |
| Batch Size | 16 | |
| Learning Rate | 2e-5 | AdamW オプティマイザを使用 |
| Max Length | 256 | トークン化の最大長 |
| Warmup Ratio | 0.1 | 学習初期の学習率ウォームアップ |
| Weight Decay | 0.01 | 過学習抑制のための重み減衰 |
精度の向上のために以下の手法を組み合わせています。
Multi-sample Dropout
最終層のドロップアウトを複数回行い、平均を取ることで汎化性能を向上させています。
Layer Re-initialization
エンコーダーの最終層(通常は最終1層)を再初期化することで、特定のタスク(ヘイトスピーチ検出)への適応を促進しています。
Difficulty-aware Learning
難易度分類モデルによって「困難」と判定されたデータには、人間による高精度なラベルを優先的に割り当てる設定を行っています。
モデルの評価には以下の指標を用いています。
F1-Score (Macro)
ヘイト / 非ヘイトの不均衡を考慮したメイン指標
Accuracy
全体の正解率
Precision / Recall
各クラスに対する適合率と再現率
本リポジトリは、「2025年度卒業生 鍛原大成」の修士論文で使用した実験コードです。
研究内容は研究引き継ぎ資料_鍛原大成を参照してください。
SNS上のヘイトスピーチ検出において、データのラベリングには時間とコストを要します。本プロジェクトでは、大規模言語モデル(LLM)を活用してこのラベリング工程を効率化します。そのために、LLMラベルの精度向上および、人間による高品質なラベルとLLMによる擬似ラベルを最適に組み合わせる手法を確立することを目的としています。
本リポジトリには、ヘイトスピーチ検出モデルの精度向上とラベリングコスト削減に向けた、以下の実験および検証コードが含まれています。
LLMによる自動ラベリングの検証 GPT-4やGPT-4oなどのLLMを用い、few-shotプロンプティングやRAG(検索拡張生成)を組み合わせた際のラベリング精度を評価しています。
LLMラベル vs 人間ラベル それぞれのデータセットで学習したモデルの分類精度を比較しています。
難易度分類モデルの構築 分類が困難な投稿を事前に識別するモデルを構築し、人間が注力すべきデータを切り分ける手法を検討しています。
ハイブリッド学習の検証 人間のラベルとLLMの擬似ラベルを混合して学習させた際のモデル性能の変化を分析し、最適な混合比率を検証しています。
使用技術の概要
モデル: LUKE-base, DeBERTa-v3-base などの事前学習済みモデル
手法: Multi-sample dropout, Layer re-initialization, Zero-shot/Few-shot learning
データ: 日本語ヘイトスピーチ検出用データセット
--> データセットの構築は過去の倉嶋の研究で作成 (構築に使用したコードはこちら)
.
├── .gitignore
├── .python-version
├── pyproject.toml
├── uv.lock
├── README.md
└── src/
├── 000_精度検証/ # 既存の日本語事前学習済みモデル(LUKE, DeBERTa等)の性能評価
│ ├── train_deberta-v3-base.py
│ ├── train_luke-base.py
│ ├── train_luke-base_multi-sample-dropout.py
│ ├── train_luke-base_multi-sample-dropout_layer-re-initialization.py
│ ├── training_arguments.json
│ ├── validation.ipynb
│ └── models/ # 各実験手法ごとのテスト結果(CSV)を格納
│ ├── result.csv
│ ├── Baseline(9000)_LUKE-base/test.csv
│ ├── Baseline(9000)_LUKE-base_Multi-sample-dropout/test.csv
│ ├── Baseline(9000)_LUKE-base_Multi-sample-dropout_Layer-re-initialization/test.csv
│ └── Baseline(9000)_deberta-v3-base/test.csv
├── 001_前処理/ # 生データのクリーニングおよび学習用フォーマットへの変換
│ └── preprocess.ipynb
├── 002_難易度分類モデル&LLMラベル/ # LLMによるラベリング実行と「難しさ」の判定モデル
│ ├── ラベリングの性能比較.ipynb
│ ├── LLM_labeling/ # GPT-4oを用いた様々なプロンプト手法(RAG, Few-shot等)の実験
│ │ ├── gpt-4o_cover15shot.ipynb
│ │ ├── gpt-4o_cover3shot.ipynb
│ │ ├── gpt-4o_rag15shot.ipynb
│ │ ├── gpt-4o_rag3shot.ipynb
│ │ ├── gpt-4o_rag3shot_normal.ipynb
│ │ ├── gpt-4o_rag3shot_hate.ipynb
│ │ ├── gpt-4o_rand15shot.ipynb
│ │ ├── gpt-4o_rand3shot.ipynb
│ │ ├── gpt-4o_zero-shot.ipynb
│ │ └── labeled_data/
│ │ ├── result_with_gpt-4.csv
│ │ ├── result_with_gpt-4o.csv
│ │ ├── result_with_gpt-4o_all_3_rag.csv
│ │ ├── result_with_gpt-4o_all_3_random.csv
│ │ ├── result_with_gpt-4o_all_3_sample.csv
│ │ ├── result_with_gpt-4o_all_15_rag.csv
│ │ ├── result_with_gpt-4o_all_15_random.csv
│ │ ├── result_with_gpt-4o_all_15_sample.csv
│ │ ├── result_with_gpt-4o_hate.csv
│ │ └── result_with_gpt-4o_normal.csv
│ └── difficulty_model/ # 投稿がヘイト判定困難かどうかを予測する難易度分類モデル
│ ├── difficulty.ipynb
│ ├── train_difficulty.py
│ ├── training_arguments.json
│ └── fold_0-4_difficulty_LUKE-base_Multi-sample-dropout/test.csv
├── 003_LLM+人間で学習したモデル/ # 人間とLLMのラベルを混合したハイブリッド学習の検証
│ ├── train_cross.py
│ ├── train_cross_add.py
│ ├── train_cross_add_gpt4.py
│ ├── training_arguments.json
│ ├── verification.ipynb
│ ├── verification_add.ipynb
│ ├── 結果の分析.ipynb
│ ├── LLM_labeling/
│ │ ├── result_with_gpt-4.csv
│ │ ├── result_with_gpt-4o_all.csv
│ │ ├── result_with_gpt-4o_all_15_rag.csv
│ │ ├── result_with_gpt-4o_hate.csv
│ │ └── result_with_gpt-4o_normal.csv
│ ├── results_verification/
│ │ ├── gpt4o_0.0716/test.csv
│ │ ├── gpt4o_0.0752/test.csv
│ │ ├── gpt4o_0.0831/test.csv
│ │ ├── gpt4o_0.1207/test.csv
│ │ ├── gpt4o_0.73/test.csv
│ │ ├── gpt4o_1/test.csv
│ │ └── human/test.csv
│ └── results_verification_add/
│ ├── gpt4/test.csv
│ ├── gpt4/test_sample.csv
│ ├── gpt4o_0.0716/test.csv
│ ├── gpt4o_0.0752/test.csv
│ ├── gpt4o_0.0831/test.csv
│ ├── gpt4o_0.1207/test.csv
│ ├── gpt4o_0.73/test.csv
│ ├── gpt4o_1/test.csv
│ └── human/test.csv
├── 004_LLMのみで学習したモデル/ # LLMの擬似ラベルのみで学習した際の性能限界を検証
│ ├── train.ipynb
│ ├── train_label.py
│ ├── training_arguments.json
│ ├── labeled_data/
│ │ ├── result_with_gpt-4.csv
│ │ ├── result_with_gpt-4o_all.csv
│ │ ├── result_with_gpt-4o_all_15_rag.csv
│ │ ├── result_with_gpt-4o_hate.csv
│ │ └── result_with_gpt-4o_normal.csv
│ └── results_model/
│ ├── gpt-4/test.csv
│ ├── gpt-4o_best/test.csv
│ └── human/test.csv
├── 005_人間ラベルの分析/ # データセット自体の傾向や、LLMと人間の判断の乖離を分析
│ ├── analysis_dataset.ipynb
│ └── data/
│ ├── hate_speech_dataset_preprocessed.csv
│ ├── llm_vs_human_label.csv
│ ├── llm_vs_human_noun_analysis.csv
│ └── result_with_gpt-4o_all_15_rag.csv
└── data/ # 元データおよび前処理済みデータセット
├── hate_speech_dataset.csv
├── hate_speech_dataset_preprocessed.csv
└── tweet_annotate_data_cleaned_10000.csv
本リポジトリでは Python パッケージ管理に uv を使用しています。
# リポジトリのクローン
git clone https://github.com/sakurai-lab/taisei_kajiwara_research2025.git
cd taisei_kajiwara_research2025
# uvのインストール(未導入の場合)
curl -LsSf https://astral.sh/uv/install.sh | sh
# 仮想環境の作成と依存関係の同期
uv sync
# 仮想環境の有効化
source .venv/bin/activate # macOS/Linux
.venv\Scripts\activate # Windows
OPENAI_API_KEY = your_api_key_here各工程は src 下の番号順に実行することを想定しています。
既存モデル(LUKE, DeBERTa)のベースライン精度を計測します。
学習済みの結果比較は validation.ipynb で確認できます。
生データから不要な文字列を除去し、学習用のデータセットを作成します。
LLMによる自動ラベリングと、投稿の「ヘイト判定難易度」を予測するモデルの構築を行います。
LLMラベリング: LLM_labeling/ 内の各ノートブック(例: gpt-4o_rag15shot.ipynb)を実行し、擬似ラベルを生成します。
難易度分類モデルの学習:difficulty.ipynb で学習を行います。
本研究のメインとなる、人間ラベルとLLMラベルを混合したハイブリッドデータセットの精度検証です。
交差検証の実行 verification.ipynb で単体での学習を行います。 verification_add.ipynb で人間ラベルデータで学習したモデルに追加学習を行います。
実験結果の可視化 結果の分析.ipynb で行います。
人間によるラベルを一切使わず、LLMの擬似ラベルのみで学習した際の性能を検証します。
データセットの質的な分析や、誤分類の傾向を品詞単位で分析します。
本リポジトリのモデル学習(LUKE, DeBERTa-v3 等)で使用されている標準的な設定は以下の通りです。
ハイパーパラメータの詳細な設定値は、各実行ディレクトリの training_arguments.json を参照してください。
| 項目 | 設定値 | 備考 |
|---|---|---|
| Base Model | studio-ousia/luke-base または microsoft/deberta-v3-base | |
| Epochs | 5 | データセットサイズにより調整 |
| Batch Size | 16 | |
| Learning Rate | 2e-5 | AdamW オプティマイザを使用 |
| Max Length | 256 | トークン化の最大長 |
| Warmup Ratio | 0.1 | 学習初期の学習率ウォームアップ |
| Weight Decay | 0.01 | 過学習抑制のための重み減衰 |
精度の向上のために以下の手法を組み合わせています。
Multi-sample Dropout
最終層のドロップアウトを複数回行い、平均を取ることで汎化性能を向上させています。
Layer Re-initialization
エンコーダーの最終層(通常は最終1層)を再初期化することで、特定のタスク(ヘイトスピーチ検出)への適応を促進しています。
Difficulty-aware Learning
難易度分類モデルによって「困難」と判定されたデータには、人間による高精度なラベルを優先的に割り当てる設定を行っています。
モデルの評価には以下の指標を用いています。
F1-Score (Macro)
ヘイト / 非ヘイトの不均衡を考慮したメイン指標
Accuracy
全体の正解率
Precision / Recall
各クラスに対する適合率と再現率