SEED 数据集特征提取与处理代码解析 - Python 代码详解
这段代码的目标是根据数据文件进行特征提取,并将提取的特征保存为 Numpy 数组文件。
代码解释如下:
-
file_path = 'D:/project/4D-CRNN/SEED/Preprocessed_EEG/':设置数据文件的路径。 -
people_name和short_name是两个包含数据文件名称和简短名称的列表,用于遍历所有数据文件。 -
X = np.empty([0, 62, 5])和y = np.empty([0, 1]):创建空的 Numpy 数组X和y,用于存储特征和标签。 -
for i in range(len(people_name)):- 从数据文件中加载数据并进行特征分解和标签处理,调用
decompose函数,将返回的特征decomposed_de和标签label分别添加到X和y数组中。
- 从数据文件中加载数据并进行特征分解和标签处理,调用
-
np.save("D:/project/4D-CRNN/SEED/DE0.5s/X_1D.npy", X)和np.save("D:/project/4D-CRNN/SEED/DE0.5s/y.npy", y):将特征数组X和标签数组y保存为 Numpy 数组文件。 -
X = np.load('D:/project/4D-CRNN/SEED/DE0.5s/X_1D.npy')和y = np.load('D:/project/4D-CRNN/SEED/DE0.5s/y.npy'):从 Numpy 数组文件中加载特征数组X和标签数组y。 -
X89是一个新的 Numpy 数组,用于存储按照特定方式转换后的特征。 -
X89[:, 0, 2, :] = X[:, 3, :]:将原始特征中的特定部分复制到转换后的特征中。 -
X89[:, 0, 3:6, :] = X[:, 0:3, :]:将原始特征中的特定部分复制到转换后的特征中。 -
X89[:, 0, 6, :] = X[:, 4, :]:将原始特征中的特定部分复制到转换后的特征中。 -
X89[:, i + 1, :, :] = X[:, 5 + i * 9:5 + (i + 1) * 9, :]:将原始特征中的特定部分复制到转换后的特征中。 -
X89[:, 6, 1:8, :] = X[:, 50:57, :]:将原始特征中的特定部分复制到转换后的特征中。 -
X89[:, 7, 2:7, :] = X[:, 57:62, :]:将原始特征中的特定部分复制到转换后的特征中。 -
np.save("D:/project/4D-CRNN/SEED/DE0.5s/X89.npy", X89):将转换后的特征数组X89保存为 Numpy 数组文件。
关于文件保存问题,你需要检查保存文件的路径是否正确,确保保存路径中的文件夹已经存在。如果文件夹不存在,可以尝试创建文件夹,然后再保存文件。
代码解读:
import os
import sys
import math
import numpy as np
# import pandas as pd
import scipy.io as sio
from sklearn import preprocessing
from scipy.signal import butter, lfilter
from scipy.io import loadmat
def decompose(file, name):
# trial*channel*sample
data = loadmat(file)
frequency = 200
decomposed_de = np.empty([0, 62, 5])
label = np.array([])
all_label = [1, 0, -1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 0, 1, -1]
for trial in range(15): #15个试验
# tmp_idx = trial + 3
# tmp_name = list(data.keys())[tmp_idx]
tmp_trial_signal = data[name + '_eeg' + str(trial + 1)]
num_sample = int(len(tmp_trial_signal[0]) / 100)
print('{}-{}'.format(trial + 1, num_sample))
temp_de = np.empty([0, num_sample])
label = np.append(label, [all_label[trial]] * num_sample) #将当前试验的标签重复num_sample次,然后添加到标签数组中。
for channel in range(62):
trial_signal = tmp_trial_signal[channel]
# 因为SEED数据没有基线信号部分
delta = butter_bandpass_filter(trial_signal, 1, 4, frequency, order=3)
theta = butter_bandpass_filter(trial_signal, 4, 8, frequency, order=3)
alpha = butter_bandpass_filter(trial_signal, 8, 14, frequency, order=3)
beta = butter_bandpass_filter(trial_signal, 14, 31, frequency, order=3)
gamma = butter_bandpass_filter(trial_signal, 31, 51, frequency, order=3)
DE_delta = np.zeros(shape=[0], dtype=float)
DE_theta = np.zeros(shape=[0], dtype=float)
DE_alpha = np.zeros(shape=[0], dtype=float)
DE_beta = np.zeros(shape=[0], dtype=float)
DE_gamma = np.zeros(shape=[0], dtype=float)
for index in range(num_sample):
DE_delta = np.append(DE_delta, compute_DE(delta[index * 100:(index + 1) * 100]))#计算当前样本Delta频带的差分熵,并将结果添加到Delta频带差分熵数组中
DE_theta = np.append(DE_theta, compute_DE(theta[index * 100:(index + 1) * 100]))
DE_alpha = np.append(DE_alpha, compute_DE(alpha[index * 100:(index + 1) * 100]))
DE_beta = np.append(DE_beta, compute_DE(beta[index * 100:(index + 1) * 100]))
DE_gamma = np.append(DE_gamma, compute_DE(gamma[index * 100:(index + 1) * 100]))
temp_de = np.vstack([temp_de, DE_delta])#将Delta频带的差分熵数组作为一行添加到临时特征数组中
temp_de = np.vstack([temp_de, DE_theta])
temp_de = np.vstack([temp_de, DE_alpha])
temp_de = np.vstack([temp_de, DE_beta])
temp_de = np.vstack([temp_de, DE_gamma])
temp_trial_de = temp_de.reshape(-1, 5, num_sample)#(样本数量,频带数量,样本长度)
temp_trial_de = temp_trial_de.transpose([2, 0, 1])
decomposed_de = np.vstack([decomposed_de, temp_trial_de])
print("trial_DE shape:", decomposed_de.shape)
return decomposed_de, label
def butter_bandpass(lowcut, highcut, fs, order=5):
nyq = 0.5 * fs
low = lowcut / nyq
high = highcut / nyq
b, a = butter(order, [low, high], btype='band')
return b, a
def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
b, a = butter_bandpass(lowcut, highcut, fs, order=order)
y = lfilter(b, a, data)
return y
def compute_DE(signal):
variance = np.var(signal, ddof=1)
return math.log(2 * math.pi * math.e * variance) / 2
# 究极整合版
import os
import numpy as np
file_path = 'D:/project/4D-CRNN/SEED/Preprocessed_EEG/'
people_name = ['1_20131027', '1_20131030', '1_20131107', #定义一个包含数据文件名称的列表,用于遍历所有数据文件
'6_20130712', '6_20131016', '6_20131113',
'7_20131027', '7_20131030', '7_20131106',
'15_20130709', '15_20131016', '15_20131105',
'12_20131127', '12_20131201', '12_20131207',
'10_20131130', '10_20131204', '10_20131211',
'2_20140404', '2_20140413', '2_20140419',
'5_20140411', '5_20140418', '5_20140506',
'8_20140511', '8_20140514', '8_20140521',
'13_20140527', '13_20140603', '13_20140610',
'3_20140603', '3_20140611', '3_20140629',
'14_20140601', '14_20140615', '14_20140627',
'11_20140618', '11_20140625', '11_20140630',
'9_20140620', '9_20140627', '9_20140704',
'4_20140621', '4_20140702', '4_20140705']
short_name = ['djc', 'djc', 'djc', 'mhw', 'mhw', 'mhw', 'phl', 'phl', 'phl', #定义一个包含简短名称的列表,用于标识数据文件的来源
'zjy', 'zjy', 'zjy', 'wyw', 'wyw', 'wyw', 'ww', 'ww', 'ww',
'jl', 'jl', 'jl', 'ly', 'ly', 'ly', 'sxy', 'sxy', 'sxy',
'xyl', 'xyl', 'xyl', 'jj', 'jj', 'jj', 'ys', 'ys', 'ys',
'wsf', 'wsf', 'wsf', 'wk', 'wk', 'wk', 'lqj', 'lqj', 'lqj']
X = np.empty([0, 62, 5])#特征
y = np.empty([0, 1])#标签
for i in range(len(people_name)):
file_name = file_path + people_name[i]
print('processing {}'.format(people_name[i]))
decomposed_de, label = decompose(file_name, short_name[i])
X = np.vstack([X, decomposed_de])
y = np.append(y, label)
np.save("D:/project/4D-CRNN/SEED/DE0.5s/X_1D.npy", X)
np.save("D:/project/4D-CRNN/SEED/DE0.5s/y.npy", y)
X = np.load('D:/project/4D-CRNN/SEED/DE0.5s/X_1D.npy')
y = np.load('D:/project/4D-CRNN/SEED/DE0.5s/y.npy')
# 生成8*9的矩阵形式
X89 = np.zeros((len(y), 8, 9, 5))
X89[:, 0, 2, :] = X[:, 3, :] #将原始特征中的某一部分复制到转换后的特征中
X89[:, 0, 3:6, :] = X[:, 0:3, :]
X89[:, 0, 6, :] = X[:, 4, :]
for i in range(5):#5个频带
X89[:, i + 1, :, :] = X[:, 5 + i * 9:5 + (i + 1) * 9, :]
X89[:, 6, 1:8, :] = X[:, 50:57, :]
X89[:, 7, 2:7, :] = X[:, 57:62, :]
np.save("D:/project/4D-CRNN/SEED/DE0.5s/X89.npy", X89)但保存的文件没在文件夹里
详细解释:
-
decompose函数:用于对每个试验的数据进行特征分解,包括对每个通道的脑电信号进行频带滤波,并计算每个频带的差分熵。 -
butter_bandpass函数:用于设计一个带通滤波器,用于将脑电信号分解成不同的频带。 -
butter_bandpass_filter函数:使用设计好的带通滤波器对脑电信号进行滤波。 -
compute_DE函数:计算信号的差分熵。 -
主程序:遍历每个数据文件,进行特征提取和标签处理,并将提取的特征和标签保存为 Numpy 数组文件。最后,将原始特征进行转换,并保存为另一个 Numpy 数组文件。
需要注意的地方:
- 确保数据文件的路径正确,并检查目标文件夹是否存在。
- SEED 数据集的格式和特征提取方法可能存在差异,需要根据实际情况进行调整。
- 代码中使用的频带范围和特征转换方式可以根据实际应用需求进行修改。
- 文件保存问题,检查保存文件的文件路径是否正确,确保保存路径中的文件夹已经存在,如果不存在,可以尝试创建文件夹,然后再保存文件。
原文地址: https://www.cveoy.top/t/topic/QGs 著作权归作者所有。请勿转载和采集!