iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0
自我挑戰組

從多數決到可信投票:30 天打造 TACT 大語言模型推理聚合方法系列 第 5

Day 5|高信心真的比較常答對嗎?用 AUC 把方向量出來

  • 分享至 

  • xImage
  •  

第四篇把原始信心換成題內排名,總算解決了尺度亂飄的問題。可惜排名只告訴我誰比較有把握,還沒回答最關鍵的一句:有把握的軌跡,真的比較常答對嗎?

今天會用有答案的開發集量這件事。測試題不需要答案標籤,先別被公式裡的 y 嚇到。

AUC 在這裡問的是什麼

從同一題隨機抽一條正確軌跡和一條錯誤軌跡。若正確軌跡的信心較高,記 1 分;信心相同,兩邊各算一半;錯誤軌跡較高則記 0 分。把所有正誤配對平均起來,就是這一題的 AUC:

題內 AUC 定義

這裡的 AUC 不是整份測試集的答案準確率,也不是「模型有 80% 機率答對」。它只看同一題裡,信心能不能把正確軌跡排在錯誤軌跡前面。

AUC=1 代表每一條正確軌跡都排在錯誤軌跡上方;AUC=0.5 表示信心沒有辨別方向;AUC<0.5 就有意思了,錯誤軌跡反而比較有自信。

把方向攤成 -1 到 1

TACT 不直接使用 0 到 1 的 AUC,而是轉成 Somers' D:

Somers D 與 AUC

這個轉換很單純,0.5 被移到 0,正向與反向的距離也變得對稱:

AUC = 1.00  →  D =  1.00
AUC = 0.75  →  D =  0.50
AUC = 0.50  →  D =  0.00
AUC = 0.25  →  D = -0.50
AUC = 0.00  →  D = -1.00

第三篇看到的「高信心錯誤搶走票數」,在這裡就會留下負號。後面推導 γ 時,這個符號會決定票重要順著信心走,還是反過來走。

一題怎麼算

逐一跑正誤配對很容易懂,軌跡多時卻有點浪費。Mann–Whitney U 可以直接用第四篇算過的 midrank 得到同一個答案:

Mann Whitney U 與題內 AUC

是正確軌跡數,n⁰ 是錯誤軌跡數。Python 實作如下:

from dataclasses import dataclass

import numpy as np
from scipy.stats import rankdata

@dataclass(frozen=True)
class ItemDiscrimination:
    auc: float
    d: float
    n_pairs: int

def item_discrimination(
    confidence: list[float] | np.ndarray,
    correct: list[int] | np.ndarray,
) -> ItemDiscrimination | None:
    c = np.asarray(confidence, dtype=float)
    y = np.asarray(correct, dtype=int)

    if c.ndim != 1 or c.size == 0 or c.shape != y.shape:
        raise ValueError("confidence and correct must be equal-length vectors")
    if not np.all(np.isfinite(c)):
        raise ValueError("confidence must be finite")
    if not np.all(np.isin(y, [0, 1])):
        raise ValueError("correct must contain only 0 and 1")

    positive = y == 1
    n1 = int(positive.sum())
    n0 = int((~positive).sum())
    if n1 == 0 or n0 == 0:
        return None

    ranks = rankdata(c, method="average")
    u = float(ranks[positive].sum() - n1 * (n1 + 1) / 2)
    auc = u / (n1 * n0)

    return ItemDiscrimination(
        auc=auc,
        d=2.0 * auc - 1.0,
        n_pairs=n1 * n0,
    )

用三個小例子檢查正向、反向和信心平手:

examples = [
    ([0.80, 0.70, 0.60, 0.55], [1, 1, 0, 0]),
    ([0.55, 0.60, 0.80, 0.70], [1, 1, 0, 0]),
    ([0.80, 0.50, 0.50, 0.40], [1, 1, 0, 0]),
]

for confidence, correct in examples:
    print(item_discrimination(confidence, correct))

輸出為:

ItemDiscrimination(auc=1.0,   d= 1.0, n_pairs=4)
ItemDiscrimination(auc=0.0,   d=-1.0, n_pairs=4)
ItemDiscrimination(auc=0.875, d= 0.75, n_pairs=4)

第三組有一組正誤軌跡同為 0.50,midrank 會自動給那個配對半分,因此 AUC 是 0.875。

全對或全錯的題目算不出 D

一題若 16 條軌跡全部答對,就找不到錯誤軌跡配對;全部答錯也一樣。程式在這兩種情況回傳 None,不硬塞 0。

回傳 0 會暗示「信心沒有方向」,但眼前其實沒有做比較的條件。這些題目對模型整體準確率仍然有用,只是不能拿來估題內辨別度。TACT 會在開發集估 D 時略過它們,測試時照常投票。

n_pairs=n¹×n⁰ 也值得保存。一題有 8 條正確、8 條錯誤時,共有 64 組比較;15 對 1 只有 15 組。兩題都能算 D,資訊量差很多。下一篇合併多題結果時,這個數字會變成權重。

別把所有題目的軌跡倒進同一池

想像兩道題:簡單題的軌跡全部答對,信心落在 0.90 左右;困難題全部答錯,信心只有 0.30。若忽略題目邊界,把所有軌跡混著算,AUC 會等於 1,看起來像完美的信心通道。

實際上,任何一題內都沒有正誤軌跡可以比較。那個漂亮的 AUC 只量到「簡單題信心高、困難題信心低」,無法證明信心能改善同一題的投票。TACT 堅持在題內算 D,就是為了擋掉這種難度混淆。

信心正確性耦合強度掃描

圖:以 κ_c 從負值掃到正值的合成測試。κ_c 小於零代表高信心反而更常出錯;AUC 方向閘門能辨識正負方向,單向 CISC 則會在反向訊號區快速失準。

標籤只在開發階段出現

correct 需要標準答案,所以今天寫的是 TACT-dev 的估計步驟。開發集會估出一個全域信任方向,測試集只要答案、信心和這個已經決定的 γ,不會偷看測試答案。

目前還缺兩件事:每題的 D 會晃,多題合併後也要知道估計有多不確定。第六篇會用正誤配對數做 van Elteren 式合併,再處理平手修正與標準誤。只有方向還不夠穩時,γ 才有理由停在 0。

論文預印本:TACT: Trust-Anchored Confidence Tempering for Self-Consistency Voting in Large Language Models


上一篇
Day 4|同樣是 0.9,為什麼不能直接拿來比?
下一篇
Day 6|每題的 D 都不一樣,該聽誰的?
系列文
從多數決到可信投票:30 天打造 TACT 大語言模型推理聚合方法6
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言