def test_cov_scaling(): """Test rescaling covs.""" evoked = read_evokeds(ave_fname, condition=0, baseline=(None, 0), proj=True) cov = read_cov(cov_fname)['data'] cov2 = read_cov(cov_fname)['data'] assert_array_equal(cov, cov2) evoked.pick_channels([ evoked.ch_names[k] for k in pick_types(evoked.info, meg=True, eeg=True) ]) picks_list = _picks_by_type(evoked.info) scalings = dict(mag=1e15, grad=1e13, eeg=1e6) _apply_scaling_cov(cov2, picks_list, scalings=scalings) _apply_scaling_cov(cov, picks_list, scalings=scalings) assert_array_equal(cov, cov2) assert cov.max() > 1 _undo_scaling_cov(cov2, picks_list, scalings=scalings) _undo_scaling_cov(cov, picks_list, scalings=scalings) assert_array_equal(cov, cov2) assert cov.max() < 1 data = evoked.data.copy() _apply_scaling_array(data, picks_list, scalings=scalings) _undo_scaling_array(data, picks_list, scalings=scalings) assert_allclose(data, evoked.data, atol=1e-20) # check that input data remain unchanged. gh-5698 _regularized_covariance(data) assert_allclose(data, evoked.data, atol=1e-20)
def test_cov_scaling(): """Test rescaling covs.""" evoked = read_evokeds(ave_fname, condition=0, baseline=(None, 0), proj=True) cov = read_cov(cov_fname)['data'] cov2 = read_cov(cov_fname)['data'] assert_array_equal(cov, cov2) evoked.pick_channels([evoked.ch_names[k] for k in pick_types( evoked.info, meg=True, eeg=True )]) picks_list = _picks_by_type(evoked.info) scalings = dict(mag=1e15, grad=1e13, eeg=1e6) _apply_scaling_cov(cov2, picks_list, scalings=scalings) _apply_scaling_cov(cov, picks_list, scalings=scalings) assert_array_equal(cov, cov2) assert cov.max() > 1 _undo_scaling_cov(cov2, picks_list, scalings=scalings) _undo_scaling_cov(cov, picks_list, scalings=scalings) assert_array_equal(cov, cov2) assert cov.max() < 1 data = evoked.data.copy() _apply_scaling_array(data, picks_list, scalings=scalings) _undo_scaling_array(data, picks_list, scalings=scalings) assert_allclose(data, evoked.data, atol=1e-20) # check that input data remain unchanged. gh-5698 _regularized_covariance(data) assert_allclose(data, evoked.data, atol=1e-20)
def test_regularized_covariance(): """Test unchanged data with regularized_covariance.""" evoked = read_evokeds(ave_fname, condition=0, baseline=(None, 0), proj=True) data = evoked.data.copy() # check that input data remain unchanged. gh-5698 _regularized_covariance(data) assert_allclose(data, evoked.data, atol=1e-20)
def fit(self, X, y=None): """Estimate the CSP decomposition on epochs. Parameters ---------- X : Dataframe, shape (n_epochs,n_columns) dataframe with mode magnitudes at each channel corresponding window, trial and label - The data on which to estimate the CSP. Returns ------- self : instance of CSP Returns the modified instance. """ y = X['label'].reset_index(drop=True) trials = X['trial'].reset_index(drop=True) X = X.values[:, :-4] X = StandardScaler().fit_transform(X) if not isinstance(X, np.ndarray): raise ValueError("X should be of type ndarray (got %s)." % type(X)) self._check_Xy(X, y) n_channels = X.shape[1] self._classes = np.unique(y) n_classes = len(self._classes) if n_classes < 2: raise ValueError("n_classes must be >= 2.") covs = np.zeros((n_classes, n_channels, n_channels)) sample_weights = list() for class_idx, this_class in enumerate(self._classes): if self.cov_est == "concat": # concatenate epochs class_ = X[y == this_class].T cov = _regularized_covariance( class_, reg=self.reg, method_params=self.cov_method_params, rank=self.rank) weight = sum(y == this_class) elif self.cov_est == "epoch": class_ = X[y == this_class] cov = np.zeros((n_channels, n_channels)) for this_X in class_: cov += _regularized_covariance( this_X, reg=self.reg, method_params=self.cov_method_params, rank=self.rank) cov /= len(class_) weight = len(class_) covs[class_idx] = cov if self.norm_trace: # Append covariance matrix and weight. Prior to version 0.15, # trace normalization was applied, but was breaking results for # some usecases by changing the apparent ranking of patterns. # Trace normalization of the covariance matrix was removed # without signigificant effect on patterns or performances. # If the user interested in this feature, we suggest trace # normalization of the epochs prior to the CSP. covs[class_idx] /= np.trace(cov) sample_weights.append(weight) if n_classes == 2: eigen_values, eigen_vectors = linalg.eigh(covs[0], covs.sum(0)) # sort eigenvectors ix = np.argsort(np.abs(eigen_values - 0.5))[::-1] else: # The multiclass case is adapted from # http://github.com/alexandrebarachant/pyRiemann eigen_vectors, D = _ajd_pham(covs) # Here we apply an euclidean mean. See pyRiemann for other metrics mean_cov = np.average(covs, axis=0, weights=sample_weights) eigen_vectors = eigen_vectors.T # normalize for ii in range(eigen_vectors.shape[1]): tmp = np.dot(np.dot(eigen_vectors[:, ii].T, mean_cov), eigen_vectors[:, ii]) eigen_vectors[:, ii] /= np.sqrt(tmp) # class probability class_probas = [np.mean(y == _class) for _class in self._classes] # mutual information mutual_info = [] for jj in range(eigen_vectors.shape[1]): aa, bb = 0, 0 for (cov, prob) in zip(covs, class_probas): tmp = np.dot(np.dot(eigen_vectors[:, jj].T, cov), eigen_vectors[:, jj]) aa += prob * np.log(np.sqrt(tmp)) bb += prob * (tmp**2 - 1) mi = -(aa + (3.0 / 16) * (bb**2)) mutual_info.append(mi) ix = np.argsort(mutual_info)[::-1] # sort eigenvectors eigen_vectors = eigen_vectors[:, ix] self.filters_ = eigen_vectors.T self.patterns_ = linalg.pinv2(eigen_vectors) pick_filters = self.filters_[:self.n_components] X = np.dot(pick_filters, X.T) # compute features (mean band power) X = pd.DataFrame(X.T) X, y = mean_trial(X, trials, y) # To standardize features self.mean_ = X.mean(axis=0) self.std_ = X.std(axis=0) return self
def fit(self, X, y): """Estimate the SPoC decomposition on epochs. Parameters ---------- X : ndarray, shape (n_epochs, n_channels, n_times) The data on which to estimate the SPoC. y : array, shape (n_epochs,) The class for each epoch. Returns ------- self : instance of SPoC Returns the modified instance. """ if not isinstance(X, np.ndarray): raise ValueError("X should be of type ndarray (got %s)." % type(X)) self._check_Xy(X, y) if len(np.unique(y)) < 2: raise ValueError("y must have at least two distinct values.") # The following code is direclty copied from pyRiemann # Normalize target variable target = y.astype(np.float64) target -= target.mean() target /= target.std() n_epochs, n_channels = X.shape[:2] # Estimate single trial covariance covs = np.empty((n_epochs, n_channels, n_channels)) for ii, epoch in enumerate(X): covs[ii] = _regularized_covariance(epoch, reg=self.reg) C = covs.mean(0) Cz = np.mean(covs * target[:, np.newaxis, np.newaxis], axis=0) # solve eigenvalue decomposition evals, evecs = linalg.eigh(Cz, C) evals = evals.real evecs = evecs.real # sort vectors ix = np.argsort(np.abs(evals))[::-1] # sort eigenvectors evecs = evecs[:, ix].T # spatial patterns self.patterns_ = linalg.pinv(evecs).T # n_channels x n_channels self.filters_ = evecs # n_channels x n_channels pick_filters = self.filters_[:self.n_components] X = np.asarray([np.dot(pick_filters, epoch) for epoch in X]) # compute features (mean band power) X = (X**2).mean(axis=-1) # To standardize features self.mean_ = X.mean(axis=0) self.std_ = X.std(axis=0) return self
def fit(self, inst): """Fit""" if isinstance(inst, BaseRaw): if self.picks_ is None: raise ValueError('picks should be provided') self.max_components = len(self.picks_) inst_signal = inst.copy() inst_signal.filter(picks=self.picks_, **self.filt_params_signal) self.Xs = inst_signal #noise inst_noise = inst.copy() inst_noise.filter(picks=self.picks_, **self.filt_params_noise) # subtract signal: inst_noise._data[self.picks_] -= inst_signal._data[self.picks_] cov_signal = compute_raw_covariance(inst_signal, picks=self.picks_, method=self.estimator, rank=self.rank) cov_noise = compute_raw_covariance(inst_noise, picks=self.picks_, method=self.estimator, rank=self.rank) del inst_noise del inst_signal else: if isinstance(inst, BaseEpochs) or isinstance(inst, np.ndarray): # data X is epoched # part of the following code is copied from mne csp n_epochs, n_channels, n_samples = inst.shape self.max_components = n_channels #reshape for filtering X_aux = np.reshape(inst, [n_epochs, n_channels * n_samples]) X_s = filter_data(X_aux, self.sampling_freq, **self.filt_params_signal) #rephase for filtering X_aux = np.reshape(inst, [n_epochs, n_channels * n_samples]) X_n = filter_data(X_aux, self.sampling_freq, **self.filt_params_noise) # subtract signal: X_n -= X_s # Estimate single trial covariance #reshape to original shape X_s = np.reshape(X_s, [n_epochs, n_channels, n_samples]) self.Xs = X_s covs = np.empty((n_epochs, n_channels, n_channels)) for ii, epoch in enumerate(X_s): covs[ii] = _regularized_covariance( epoch, reg=self.estimator, method_params=self.cov_method_params, rank=self.rank) cov_signal = covs.mean(0) #% Covariance matrix for the flanking frequencies (noise) #reshape to original shape X_n = np.reshape(X_n, [n_epochs, n_channels, n_samples]) # Estimate single trial covariance covs_n = np.empty((n_epochs, n_channels, n_channels)) for ii, epoch in enumerate(X_n): covs_n[ii] = _regularized_covariance( epoch, reg=self.estimator, method_params=self.cov_method_params, rank=self.rank) cov_noise = covs_n.mean(0) else: raise NotImplementedError() eigvals_, eigvects_ = eigh(cov_signal.data, cov_noise.data) # #sort in descencing order ix = np.argsort(eigvals_)[::-1] self.eigvals_ = eigvals_[ix] self.filters_ = eigvects_[:, ix] # self.filters_ = eigvects_ self.patterns_ = np.linalg.pinv(self.filters_) return self
def fit(self, X, y): """Estimate the CSP decomposition on epochs. Parameters ---------- X : ndarray, shape (n_epochs, n_channels, n_times) The data on which to estimate the CSP. y : array, shape (n_epochs,) The class for each epoch. Returns ------- self : instance of CSP Returns the modified instance. """ #numpy配列でないとエラー if not isinstance(X, np.ndarray): raise ValueError("X should be of type ndarray (got %s)." % type(X)) self._check_Xy(X, y) #チャンネル数 n_channels = X.shape[1] #クラス数 self._classes = np.unique(y) n_classes = len(self._classes) if n_classes < 2: raise ValueError("n_classes must be >= 2.") #クラス数*チャンネル数*チャンネル数の0行列 covs = np.zeros((n_classes, n_channels, n_channels)) sample_weights = list() #クラス数分 for class_idx, this_class in enumerate(self._classes): if self.cov_est == "concat": # concatenate epochs #class_は各クラスごとのデータに分割する class_ = np.transpose(X[y == this_class], [1, 0, 2]) class_ = class_.reshape(n_channels, -1) #エポック数×時間 #正則化共分散行列? cov = co._regularized_covariance( class_, reg=self.reg, method_params=self.cov_method_params, rank=self.rank) #各エポック数 weight = sum(y == this_class) elif self.cov_est == "epoch": class_ = X[y == this_class] cov = np.zeros((n_channels, n_channels)) for this_X in class_: cov += _regularized_covariance( this_X, reg=self.reg, method_params=self.cov_method_params, rank=self.rank) cov /= len(class_) weight = len(class_) #2*10*10 covs[class_idx] = cov if self.norm_trace: # Append covariance matrix and weight. Prior to version 0.15, # trace normalization was applied, but was breaking results for # some usecases by changing the apparent ranking of patterns. # Trace normalization of the covariance matrix was removed # without signigificant effect on patterns or performances. # If the user interested in this feature, we suggest trace # normalization of the epochs prior to the CSP. covs[class_idx] /= np.trace(cov) sample_weights.append(weight) if n_classes == 2: #固有値と固有ベクトルを計算 eigen_values, eigen_vectors = la.eigh(covs[0], covs.sum(0)) # sort eigenvectors self.ev = np.abs(eigen_values - 0.5) ix = np.argsort(np.abs(eigen_values - 0.5))[::-1] else: # The multiclass case is adapted from # http://github.com/alexandrebarachant/pyRiemann eigen_vectors, D = _ajd_pham(covs) # Here we apply an euclidean mean. See pyRiemann for other metrics mean_cov = np.average(covs, axis=0, weights=sample_weights) eigen_vectors = eigen_vectors.T # normalize for ii in range(eigen_vectors.shape[1]): tmp = np.dot(np.dot(eigen_vectors[:, ii].T, mean_cov), eigen_vectors[:, ii]) eigen_vectors[:, ii] /= np.sqrt(tmp) # class probability class_probas = [np.mean(y == _class) for _class in self._classes] # mutual information mutual_info = [] for jj in range(eigen_vectors.shape[1]): aa, bb = 0, 0 for (cov, prob) in zip(covs, class_probas): tmp = np.dot(np.dot(eigen_vectors[:, jj].T, cov), eigen_vectors[:, jj]) aa += prob * np.log(np.sqrt(tmp)) bb += prob * (tmp**2 - 1) mi = -(aa + (3.0 / 16) * (bb**2)) mutual_info.append(mi) ix = np.argsort(mutual_info)[::-1] # sort eigenvectors #eigen_vectors = eigen_vectors[:, ix] self.filters_ = eigen_vectors.T #ムーアペンローズの疑似逆行列 self.patterns_ = la.pinv2(eigen_vectors) pick_filters = self.filters_[:self.n_components] #エポックごとに計算する X = np.asarray([np.dot(pick_filters, epoch) for epoch in X]) # compute features (mean band power) X = (X**2).mean(axis=2) # To standardize features self.mean_ = X.mean(axis=0) self.std_ = X.std(axis=0) return self