Skip to content
睡眠與生理

用 Potato 標註睡眠與生理訊號

以 30 秒為一幀為多導睡眠圖分期,標記 EEG 偽跡和癲癇發作,或稽核 ECG 心搏,再把每位評分者的標籤匯出為 BIDS events 檔案。

Potato 在瀏覽器中顯示多導睡眠圖、腦電(EEG)、心電(ECG)和可穿戴裝置記錄,標註者可以按 30 秒一幀判定睡眠分期,也可以在訊號上把偽跡、癲癇發作、心搏和活動片段標為區間和事件。Potato 免費開源,執行在你自己的伺服器上,並把每位評分者的標籤分開儲存,匯出為 BIDS events 檔案。

睡眠分期為多導睡眠圖的每個 30 秒幀(epoch)判定一個分期,即美國睡眠醫學會(AASM)定義的 W、N1、N2、N3 和 R(REM)五期之一。在 AASM 的評分者間信度項目中,2,500 多名評分者為同樣的 1,800 幀分期,睡眠分期的平均一致率為 82.6%(Rosenberg and Van Hout, 2013)。與多數評分的一致率以 N1 最低,為 63.0%,N3 次之,為 67.4%。因此,報告 N1 或 N3 時長的研究,能從每段記錄安排多名評分者、並給出評分者之間的一致性數值中獲益。Potato 執行的正是這類研究:把每段記錄發給你設定人數的評分者,並把每位評分者的分期存在該評分者的名下。

Potato 中的睡眠與生理任務

下表每一行都使用 Potato 2.13 新增的 time_series 顯示類型和 interval_label 方案,連結頁面給出了配置。

任務Potato 的做法文件
睡眠分期分幀模式一次顯示一個 30 秒幀,按分期鍵即為該幀標註並跳到下一幀時間序列
標記覺醒或呼吸暫停在同一張圖上新增第二個自由模式方案,標註者點選標記事件,拖動標記區間時間序列
標記 EEG 偽跡、癲癇發作和棘波自由模式,每個區間作用於所有通道或某一個通道行,由 channel_scope 設定時間序列
稽核 ECG 心搏和節律WFDB 記錄從 .hea 標頭檔案開啟,.atr 檔案中的心搏和節律作為點事件和區間載入,供標註者修正時間序列
標註可穿戴裝置記錄每個通道一列的 CSV 或 Parquet 檔案(例如加速度計各軸),在自由模式下標註時間序列
評分者間一致性所有評分者的逐幀分期寫在同一個匯出檔案中,可用於計算 Cohen's kappa 或 Fleiss' kappa標註者間一致性

一項由三名評分者完成的睡眠分期研究

下面的配置讓三名評分者在一個 EEG 通道行、一個 EOG 通道行和一個頦肌 EMG 通道行上,以 30 秒為一幀為每段記錄分期。時間序列頁面列出了所有選項和條目格式。

yaml
annotation_task_name: "Sleep staging"
task_dir: .
media_directory: media
output_annotation_dir: annotation_output
data_files: [data/psg.json]       # each item names its EDF file in "signal"
item_properties: {id_key: id, text_key: note}
user_config:
  allow_all_users: true
 
num_annotators_per_item: 3
 
instance_display:
  fields:
    - key: signal
      type: time_series
      label: "PSG"
      display_options:
        window: 30
        channels:
          - {name: "EEG Fpz-Cz", range: [-120, 120]}
          - {name: "EOG", range: [-150, 150]}
          - "EMG chin"
 
annotation_schemes:
  - annotation_type: interval_label
    name: stage
    description: "Sleep stage of each 30-second epoch"
    signal_field: signal
    mode: epoch
    epoch_length: 30
    pre_annotations: false
    require_all_epochs: true
    label_requirement: {required: true}
    labels:
      - {name: W, key_value: "1"}
      - {name: N1, key_value: "2"}
      - {name: N2, key_value: "3"}
      - {name: N3, key_value: "4"}
      - {name: REM, key_value: "5"}

num_annotators_per_item: 3 把每段記錄發給三名評分者。EDF+ 檔案中已有的睡眠圖(hypnogram)會以虛線顯示為起點,pre_annotations: false 隱藏這份睡眠圖,使三次評分彼此獨立。require_all_epochs 與 label_requirement 同時設定時,每一幀都有分期之前,Next 一直不可用。

匯入記錄與匯出標籤

每段記錄的副檔名決定使用哪個讀取器:

  • EDF 和 BDF。 EDF、EDF+、BDF 和 BDF+ 檔案無需額外的庫即可開啟。EDF+ 註釋作為預標註載入,preannotation_labels 把“Sleep stage 2”這類睡眠圖名稱改為方案的標籤。
  • WFDB。 PhysioNet 記錄從 .hea 檔案開啟,需要 signals 可選依賴(pip install 'potato-annotation[signals]')。多段記錄需要先拼接再載入。
  • CSV 和 Parquet。 一個時間列加上每個通道一列,適合可穿戴裝置匯出的資料。條目欄位中指定的 BIDS events.tsv 會作為預標註載入。

訊號檔案由 Potato 伺服器從媒體目錄讀取,這個顯示類型拒絕 URL。bids_events 匯出為每位評分者的每段記錄寫出一個 events.tsv,包含 BIDS 規範要求的 onset 和 duration 列:

bash
python -m potato.export -c config.yaml -f bids_events -o exports/bids

Potato 的一致性指標不覆蓋 interval_label 方案。interval_label 匯出寫出 intervals.csv,在分幀模式下,這個檔案中每位評分者的每一幀各佔一行。按 instance_id 和 start 連線這些行,就得到每幀一行、包含每位評分者分期的表格,可用於計算兩名評分者的 Cohen's kappa 或更多評分者的 Fleiss' kappa。

與 EDFbrowser、Lunascope 及 MNE-Python 的分工

EDFbrowser 是用於 EDF、EDF+ 和 BDF 檔案的免費檢視器、註釋器和工具箱,帶有註釋編輯器和睡眠圖,適合一名評分者在桌面上逐個處理檔案。Lunascope 是用於睡眠訊號視覺化、註釋和分析的桌面應用,支援自動分期和從美國國家睡眠研究資源庫(National Sleep Research Resource)匯入資料,適合先由模型分期的大型佇列。MNE-Python 讓 EEG 研究者在 raw.plot() 上拖動添加註釋,適合在指令碼化分析中完成的標註。對於 ECG,PhysioNet 的 LightWAVE 可以在瀏覽器中檢視和編輯 WFDB 註釋。當多名評分者標註同樣的記錄時,Potato 更合適,因為 Potato 把每段記錄分配給設定人數的評分者,並把每位評分者的標籤分開匯出。

藉助程式設計智慧體搭建研究

potato-skill 1.2.0 認得 interval_label 和 time_series 這兩個名稱,並指導 Claude Code、Codex 或 Cursor 完成研究設計這一側的工作,例如向評分者問什麼、每段記錄由幾名評分者檢視、培訓和注意力檢查,以及匯出。這個技能目前還沒有記錄訊號檔案格式、顯示選項和 signals 可選依賴。請讓智慧體參考時間序列頁面及其 Markdown 副本 https://www.potatoannotator.com/docs/annotation-types/time-series.md,以瞭解格式和選項。

常見問題

有沒有免費軟體可以按 30 秒一幀為睡眠分期?

Potato 是免費的開源軟體(GPL-3.0-or-later),在 interval_label 方案的分幀模式下,一次一個 30 秒幀地為多導睡眠圖分期。按分期鍵即為當前幀標註並跳到下一幀,[ 和 ] 只移動不標註。圖下方的條帶按分期為每個已評分的幀著色。

能否只在部分 EEG 通道上標記癲癇發作或偽跡?

能。設定 channel_scope: channel 時,區間作用於拖動開始所在的通道行;設定 channel_scope: either 時,圖上方的開關用來在某一個通道行和所有通道之間選擇。電極偽跡可以只落在一個通道行上,而全面性癲癇發作橫跨所有通道。儲存的區間記錄通道名稱,所有通道則記為 null,匯出中的 channel 列指明同一個通道行。

評分者能否從已有的睡眠圖出發修正分期?

能。EDF+ 檔案中的分期註釋會作為虛線的起始睡眠圖載入,preannotation_labels 把“Sleep stage 2”這類名稱對映到方案的標籤。評分者可以保留、編輯或丟棄這些起始分期,未被改動的分期匯出時 source 為 file。

如何把人工 EEG 註釋儲存到檔案?

Potato 把每位標註者的標籤儲存在 Potato 伺服器上,python -m potato.export 把這些標籤寫入 intervals.csv,或為每位標註者的每段記錄寫出一個 BIDS events.tsv。intervals.csv 的每一行記錄標註者、條目、標籤、起止時間和通道。

延伸閱讀

參考文獻

  1. Rosenberg and Van Hout (2013). The American Academy of Sleep Medicine Inter-scorer Reliability Program: Sleep Stage Scoring. Journal of Clinical Sleep Medicine 9(1). https://doi.org/10.5664/jcsm.2350

從這裡開始

其他領域

全部應用場景