1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

初心者向け──LLM開発コンペにおけるHLE誤答分析

Last updated at Posted at 2025-10-29

はじめに

こんにちは。
LLM開発コンペチームRAMENに参加したのデータ班メンバーです。

プロジェクトの前半では、主にSeedの収集を担当していましたが、
後半からは評価班が出してくれたHLE(Humanity’s Last Exam)の正誤表をもとに、
評価結果を分析しました。

この記事では、私が実際にColab上で行った分析コードとともに、
初心者としてどのように気づきを得ていったのかを紹介します。

誤答分析の目的

LLM開発において、HLEで更に高得点を取るためにはどうすればよいか、
初心者なりに考えた結果、思い出したのは受験勉強でした。

ー「なぜ間違えたのか」を知り、
 また間違えないように工夫することでスコアを上げるー

これをLLM開発にも応用できるんじゃないかと。

誤答の種類によって、取り得る対策がまったく違います。

・計算問題の誤り → 計算ミス?定義や定理、公式などの理解不足?
・知識問題の誤り → 知識を得る/整理する?
・回答は正しいが形式が違う → 回答前に指定フォーマットを確認する?

どの問題でなぜ間違えたかが分からないと、
Seed改善やプロンプト修正の方向性を誤ります。

どんなタイプの誤答が多いのか、初心者なりに分析してみました。

Step 1. 評価ログをColabで分析

評価班が出してくれたHLEの評価結果はJSON形式でした。
以下コード(抜粋)で分析してみました。

# 正解が単一英字(A–Eなど)→MC、モデル回答が一文字A–E以外なら違反
def is_mc(ans):
    return bool(re.fullmatch(r"[A-Za-z]", str(ans).strip())) if ans is not None else False

df["IsMC"] = df["CorrectAnswer"].map(is_mc)

df["FormatViolation"] = False
df.loc[df["IsMC"], "FormatViolation"] = ~df.loc[df["IsMC"], "ModelAnswer"].astype(str)\
    .str.strip().str.upper().str.fullmatch(r"[A-E]")

acc_mc  = (df.loc[df["IsMC"], "IsCorrect"]  == "yes").mean()*100 if df["IsMC"].any() else np.nan
acc_nmc = (df.loc[~df["IsMC"], "IsCorrect"] == "yes").mean()*100 if (~df["IsMC"]).any() else np.nan
print("\nAccuracy by format:")
print("MC:", f"{acc_mc:.2f}%")
print("Non-MC:", f"{acc_nmc:.2f}%")
print("Format violations (MC only):", int(df["FormatViolation"].sum()))

plt.figure()
plt.bar(["Non-MC","MC"], [acc_nmc, acc_mc])
plt.ylabel("Accuracy (%)")
plt.title("Accuracy by Question Format")
plt.show()
#  問題タイプ分類(ヒューリスティック)
def problem_type(ca, ma):
    s = str(ca or "")
    if re.fullmatch(r"[A-Za-z]", s.strip()):
        return "MC"
    if re.fullmatch(r"[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?", s.strip()):
        return "PureNumeric"
    if re.match(r"^\s*[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?\s*[a-zA-Zµ%/·\*\^\-\_]+", s):
        return "UnitNumeric"
    if any(tok in s for tok in ["\\frac","\\int","\\sum","_{","}\\","$","^"]):
        return "Symbolic"
    if re.fullmatch(r"[A-Za-z][A-Za-z0-9]{1,5}", s.strip()):
        return "Code"
    return "OpenText"

df["Type"] = df.apply(lambda r: problem_type(r["CorrectAnswer"], r["ModelAnswer"]), axis=1)

type_acc = df.groupby("Type")["IsCorrect"].apply(lambda x: (x=="yes").mean()*100).sort_values(ascending=False)
print("\nAccuracy by Type (%):\n", type_acc)

fmt_viol_by_type = df.groupby("Type")["FormatViolation"].sum()
print("\nFormat violations by Type:\n", fmt_viol_by_type)

Qwen3-235B-A22Bの評価結果を分析したところ、
Format violations (MC only): 122/222
となり、“フォーマットミス”が多く検出されました。

Step 2. 目視確認して分かった落とし穴

誤答だけでなく、正答もいくつか見てみると、判定結果は以下の通りでした。

正答 モデルの回答 判定
4 The answer is 4. ✅(形式違いだが正解扱い)
A The answer is B ❌(本来は“選択ミス”だが、誤って“フォーマットミス”に分類していた)
Mars Mars. ✅(形式違いだが正解)

つまり、
"The answer is 4." のような出力は正解扱いになっていた一方で、
正答がAなのに「The answer is B」と出力したケースは、
本来は「選択ミス」であるにも関わらず、“フォーマットミス”として誤分類していました。

Step 3. 質問文から誤答分析

フォーマットミスの項目を除き、誤答タイプを再定義する必要があったため、
思い切って考え方を変え、質問文を分類することで誤答タイプを推測してみました。

classify_question 内容
Calculation 数字・数式が多ければ計算問題
Knowledge 固有名詞(大文字開始の単語が多い)や "Act", "Author", "Law" などが多ければ知識問題
Reasoning Yes/No, True/False, 正誤判定なら推論問題
Language 言語・翻訳系

以下、コードを抜粋して載せます。

#judge=="yes" → 正解 と仮定
df["IsCorrect"] = df["judge"].apply(lambda x: True if str(x).lower()=="yes" else False)

#全体統計
total = len(df)
correct = df["IsCorrect"].sum()

#category列を "Math/Algebra" のように "/" 区切りにして細分類
df["MainCategory"] = df["category"].apply(lambda x: str(x).split("/")[0])
df["SubCategory"] = df["category"].apply(lambda x: str(x).split("/")[1] if "/" in str(x) else "General")

def classify_question(text):
    """問題文の性質を簡易分類"""
    if pd.isna(text):
        return "Unknown"

    #数字・数式が多ければ計算問題
    if re.search(r"\d|=|\+|\-|\*|/|log|sin|cos|tan|√|∑|π", text, re.IGNORECASE):
        return "Calculation"

    #固有名詞(大文字開始の単語が多い)や "Act","Author" などが多ければ知識問題
    if len(re.findall(r"\b[A-Z][a-z]+\b", text)) >= 3 or re.search(r"Act|War|Author|King|Law|Novel|State", text, re.IGNORECASE):
        return "Knowledge"

    #Yes/No, True/False, 正誤判定なら推論問題
    if re.search(r"Yes|No|True|False|correct|incorrect", text, re.IGNORECASE):
        return "Reasoning"

    #言語・翻訳系
    if re.search(r"translate|pronounce|language|word|spelling", text, re.IGNORECASE):
        return "Language"

    return "General"

#新しい列を追加
df["ProblemType"] = df["question"].apply(classify_question)

#誤答のみ集計
wrong_df = df[~df["IsCorrect"]]
summary_type = (
    wrong_df.groupby(["MainCategory","SubCategory","ProblemType"])
    .size()
    .reset_index(name="WrongCount")
    .sort_values(["MainCategory","SubCategory","WrongCount"], ascending=[True,True,False])
)

display(summary_type)

分析してみると結果は以下のようになりました。

MainCategory SubCategory ProblemType WrongCount
0 Biology Medicine Calculation 10
1 Chemistry General Calculation 6
2 Computer Science AI Calculation 11
3 Engineering General Calculation 2
4 Humanities Social Science Calculation 7
5 Humanities Social Science Knowledge 3
6 Math General Calculation 34
7 Math General Reasoning 1
8 Other General Calculation 7
9 Other General Knowledge 2
10 Physics General Calculation 9
11 Physics General Knowledge 1

これをもとに、Seed改善やプロンプト修正の議論ができたかな…?と思います。

学びと改善ポイント

評価結果の分析を通して得た学びは以下の通りです。

・目視確認の重要性
・誤答タイプ(間違える問題の傾向)を分析することでLLM強化の方向性がわかるかも

一方で、初心者の分析なのでまだまだ改善の余地があるかと思います。
例えば、問題分類基準の見直し・精緻化やCoTに基づく誤答分析など、挙げればきりがないですね…。

まとめ

ポイント 内容
目的 評価結果から誤答傾向を把握し、Seed改善に繋げる
課題 フォーマットと選択ミスを混同していた
対処 どのような問題を間違えたかに着目してみた
成果 実質的な誤答問題の把握とその対策に集中できた
学び 評価結果の目視確認をすることが重要

同じようにHLE評価ログを扱っている方は、
ぜひ一度、本当に“フォーマットミス”かどうか、目視で見直してみてくださいー!

使用環境

・Google Colab(無料)

本プロジェクトは、国立研究開発法人新エネルギー・産業技術総合開発機構(以下「NEDO」)の「日本語版医療特化型LLMの社会実装に向けた安全性検証・実証」における基盤モデルの開発プロジェクトの一環として行われます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?