在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            博客專欄

            EEPW首頁(yè) > 博客 > Python實(shí)現(xiàn)對(duì)腦電數(shù)據(jù)情緒分析

            Python實(shí)現(xiàn)對(duì)腦電數(shù)據(jù)情緒分析

            發(fā)布人:AI科技大本營(yíng) 時(shí)間:2021-08-19 來(lái)源:工程師 發(fā)布文章

            腦電波是一類由大腦中局部群體神經(jīng)元同步放電所形成的具有時(shí)空特征的腦電活動(dòng)電波。德國(guó)醫(yī)生漢斯·伯格(Hans Berger)在1924年首次在人的頭骨上記錄到腦電波圖(electroencephalography,EEG)。心理學(xué)研究表明,人類的認(rèn)知和感知可以通過(guò)腦電波來(lái)表達(dá)。當(dāng)大腦的嗅覺(jué)、聽(tīng)覺(jué)、視覺(jué)、味覺(jué)及觸覺(jué)神經(jīng)受到刺激時(shí),其刺激反應(yīng)信號(hào)可以通過(guò)腦電波表達(dá)出來(lái),從而揭示感官和人員之間的心理關(guān)聯(lián)性。其中大量研究展示了使用腦電信號(hào)連續(xù)確定個(gè)人舒適感的可行性,并且可以得到更加客觀的數(shù)據(jù)。近來(lái)則有研究表明觸覺(jué)刺激與腦電波的θ,α,β這三個(gè)頻段均存在關(guān)聯(lián)性。

            傳統(tǒng)的情緒識(shí)別主要是基于面部特征、肢體動(dòng)作和語(yǔ)音的研究,這些外在特征容易偽裝,并不能反應(yīng)出真實(shí)的情緒,腦電信號(hào)可以反映大腦在加工情緒時(shí)所伴隨的神經(jīng)電生理活動(dòng),能夠很好的彌補(bǔ)傳統(tǒng)研究方法的缺陷。

            1.png

            故本項(xiàng)目通過(guò)使用python語(yǔ)言搭建KNN機(jī)器學(xué)習(xí)算法實(shí)現(xiàn)對(duì)EEG腦電波數(shù)據(jù)的情緒分析分類。其最終實(shí)現(xiàn)的效果如下圖可見(jiàn):

            2.png

            No.1 “基本介紹”

            環(huán)境要求

            本次環(huán)境使用的是python3.6.5+windows平臺(tái)。主要用的庫(kù)有:

            csv模塊。CSV庫(kù)在這里用來(lái)讀取CSV數(shù)據(jù)集文件。其中CSV文件是逗號(hào)分隔值文件,是一種常用的文本格式,用以存儲(chǔ)表格數(shù)據(jù),包括數(shù)字或者字符。很多程序在處理數(shù)據(jù)時(shí)都會(huì)碰到csv這種格式的文件,它的使用是比較廣泛的。

            scipy模塊。scipy作為高級(jí)科學(xué)計(jì)算庫(kù):和numpy聯(lián)系很密切,scipy一般都是操控numpy數(shù)組來(lái)進(jìn)行科學(xué)計(jì)算、統(tǒng)計(jì)分析,所以可以說(shuō)是基于numpy之上了。scipy有很多子模塊可以應(yīng)對(duì)不同的應(yīng)用,例如插值運(yùn)算,優(yōu)化算法等等。scipy則是在numpy的基礎(chǔ)上構(gòu)建的更為強(qiáng)大,應(yīng)用領(lǐng)域也更為廣泛的科學(xué)計(jì)算包。正是出于這個(gè)原因,scipy需要依賴numpy的支持進(jìn)行安裝和運(yùn)行。以Python為基礎(chǔ)的scipy的另一個(gè)好處是,它還提供了一種強(qiáng)大的編程語(yǔ)言,可用于開(kāi)發(fā)復(fù)雜的程序和專門的應(yīng)用程序。使用scipy的科學(xué)應(yīng)用程序受益于世界各地的開(kāi)發(fā)人員在軟件領(lǐng)域的許多小眾領(lǐng)域中開(kāi)發(fā)的附加模塊。

            pathlib模塊。該模塊提供了一些使用語(yǔ)義表達(dá)來(lái)表示文件系統(tǒng)路徑的類,這些類適合多種操作系統(tǒng)。

            Pickle模塊。python的pickle模塊實(shí)現(xiàn)了基本的數(shù)據(jù)序列和反序列化。通過(guò)pickle模塊的序列化操作我們能夠?qū)⒊绦蛑羞\(yùn)行的對(duì)象信息保存到文件中去,永久存儲(chǔ);通過(guò)pickle模塊的反序列化操作,我們能夠從文件中創(chuàng)建上一次程序保存的對(duì)象。

            以及其他常用模塊,如OpenCV等不一一介紹了。

            KNN算法介紹

            其中k近鄰算法(k Nearest Neighbor,kNN)是一種理論上比較成熟的智能算法,最初由Cover和Hart于1968年提出。kNN算法思路簡(jiǎn)單直觀:對(duì)于給定的測(cè)試樣本,基于某種距離度量找出訓(xùn)練集中與其最靠近的k個(gè)訓(xùn)練樣本,然后基于這k個(gè)“鄰居”的信息來(lái)進(jìn)行預(yù)測(cè)。

            kNN方法可以實(shí)現(xiàn)分類任務(wù)和回歸任務(wù)。在分類任務(wù)中,一般使用“投****法”,即在k個(gè)“近鄰”樣本中出現(xiàn)最多的種類標(biāo)記作為預(yù)測(cè)結(jié)果。在回歸任務(wù)中,一般使用“平均法”,即將這k個(gè)樣本的實(shí)值輸出標(biāo)記的平均值作為預(yù)測(cè)結(jié)果。在定義了相似度評(píng)價(jià)準(zhǔn)則后,還可以基于相似度的大小進(jìn)行加權(quán)投****和加權(quán)平均。相似度越大的樣本權(quán)重越大。其中KNN算法分類流程如下圖:

            3.png

            No.2 “模型搭建”

            數(shù)據(jù)集準(zhǔn)備

            首先我們使用官方提供的EEG數(shù)據(jù)集,放置data文件夾下:

            4.png

            數(shù)據(jù)特征提取

            首先我們使用官方提供的EEG數(shù)據(jù)集,放置data文件夾下:

            通過(guò)使用pickle實(shí)現(xiàn)對(duì)dat數(shù)據(jù)文件的讀取,獲取各個(gè)數(shù)據(jù)文件中特征向量,并在每個(gè)信道中進(jìn)行fft。

            其中輸入:維數(shù)為N × M的通道數(shù)據(jù),N為通道個(gè)數(shù),M為每個(gè)通道的腦電圖數(shù)據(jù)個(gè)數(shù)。

            輸出:維度為N x M的FFT結(jié)果。N表示信道數(shù),M表示每個(gè)信道的FFT數(shù)據(jù)數(shù)。

            關(guān)鍵代碼如下:

            for file in os.listdir("../data"):
                  fname = Path("../data/"+file)
                  x = cPickle.load(open(fname, 'rb'), encoding="bytes")
                  for i in range(40):
                            num+=1
                            eeg_realtime = x[b'data'][i]
                            label = x[b'labels'][i]
                            if label[0] >6:
                                val_v = 3
                            elif label[0] < 4:
                                val_v = 1
                            else:
                                val_v = 2
                            if label[1] > 6:
                                val_a = 3
                            elif label[1] < 4:
                                val_a = 1
                            else:
                                val_a = 2
                            if i < 39:
                                va_label.write(str(val_v) + ",")
                                ar_label.write(str(val_a) + ",")
                            if num==1280:
                                va_label.write(str(val_v) )
                                ar_label.write(str(val_v) )
                            eeg_raw = np.reshape(eeg_realtime, (40, 8064))
                            eeg_raw = eeg_raw[:32, :]
                            eeg_feature_arr = self.get_feature(eeg_raw)
                            for f in range(160):
                                if f == 159:
                                    fout_data.write(str(eeg_feature_arr[f]))
                                else:
                                    fout_data.write(str(eeg_feature_arr[f]) + ",")
                            fout_data.write("\n")
                            print(file + " Video watched")

            然后從計(jì)算fft得到所有通道的頻率。輸入:維數(shù)為N × M的通道數(shù)據(jù),N為通道個(gè)數(shù),M為每個(gè)通道的腦電圖數(shù)據(jù)個(gè)數(shù)。輸出:每個(gè)通道的頻帶:Delta, Theta, Alpha, Beta和Gamma。

            # Length data channel
            L = len(all_channel_data[0])
            # Sampling frequency
            Fs = 128
            # Get fft data
            data_fft = self.do_fft(all_channel_data)
            # Compute frequencymotio
            frequency = map(lambda x: abs(x // L), data_fft)
            frequency = map(lambda x: x[: L // 2 + 1] * 2, frequency)
            f1, f2, f3, f4, f5 = itertools.tee(frequency, 5)
            # List frequency
            delta = np.array(list(map(lambda x: x[L * 1 // Fs - 1: L * 4 // Fs], f1)))
            theta = np.array(list(map(lambda x: x[L * 4 // Fs - 1: L * 8 // Fs], f2)))
            alpha = np.array(list(map(lambda x: x[L * 5 // Fs - 1: L * 13 // Fs], f3)))
            beta = np.array(list(map(lambda x: x[L * 13 // Fs - 1: L * 30 // Fs], f4)))
            gamma = np.array(list(map(lambda x: x[L * 30 // Fs - 1:L * 50 // Fs], f5)))

            模型預(yù)測(cè)

            從特征得到arousal值和valence值。其中Valence-Arousal分別代表情緒的正負(fù)向程度和激動(dòng)程度,基于這兩個(gè)維度可以構(gòu)成一個(gè)情感平面空間,任何一個(gè)情感狀態(tài)可以通過(guò)具體的Valence-Arousal數(shù)值,映射到VA平面空間中具體的一個(gè)點(diǎn)。

            輸入:來(lái)自所有頻帶和信道的特征(標(biāo)準(zhǔn)差和平均值),維度為1 × M(特征數(shù)量)。

            輸出:由每一種arousal和valence產(chǎn)生的1至3級(jí)情緒。1表示低,2表示中性,3表示高。

            self.train_arousal = self.train_arousal[40*(index-1):40*index]
            self.train_valence = self.train_valence[40*(index-1):40*index]
            self.class_arousal = np.array([self.class_arousal[0][40*(index-1):40*index]])
            self.class_valence = np.array([self.class_valence [0][40*(index-1):40*index]])
            distance_ar = list(map(lambda x: ss.distance.canberra(x, feature), self.train_arousal))
            # Compute canberra with valence training data
            distance_va = list(map(lambda x: ss.distance.canberra(x, feature), self.train_valence))
            # Compute 3 nearest index and distance value from arousal
            idx_nearest_ar = np.array(np.argsort(distance_ar)[:3])
            val_nearest_ar = np.array(np.sort(distance_ar)[:3])
            # Compute 3 nearest index and distance value from arousal
            idx_nearest_va = np.array(np.argsort(distance_va)[:3])
            val_nearest_va = np.array(np.sort(distance_va)[:3])
            # Compute comparation from first nearest and second nearest distance.、If comparation less or equal than 0.7, then take class from the first nearest distance. Else take frequently class.
            # Arousal
            comp_ar = val_nearest_ar[0] / val_nearest_ar[1]

            然后從特征中獲取情感類。

            輸入:來(lái)自所有頻段和信道的特征(標(biāo)準(zhǔn)偏差),尺寸為1 × M(特征數(shù)量)。

            輸出:根據(jù)plex模型,情緒在1到5之間的類別。

            class_ar, class_va = self.predict_emotion(feature,fname)
            print(class_ar, class_va)
            if class_ar == 2.0 or class_va == 2.0:
                emotion_class = 5
            if class_ar == 3.0 and class_va == 1.0:
                emotion_class = 1
            elif class_ar == 3.0 and class_va == 3.0:
                emotion_class = 2
            elif class_ar == 1.0 and class_va == 3.0:
                emotion_class = 3
            elif class_ar == 1.0 and class_va == 1.0:
                emotion_class = 4

            預(yù)測(cè)結(jié)果如下圖可見(jiàn):

            5.png

            完整代碼

            鏈接:

            https://pan.baidu.com/s/1BX58sJv037eIJx9A8jWt3g

            提取碼:rwpe

            *博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



            關(guān)鍵詞: Python

            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉