Merge the keyword pooling into cluster-keywords

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-17 22:38:30 +08:00
co-authored by Claude Opus 5
parent 5cf2b8ee8c
commit de8b8ee678
18 changed files with 526 additions and 626 deletions
+8
View File
@@ -439,3 +439,11 @@
提示詞、同一判斷體制下受檢,兩者落點差異本身即可報告
的結果。代價:候選集召回由雙通道減為單通道,若實測
召回不足再議。
- **詞彙表建構併為單一步驟**:原分為進池(步驟 2-1)與
分群(步驟 2-2)兩個子命令,合併為一個
`cluster-keywords`——自兩份標註歸檔直接產出五份檔案
`source-` 兩份記錄進來的關鍵字與其出處,`result-`
兩份記錄算出的分割,`keywords-to-merge.json` 為交給
模型的碼),歸檔併入 `runs/02-cluster/`。理由:兩者
之間沒有需要檢視的決策點,拆成兩步只增加讀者要理解
的環節;驗證能力不變,五份產物各自可查。
+22 -23
View File
@@ -13,9 +13,10 @@ LLM。設計原則見 `research-plan.md`;本檔記載可重現的
演算法細節。
編號的所指為**研究程序的工序**,不是定義檔:步驟 1 與
步驟 3 有定義檔(`prompts/`),步驟 2 沒有——它是確定性
計算。有無定義檔的區別即「該步是否為 LLM 判斷」,由
`prompts/`否存在同號檔案直接可見。
步驟 3 有定義檔(`prompts/`),步驟 2 沒有——它是單一
確定性計算,由 `cluster-keywords` 一個子命令完成。有無
定義檔的區別即「該步是否為 LLM 判斷」,由 `prompts/`
否存在同號檔案直接可見。
## 步驟 2 詞彙表建構——詞向量分群
@@ -23,16 +24,15 @@ LLM。設計原則見 `research-plan.md`;本檔記載可重現的
恰屬一組、不遺漏、不新增)由演算法結構保證,無須事後
驗證。
### 步驟 2-1 進池
### 進池
兩次標註執行的全部關鍵字取聯集、逐字串精確去重、字典序
排列,寫成純文字檔(一行一個關鍵字)。失敗與拒答的記錄
跳過(其歌曲不貢獻關鍵字);解析時偵測重複鍵,違規即
失敗。同時寫出處 CSV(欄位 Keyword、Run、Song,一列一筆
出現,依三欄排序),供收斂軌跡分析;出處記錄不進任何
下游輸入。
排列。失敗與拒答的記錄跳過(其歌曲不貢獻關鍵字);解析
時偵測重複鍵,違規即失敗。同時記出處(欄位 Keyword、
Run、Song,一列一筆出現,依三欄排序),供收斂軌跡分析;
出處記錄不進任何下游輸入。
### 步驟 2-2 分群
### 分群
- **嵌入**`sentence-transformers/all-mpnet-base-v2`
(釘定 revision),關鍵字的連字號先還原為空格再編碼,
@@ -47,12 +47,14 @@ LLM。設計原則見 `research-plan.md`;本檔記載可重現的
實作本步,四種模型六次執行全部無法維持完整分割,
已棄用(詳見 `decision-log.md` 2026-08-05;棄用的
定義檔止於 git 歷史,見 `git log -- prompts/`)。
- **產物**三份。分群明細 CSV(欄位 Group、Keyword
一列一個成員,依兩欄排序)記錄機器算出的分割;組名
純文字檔(一行一個,字典序)是分群結果的可讀清單
定案碼表 JSON`{"keywords": [...]}`)記錄實際交給
模型的碼,即組名加上先驗主題詞。前兩份只含分群結果,
只有第三份含研究者的介入。
- **產物**五份,前綴分別標示來源與結果。
`source-keywords.txt`(進池後的關鍵字,一行一個)與
`source-provenance.csv`(出處)記錄進來的是什麼
`result-keywords.txt`(組名,一行一個)與
`groups.csv`(欄位 Group、Keyword,一列一個成員)
記錄算出來的分割;`keywords-to-merge.json`
`{"keywords": [...]}`)是實際交給模型的碼,即組名
加上先驗主題詞。只有最後一份含研究者的介入。
- **可重現性**:同一輸入、同一釘定模型、同一參數逐次
重現。不同 CPU/BLAS 實作的浮點尾數差異可能使邊界
詞的歸屬翻動,屬已揭露的限制;論文所用碼表逐字
@@ -110,15 +112,12 @@ LLM。設計原則見 `research-plan.md`;本檔記載可重現的
依歌曲 ID 升序。步驟 3 的輸入由同一子命令、同一工作
儲存產出(見下),兩步的語料同一性由此成立;各步
輸入檔的 SHA-256 記入該步 meta。
- **步驟 1 → 2-1**`pool-keywords` 讀兩份執行歸檔的
- **步驟 1 → 2**`cluster-keywords` 讀兩份執行歸檔的
`output.jsonl`(一律以換行字元 `\n` 切行——歌詞含
U+0085 等控制字元時,`str.splitlines()` 類的通用切行
會截斷 JSON 字串,實測踩中),輸出關鍵字純文字檔與
出處 CSV
- **步驟 2-12-2**`cluster-keywords` 讀關鍵字池純
文字檔,輸出分群明細 CSV、組名純文字檔與定案碼表
JSON。
- **步驟 2-2 → 3 輸入檔**`export-llm-input --extras
會截斷 JSON 字串,實測踩中),進池後直接分群,一次
產出上列五份檔案
- **步驟 2 → 3 輸入檔**`export-llm-input --extras
<定案碼表>` 自工作儲存產出步驟 3 的輸入,每筆
`{"id": "song-<ID>", "content": <字串>}``content` 為
固定鍵序序列化的 `{"lyrics": …, "keywords": [...]}`
+4 -5
View File
@@ -49,10 +49,9 @@ pop-fem-audit/
│ │ │ │ # Wikidata into the snapshot CSV
│ │ │ ├── fetch_lyrics.py # fetch missing lyrics from the
│ │ │ │ # public APIs into the lyrics dir
│ │ │ ├── pool_keywords.py # pool the two tagging runs'
│ │ │ │ # keywords (step 2-1)
│ │ │ ├── cluster_keywords.py # build the vocabulary by
│ │ │ │ # embedding + clustering (step 2-2)
│ │ │ ├── cluster_keywords.py # pool the tagging runs'
│ │ │ │ # keywords and cluster them
│ │ │ │ # into the codes (step 2)
│ │ │ └── run_llm.py # API 執行器:一份定義檔+一份輸入
│ │ │ # →歸檔至指定目錄(Batch API);
│ │ │ # 比對與仲裁編排由獨立子命令承擔
@@ -69,7 +68,7 @@ pop-fem-audit/
│ │ ├── output.jsonl # 該次執行原始輸出
│ │ └── meta.json # model ID、temperature、時間戳、
│ │ # batch ID、token 用量
│ └── 02-01-pool/ 02-02-cluster/ # 確定性步驟:無執行變異,
│ └── 02-cluster/ # 確定性步驟:無執行變異,
│ # 不分 run<N> 層
├── results/ # 論文引用的報表 CSV(export 產出;
│ # 「可再生仍 commit」的唯一例外)
+5 -5
View File
@@ -97,8 +97,8 @@
thematic keywords:前導研究三粒度比較(keywords 過碎、
themes 過早抽象)之繼承,於執行前鎖定,防止事後擇優。
2. **詞彙表建構(步驟 2**:兩次執行的關鍵字取聯集去重
(步驟 2-1 進池),以句向量模型嵌入階層式聚合分群
(步驟 2-2),k=50,組名取 medoid。完整分割由演算法
,以句向量模型嵌入階層式聚合分群k=50,組名取
medoid;進池與分群為同一個確定性子命令。完整分割由演算法
結構保證。頻次不入收斂:頻率的分析角色由步驟 3 編碼
承擔;池中頻次含跨執行噪音。
3. **編碼(步驟 3**:以定稿詞彙表對全部歌曲 2+1 編碼
@@ -124,9 +124,9 @@
03-02-code-arb.md;仲裁定義檔同 prefix 加 `-arb`。檔名
與目錄名補零只為排序,正文一律寫「步驟 1」「步驟 3-2」。
編號的所指是工序而非定義檔,因此確定性的第 2 步雖無
定義檔仍佔一個編號,其歸檔為 `runs/02-01-pool/`
`runs/02-02-cluster/`。檔名不帶版本號——版本即 git
歷史,失敗的版本不保留,需要回看的舊版都在 git history
定義檔仍佔一個編號,其歸檔為 `runs/02-cluster/`。檔名不帶
版本號——版本即 git 歷史,失敗的版本不保留,需要回看的
舊版都在 git history
每次執行的定義檔快照隨 `runs/` 自我完備。全部中間交接檔
同隨 `runs/` 歸檔(交接契約見 `methodology.md`)。