Я следую ответ на этот вопрос и этот учебник scikit-learn, чтобы удалить артефакты из сигнала ЭЭГ. Они кажутся достаточно простыми, и я определенно упускаю здесь что-то очевидное.
Извлеченные компоненты не имеют той же длины, что и мой сигнал. У меня есть 88 каналов нескольких часов записей, поэтому форма моей сигнальной матрицы (88, 8088516). Тем не менее, выход ICA равен (88, 88). В дополнение к тому, что он такой короткий, кажется, что каждый компонент улавливает очень большие, выглядящие шумными отклонения (таким образом, из 88 компонентов только пара выглядит как сигнал, остальные выглядят как шум). Я также ожидал, что только несколько компонентов будут выглядеть шумными. Я подозреваю, что я делаю что-то не так здесь?
Матрица (каналы x выборки) имеет вид (88, 8088516).
Пример кода (просто с использованием случайной матрицы для минимальных рабочих целей):
import numpy as np
from sklearn.decomposition import FastICA
import matplotlib.pyplot as plt
samples_matrix = np.random.random((88, 8088516))
# Compute ICA
ica = FastICA(n_components=samples_matrix.shape[0]) # Extracting as many components as there are channels, i.e. 88
components = ica.fit_transform(samples_matrix) # Reconstruct signals
A_ = ica.mixing_ # Get estimated mixing matrix
Форма компонентов (88, 88). Один график выглядит так:
plt.plot(components[1])
Я ожидал, что компоненты будут временными рядами той же длины, что и мой оригинал, как показано в ответе на этот вопрос. Я действительно не уверен, как двигаться дальше с удалением компонентов и реконструкцией сигнала на данный момент.
Также не могли бы вы предоставить минимальный воспроизводимый пример с некоторыми данными, которые вы используете?
Оба добавлены, спасибо! К сожалению, файл данных огромен, но я думаю, что случайно сгенерированная матрица того же размера также иллюстрирует суть. Если это можно сделать лучше, не связывая фактические данные, пожалуйста, дайте мне знать!
В sklearn
набор данных обычно представлен выборкой, занимающей один ряд. То есть я ожидаю, что ваш набор данных будет иметь форму (8088516, 88).
Вам нужно запустить fit_transform
для транспонирования вашего samples_matrix
вместо самого samples_matrix
(поэтому предоставьте методу матрицу 8088516 x 88 вместо 88x8088516).
ica.fit_transform(samples_matrix.transpose())
или проще
ica.fit_transform(samples_matrix.T)
который даст вам набор сигналов 8088516 x 88 (88 компонентов, каждый из сигналов такой же длины, как и оригинал) для построения графика. Как я упомянул ниже в своем комментарии, из-за больших инверсий матриц и т. д. Моя установка рекомендовала не более 64 компонентов.
Чтобы поддержать это предложение, я смотрю на ваш учебник, они поставили свою игрушечную проблему следующим образом:
n_samples = 2000
time = np.linspace(0, 8, n_samples)
s1 = np.sin(2 * time) # Signal 1 : sinusoidal signal
s2 = np.sign(np.sin(3 * time)) # Signal 2 : square signal
s3 = signal.sawtooth(2 * np.pi * time) # Signal 3: saw tooth signal
S = np.c_[s1, s2, s3]
S += 0.2 * np.random.normal(size=S.shape) # Add noise
S /= S.std(axis=0) # Standardize data
# Mix data
A = np.array([[1, 1, 1], [0.5, 2, 1.0], [1.5, 1.0, 2.0]]) # Mixing matrix
X = np.dot(S, A.T) # Generate observations
что дает X.shape
из (2000,3)
для разделения 3 компонентов, указывая на то, что это предпочтительный формат матрицы для метода FastICA
.
как долго он у вас работает? Мой работает уже более часа (и единственное изменение, которое было сделано, это добавление .transpose()), работает на V100 (и до 5 компонентов только в качестве отправной точки). Я не был уверен, следует ли этого ожидать или у меня возникла другая проблема с моими вычислениями.
Можете ли вы также объяснить, почему его нужно транспонировать?
Это займет довольно много времени. У вас много точек данных! По сути, вы попросили его создать 88 компонентов из временного ряда длиной 88 точек, но с 8 миллионами каналов, тогда как на самом деле вы хотите создать 88 компонентов из 88 каналов с 8 миллионами выборок. Вы можете понять, почему время сходимости в первом случае было намного быстрее!
Я не знаю, ваши данные из ситуации, когда субъект отдыхает, или это ERP. В любом случае, сегментация на более мелкие разделы будет полезна, если вы ищете релевантные изменения.
Сначала я не знал, что такое V100, но Scikit-learn использует только ЦП. scikit-learn.org/stable/faq.html#will-you-add-gpu-support
Поскольку у вас есть фактический TPU, попробуйте реализацию FastICA TensorFlow здесь medium.com/analytics-vidhya/…. Это определенно будет кричать на этом оборудовании.
Не могли бы вы дать ссылку на уроки, которым вы следовали?