基於機器學習的心律失常分類(二)——讀取MIT-BIH數據庫中的心電數據[MATLAB]
在上一篇文章中介紹了心電信號的一些基本理論,本篇文章將着重介紹什么是MIT-BIH數據庫,以及如何獲取、讀取MIT-BIH心律失常數據庫中的心電數據。
我剛開始接觸的時候特別迷茫,看了很多帖子才搞清楚。這篇絕對良心靠譜細致!!!
一、MIT-BIH心律失常數據庫
目前有三個得到國際認可的心電數據庫可以被用作臨床標准,分別是由美國麻省理工學院提供的MIT-BIH心律失常數據庫,美國心臟學會的AHA數據庫以及歐洲ST-T心電數據庫。其中,MIT-BIH數據庫擁有大量數據並且有權威專家對其進行了詳細的注釋和標記,在對心律失常分類和臨床研究中應用最為廣泛。因此,本文的使用標准的MIT-BIH數據庫的心電數據,並通過與權威專家提供的注釋進行比較來分析和評估實驗取得的結果。
該數據庫包括47個測試個體單位的4000多個24小時的周期性動態心電數據,有48個時長約為30min的記錄文件,共計109500個心拍,其中異常心拍約占30%。MIT-BIH數據庫中包含的心電記錄文件共有三種類型。
(1)頭文件(.hea):記錄文件中的頭文件中的信息包括各個記錄的所有數據的相關屬性信息。包括采樣頻率,導聯號,數據格式,分辨率,ADC,年齡等。
(2)數據文件(.dat):數據文件統一采用了“212”數據存儲模式,每一個數據文件有兩個導聯的信號數據。
(3)注釋文件(.art):注釋文件中有權威專家標注的心拍類型與R波位置,為后面算法驗證其有效性提供了依據。
數據庫對不同的心律失常類型做了統一命名,如下表所示。本文主要分析正常心電(N)、左束支阻滯(L)、右束支阻滯(R)及室性早搏(V)四種心拍類型。

二、如何獲取MIT-BIH的數據
開源數據網站PhysioNet(https://archive.physionet.org/)提供了諸如MIMIC、MIT-BIH等豐富的生理信號數據庫。
獲取MIT-BIH數據庫數據,可以使用提供的PhysioBank ATM (PhysioBank ATM),在線地顯示選定的數據,並將數據保存為txt或其他的形式。

- 在Database下拉框中選擇MIT-BIH Arrhythmia Database(mitdb):

2. 簡單介紹下各字段含義及下載方式

1>Input
(1)Database:所選取的數據庫,我們已經選擇了MIT-BIH心律失常數據庫;
(2)Record:文件編號,mitbih數據庫一共有48個不同編號的文件,每一個編號分別對應一個個體的采集數據;
(3)Singals:每個數據文件呢包括兩個導聯數據,通俗一點就是對每一個個體采集心電數據時用了兩種方式,然后都給記錄下來,可以選擇使用其中一種方式,也可以都使用;
(4)Annotations:就是指注釋。
2>Output
(5)Length:默認的數據顯示長度為10s,用戶也可以選擇1min、1hour顯示,我下載的 是一個小時的;
(6)Time format:時間格式,看個人需要那種查看,一般默認第一個就好了;
(7)Data format:資料格式,一般默認第一個標准就好了。
3>Toolbox

共13個選項,比如選擇在plot waveforms,就是直接在顯示器中繪制數據波形。在顯示的過程中可以點擊下面的進度條,選擇顯示的區間。10s的心電數據顯示如下:

但是針對我們要對數據進行分析處理下載數據文件來說,要選擇“Make zip file of record”,就可以得到如下圖所示的下載地址,點擊100.zip就可以下載編號100的數據文件了,然后可以繼續下載其它編號的文件。

因為我是用matlab來分別處理.hea/.dat/.art這三個數據,所以我下載的zip壓縮包。但如果你想直接對txt或者mat文件進行處理,也可以選擇相應的下載方式~看個人需求,我就按照我自己使用的來說啦
3. 下載完成的數據文件

三、如何讀取MIT-BIH的數據
本文是使用MATLAB編程工具對三種文件進行讀取處理的,一個一個來說。
- 頭文件(.hea)
以記錄100的頭文件100.hea為例進行說明,其文件內容如下:

該頭文件的第一行為記錄行,指出該記錄為一包含兩個采樣率為360 Hz的信號,每一信號的長度為65萬個采樣點,采樣開始時間和日期沒有記錄。后面緊跟的兩行為信號技術規范說明行,從中可以看出,兩個導聯信號都包含在文件100.dat 中,每一信號都是以12位的位壓縮格式(即“212”格式)進行存儲的,兩個信號的增益都是每200ADC units/mV ,ADC的分辨率為11位.ADC零值為1024,在這里基線值沒有明確給出,但可以認為它等於ADC零值1024。兩個信號的第一采樣點的值分別為995和1011 (可以看出這他們都略低於0 V),65萬個采樣點的校驗數分別為-22131和20052 ,輸人輸出可以以任何尺寸的塊來執行,因為文件內容說明了這兩個信號的該值都為0,信號描述字段說明了這兩個信號分別采自MLII 導聯和V5導聯。文件的最后兩行包含了注釋字符串,其中第一行說明了患者的性別和年齡以及記錄數據,第二行列出了患者的用葯情況。
上面一大段介紹了一下內容含義,那么如何用matlab將這些內容讀取出來呢,就需要根據存儲格式來讀取,直接放代碼吧~
PATH= 'C:\Users\ccc\Desktop\\數據\1_源數據\mit-bih-arrhythmia-database-1.0.0'; %數據文件所在文件夾地址 HEADERFILE= '100.hea'; %選擇記錄編號 % 通過函數 fullfile 獲得頭文件的完整路徑 signalh= fullfile(PATH, HEADERFILE); % 打開頭文件,其標識符為 fid1 ,屬性為'r'--“只讀” fid1=fopen(signalh,'r'); % 讀取頭文件的第一行數據,字符串格式 z= fgetl(fid1); % 按照格式 '%*s %d %d %d' 轉換數據並存入矩陣 A 中 A= sscanf(z, '%*s %d %d %d',[1,3]); nosig= A(1); % 信號通道數目 sfreq=A(2); % 數據采樣頻率 SAMPLES2READ = 10*sfreq; %取十秒數據 for k=1:nosig % 讀取每個通道信號的數據信息 z= fgetl(fid1); A= sscanf(z, '%*s %d %d %d %d %d',[1,5]); dformat(k)= A(1); % 信號格式; 這里只允許為 212 格式 gain(k)= A(2); % 每 mV 包含的整數個數 bitres(k)= A(3); % 采樣精度(位分辨率) zerovalue(k)= A(4); % ECG 信號零點相應的整數值 firstvalue(k)= A(5); % 信號的第一個整數值 (用於偏差測試) end; fclose(fid1); clear A;
以上就可以讀取出頭文件的內容了。
2. 數據文件(.dat)
MIT-BIH數據庫中數據存儲格式有Format 8、Format 16、Format 212、Format 310等8種,會在頭文件中進行說明。最常用的就是212,是針對兩個導聯信號的數據記錄。
為了方便,將兩個導聯信號設定為信號0和信號1。格式212存儲中,這兩個信號交替存儲,每三個字節存儲兩個數據,這兩個數據分別來自信號0和信號1,信號0的采樣數據取自第一字節對(共16位)的最低12位,信號1的采樣數據由第一字節對的剩余4位(作為組成信號1采樣數據的12位的高4位)和下一字節的8位(作為組成信號1采樣數據的12位的低8位)共同組成。

按照“212"的格式,從第一字節讀起,每三個字節(24位)表示兩個值,,第一組為“E3 33 F3",兩個值則分別為0x3E3和0x3F3,轉換為十進制分別為995和1011,代表的信號幅度分別為4.975mV和5.055 mV,這兩個值分別是兩個信號的第一采樣點,后面依此類推,分別表示了兩個信號的采樣值。
使用MATLAB讀取數據文件:
PATH= 'C:\Users\ccc\Desktop\\數據\1_源數據\mit-bih-arrhythmia-database-1.0.0'; %數據文件所在文件夾地址 DATAFILE='100.dat'; %選擇記錄編號 %.dat文件的數據格式讀取為每行三個字節,即三個八位的二進制數字,其內容含義為 % 0000 0000 || 0000 0000 || 0000 0000 %sign1(L)低八位信息||左四位sign2(R)信息,右四位sign1(L)信息||sign2(R)低八位信息 %將第二字節的信息處理后,后四位移至第一字節最左位即得到完整的sign1 %將第二字節的信息處理后,前四位移至第一字節最左位即得到完整的sign2. signald = fullfile(PATH , DATAFILE); fid2 = fopen(signald,'r'); A= fread(fid2, [3, SAMPLES2READ], 'uint8')'; fclose(fid2); %對第二字節做左位移運算,位移距離-4 %得到第二字節左四位,即sign2的高四位,包括符號位,右高信息 M_R_H = bitshift(A(:,2), -4); %對第二字節和1111做與運算, %保留第二字節右四位,即sign1的低四位,包括符號位,左高信息 M_L_H = bitand(A(:,2), 15); %對第二字節和1000做與運算, %保留第二字節右邊第四位,獲取sign2符號位,並向左位移九位,與整體sign1進行運算 PRL=bitshift(bitand(A(:,2),8),9); %對第二字節和10000000做與運算, %保留第二字節右邊第四位,獲取sign1符號位,並向左位移5位,與整體sign2進行運算 PRR=bitshift(bitand(A(:,2),128),5); %M矩陣為sign1,2的存儲矩陣,存儲100.dat處理后數據 %將sign1(L)高位移至sign1低位前(A(:,1)) %將sign2(R)高位移至sign2低位前(A(:,3)) %最后將信號符號位信息去掉 M( : , 1)= bitshift(M_L_H,8)+ A(:,1)-PRL; M( : , 2)= bitshift(M_R_H,8)+ A(:,3)-PRR; %將sign的數值與零點做減法得到正負值 %再將得到的具有正負性的值與每mV的整數值相除,即得到電壓多少mV M( : , 1)= (M( : , 1)- zerovalue(1))/gain(1); M( : , 2)= (M( : , 2)- zerovalue(2))/gain(2); %將我們設定的采樣個數除以頻率即得到這段樣品的測定時間。 TIME =(0:(SAMPLES2READ-1))/sfreq; %釋放變量 clear A M_R_H M_L_H PRR PRL;

矩陣M里就存儲了兩個導聯的信號了,可以單獨提取處理。
3. 注釋文件(.atr)
注釋文件里有專家標注的R波位置以及每個心拍的類型,為后續分類提供了可靠的依據。

這個存儲格式不想過多說明了,可以看看參考文獻,里面有詳細說明。舉個例子說明它的注釋信息吧。

圖中N表示正常心拍,A表示房性心博。
通過matlab提取注釋信息:
PATH= 'C:\Users\ccc\Desktop\\數據\1_源數據\mit-bih-arrhythmia-database-1.0.0'; %數據文件所在文件夾地址 ATRFILE='100.atr'; %選擇記錄編號 atrd= fullfile(PATH, ATRFILE); % attribute file with annotation data fid3=fopen(atrd,'r'); A= fread(fid3, [2, inf], 'uint8')'; fclose(fid3); ATRTIME=[]; ANNOT=[]; sa=size(A); saa=sa(1); i=1; while i<=saa annoth=bitshift(A(i,2),-2); if annoth==59 ANNOT=[ANNOT;bitshift(A(i+3,2),-2)]; ATRTIME=[ATRTIME;A(i+2,1)+bitshift(A(i+2,2),8)+... bitshift(A(i+1,1),16)+bitshift(A(i+1,2),24)]; i=i+3; elseif annoth==60 % nothing to do! elseif annoth==61 % nothing to do! elseif annoth==62 % nothing to do! elseif annoth==63 hilfe=bitshift(bitand(A(i,2),3),8)+A(i,1); hilfe=hilfe+mod(hilfe,2); i=i+hilfe/2; else ATRTIME=[ATRTIME;bitshift(bitand(A(i,2),3),8)+A