精华内容
下载资源
问答
  • MNE中数据结构Raw及其用法简介前言初始Raw对象结构从头...最近在根据【脑机接口社区】的博客和公众号的推文学习python中mne库的用法,也算是真正开始上手EEG信号处理的代码了吧。本系列的推文所用的脑机接口均为Open

    1. 前言

    最近在根据【脑机接口社区】的博客和公众号的推文学习python中mne库的用法,也算是真正开始上手EEG信号处理的代码了吧。本系列的推文所用的脑机接口均为OpenBCI,欢迎各位大佬一同交流!


    2. 初始Raw对象结构

    Raw对象主要是用来存储连续型的数据,其核心的数据主要为n_channels和n_times(时间×频率),其中也包括了Info对象。

    • Raw结构查看
    # 引入python库
    import mne
    from mne.datasets import sample
    import matplotlib.pyplot as plt
    
    # sample的存放地址
    data_path = sample.data_path()
    # 该fif文件存放地址
    fname = data_path + '/MEG/sample/sample_audvis_raw.fif'
    
    """
    如果上述给定的地址中存在该文件,则直接加载本地文件,
    如果不存在则在网上下载改数据
    """
    raw = mne.io.read_raw_fif(fname)
    print(raw.info)
    
    • 通过打印raw查看数据
    <Info | 19 non-empty fields
        bads : list | 0 items
        ch_names : list | MEG 0113, MEG 0112, MEG 0111, MEG 0122, MEG 0123, EEG 053, EEG 052, EEG 051
        chs : list | 8 items (EEG: 8)
        comps : list | 0 items
        custom_ref_applied : bool | False
        dev_head_t : Transform | 3 items
        dig : Digitization | 0 items
        events : list | 0 items
        file_id : dict | 4 items
        highpass : float | 0.0 Hz
        hpi_meas : list | 0 items
        hpi_results : list | 0 items
        lowpass : float | 128.0 Hz
        meas_date : NoneType | unspecified
        meas_id : dict | 4 items
        nchan : int | 8
        proc_history : list | 0 items
        projs : list | 0 items
        sfreq : float | 256.0 Hz
        acq_pars : NoneType
        acq_stim : NoneType
        ctf_head_t : NoneType
        description : NoneType
        dev_ctf_t : NoneType
        device_info : NoneType
        experimenter : NoneType
        gantry_angle : NoneType
        helium_info : NoneType
        hpi_subsystem : NoneType
        kit_system_id : NoneType
        line_freq : NoneType
        proj_id : NoneType
        proj_name : NoneType
        subject_info : NoneType
        utc_offset : NoneType
        xplotter_layout : NoneType
    >
    
    • 从上述信息中可以看出不良通道bads,通道名称ch_names,采样频率sfreq等等。

    3. 从头创建Raw对象

    • 函数:mne.io.RawArray,其构造函数只接受矩阵和info对象
    • 创建一个Raw对象时,需要准备两种数,一种是data数据,一种是info数据,其中data数据是一个二维数据,格式为(n_channels,n_times)

    (1)获取OpenBCI的脑电数据

    • 利用brainflow库进行数据的获取。以下代码用的是(SYNTHETIC_BOARD)合成板
    import time
    import numpy as np
    import matplotlib
    #matplotlib.use ('Agg')
    from brainflow.board_shim import BoardShim, BrainFlowInputParams, BoardIds
    import mne
    
    BoardShim.enable_dev_board_logger ()
    # use synthetic board for demo
    params = BrainFlowInputParams ()
    board = BoardShim (BoardIds.SYNTHETIC_BOARD.value, params)
    board.prepare_session ()
    board.start_stream ()
    time.sleep (10) #获取10s的数据
    data = board.get_board_data ()
    board.stop_stream ()
    board.release_session ()
    
    eeg_channels = BoardShim.get_eeg_channels (BoardIds.SYNTHETIC_BOARD.value)
        eeg_data = data[eeg_channels, :]
    
    • 如果直接用脑机接口,可以将board = BoardShim (BoardIds.SYNTHETIC_BOARD.value, params)改成board = BoardShim (BoardIds.CYTON_BOARD_BOARD.value, params) 然后再改变端口,改变端口有两种办法,一种是暴力法,直接改boardshim库中的代码;另一种是采用另一种获取数据的代码。

    方法一
    boardshim.py >>> serial_port=‘COM3’
    方法一

    方法二

    def main ():
    	parser = argparse.ArgumentParser ()
        # use docs to check which parameters are required for specific board, e.g. for Cyton - set serial port
        parser.add_argument ('--ip-port', type = int, help  = 'ip port', required = False, default = 0)
        parser.add_argument ('--ip-protocol', type = int, help  = 'ip protocol, check IpProtocolType enum', required = False, default = 0)
        parser.add_argument ('--ip-address', type = str, help  = 'ip address', required = False, default = '')
        parser.add_argument ('--serial-port', type = str, help  = 'serial port', required = False, default = 'COM3')
        parser.add_argument ('--mac-address', type = str, help  = 'mac address', required = False, default = '')
        parser.add_argument ('--other-info', type = str, help  = 'other info', required = False, default = '')
        parser.add_argument ('--streamer-params', type = str, help  = 'other info', required = False, default = '')
        parser.add_argument ('--board-id', type = int, help  = 'board id, check docs to get a list of supported boards',default=0)
        parser.add_argument ('--log', action = 'store_true')
        args = parser.parse_args ()
    
        params = BrainFlowInputParams ()
        params.ip_port = args.ip_port
        params.serial_port = args.serial_port
        params.mac_address = args.mac_address
        params.other_info = args.other_info
        params.ip_address = args.ip_address
        params.ip_protocol = args.ip_protocol
    
        if (args.log):
            BoardShim.enable_dev_board_logger ()
        else:
            BoardShim.disable_board_logger ()
    
        board = BoardShim (args.board_id, params)
        board.prepare_session ()
    
        board.start_stream ()
        time.sleep (1)
        board.config_board ('/2') # enable analog mode only for Cyton Based Boards!
        time.sleep (5)
        data = board.get_board_data ()
    

    如果不清楚端口是否连接成功,可以采用以下代码

    def get_port():
        import serial.tools.list_ports
        port_list = list(serial.tools.list_ports.comports())
        if len(port_list) == 0:
            print('找不到串口')
        else:
            for i in range(0,len(port_list)):
                print(port_list[i])
    
    

    (2)创建Raw对象

    • 创建info结构
    • 内容包括:通道类型ch_types和通道名称ch_names
    • 设置采样频率sfreq为合成板默认的频率256Hz
    	# Creating MNE objects from brainflow data arrays
        ch_types = ['eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg', 'eeg']
        ch_names = ['MEG 0113', 'MEG 0112', 'MEG 0111', 'MEG 0122', 'MEG 0123', 'EEG 053', 'EEG 052', 'EEG 051']#通道一般自行设定
        sfreq = BoardShim.get_sampling_rate (BoardIds.SYNTHETIC_BOARD.value)
        info = mne.create_info (ch_names = ch_names, sfreq = sfreq, ch_types = ch_types)
    
    • 利用mne.io.RawArray类创建Raw对象
    	raw = mne.io.RawArray (eeg_data, info)
    
    • 保存,载入刚才保存的数据并打印信息
        picks = mne.pick_types(
            info, meg=False, eeg=True, stim=False,
            include=ch_names
        )
        raw.save("raw.fif", picks=picks, overwrite=True)
    
        raw_fif_data = mne.io.read_raw_fif("raw.fif", preload=True, verbose='ERROR')
        print(raw_fif_data.info)
    

    (3)展示数据信号图

    scalings = {'eeg': 1000}#采用1000倍缩小。
    #scalings = 'auto' 也可以采用自动缩放比例
    raw.plot(n_channels=8, scalings=scalings, title='Data from arrays',
             show=True, block=True)
    

    以下展示1000倍和8000倍缩小的数据波形。
    1000倍缩小的图
    8000倍缩放的图

    4. 数据的相关绘制

    • 通常raw的数据访问方式如下:
      data, times = raw[picks, time_slice]
      picks:是根据条件挑选出来的索引;
      time_slice:时间切片
    • 想要获取raw中所有数据,以下两种方式均可:
      data,times=raw[:]
      data,times=raw[:,:]

    (1)获取0-10秒内的良好的EEG数据

    • 根据type来选择 那些良好的EEG信号(良好的EEG信号,通过设置exclude=“bads”) channel,结果为 channels所对应的的索引
    picks = mne.pick_types(raw.info, eeg=True, exclude='bads')
    t_idx = raw.time_as_index([0., 10.])
    data, times = raw[picks, t_idx[0]:t_idx[1]]
    plt.plot(times,data.T)
    plt.title("Sample channels")
    plt.show()
    

    • 这图是真滴丑,应该需要改改颜色。

    (2)获取采样频率sfreq

    采样频率,也称为采样速度或者采样率,定义了每秒从连续信号中提取并组成离散信号的采样个数,它用赫兹(Hz)来表示。
    采样频率的倒数是采样周期或者叫作采样时间,它是采样之间的时间间隔。
    通俗的讲采样频率是指计算机每秒钟采集多少个信号样本。

    
    sfreq=raw.info['sfreq']
    """
    获取索引为m到n的样本,每个样本从第k次到第h次.
    data,times=raw[m:n,k:h]
    
    其中data为索引为m到n的样本,每个样本从第k次到第h次.
    times是以第k次采样的时间作为开始时间,第h次采样时的时间为结束时间的时间数组。
    """
    data,times=raw[:3,int(sfreq*1):int(sfreq*3)]
    plt.plot(times,data.T)
    plt.title("Sample channels")
    

    以下几幅图因为用的是合成板,所以无法确定通道的位置,因而借用以下脑机接口社区的图片

    (3)绘制各通道的功率谱密度

    raw.plot_psd()
    plt.show()
    

    (4)绘制SSP矢量图

    raw.plot_projs_topomap()
    plt.show()
    

    (5)绘制通道频谱图作为topography

    raw.plot_psd_topo()
    plt.show()
    

    (6)绘制电极位置

    raw.plot_sensors()
    plt.show()
    

    展开全文
  • 感谢微信公众号 脑机接口社区文章《脑电分析系列[MNE-Python-5]| Python机器学习算法随机森林判断睡眠类型》之pycharm和anaconda对比,并记录其中遇到的问题,欢迎各位大佬一起探讨研究! Env—— Anaconda3:内置...

    感谢微信公众号 脑机接口社区文章《脑电分析系列[MNE-Python-5]| Python机器学习算法随机森林判断睡眠类型》之pycharm和anaconda对比,并记录其中遇到的问题,欢迎各位大佬一起探讨研究!

    Env——

    Anaconda3:内置python3.8.12

    Pycharm 使用本地python3.8.0

    mne version: 0.21.2

    1. Pycharm

    源码使用《脑机接口社区文章《脑电分析系列[MNE-Python-5]| Python机器学习算法随机森林判断睡眠类型》源码,如下——
    """
    脑电分析系列[MNE-Python-5]| Python机器学习算法
    随机森林判断睡眠类型
    """
    
    """
    案例介绍
    本案例通过对多导睡眠图(Polysomnography,PSG)
    数据进行睡眠阶段的分类来判断睡眠类型。
    训练:对Alice的睡眠数据进行训练;
    
    测试:利用训练结果对Bob的睡眠数据进行测试,判断其睡眠类型。
    
    在分析之前,先简单介绍一下多导睡眠图
    
    多导睡眠图(Polysomnography,PSG)又称睡眠脑电图。
    主要用于睡眠和梦境研究以及抑郁症和睡眠呼吸暂停综合征的诊断。
    多导睡眠图是通过不同部位的生物电或通过不同传感获得生物讯号,
    经前置放大,输出为不同的电讯号,记录出不同的图形以供分析。
    """
    
    """
    数据集介绍
    
    本案例用的数据是来自于PhysioNet上关于健康受试者的年龄对睡眠影响研究的公开数据集的一个子集。
    
    mne.datasets.sleep_physionet.age.fetch_data可以下载PhysioNet数据集的子数据集。
    
    该子数据集中包含20位受试者的实验数据,记录当时年龄为25-34岁的10位男性和10位女性的实验数据。
    由于受试者13的第二个记录遗失了,所以除了受试者13以外,每个受试者都有两次夜间记录。
    
    Sleep Physionet数据集使用8个标签进行标注,代表8各阶段:
    
    Wake (W),
    
    Stage 1,
    
    Stage 2,
    
    Stage 3,
    
    Stage 4,
    
    REM(R),
    
    Movement time(M),
    
    Stage(?). Stage(?)-(not scored)  
    
    唤醒-Wake(W)、第1阶段、第2阶段、第3阶段、第4阶段、
    对应于从轻度睡眠到深度睡眠的范围;REM睡眠(R),
    其中REM是Rapid Eye的缩写,表示快速眼运动睡眠,
    运动(M)和阶段(?)的任何未得分部分。
    """
    
    # 第一步:导入工具库
    import numpy as np
    import matplotlib.pyplot as plt
    
    import mne
    from mne.datasets.sleep_physionet.age import fetch_data
    from mne.time_frequency import psd_welch
    
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.metrics import accuracy_score
    from sklearn.metrics import confusion_matrix
    from sklearn.metrics import classification_report
    from sklearn.pipeline import make_pipeline
    from sklearn.preprocessing import FunctionTransformer
    
    """  第二步:加载数据  """
    """
    在这里,我们从两个主题下载数据,
    最终目标是获得时间片段(epochs)及其相关的地面真理。
    
    
    
    MNE为我们提供了
    mne.datasets.sleep_physionet.age.fetch_data(),
    可以方便地从Sleep Physionet数据集下载数据。  
    
    给定主题和记录的列表,提取程序将下载数据并为每个主题提供数据, 一对文件:
    
    -PSG.edf包含多导睡眠图。来自EEG头盔的原始数据,
    
    -Hypnogram.edf包含专家记录的注释。
    
    
    
    然后,将这两个对象合并到mne.io.Raw对象中,
    就可以根据注释的描述提取事件以获得时间片段(epochs)。
    """
    
    
    """
    可以通过
    mne.datasets.sleep_physionet.age.fetch_data(subjects,recording,path)
    来获取PhysioNet多导睡眠图数据集文件。
    subjects:表示想要使用哪些受试者对象,可供选择的受试者对象范围为0-19。
    recording:表示夜间记录的编号(索引),有效值为:[1]、[2]或[1、2]。
    
    path:PhysioNet数据的存放地址,如果没有给定,则加载默认存放数据的地址;
    如果默认存放数据集的地址不存在数据,则从网络中下载相关数据。
    """
    # mne.datasets.sleep_physionet.age.fetch_data(subjects,recording,path)
    # 选择两个受试者实验对象ALICE, BOB(该名字并非实验中的真实名,这里是为了方便才临时取的名字)
    ALICE, BOB = 0, 1
    # 加载ALICE, BOB的实验数据文件
    # path = 'mne_data'.replace("\\", "/")
    [alice_files, bob_files] = fetch_data(subjects=[ALICE, BOB],
                                          recording=[1])
    
    # 通道名称映射
    mapping = {'EOG horizontal': 'eog',
               'Resp oro-nasal': 'misc',
               'EMG submental': 'misc',
               'Temp rectal': 'misc',
               'Event marker': 'misc'}
    
    #读取ALICE的edf文件,和其对应的注释文件
    raw_train = mne.io.read_raw_edf(alice_files[0])
    annot_train = mne.read_annotations(alice_files[1])
    
    raw_train.set_annotations(annot_train, emit_warning=False)
    raw_train.set_channel_types(mapping)
    
    # 绘制空0s开始,时间窗口长度为40s的连续通道数据波形图
    raw_train.plot(duration=40, scalings='auto')
    plt.show()
    
    
    """
    这里仅使用5个阶段:唤醒(W),阶段1,阶段2,阶段3/4和REM睡眠(R)。 
    
    为此,这里使用mne.events_from_annotations()中的event_id参数来选择我们感兴趣的事件,
    并将事件标识符与每个事件相关联。
    """
    """
    睡眠表示与事件映射
    """
    annotation_desc_2_event_id = {'Sleep stage W': 1,
                                  'Sleep stage 1': 2,
                                  'Sleep stage 2': 3,
                                  'Sleep stage 3': 4,
                                  'Sleep stage 4': 4,
                                  'Sleep stage R': 5}
    
    events_train, _ = mne.events_from_annotations(
        raw_train, event_id=annotation_desc_2_event_id, chunk_duration=30.)
    
    # 创建一个新的event_id以统一 阶段3和4
    event_id = {'Sleep stage W': 1,
                'Sleep stage 1': 2,
                'Sleep stage 2': 3,
                'Sleep stage 3/4': 4,
                'Sleep stage R': 5}
    
    # 绘制事件数据
    mne.viz.plot_events(events_train, event_id=event_id,
                        sfreq=raw_train.info['sfreq'])
    
    # 保留颜色代码以便进一步绘制
    stage_colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
    
    """  根据注释中的事件从数据创建epochs(时间片段)  """
    tmax = 30. - 1. / raw_train.info['sfreq']  # tmax in included
    """
    所创建的是时间从tmin=0开始,到tmax为止的epochs
    """
    epochs_train = mne.Epochs(raw=raw_train, events=events_train,
                              event_id=event_id, tmin=0., tmax=tmax, baseline=None)
    
    print(epochs_train)
    
    """
    第三步:加载Bob的数据作为测试数据
    
    按照上述相同的步骤来获取Bob的测试数据
    """
    
    raw_test = mne.io.read_raw_edf(bob_files[0])
    annot_test = mne.read_annotations(bob_files[1])
    raw_test.set_annotations(annot_test, emit_warning=False)
    raw_test.set_channel_types(mapping)
    events_test, _ = mne.events_from_annotations(
        raw_test, event_id=annotation_desc_2_event_id, chunk_duration=30.)
    epochs_test = mne.Epochs(raw=raw_test, events=events_test, event_id=event_id,
                             tmin=0., tmax=tmax, baseline=None)
    
    print(epochs_test)
    
    """
    特征工程
    
    观察不同睡眠阶段的功率谱密度(PSD)图,可以看到不同睡眠阶段具有不同的特征。
    这些签名在Alice和Bob的数据中保持相似。
    
    在本节的其余部分中,将基于特定频带中的相对功率来创建EEG特征,
    以捕获数据中睡眠阶段之间的差异。
    """
    
    fig, (ax1, ax2) = plt.subplots(ncols=2)
    
    # iterate over the subjects
    stages = sorted(event_id.keys())
    for ax, title, epochs in zip([ax1, ax2],
                                 ['Alice', 'Bob'],
                                 [epochs_train, epochs_test]):
    
        for stage, color in zip(stages, stage_colors):
            epochs[stage].plot_psd(area_mode=None, color=color, ax=ax,
                                   fmin=0.1, fmax=20., show=False,
                                   average=True, spatial_colors=False)
        ax.set(title=title, xlabel='Frequency (Hz)')
    ax2.set(ylabel='uV^2/hz (dB)')
    ax2.legend(ax2.lines[2::3], stages)
    plt.tight_layout()
    plt.show()
    
    """
    第四步:设计scikit-learn 转换器
    
    创建一个函数,根据特定频带中的相对功率提取脑电图特征,
    从而能够根据脑电图信号预测睡眠阶段。
    """
    
    def eeg_power_band(epochs):
        """脑电相对功率带特征提取
        该函数接受一个""mne.Epochs"对象,
        并基于与scikit-learn兼容的特定频带中的相对功率创建EEG特征。
        Parameters
        ----------
        epochs : Epochs
            The data.
        Returns
        -------
        X : numpy array of shape [n_samples, 5]
            Transformed data.
        """
        # 特定频带
        FREQ_BANDS = {"delta": [0.5, 4.5],
                      "theta": [4.5, 8.5],
                      "alpha": [8.5, 11.5],
                      "sigma": [11.5, 15.5],
                      "beta": [15.5, 30]}
    
        psds, freqs = psd_welch(epochs, picks='eeg', fmin=0.5, fmax=30.)
        # 归一化 PSDs
        psds /= np.sum(psds, axis=-1, keepdims=True)
    
        X = []
        for fmin, fmax in FREQ_BANDS.values():
            psds_band = psds[:, :, (freqs >= fmin) & (freqs < fmax)].mean(axis=-1)
            X.append(psds_band.reshape(len(psds), -1))
    
        return np.concatenate(X, axis=1)
    
    """
    第五步:根据 Alice的数据来预测Bob的睡眠阶段 
    
    使用scikit-learn进行多分类
    
    下面展示了解决如何从爱丽丝的数据中预测鲍勃的睡眠阶段并尽可能避免重复样板代码的问题。
    
    这里将利用sckit-learn的Pipeline和FunctionTransformer。
    
    扩展:[Pipeline可以将许多算法模型串联起来,
    可以用于把多个estamitors级联成一个estamitor,
    比如将特征提取、归一化、分类组织在一起形成一个典型的机器学习问题工作流。
    FunctionTransformer将python函数转换为与estamitor兼容的对象。]
    """
    
    pipe = make_pipeline(FunctionTransformer(eeg_power_band, validate=False),
                         RandomForestClassifier(n_estimators=100, random_state=42))
    # 训练
    y_train = epochs_train.events[:, 2]
    pipe.fit(epochs_train, y_train)
    
    # 预测
    y_pred = pipe.predict(epochs_test)
    
    # 评估准确率
    y_test = epochs_test.events[:, 2]
    acc = accuracy_score(y_test, y_pred)
    
    print("Accuracy score: {}".format(acc))
    '''
    预测的准确精度为84.7%
    查看分类报告做进一步分析
    '''
    print(classification_report(y_test, y_pred, target_names=event_id.keys()))
    """
    从分类报告中可以看出,
    
    Bob的每个阶段训练测试样本,以及对应的睡眠阶段的精度。
    
    比如W阶段的精度为86%,测试样本为1856。测试总样本为2802。也可以看到其他一些指标比如召回率和F1值。
    """
    
    问题1:由于我本地没有该实验所需数据集,默认从官网下载,可能由于我的网络问题,ssl一直拒绝下载,报错如下:
    Using default location ~/mne_data for PHYSIONET_SLEEP...
    Error while fetching file https://physionet.org/physiobank/database/sleep-edfx/sleep-cassette//SC4001E0-PSG.edf. Dataset fetching aborted.
    Traceback (most recent call last):
      File "D:\python\lib\urllib\request.py", line 1317, in do_open
        h.request(req.get_method(), req.selector, req.data, headers,
      File "D:\python\lib\http\client.py", line 1230, in request
        self._send_request(method, url, body, headers, encode_chunked)
      File "D:\python\lib\http\client.py", line 1276, in _send_request
        self.endheaders(body, encode_chunked=encode_chunked)
      File "D:\python\lib\http\client.py", line 1225, in endheaders
        self._send_output(message_body, encode_chunked=encode_chunked)
      File "D:\python\lib\http\client.py", line 1004, in _send_output
        self.send(msg)
      File "D:\python\lib\http\client.py", line 944, in send
        self.connect()
      File "D:\python\lib\http\client.py", line 1399, in connect
        self.sock = self._context.wrap_socket(self.sock,
      File "D:\python\lib\ssl.py", line 500, in wrap_socket
        return self.sslsocket_class._create(
      File "D:\python\lib\ssl.py", line 1040, in _create
        self.do_handshake()
      File "D:\python\lib\ssl.py", line 1309, in do_handshake
        self._sslobj.do_handshake()
    ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1108)
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "F:/mne_demo/mne_sklearn_random_trees_judge_sleeping_type.py", line 110, in <module>
        [alice_files, bob_files] = fetch_data(subjects=[ALICE, BOB],
      File "<decorator-gen-457>", line 24, in fetch_data
      File "D:\python\lib\site-packages\mne\datasets\sleep_physionet\age.py", line 122, in fetch_data
        psg_fname = _fetch_one(psg_records['fname'][idx].decode(),
      File "D:\python\lib\site-packages\mne\datasets\sleep_physionet\_utils.py", line 38, in _fetch_one
        _fetch_file(url, destination, print_destination=False,
      File "<decorator-gen-3>", line 24, in _fetch_file
      File "D:\python\lib\site-packages\mne\utils\fetching.py", line 117, in _fetch_file
        _get_http(url, temp_file_name, initial_size, timeout, verbose_bool)
      File "D:\python\lib\site-packages\mne\utils\fetching.py", line 43, in _get_http
        response = request.urlopen(request.Request(url), timeout=timeout)
      File "D:\python\lib\urllib\request.py", line 222, in urlopen
        return opener.open(url, data, timeout)
      File "D:\python\lib\urllib\request.py", line 525, in open
        response = self._open(req, data)
      File "D:\python\lib\urllib\request.py", line 542, in _open
        result = self._call_chain(self.handle_open, protocol, protocol +
      File "D:\python\lib\urllib\request.py", line 502, in _call_chain
        result = func(*args)
      File "D:\python\lib\urllib\request.py", line 1360, in https_open
        return self.do_open(http.client.HTTPSConnection, req,
      File "D:\python\lib\urllib\request.py", line 1320, in do_open
        raise URLError(err)
    urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1108)>
    
    Process finished with exit code 1
    
    

    最初我想这去报错中提到的这个链接https://physionet.org/physiobank/database/sleep-edfx/sleep-cassette//SC4001E0-PSG.edf将数据集下载下来并放到默认路径(./~/mne_data/physionet-sleep-data/,注fetch_data函数中path路径自定义的话写到physionet-sleep-data的上一层即可,该方法会自动给你自定义的path后面追加“/physionet-sleep-data/”)就ok了,后来发现我想的太简单了,失败后我尝试自己定义该函数的path,仍是无果,粗心的没有注意到这是报错的链接已经变了,换了一个链接,也就是说明数据集并非只有一个edf文件,昨晚尝试下载了两个之后放弃了pycharm。不得已只能上Anaconda平台试试

    2.Anaconda上在jupyter notebook上使用代码与pycharm一致

    昨晚报错:一直显示内核正忙,console也显示正在下载,重启后仍是如此,这校园网决绝子,真垃圾!同样这里我使用anaconda console上提供的链接前往下载,放到了anaconda 默认数据集路径,即c盘下当前用户名的mne_data/physionet-sleep-data/下,还是无果,此时仍没有注意到再次运行console的下载链接已改变,于是今晚只能放弃。

    但是当我今天重新打开电脑使用anaconda再次运行该程序,竟然网络下载成功了,在C:\User\xxx\mne_data\physionet-sleep-data(注:这里的xxx是你当前windows开机登录的用户名)一共下载了4个edf文件,如下所示——在这里插入图片描述

    果然还是败坑爹的校园网所“赐”,我尝试把这四个数据集放到我的pycharm python项目文件所在位置的mne_data\physionet-sleep-data\,运行通过…

    在这里插入图片描述
    在这里插入图片描述
    然后运行过一次之后,我删掉项目路径mne_data\physionet-sleep-data\的四个数据集文件,发现还是成功,重启pycharm还是成功,所以这里应该是fetch_data这个方法对path的应该有其他解读,一种就是自定义path或初始path为“./mne_data”,另一种就是使用当前user下的mne_data路径,所以我尝试把两处的数据集都删除,果然pycharm console又开始下载数据集,不得不吐槽以下pycharm下载数据集真的拉跨,一片红,而且今天第一次开机应该不能是网络的问题,否则anaconda上也会下载失败,又或许是我之前最初python做其他项目时对python package不太了解,无形中可能修改了某些属性导致,欢迎大家一起讨论pycharm使用体验或指出解决办法,灰常感谢!到此可以确认昨天真的是应为网络问题。

    pycharm成功后,尝试Anaconda上是否能通过该实验所有代码
    报错在这一行——raw_train.set_channel_types(mapping) # 125 Line

    这里我初步怀疑时mne版本问题,想了以下我之前做mne官网的example是下载的0.24.0版本的mne package,查了pycharm的mne版本发现是0.21.2,所以尝试卸载重装mne,激活你的项目所在的anaconda虚拟环境后输入命令如下:pip install -U mne==0.21.2即可,
    这里我的虚拟环境为TF2

    这里我的虚拟环境为TF2

    重新运行,通过 😦 ->>> 😃

    这里还得提一下,关于有时候anaconda上同一段代码会生成两个一模一样的图的问题,如下所示:
    """
    这里仅使用5个阶段:唤醒(W),阶段1,阶段2,阶段3/4和REM睡眠(R)。 
    
    为此,这里使用mne.events_from_annotations()中的event_id参数来选择我们感兴趣的事件,
    并将事件标识符与每个事件相关联。
    """
    """
    睡眠表示与事件映射
    """
    annotation_desc_2_event_id = {'Sleep stage W': 1,
                                  'Sleep stage 1': 2,
                                  'Sleep stage 2': 3,
                                  'Sleep stage 3': 4,
                                  'Sleep stage 4': 4,
                                  'Sleep stage R': 5}
    
    events_train, _ = mne.events_from_annotations(
        raw_train, event_id=annotation_desc_2_event_id, chunk_duration=30.)
    
    # 创建一个新的event_id以统一 阶段3和4
    event_id = {'Sleep stage W': 1,
                'Sleep stage 1': 2,
                'Sleep stage 2': 3,
                'Sleep stage 3/4': 4,
                'Sleep stage R': 5}
    
    # 绘制事件数据
    mne.viz.plot_events(events_train, event_id=event_id,
                        sfreq=raw_train.info['sfreq'])
    # 保留颜色代码以便进一步绘制
    # stage_colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
    
    上述代码运行结果——

    在这里插入图片描述

    把上述代码最后一行注释取消后,运行结果才正常,希望有大佬能制出这其中的不同,感激不尽 😃

    在这里插入图片描述

    到此,本次实验就结束了,如有不足,希望各位大佬批评指正,感谢 😃

    最后再次感谢微信公众号——脑际接口社区 分享的文章《脑电分析系列[MNE-Python-5]| Python机器学习算法随机森林判断睡眠类型》!!! 😃

    展开全文
  • 点击上面"脑机接口社区"关注我们更多技术干货第一时间送达有很多社区朋友在后台留言问社区的历史文章如何查找。Rose整理了一些非常实用的方法,方便大家查看。设置星标由于微信...

    有很多社区朋友在后台留言问社区的历史文章如何查找。Rose整理了一些非常实用的方法,方便大家查看。

    设置星标

    由于微信的推文不再像以前一样按照时间线展示了,所以没点"在看"或者没有设置"星标",可能会错过甚至看不到我们精彩的分享了!

    如果不想错过我们的精彩分享,赶紧"星标"我们吧!

    利用社区推荐搜索来搜精彩文章

    具体操作如下图:

    在最新推送的文章上方,有社区推荐搜索,第一步点进去;

    第二步,选择关键字;

    第三步,根据关键字展示对应的内容;

    第四步,也可以自己输入关键字,获取想要的内容。

    查看历史汇总文章

    进入公众号后台,可以看到脑电干货、文章精选两个按钮。

    脑电干货分类中汇总了包括脑机头条汇总、脑电数据分析工具、脑科学与脑电汇总、算法原理与实现以及历史文章。

    • 脑机头条汇总主要包括国内外脑机接口、脑机-机器人等最新资讯;

    • 脑电数据分析工具包括EEGLAB使用教程、MNE-Python使用教程、ERPLAB使用教程等多种脑电数据分析工具使用教程;

    • 脑科学与脑电汇总包括脑科学、脑机知识、神经科学、脑电信号等基础知识分享;

    • 算法原理与实现包括常见脑电数据特征提取、脑电数据分析以及机器学习、深度学习等人工智能技术处理脑电数据的原理与实现;

    • 历史文章包括以前发过的文章以及每天更新的文章。

    文章精选分类主要包括MNE-Python教程合集,EEGLAB教程合集、脑机视频汇总以及论文与数据资源。

    • MNE-Python教程合集包括MNE处理脑电数据的文章汇总;

    • EEGLAB教程合集包括利用EEGLAB来处理脑电数据的文章汇总;

    • 脑机视频汇总包括脑电处理与分析的视频教程汇总;

    • 论文与数据资源包括不定期的论文分享汇总和EEG、MEG等脑电公开数据集下载地址汇总。

    文章来源于网络,仅用于学术分享,不用于商业行为,若有侵权及疑问,请后台留言!

    更多阅读

    手把手教你EMD算法原理与Python实现(更新)

    MNE-Python专辑 | MNE-Python详细安装与使用(更新)

    TensorFlow处理运动想象分类任务

    ICA处理脑电资料汇总

    收藏 | 脑电EEG基础与处理汇总

    脑机接口BCI学习交流QQ群:903290195

    展开全文
  • 脑机接口的数据集和算法库 ·· 目录 接触 致谢 关于该项目 当我是脑机接口的菜鸟时,最让我烦恼的是三件事: 注入导电胶 预处理不同格式的EEG数据 一遍又一遍地复制并粘贴MATLAB中的算法代码 对于第一个问题,我...
  • 脑机接口社区和网上大部分博主所写的步骤和代码都是通过读取fif文件创建epoch对象,然而我并没有“具有event”的fif文件,也就是以下代码中的event_fname,所以我用的是第二个方法。 2.读取fif文件创建Epoch对象 ...

    1. 前言

    脑机接口社区和网上大部分博主所写的步骤和代码都是通过读取fif文件创建epoch对象,然而我并没有“具有event”的fif文件,也就是以下代码中的event_fname,所以我用的是第二个方法。


    2. 读取fif文件创建Epoch对象

    步骤:

    • 1)读取fif文件,构建raw对象;
    • 2)创建event对象;
    • 3)创建epoch对象;
    • 4)对epoch进行叠加平均得到evoked对象;
    • 5)绘制evoked。

    代码

    import mne
    from mne import io
    from mne.datasets import sample
    
    data_path = sample.data_path()
    
    raw_fname = data_path + '/MEG/sample/sample_audvis_filt-0-40_raw.fif'
    event_fname = data_path + '/MEG/sample/sample_audvis_filt-0-40_raw-eve.fif'
    event_id, tmin, tmax = 1, -0.2, 0.5
    
    # 读取fif文件,创建raw对象
    raw = io.read_raw_fif(raw_fname)
    # 读取包含event的fif文件,创建event对象
    events = mne.read_events(event_fname)
    
    """
     挑选通道:EEG + MEG - bad channels 
    """
    raw.info['bads'] += ['MEG 2443', 'EEG 053']  # bads + 2 more
    picks = mne.pick_types(raw.info, meg=True, eeg=False, stim=True, eog=True,
                           exclude='bads')
    
    # 读取Epoch数据
    epochs = mne.Epochs(raw, events, event_id, tmin, tmax, proj=True,
                        picks=picks, baseline=(None, 0), preload=True,
                        reject=dict(grad=4000e-13, mag=4e-12, eog=150e-6))
    """
    对epochs数据进行求平均获取诱发响应
    """
    evoked = epochs.average()
    
    evoked.plot(time_unit='s')
    plt.show()
    
    Read a total of 4 projection items:
            PCA-v1 (1 x 102)  idle
            PCA-v2 (1 x 102)  idle
            PCA-v3 (1 x 102)  idle
            Average EEG reference (1 x 60)  idle
        Range : 6450 ... 48149 =     42.956 ...   320.665 secs
    Ready.
    Current compensation grade : 0
    72 matching events found
    Applying baseline correction (mode: mean)
    Not setting metadata
    Created an SSP operator (subspace dimension = 3)
    4 projection items activated
    Loading data for 72 events and 106 original time points ...
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on MAG : ['MEG 1711']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
        Rejecting  epoch based on EOG : ['EOG 061']
    17 bad epochs dropped
    

    在这里插入图片描述


    3. 无事件,创建Event和Epoch对象

    主要是通过创建等距事件数组mne.make_fixed_length_events(),其中,参数:duration–持续时间,overlap–事件之间重叠时间,本项目中所用到的duration=4,overlap=2
     

    (1)创建events

    	#创建event对象,重叠时间overlap:2s
        # 创建等距事件,默认id为1
        events =  mne.make_fixed_length_events(raw, duration=4.,overlap=2)
        scalings = {'eeg': 'auto'}
        raw.plot(scalings=scalings)
        # 绘制事件
        fig = mne.viz.plot_events(events, sfreq=raw.info['sfreq'], first_samp=raw.first_samp )
        fig.subplots_adjust(right=0.7)  # make room for legend
        # 将事件和原始数据一起绘制
        plt.show()
    

     

    (2)创建epochs

    epochs = mne.Epochs(raw,new_events)
    epochs.plot()
    plt.show()
    


    图最上面的1表示events_id,下面的则是epochs_id。
     

    (3)查看分段后的数据

    #原数据
    print(raw.get_data().shape)
    #分段后
    for epoch in epochs[:3]:
        print(len(epoch))
        print(len(epoch[0]))
        print(epoch)
    
    
    (8, 5218)
    8
    180
    [[ -144.65019872  -685.67894627  -227.6085117  ... -1445.9131992
      -1523.38469579 -2072.20708348]
     [ -700.87143473  -501.35742716  -187.27423624 ... -1995.3743339
      -1903.86932901 -1643.93585733]
     [ -456.88209006  -372.8651528   -384.00986715 ... -2048.47870871
      -1663.99854513 -1792.61396261]
     ...
     [ -769.59106093  -702.97280532   -91.71081191 ... -1996.27233535
      -1679.9616664  -1546.97546035]
     [ -574.18893902  -369.95935528  -223.22617047 ... -1660.25699322
      -1806.17081158 -1719.39670269]
     [ -295.74407607  -518.31066542  -336.61639052 ... -1712.76458388
      -1929.28606826 -2012.93792372]]
    8
    180
    [[ -707.20416935  -626.05258854  -612.95868595 ... -1481.36405094
      -1348.98813541 -1698.79764469]
     [ -458.14901968  -615.92480704  -187.62082144 ... -1430.62802359
      -1880.09933706 -1626.21939322]
     [ -526.66955332  -398.55254892  -653.84789804 ... -1420.9714332
      -1796.1278663  -2073.63830332]
     ...
     [ -374.16785548   -90.98960231  -568.29407619 ... -1606.54258082
      -1825.51584743 -1605.62674831]
     [ -255.34345128  -331.41754796  -533.958411   ... -1648.40839269
      -1646.59162023 -2106.65924718]
     [ -266.09665386   -78.22556011  -421.66559307 ... -1967.04214947
      -1982.07681744 -1555.67239849]]
    8
    180
    [[ -437.02776043  -699.90239422  -515.13240521 ... -1759.97719281
      -1768.87514202 -1925.14613812]
     [ -664.01724096  -572.2451615   -232.91456457 ... -2027.06306311
      -1414.0014176  -1854.27375647]
     [ -253.44605431   -73.06336388  -662.15906701 ... -1913.50916466
      -1836.01087365 -1526.49732384]
     ...
     [  -66.20364908  -391.96851114    14.12264486 ... -1448.15469889
      -1935.92801432 -1539.35867838]
     [ -567.57007071  -414.43033072  -277.36804434 ... -1992.26941153
      -1866.29803702 -1592.40033194]
     [ -670.90289424  -546.58743404  -321.15170405 ... -1712.06051753
      -1547.58969234 -1725.77963374]]
    
    展开全文
  • 脑机接口技术介绍、应用与挑战

    千次阅读 2020-04-19 20:57:24
    本分享为脑机学习者Rose整理发表于公众号:脑机接口社区(微信号:Brain_Computer).QQ交流群:941473018 脑机接口简介 脑机接口的概念最先于1973年提出,伴随着计算机性能的飞速提高,在美国“人类计划”的资金...
  • 从运动脑机接口到情绪脑机接口(1) 脑机接口(BMI)是一种闭环控制系统,通过记录和调控神经活动的方式与大脑进行交互。目前应用是恢复失去的神经功能,尤其是恢复瘫痪患者的运动功能。由于运动脑机接口可以精确地...
  • P300脑机接口及数据集处理

    千次阅读 2020-09-17 08:11:25
    点击上面"脑机接口社区"关注我们更多技术干货第一时间送达文章来源|CSDN网友pengchengIT授权分享在此非常感谢pengchengIT!本篇文章主要介绍了P300...
  • 脑机接口(BCI)能够控制有严重运动障碍患者的辅助设备。BCI的局限性在于长期可靠性差和每天重新校准时间长,这在现实世界的实用性有一定的限制。为了开发无需重新校准即可实现稳定性能的方法,加...
  • 脑机接口基本架构和常见概念

    千次阅读 2020-11-13 09:09:42
    点击上面"脑机接口社区"关注我们更多技术干货第一时间送达图片来源于网络作者|HNU君陌本文由作者授权分享脑机接口BCI技术是一种涉及神经科学、信号检测、信号处理、模式识别...
  • 通过以下代码可以从一个bdf文件中读取数据(需要将以下代码保存为... 欢迎加入BCIduino脑机接口开源社区(公众号“BCIduino脑机接口社区”)…更多代码还需要大家一起写/整理… (加入社群…请扫码备注“BCI”即可…)
  • 深度学习技术在脑机接口中的应用

    千次阅读 2020-08-30 08:37:11
    点击上面"脑机接口社区"关注我们更多技术干货第一时间送达大家好!Rose给大家分享一下深度学习技术在脑机接口中的应用。什么是脑机接口?脑机接口(BCI)是一种系统,可将受...
  • 点击上面"脑机接口社区"关注我们更多技术干货第一时间送达团队简介类计算与混合智能研究中心已获五邑大学350万启动一期建设。中心团队现有教师6人,其中教授1人,特聘教授3...
  • 后面就是代码部分了,数据集下载不复杂,很值得拿来练练手 若想查阅本文文字部分,可【脑机接口社区】公众号搜索“利用LSTM(长短期记忆网络)来处理脑电数据”获得,通过学习平台上的文章,本人不断增进对脑机接口的...
  • 点击上面"脑机接口社区"关注我们更多技术干货第一时间送达侵入式脑机接口研究人员已经测试了许多大脑部位的电刺激,旨在通过使用植入物来恢复视力。例如,研究人员曾尝试对因色素性视...
  • 脑机接口技术

    千次阅读 2020-07-24 09:37:49
    点击上面"脑机接口社区"关注我们更多技术干货第一时间送达介绍脑机接口技术是一种与活动的大脑和计算机系统进行交互的系统,可以使用大脑中产生的信号来模拟计算机。实现脑机接口...
  • 本分享为脑机学习者Rose整理发表于公众号:脑机接口社区(微信号:Brain_Computer).QQ交流群:941473018 撰文 | 李澄宇(中科院神经所PI) 赵维杰(NSR新闻编辑) 脑机接口能做什么?带上电极帽,你可以在实验室中用...
  • 参考脑机接口社区公众号文章《脑电分析系列[MNE-Python-11]| 信号空间投影SSP 应用》(以下简称《文章》)学习记录 首先感谢脑机接口社区公众号分享的《文章》,该博客仅作为本人在实际学习和理解该文章知识的记录和...
  • 本分享为脑机学习者Rose整理发表于公众号:脑机接口社区(微信号:Brain_Computer).QQ交流群:894157769 脑机接口主流算法解析线上讲座已经结束,这次讲座包括四场: 讲座1–SSVEP算法解析 讲座2–ERP/P300算法解析 ...
  • 点击上面"脑机接口社区"关注我们更多技术干货第一时间送达脑机接口主流算法解析课程包括四场:课程1:SSVEP算法解析课程2:ERP/P300算法解析课程3:运动想象算法解...
  • 脑机接口社区文章《脑电分析系列[MNE-Python-9]| 参考电极应用》pycharm+python3.8.0学习记录及问题分析 出自“脑机接口社区”文章——《脑电分析系列[MNE-Python-9]| 参考电极应用》,感谢公众号文章分享! Env: ...
  • 脑机接口,风口还是入口? 冬去春来,脑机接口(BMI)领域似乎要迎来一个“小阳春”。 资本对脑机接口应用前景的信心,在融资数量和金额上清晰地表现出来,这让不少人断言:脑机接口的风口来了。近日,一项发表于...
  • 点击上面"脑机接口社区"关注我们更多技术干货第一时间送达用户控制机械臂的2D连续运动以在计算机屏幕上跟踪随机运动的目标。图片来源:Edelman et al., S...
  • 点击上面"脑机接口社区"关注我们更多技术干货第一时间送达脑机接口和卷积神经网络的初学指南分为两部分,第一部分主要介绍脑机接口和AI +研究论文的概貌;第二部分主要深入解释...
  • 脑机接口社区就是这样一个连接学界、 企业界和爱好者的平台渠道。 社区鼓励高校实验室、企业或个人在我们平台上分享优质内容。 稿件要求 稿件系个人原创作品,若已在其他平台发表,请明确标注。 稿件一经录取,便...
  • 脑机接口(BCI)的研究方法

    千次阅读 多人点赞 2020-10-19 14:52:30
    “ 嘘!悄悄插播的哦” (图1 ...BCIduino脑机接口社区由来自北京航空航天大学、康奈尔大学、北京大学、首都医科大学等硕博发起成立,欢迎扫码加入社群,备注"BCI",也欢迎采购BCIduino脑电模块(某宝搜索即可)
  • 行业科技部发布科技创新2030—“科学与类研究”重大项目2021年度申报指南2021年9月份,科技部发布科技创新 2030—“科学与类研究”重大项目2021年度项目申报指南,资助金...
  • 点击上面"脑机接口社区"关注我们更多技术干货第一时间送达在去年1月16日,浙江大学对外宣布了"双计划"重要科研成果,求是高等研究院脑机接口团队与浙江大学...
  • 脑机接口恢复失去的情绪功能 一般来说,用作电刺激的情绪脑机接口有两个主要成分(图3a):相关情绪状态的神经解码器(图3b)和反馈控制器(图3c),用解码的情绪作为反馈来调整刺激参数。运动脑机接口可以是在物理...
  • 快速入门脑机接口:BCI基础(一)

    千次阅读 2020-08-24 08:46:33
    点击上面"脑机接口社区"关注我们更多技术干货第一时间送达在本模块中,将介绍脑机接口的基础知识。定义:脑机接口是什么?脑机接口(BCI)是允许大脑与各种机器之间进行通信的系...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,007
精华内容 3,602
关键字:

脑机接口社区