def test_embedded_sequence_1_4(self): self.assertEqual( embed_seq(self.data, 1, 4).all(), numpy.asarray([[0., 1., 2., 3.], [1., 2., 3., 4.], [2., 3., 4., 5.], [3., 4., 5., 6.], [4., 5., 6., 7.], [5., 6., 7., 8.]]).all())
def svd_entropy(X, Tau, DE, W = None): """Compute SVD Entropy from either two cases below: 1. a time series X, with lag tau and embedding dimension dE (default) 2. a list, W, of normalized singular values of a matrix (if W is provided, recommend to speed up.) If W is None, the function will do as follows to prepare singular spectrum: First, computer an embedding matrix from X, Tau and DE using pyeeg function embed_seq(): M = embed_seq(X, Tau, DE) Second, use scipy.linalg function svd to decompose the embedding matrix M and obtain a list of singular values: W = svd(M, compute_uv=0) At last, normalize W: W /= sum(W) Notes ------------- To speed up, it is recommended to compute W before calling this function because W may also be used by other functions whereas computing it here again will slow down. """ if W is None: Y = pyeeg.embed_seq(X, Tau, DE) W = svd(Y, compute_uv = 0) W /= sum(W) # normalize singular values return -1*sum(W * log(W))
def apply_svd_embed_seq(self): for e in xrange(self.data.shape[0]): if np.all(self.data[e][:1000] == 0): continue name = 'svd_embed_seq_e' + str(e) value = pyeeg.embed_seq(self.data[e], 4, 20) value = np.linalg.svd(value, compute_uv = 0) value /= sum(value) self.svd_embed_seq[name] = value
def match(signal, m, r): N = len(signal) Em = pyeeg.embed_seq(signal, 1, m) Emp = pyeeg.embed_seq(signal, 1, m + 1) Cm, Cmp = np.zeros(N - m - 1) + 1e-100, np.zeros(N - m - 1) + 1e-100 # in case there is 0 after counting. Log(0) is undefined. for i in range(0, N - m): for j in range(i + 1, N - m): # no self-match # if max(abs(Em[i]-Em[j])) <= R: # v 0.01_b_r1 if pyeeg.in_range(Em[i], Em[j], r): Cm[i] += 1 # if max(abs(Emp[i] - Emp[j])) <= R: # v 0.01_b_r1 if abs(Emp[i][-1] - Emp[j][-1]) <= r: # check last one Cmp[i] += 1 return sum(Cm), sum(Cmp)
def sampen2(X, M, R): N = len(X) Em = pyeeg.embed_seq(X, 1, M) Emp = pyeeg.embed_seq(X, 1, M + 1) Cm, Cmp = np.zeros(N - M - 1) + 1e-100, np.zeros(N - M - 1) + 1e-100 # in case there is 0 after counting. Log(0) is undefined. for i in xrange(0, N - M): for j in xrange(i + 1, N - M): # no self-match # if max(abs(Em[i]-Em[j])) <= R: # v 0.01_b_r1 if pyeeg.in_range(Em[i], Em[j], R): Cm[i] += 1 # if max(abs(Emp[i] - Emp[j])) <= R: # v 0.01_b_r1 if abs(Emp[i][-1] - Emp[j][-1]) <= R: # check last one Cmp[i] += 1 Samp_En = np.log(sum(Cm) / sum(Cmp)) return Samp_En
def test_embedded_sequence_2_3(self): self.assertEqual( embed_seq(self.data, 2, 3).all(), numpy.asarray( [ [0., 2., 4.], [1., 3., 5.], [2., 4., 6.], [3., 5., 7.], [4., 6., 8.] ] ).all() )
def test_embedded_sequence_4_1(self): self.assertEqual( embed_seq(self.data, 2, 3).all(), numpy.asarray( [ [0.], [1.], [2.], [3.], [4.], [5.], [6.], [7.], [8.] ] ).all() )
def test_embedded_sequence_4_1(self): self.assertEqual( embed_seq(self.data, 2, 3).all(), numpy.asarray([[0.], [1.], [2.], [3.], [4.], [5.], [6.], [7.], [8.]]).all())
def calculate_features(samples): data = samples if not samples: print("no samples") return [] band = [0.5, 4, 7, 12, 30] a = randn(4097) # approx = pyeeg.ap_entropy(data, 5, 1) approx = 0 DFA = pyeeg.dfa(data) first_order_diff = [data[i] - data[i - 1] for i in range(1, len(data))] fisher_info = pyeeg.fisher_info(data, 1, 1, W=None) embed_seq = pyeeg.embed_seq(data, 1, 1) hfd = pyeeg.hfd(data, 6) hjorth = pyeeg.hjorth(data, D=None) hurst = pyeeg.hurst(data) PFD = pyeeg.pfd(data) sam_ent = pyeeg.samp_entropy(data, 1, 2) spectral_entropy = pyeeg.spectral_entropy(data, band, 256, Power_Ratio=None) svd = pyeeg.svd_entropy(data, 6, 4, W=None) PSI = pyeeg.bin_power(data, band, 256) # # Power Spectral Intensity (PSI) and Relative Intensity Ratio (RIR) Two 1- D v ec t o rs # # print("bin_power = ", PSI) # # Petrosian Fractal Dimension (PFD) Ascalar # print("PFD = ", PFD) # # Higuchi Fractal Dimension (HFD) Ascalar # print("hfd = ", hfd) # # Hjorth mobility and complexity Two s c a la rs # print("hjorth = ", hjorth) # # Spectral Entropy (Shannon’s entropy of RIRs) Ascalar # print("spectral_entropy = ", spectral_entropy) # # SVD Entropy Ascalar # print("svd = ", svd) # # Fisher Information Ascalar # print("fisher_info = ", fisher_info) # # Approximate Entropy (ApEn) Ascalar # print("approx entrophy = ", approx) # # Detrended Fluctuation Analysis (DFA) Ascalar # print("DFA = ", DFA) # # HurstExponent(Hurst) Ascalar # print("Hurst_Exponent = ", hurst) # # Build a set of embedding sequences from given time series X with lag Tau and embedding dimension # print("embed_seq = ", embed_seq) # # Compute the first order difference of a time series. # print("first_order_diff = ", first_order_diff) return { 'approximate': approx, 'DFA': DFA, 'fisher_info': fisher_info, 'embed_seq': embed_seq, 'hfd': hfd, 'hjorth': hjorth, 'hurst': hurst, 'PFD': PFD, 'sam_ent': sam_ent, 'spectral_entropy': spectral_entropy, 'svd': svd, 'PSI': PSI, 'first_order_diff': first_order_diff }
def compute_pyeeg_feats(self, rec): # these values are taken from the tuh paper TAU, DE, Kmax = 4, 10, 5 pwrs, pwrrs, pfds, hfds, mblts, cmplxts, ses, svds, fis, hrsts = [], [], [], [], [], [], [], [], [], [] dfas, apes = [], [] for window_id, window in enumerate(rec.signals): for window_electrode_id, window_electrode in enumerate(window): # taken from pyeeg code / paper electrode_diff = list(np.diff(window_electrode)) M = pyeeg.embed_seq(window_electrode, TAU, DE) W = scipy.linalg.svd(M, compute_uv=False) W /= sum(W) power, power_ratio = self.bin_power(window_electrode, self.bands, rec.sampling_freq) pwrs.extend(list(power)) # mean of power ratio is 1/(len(self.bands)-1) pwrrs.extend(list(power_ratio)) pfd = pyeeg.pfd(window_electrode, electrode_diff) pfds.append(pfd) hfd = pyeeg.hfd(window_electrode, Kmax=Kmax) hfds.append(hfd) mobility, complexity = pyeeg.hjorth(window_electrode, electrode_diff) mblts.append(mobility) cmplxts.append(complexity) se = self.spectral_entropy(window_electrode, self.bands, rec.sampling_freq, power_ratio) ses.append(se) svd = pyeeg.svd_entropy(window_electrode, TAU, DE, W=W) svds.append(svd) fi = pyeeg.fisher_info(window_electrode, TAU, DE, W=W) fis.append(fi) # this crashes... # ape = pyeeg.ap_entropy(electrode, M=10, R=0.3*np.std(electrode)) # apes.append(ape) # takes very very long to compute # hurst = pyeeg.hurst(electrode) # hrsts.append(hurst) # takes very very long to compute # dfa = pyeeg.dfa(electrode) # dfas.append(dfa) pwrs = np.asarray(pwrs).reshape(rec.signals.shape[0], rec.signals.shape[1], len(self.bands) - 1) pwrs = np.mean(pwrs, axis=0) pwrrs = np.asarray(pwrrs).reshape(rec.signals.shape[0], rec.signals.shape[1], len(self.bands) - 1) pwrrs = np.mean(pwrrs, axis=0) pfds = np.asarray(pfds).reshape(rec.signals.shape[0], rec.signals.shape[1]) pfds = np.mean(pfds, axis=0) hfds = np.asarray(hfds).reshape(rec.signals.shape[0], rec.signals.shape[1]) hfds = np.mean(hfds, axis=0) mblts = np.asarray(mblts).reshape(rec.signals.shape[0], rec.signals.shape[1]) mblts = np.mean(mblts, axis=0) cmplxts = np.asarray(cmplxts).reshape(rec.signals.shape[0], rec.signals.shape[1]) cmplxts = np.mean(cmplxts, axis=0) ses = np.asarray(ses).reshape(rec.signals.shape[0], rec.signals.shape[1]) ses = np.mean(ses, axis=0) svds = np.asarray(svds).reshape(rec.signals.shape[0], rec.signals.shape[1]) svds = np.mean(svds, axis=0) fis = np.asarray(fis).reshape(rec.signals.shape[0], rec.signals.shape[1]) fis = np.mean(fis, axis=0) return list(pwrs.ravel()), list(pwrrs.ravel( )), pfds, hfds, mblts, cmplxts, ses, svds, fis, apes, hrsts, dfas
def myFeaturesExtractor( X, myM, myV): # X has to be a matrix where each row is a channel N = len(X) # number of channels L = len(X[0]) maxtLyap = min(500, L // 2 + L // 4) lyapLags = np.arange(maxtLyap) / Fs # get number of features nFeatures = nMono * N + N * (N - 1) / 2 # here we initialize the list of features // We will transform it to an array later featList = np.zeros((int(nFeatures))) # deal with monovariate features first for kChan in range(N): kFeat = 0 mySig = X[kChan, :] #========== Stats ======================== myMean = myM[kChan] featList[nMono * kChan + kFeat] = myMean kFeat += 1 myMax = max(mySig) featList[nMono * kChan + kFeat] = myMax kFeat += 1 myMin = min(mySig) featList[nMono * kChan + kFeat] = myMin kFeat += 1 peak = max(abs(np.array([myMin, myMax]))) featList[nMono * kChan + kFeat] = peak kFeat += 1 myVar = myV[kChan] featList[nMono * kChan + kFeat] = myVar kFeat += 1 featList[nMono * kChan + kFeat] = sp.skew(mySig) kFeat += 1 featList[nMono * kChan + kFeat] = sp.kurtosis(mySig) kFeat += 1 myRMS = rms(mySig) featList[nMono * kChan + kFeat] = myRMS kFeat += 1 featList[nMono * kChan + kFeat] = peak / myRMS kFeat += 1 featList[nMono * kChan + kFeat] = totVar(mySig) kFeat += 1 featList[nMono * kChan + kFeat] = pyeeg.dfa(mySig) kFeat += 1 featList[nMono * kChan + kFeat] = pyeeg.hurst(mySig) kFeat += 1 hMob, hComp = pyeeg.hjorth(mySig) featList[nMono * kChan + kFeat] = hMob kFeat += 1 featList[nMono * kChan + kFeat] = hComp kFeat += 1 ## ======== fractal ======================== # Now we need to get the embeding time lag Tau and embeding dmension ac = delay.acorr(mySig, maxtau=maxTauLag, norm=True, detrend=True) Tau = firstTrue(ac < corrThresh) # embeding delay f1 , f2 , f3 = dimension.fnn(mySig, dim=dim, tau=Tau, R=10.0, A=2.0, metric='euclidean',\ window=10,maxnum=None, parallel=True) myEmDim = firstTrue(f3 < fracThresh) # Here we construct the Embeding Matrix Em Em = pyeeg.embed_seq(mySig, Tau, myEmDim) U, s, Vh = linalg.svd(Em) W = s / np.sum(s) # list of singular values in decreasing order FInfo = pyeeg.fisher_info(X, Tau, myEmDim, W=W) featList[nMono * kChan + kFeat] = FInfo kFeat += 1 featList[nMono * kChan + kFeat] = Tau kFeat += 1 featList[nMono * kChan + kFeat] = myEmDim kFeat += 1 #======================================== PFD = pyeeg.pfd(mySig, D=None) hfd6 = pyeeg.hfd(mySig, 6) hfd10 = pyeeg.hfd(mySig, 10) # Now we fit aline and get its slope to have Lyapunov exponent divAvg = lyapunov.mle(Em, maxt=maxtLyap, window=3 * Tau, metric='euclidean', maxnum=None) poly = np.polyfit(lyapLags, divAvg, 1, rcond=None, full=False, w=None, cov=False) LyapExp = poly[0] featList[nMono * kChan + kFeat] = PFD kFeat += 1 featList[nMono * kChan + kFeat] = hfd6 kFeat += 1 featList[nMono * kChan + kFeat] = hfd10 kFeat += 1 featList[nMono * kChan + kFeat] = LyapExp kFeat += 1 ## ======== Entropy ======================== tolerance = 1 / 4 entropyDim = max([myEmDim, PFD]) featList[nMono * kChan + kFeat] = pyeeg.samp_entropy( mySig, entropyDim, tolerance) kFeat += 1 featList[nMono * kChan + kFeat] = pyeeg.svd_entropy(mySig, Tau, myEmDim, W=W) kFeat += 1 # here we compute bin power power, power_Ratio = pyeeg.bin_power(mySig, freqBins, Fs) featList[nMono * kChan + kFeat] = pyeeg.spectral_entropy( mySig, freqBins, Fs, Power_Ratio=power_Ratio) kFeat += 1 ## ======== Spectral ======================== for kBin in range(len(freqBins) - 1): featList[nMono * kChan + kFeat] = power[kBin] kFeat += 1 featList[nMono * kChan + kFeat] = power_Ratio[kBin] kFeat += 1 # deal with multivariate features first #============ connectivity ================== corrList = connectome(X) nConnect = len(corrList) if N * (N - 1) / 2 != nConnect: raise ValueError('incorrect number of correlation coeffs') for kC in range(nConnect): featList[-nConnect + kC] = corrList[kC] return featList