Не уверен, что лучше задать это здесь или в StackExchange, но, поскольку это вопрос программирования, а также, возможно, математический вопрос, здесь идет речь.
Вопрос о FastICA.
С учетом входного временного ряда («наблюдения» ниже), где каждый временной ряд представляет собой линейную смесь сигналов n_components, ICA возвращает сигналы и матрицу микширования. Из http://www.cs.jhu.edu/~ayuille/courses/Stat161-261-Spring14/HyvO00-icatut.pdf, раздела 3 я понимаю, что максимум один сигнал может быть гауссовским шумом. Но ниже я, кажется, демонстрирую, что FastICA восстанавливает два сигнала, даже когда оба являются шумом (здесь как функция длины временного ряда от одного временного шага до 10000 временных шагов, для 16 временных рядов):
# Snippet below adapted from http://scikit-learn.org/stable/auto_examples/decomposition/plot_ica_blind_source_separation.html
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
from sklearn.decomposition import FastICA, PCA
for i in [1, 2, 3, 4, 5, 10, 20, 100, 1000, 10000]: # number of timepoints
# Generate sample data
np.random.seed(0)
n_samples = i
time = np.linspace(0, 8, n_samples)
#
s1 = np.array([np.random.normal() for q in range(i)])
s2 = np.array([np.random.normal() for q in range(i)])
#
S = np.c_[s1, s2]
S += 0.2 * np.random.normal(size=S.shape) # Add extra noise, just to muddy the signals
#
S /= S.std(axis=0) # Standardize data
# Mix data
A = np.array([[np.random.normal(), np.random.normal()] for j in range(16)]) # Mixing matrix
X = np.dot(S, A.T) # Generate observations
#
# Compute ICA
ica = FastICA(n_components=2)
print i, "\t",
try:
S_ = ica.fit_transform(X) # Reconstruct signals
except ValueError:
print "ValueError: ICA does not run"
continue
A_ = ica.mixing_ # Get estimated mixing matrix
#
# We can `prove` that the ICA model applies by reverting the unmixing.
print np.allclose(X, np.dot(S_, A_.T) + ica.mean_) # X - AS ~ 0
Выход:
1 ValueError: ICA does not run
2 False
3 True
4 True
5 True
10 True
20 True
100 True
1000 True
10000 True
Почему это работает? Т.е. почему X - AS ~ 0 (условие allclose () выше)? Обратите внимание, что он по-прежнему работает, если число сгенерированных нами наборов данных намного больше, чем 16, которые я использовал здесь (например, 1000 временных рядов все еще работают).