Files
pop-fem-audit/docs/methodology.md
T
2026-08-17 22:38:31 +08:00

182 lines
9.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 方法細節
(全文方法節底稿。演算法在執行前寫定;任何修訂記入
`decision-log.md`。定義檔全文見 `prompts/`,執行紀錄見
`runs/`。)
## 自然編碼管線總覽
三個步驟:步驟 1 自由標註(兩次執行進池)→ 步驟 2 詞彙表
建構(詞向量分群,確定性)→ 步驟 3 全量編碼(2+1)。歌詞
只出現在步驟 1 與步驟 3;步驟 2 完全不接觸歌詞,也不呼叫
LLM。設計原則見 `research-plan.md`;本檔記載可重現的
演算法細節。
編號的所指為**研究程序的工序**,不是定義檔:步驟 1 與
步驟 3 有定義檔(`prompts/`),步驟 2 沒有——它是單一
確定性計算,由 `cluster-keywords` 一個子命令完成。有無
定義檔的區別即「該步是否為 LLM 判斷」,由 `prompts/`
否存在同號檔案直接可見。
## 步驟 2 詞彙表建構——詞向量分群
詞彙表由確定性程序產生,不經 LLM。完整分割(每個關鍵字
恰屬一組、不遺漏、不新增)由演算法結構保證,無須事後
驗證。
### 進池
兩次標註執行的全部關鍵字取聯集、逐字串精確去重、字典序
排列。失敗與拒答的記錄跳過(其歌曲不貢獻關鍵字);解析
時偵測重複鍵,違規即失敗。同時記出處(欄位 Keyword、
Run、Song,一列一筆出現,依三欄排序),供收斂軌跡分析;
出處記錄不進任何下游輸入。
### 分群
- **嵌入**`sentence-transformers/all-mpnet-base-v2`
(釘定 revision),關鍵字的連字號先還原為空格再編碼,
輸出 768 維向量並 L2 正規化。
- **分群**:階層式聚合分群(Ward linkage),k=100。
向量既已正規化,歐氏距離與餘弦相似度單調對應;三種
linkage 實測比較,Ward 於各個 k 的組內一致性均最高
average 與 complete 皆產生吞噬半數語料的巨大異質
組)。
- **組數的取捨**:k 太小則壓縮比過高,樹上層被迫併入
不相干的詞,組雖大而無主題(k=30 最大組 491 詞、
組內一致性 0.41,成員橫跨籃球、海灘、外星人綁架);
k 太大則人工難以通覽。定於 100,理由是實測顯示雜物櫃
組於此始裂解為有主題的組,且編碼實測未見碼數過多的
副作用(詞彙表外的碼歸零、僅一個碼零使用)。
- **組名**:取 medoid——與該組中心(成員向量均值後
正規化)餘弦相似度最高的成員詞。組名因此必為模型
自己產出過的關鍵字,非任何人事後撰寫。已知限制:
組越大越異質時,medoid 只是折衷詞,可能代表不了組內
內容(實測 `mutual-individuality` 組內一致 0.70 而
編碼從未使用);此類碼於結果中呈現為零使用,據實
報告,不事後改名。
- **取捨紀錄**:曾以 LLM 單發收斂(mergecap 兩步)
實作本步,四種模型六次執行全部無法維持完整分割,
已棄用(詳見 `decision-log.md` 2026-08-05;棄用的
定義檔止於 git 歷史,見 `git log -- prompts/`)。
- **產物**:六份,前綴分別標示來源與結果。
`source-keywords.txt`(進池後的關鍵字,一行一個)與
`source-provenance.csv`(出處)記錄進來的是什麼;
`result-keywords.txt`(組名,一行一個)與
`groups.csv`(欄位 Group、Keyword,一列一個成員)
記錄算出來的分割;`keywords-to-merge.json`
`{"keywords": [...]}`)是實際交給模型的碼,即組名
加上先驗主題詞——六份中只有這一份含研究者的介入。
`meta.json` 記錄執行本身:進池的兩份執行歸檔與其有效
筆數、嵌入模型與釘定 revision、分群參數與組數、外加
的先驗詞、關鍵字總數,以及產生數字的套件版本。凡命令
列上的選擇與環境事實皆在此,不記時間戳與輸入雜湊
——前者使同環境重跑逐位元組可再生,後者只會重述 git
已保證的事。
- **可重現性**:同一輸入、同一釘定模型、同一參數逐次
重現。不同 CPU/BLAS 實作的浮點尾數差異可能使邊界
詞的歸屬翻動,屬已揭露的限制;論文所用碼表逐字
commit,引用單位為該份定案檔案。
### women-power 的注入
定案詞彙表為 100 個分群組名再加上 `women-power` 一詞,
共 101 個碼。`women-power` 是研究者任意決定的先驗主題(即本
論文的主題本身),不由資料產生,屬揭露的儀器介入。該詞
於執行時以 `--extra-keyword` 明示加入,不寫死在程式裏
——研究者的介入因此每次都出現在重現命令上,而非無聲
發生;分群結果的兩份產物不含它,只有交給模型的碼表含
它。
注入而非另設篩選軌的理由:讓研究者的主題詞與模型自己
收斂出的類別(分群已自行長出 `female-empowerment` 等組)
在同一份提示詞、同一個判斷體制下受檢,避免單目標提問
把該主題的顯著性人為抬高。兩者的落點差異本身即可報告
的結果。
## 步驟 3 編碼的 2+1 比對與仲裁
- **步驟 3-1 code**:逐首比對兩次執行的標籤集合(引述不
參與比對)。兩次皆有的標籤為共識保留、兩次皆無為
共識不標;單邊標籤送仲裁。
- **步驟 3-2 code-arb**:仲裁者看歌詞全文與該標籤的引述
(不含執行別),裁決保留者附仲裁者自己的引述,剔除
者不列。剔除集合=送裁鍵減輸出鍵,由程式推得。
- 仲裁者的引述可能與原引述不同:仲裁是對歌詞的重新
判讀,其引述是該裁決自身的依據,非轉抄。
- 送入仲裁的標籤即模型自身不穩定的邊界判斷,其裁決為
單次記錄性決定,不宣稱可再生;可重現性依計畫定義為
「程序透明+可稽核」,裁決與其輸入全程歸檔。
## 女性力量候選集
候選集為兩類歌曲的合集:定案編碼含 `women-power` 者,
以及定案編碼含研究者指認之女性力量概念域分群組者。
指認於詞彙表定案後、黃金標準編碼開始前完成,指認清單
與理由記入決策日誌。
## 軌跡對映(診斷用)
沿收斂軌跡的機械對映:原始關鍵字 →(出處記錄)歌曲、
原始關鍵字 →(分群)組,純程式查表,決定性。以其結果
與步驟 3 直接編碼的差異率作為「收斂軌跡扭曲」的診斷量,
不作主結果。
## 全管線的交接契約
每一步的輸出如何變成下一步的輸入,皆為確定性程序,規則
明定如下:
- **歌詞輸入檔(步驟 1**`export-llm-input` 自工作
儲存產出,每筆 `{"id": "song-<ID>", "content": <歌詞>}`
依歌曲 ID 升序。步驟 3 的輸入由同一子命令、同一工作
儲存產出(見下),兩步的語料同一性由此成立;各步
輸入檔的 SHA-256 記入該步 meta。
- **步驟 1 → 2**`cluster-keywords` 讀兩份執行歸檔的
`output.jsonl`(一律以換行字元 `\n` 切行——歌詞含
U+0085 等控制字元時,`str.splitlines()` 類的通用切行
會截斷 JSON 字串,實測踩中),進池後直接分群,一次
產出上列六份檔案。
- **步驟 2 → 3 輸入檔**`export-llm-input --extras
<定案碼表>` 自工作儲存產出步驟 3 的輸入,每筆
`{"id": "song-<ID>", "content": <字串>}``content` 為
固定鍵序序列化的 `{"lyrics": …, "keywords": [...]}`
依歌曲 ID 升序。碼表以參數傳入而非填進定義檔——定義
檔只規定任務形狀,換詞彙表、換演算法都不必改它。
- **步驟 3-1 兩次執行 → 3-2**:逐首比對標籤集合(鍵
集合,引述不參與比對);僅有分歧的歌入仲裁輸入
JSONL,依歌曲 ID 升序,每筆 `id` 沿用 `song-<ID>`、
`content` 為固定鍵序序列化的
`{"lyrics": …, "disagreements": …}`disagreements
鍵按字典序。
- **步驟 3 定案**:每首歌的最終標籤為共識標籤加上仲裁
保留的標籤,寫入逐首紀錄檔(歌依 ID 升序、標籤按
字典序,各標籤附其定案時的引述與來源層——共識或
仲裁)。
- **序列化通則**:所有中間檔為 UTF-8,欄序、鍵序與元素
序皆依上列規則明定,無時間戳、無隨機成分;JSON 解析
一律偵測重複鍵,違規即失敗。人讀為主的產物採純文字或
CSVCSV 依 RFC 4180,標題列字首大寫),機器交接檔採
JSON。給定相同的 LLM 執行輸出,全部交接產物逐位元組
可再生。
## 執行與稽核
- LLM 步驟以 `run-llm <定義檔> <輸入檔> <歸檔目錄>`
執行;2+1 步驟的兩次執行=重現命令清單上的兩行命令,
各自歸檔(`runs/<步驟>/run1`、`run2`),仲裁為獨立
步驟、獨立歸檔。
- 確定性步驟(進池、分群、比對、裁決套用、對映)為
子命令,其輸入輸出檔同隨 `runs/` 歸檔;因無執行變異,
歸檔目錄下不分 `run<N>` 層。
- Batch API 的每筆請求自含全部脈絡且互不可見(平台
契約),歌與歌之間的獨立性由此成立;兩次執行的獨立
性由「兩次呼叫、兩個批次、兩份歸檔」的執行結構自明。
- 每次 `run-llm` 執行的 token 用量與費用記入
`run-costs.md`,被取代的執行一併保留供總支出核算。
## 映射分析方法
(依 2026-07-30 決策,於看到結果前寫定;待黃金標準
編碼展開前補入。)