iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
Claude AI

研究生自救指南:30 天用 Claude Code 打造我的論文工具箱系列 第 14

Day 14|反向題、遺漏值、離群值:清理規則不是 prompt,是程式碼

  • 分享至 

  • xImage
  •  

昨天把 Google 表單匯出的原始檔改好欄名、刪掉重複和測試填答,287 份變成 279 份,存成 data/clean/01_renamed.csv。今天要做的三件事——反向計分、處理遺漏值、找離群值——是資料清理裡最容易做錯、做錯了又最難發現的三件。

做錯了不會報錯。它只會安靜地讓你的相關係數變號、讓平均數偏掉、讓結論反過來。

劑量換算不心算
臨床上藥物劑量換算有公式、有換算表,沒有人心算。不是因為護理師不會算,是因為一天算三十次,總有一次會錯,而錯的那一次沒有人會知道。

反向計分就是劑量換算。五點量表的反向題是 6 減原分,簡單到不可能錯——但 279 份乘以 8 題,兩千多次,一定有錯的。以前我在 Excel 裡一欄一欄拉公式,拉到第五欄的時候少選了一列,整欄往上錯一格,兩週後跑相關才發現倦怠跟睡眠品質變成負相關。

所以今天的原則只有一條:清理規則不寫在 prompt 裡,寫成程式碼。 我不叫 AI「幫我把反向題處理一下」,我叫它「依這份規則檔寫一支腳本」,然後我讀腳本、跑腳本、看紀錄。

為什麼一定要是程式碼?三個理由,都回到前面講過的東西。第一,程式碼可以重跑,這是 Day 4 的原則二——clean/ 裡的東西要能刪掉重生。第二,程式碼可以被讀,我看得懂它做了什麼,prompt 產生的結果我只看得到結果。第三,程式碼可以貼進論文的方法學附錄,「本研究反向題以 6 減原始分數計分」這句話後面,有一行程式可以對。

先寫規則檔
跟 Day 11 的 APA 規則檔一樣,規則先寫成人讀的檔,再讓它變成程式。存在 analysis/cleaning-rules.md:

清理規則(02_clean)

輸入

data/clean/01_renamed.csv(Day 13 輸出,未做任何計分)

規則一:反向計分

  • 倦怠量表 22 題(bo01–bo22),五點 Likert,1–5
  • 反向題:bo04, bo07, bo09, bo12, bo17, bo18, bo19, bo21(量表手冊 p. 6)
  • 公式:反向後分數 = 6 − 原始分數
  • 只做一次,只對 01_renamed.csv 做,輸出到新檔

規則二:遺漏值

  • 以「量表」為單位計算遺漏題數,不以整份問卷為單位
  • 倦怠量表遺漏 ≤ 4 題(22 題的 20%):以該受試者該量表已作答題目的平均補值
  • 遺漏 > 4 題:不補值,該量表分數標記為缺失,新增欄位 bo_missing_flag = True
  • 補值用「個人平均」,不用「全體平均」
  • 依據:老師建議;統計教科書第 X 章(需在論文方法學交代)

規則三:離群值

  • 只針對連續變項:每週工時(hours_week)、年資(years)
  • 每週工時合理範圍 8–84;年資合理範圍 0–45
  • 超出範圍:新增欄位 <變項>_flag = True,只標記,不刪除,不修改原值
  • 刪不刪由我看過清單後決定,並在論文交代

輸出

  • data/clean/02_cleaned.csv
  • analysis/cleaning-log.md:每一條規則影響了幾筆
    規則檔裡每一個數字都有來源:反向題號來自量表手冊、20% 的門檻來自老師、工時範圍是我自己定的(一週七天每天十二小時是上限)。指不出來源的規則,Day 11 說過,口試時答不出來。

規則二特別把「個人平均」寫進去,是因為第一版沒寫,它用了全體平均——這件事後面講。

讓它寫腳本,我讀腳本
在專案資料夾啟動 claude,打「讀 @analysis/cleaning-rules.md,寫成 analysis/02_clean.py,用 pandas,每一條規則對應一段並加註解,不要做規則檔沒寫的事」。

它寫出來大概這樣:

import pandas as pd

df = pd.read_csv("data/clean/01_renamed.csv")
log = []

規則一:反向計分(五點量表,6 − 原分)

REV = ["bo04", "bo07", "bo09", "bo12", "bo17", "bo18", "bo19", "bo21"]
df[REV] = 6 - df[REV]
log.append(f"規則一 反向計分:{len(REV)} 題 × {len(df)} 筆")

規則二:遺漏值(以量表為單位,≤4 題個人平均補值,>4 題標記)

BO = [f"bo{i:02d}" for i in range(1, 23)]
miss = df[BO].isna().sum(axis=1)
ok = miss <= 4
df.loc[ok, BO] = df.loc[ok, BO].apply(lambda r: r.fillna(r.mean()), axis=1)
df["bo_missing_flag"] = ~ok
log.append(f"規則二 補值:{miss.between(1, 4).sum()} 筆;標記缺失:{(~ok).sum()} 筆")

規則三:離群值(只標記,不刪)

for col, lo, hi in [("hours_week", 8, 84), ("years", 0, 45)]:
flag = ~df[col].between(lo, hi)
df[f"{col}_flag"] = flag
log.append(f"規則三 {col} 超出 {lo}–{hi}:{flag.sum()} 筆,已標記")

df.to_csv("data/clean/02_cleaned.csv", index=False)
with open("analysis/cleaning-log.md", "w", encoding="utf-8") as f:
f.write("\n".join(log) + "\n")
三十行。我不會寫 pandas,但我看得懂每一段在做什麼,因為它跟規則檔一段對一段。6 - df[REV] 就是規則一的公式;miss <= 4 就是規則二的門檻;between(lo, hi) 就是規則三的範圍。看得懂,才跑。

跑完 cleaning-log.md 長這樣:

規則一 反向計分:8 題 × 279 筆
規則二 補值:23 筆;標記缺失:6 筆
規則三 hours_week 超出 8–84:3 筆,已標記
規則三 years 超出 0–45:1 筆,已標記
這四行就是我論文方法學「資料處理」那一段的原料。補值 23 筆、排除 6 筆、離群 4 筆待處理,每個數字都有一行程式可以對。

然後我做三讀
腳本跑完不代表對。我做的核對是抽三筆手算:隨機挑三個受試者,打開 01_renamed.csv 看原始分數,自己算一次反向和補值,再開 02_cleaned.csv 對。

三筆都對,才算過。三筆裡有一筆不對,整支腳本重看。這跟三讀五對一樣,不是不信任,是流程。

離群值那四筆我一筆一筆看了。每週工時 168 那一筆,是有人把「每月」填成「每週」,看其他欄位可以推斷;年資 45 那一筆年齡填 28,明顯填錯。這四筆怎麼處理是我的決定,不是腳本的——腳本只負責把它們找出來。

哪裡會出錯
它會把反向題做兩次。 第一次跑完我改了規則三的範圍,重跑,結果倦怠分數全部回到原樣。原因是第二次跑的時候它讀的是 02_cleaned.csv——已經反向過的檔——再反向一次,6 減 (6 減 x) 等於 x。這就是為什麼規則一要寫「只對 01_renamed.csv 做,輸出到新檔」,也是為什麼 Day 4 說 clean 裡的東西要能刪掉重生:每一次重跑都從 01 開始,不會疊加。

它用全體平均補值。 第一版規則檔只寫「以平均補值」,它補的是那一題全體受試者的平均。這在統計上是另一種方法,不是錯,但不是我要的,而且兩種補法算出來的分量表分數會差。規則檔要寫到公式層級:「該受試者該量表已作答題目的平均」,一個字都不能省。

它順便把離群值刪了。 我寫「找出離群值」,它找出來然後刪掉,log 寫「已移除 4 筆」。跟 Day 10 一模一樣的問題:我要的是報告,它給我的是動作。刪不刪是研究者的決定,要寫進論文,不能讓腳本替我決定。規則三現在寫得很白:「只標記,不刪除,不修改原值」。

七點量表的反向不是 6 減。 我的睡眠品質量表有一題是七點的,它照倦怠量表的公式用 6 減,算出負數。規則檔裡寫「反向計分」四個字是不夠的,要寫公式,每一個量表各寫一次。

這條線畫在哪
Day 11 說第三週的線會畫得更緊。緊在這裡:AI 不碰資料,只寫碰資料的程式,而且程式我要看得懂才跑。

文獻那週,摘要卡它寫我核對,錯了是一張卡。資料這週,一個補值公式錯,279 筆全錯,而且不會報錯。所以我不讓它直接動資料,連「幫我處理一下遺漏值」這種話都不說。我說的是「依規則檔寫腳本」,中間多一層,那一層就是我讀得懂的程式碼。

我還不確定的地方
補值方法。個人平均補值是老師建議的,但我查到的文獻裡多重插補(multiple imputation)越來越常見,口試委員問起來,「老師說的」不是好答案。這件事我打算在論文限制裡寫,並在 Day 19 週回顧時再看要不要換方法。另一個是直線作答——整份問卷全填 3 的那種——目前規則檔沒有處理,我還沒決定要不要排除,也沒查到護理領域的慣例。

明天
Day 15:把清理好的資料交給 SPSS。變數名稱、value label、遺漏值代碼,這些東西手動設一次要一個下午,而且下次重跑又要再設一次。


上一篇
Day 13|問卷資料清理:從 Google 表單匯出的那份原始檔開始
下一篇
Day 15|匯出給 SPSS:變數標籤與值標籤的自動化,以及一個會讓平均數爆掉的數字
系列文
研究生自救指南:30 天用 Claude Code 打造我的論文工具箱21
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言