python - FastICA 的问题,修改一个独立的源会改变所有的输出
问题描述
我在使用 sklearn FastICA 时遇到了问题。如果预测的“源”之一以给定方式发生变化,我试图预测“测量”变量(代码中的 X)将是什么。我正在修改这个例子。
我认为问题在于 FastICA 近似于“混合”矩阵,但 ica.mixing_ 与我用来生成数据的非常不同。我知道混合矩阵是未定义的,因为乘积 np.dot(S, AT) 是相关的,将 S 更改为 S*a 并将 A 更改为 A/a 将对所有 a != 0 产生相同的结果。
有任何想法吗?感谢阅读和帮助
这是我的代码。
# this is exactly how the example start
np.random.seed(0)
n_samples = 200
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
# Here I'm changing the example. I'm modifying the 'mixing' array
# such that s1 is not mixed with neither s2 nor s3
A = np.array([[1, 0, 0], [0, 2, 1.0], [0, 1.0, 2.0]]) # Mixing matrix
# Mix data,
X = np.dot(S, A.T) # Generate observations
# Compute ICA
ica = FastICA()
S_ = ica.fit_transform(X) # Reconstruct signals
A_ = ica.mixing_ # Get estimated mixing matrix
# We can `prove` that the ICA model applies by reverting the unmixing.
assert np.allclose(X, np.dot(S_, A_.T) + ica.mean_)
# Here is where my real code starts,
# Now modify source s1
s1 *= 1.1
S = np.c_[s1, s2, s3]
S /= S.std(axis=0) # Standardize data
# regenerate observations.
# Note that original code in the example uses np.dot(S, A.T)
# (that doesn't work either). I'm using ica.inverse_transform
# because it is what is documented but also because there is an
# FastICA.mean_ that is not documented and I'm hoping
# inverse_transform uses it in the right way.
# modified_X = np.dot(S, A.T) # does not work either
modified_X = ica.inverse_transform(S)
# check that last 2 observations are not changed
# The original 'mixing' array was defined to mix s2 and s3 but not s1
# Next tests fail
np_testing.assert_array_almost_equal(X[:, 1], modified_X[:, 1])
np_testing.assert_array_almost_equal(X[:, 2], modified_X[:, 2])
解决方案
我发布我的发现以防它帮助任何人。我认为我发布的代码有两个问题
拟合 ICA 时,找不到确切的“混合”矩阵,解决方案会将源 1 泄漏到所有测量输出中。结果应该很小,有很多数据,但它应该仍然存在。但是,当增加伪造数据量或更改 FastICA 的 max_iter 或 tol 参数时,我没有看到行为发生变化。
来源的顺序是不可预测的,在代码中我假设找到的 S_ 与 S 的顺序相同(这是错误的)。循环遍历所有源(在 fit_transform 之后),一次更改一个,我看到的结果接近我的预期。其中两个来源(对我来说是 1 和 2)主要对测量变量 2 和 3 产生影响,第三个来源对测量变量 1 的影响最大,对变量 2 和 3 的影响较小。
推荐阅读
- r - 如何将小标题转换为数组?
- vba - MS 访问日期格式,如 YYYY-YY(当年和明年)
- tensorflow - 在 TF-Hub 上加载预训练模型以计算 Gensim 或 spaCy 上的 Word Mover 距离 (WMD)
- javascript - 带有正则表达式的 Javascript 拆分返回空值
- sql - 如何正确更新表格?
- c# - Task.FromResult 之间的区别
vs Task.FromResult? - javascript - KendoUI 可过滤显示内部错误状态:500
- angular - 我如何将 ngStyle 与插值一起使用
- angular - 使用角度事件单击添加和删除类
- java - 如何以编程方式从 InfluxDb 中删除测量值?