独立成分分析(Independent Component Analysis,ICA)原理及代码实现

article/2025/11/9 7:58:57

过程监控中会用到很多中方法,如主成分分析(PCA)、慢特征分析(SFA)、概率MVA方法或独立成分分析(ICA)等为主流算法。

其中PCA主要多用于降维及特征提取,且只对正太分布(高斯分布)数据样本有效;SFA被用来学习过程监控的时间相关表示,SFA不仅可以通过监测稳态分布来检测与运行条件的偏差,还可以根据时间分布来识别过程的动态异常,多用于分类分析;概率MVA方法,多以解决动力学、时变、非线性等问题。

今天要介绍的是独立成分分析(ICA),由浅入深,细细道来。

此外文末还附有ICA可实现的代码哟~不要错过

独立成分分析(Independent Component Analysis,ICA)

基本原理

在信号处理中,独立成分分析(ICA)是一种用于将多元信号分离为加性子分量的计算方法。这是通过假设子分量是非高斯信号,并且在统计上彼此独立来完成的。ICA是盲源分离的特例。一个常见的示例应用程序是在嘈杂的房间中聆听一个人的语音的“ 鸡尾酒会问题 ”。

首先,引入一下经典的鸡尾酒宴会问题(Cocktail Party Problem)。

如下图所示,假如在我们的Party中有 n n n个人,他(她)们可以同时且互相说话,我们也在房间中一些角落里共放置了n个声音接收器(Microphone)用来记录声音。宴会过后,我们从n个麦克风中得到了一组数据 X ( i ) = ( x 1 ( i ) , x 2 ( i ) , … , x n ( i ) ) ; ( i = 1 , … , m ) \mathrm{X}^{(i)}=\left(x_{1}^{(i)}, x_{2}^{(i)}, \ldots, x_{n}^{(i)}\right) ;( i=1, \ldots, m) X(i)=(x1(i),x2(i),,xn(i));(i=1,,m),其中 i i i表示采样的时间顺序,也就是说共得到了 m m m组采样,每一组采样都是 n n n维的,得到的是一个 n ∗ m n*m nm 的数据矩阵。

我们的目标是:单独从这 m m m组采样数据中分辨出每个人说话的信号。


手残灵魂画师原图之鸡尾酒宴会

这里我们还需要另一组信息,那就是声音信号。我们把每个人的声音信号,那么也就是有 n n n个信号源 S = ( s 1 , s 2 , . . . , s n ) T , s ∈ R n S=(s_1,s_2,...,s_n)^T,s\in \mathfrak{R}^n S=(s1,s2,...,sn)TsRn,且每个人发出的声音都是相互独立的。同样我们做了 m m m组采样。

假设我们令一个未知的混合系数矩阵(mixing coefficient matrix)为 A A A,用来组合叠加信号 S S S
X = A S X=AS X=AS
这里的 X X X不是一个向量,是一个矩阵。其中的列向量是 x ( i ) = A s ( i ) x^{(i)}=As^{(i)} x(i)=As(i)

由此我们可知每一个 x ( i ) x^{(i)} x(i)都是由 s ( i ) s^{(i)} s(i)的分量线性表示的。

目前我们需要明确一点,只有 X X X是已知的可测量的(由麦克风得到),其中 A 、 S A、S AS均为未知条件,我们要想办法根据 X X X来推出 S S S值。这个过程也称作为盲信号分离

由于求矩阵的逆在实际运算中会出现一些问题,那么我们令 H = A − 1 H=A^{-1} H=A1,则 s ( i ) = A − 1 x ( i ) = H x ( i ) s^{(i)}=A^{-1}x^{(i)}=Hx^{(i)} s(i)=A1x(i)=Hx(i)

其中我们 H H H可表示为,
[ h 1 T . . . h n T ] \begin{bmatrix} & h_{1}^{T} & \\ & ...&\\ & h_{n}^{T} & \end{bmatrix} h1T...hnT

h i ∈ R n h_i\in \mathfrak{R}^n hiRn,将 H H H 写成向量的形式。由此可得,
s j ( i ) = h j T x ( i ) s_{j}^{(i)}=h_{j}^{T}x^{(i)} sj(i)=hjTx(i)

ICA的不确定性(ICA ambiguities)

由于 h h h s s s都不确定,那么在没有先验知识的情况下,无法同时确定这两个相关参数。

比如上面的公式 s = h x s=hx s=hx。当 h h h 扩大两倍时, s s s 只需要同时扩大两倍即可,等式仍然满足,因此无法得到唯一的 s s s。同时如果将人的编号打乱,变成另外一个顺序,那么只需要调换A的列向量顺序即可,因此也无法单独确定 s s s。这两种情况称为原信号不确定。

还有一种ICA不适用的情况,那就是信号不能是高斯分布的。假设只有两个人发出的声音信号符合多值正态分布, s ∼ N ( 0 , 1 ) s \sim N(0,1) sN(0,1)

简而言之,不合适,不适用于没先验知识的情况。

ICA 算法

下面直接上ICA算法。

独立成分分析 ICA(Independent Component Correlation Algorithm)是一种函数,X为n维观测信号矢量,S为独立的m(m<=n)维未知源信号矢量,矩阵A被称为混合矩阵。ICA的目的就是寻找解混矩阵W(A的逆矩阵),然后对X进行线性变换,得到输出向量U。

这里使用最大似然估计来解释算法,我们假定每个 s i s_i si有概率密度 p s p_s ps,那么给定时刻原信号的联合分布就是
p ( s ) = ∏ i = 1 n p s ( s i ) \mathrm{p}(\mathrm{s})=\prod_{i=1}^{n} p_{s}\left(s_{i}\right) p(s)=i=1nps(si)
此公式代表一个假设前提:每个人发出的声音信号各自独立。

有了 p ( s ) p(s) p(s),我们可以求得 p ( x ) p(x) p(x)
p ( x ) = p s ( H x ) ∣ H ∣ = ∣ H ∣ ∏ i = 1 n p s ( h i T x ) \mathrm{p}(\mathrm{x})=\mathrm{p}_{s}(H x)|\mathrm{H}|=|\mathrm{H}| \prod_{i=1}^{n} p_{s}\left(h_{i}{ }^{T} x\right) p(x)=ps(Hx)H=Hi=1nps(hiTx)
左边是每个采样信号 x x x的概率,右边是每个原信号概率的乘积的 ∣ H ∣ |H| H倍。

若没有先验知识,我们无法求得 H H H s s s

因此我们需要知道 p s ( s i ) p_s(s_i) ps(si),我们打算选取一个概率密度函数赋给 s s s,但是我们不能选取高斯分布的密度函数。在概率论里我们知道密度函数p(x)由累计分布函数(cdf)F(x)求导得到。F(x)要满足两个性质是:单调递增和在[0,1]。我们发现sigmoid函数很适合,定义域负无穷到正无穷,值域0到1,缓慢递增。我们假定 s s s的累积分布函数符合sigmoid函数
g ( s ) = 1 1 + e − s g(s)=\frac{1}{1+e^{-s}} g(s)=1+es1
求导可得,
p s ( s ) = g ′ ( s ) = e s ( 1 + e s ) 2 p_{s}(s)=g^{\prime}(s)=\frac{e^{s}}{\left(1+e^{s}\right)^{2}} ps(s)=g(s)=(1+es)2es
这就是 s s s的密度函数。此时的 s s s是实数。

要是我们预先知道 s s s的分布函数,那就不用假设了,但在未知的情况下,sigmoid函数能够在大多数问题上取得不错的效果。

由于上式中 p s ( s ) p_s(s) ps(s)是个对称函数,因此E[s]=0(s的均值为0),那么E[x]=E[As]=0,x的均值也是0。

现在我们知道了 p s ( s ) p_s(s) ps(s),下面开始求 H H H

采样后的训练样本为 X ( i ) = ( x 1 ( i ) , x 2 ( i ) , … , x n ( i ) ) ; ( i = 1 , … , m ) \mathrm{X}^{(i)}=\left(x_{1}^{(i)}, x_{2}^{(i)}, \ldots, x_{n}^{(i)}\right) ;( i=1, \ldots, m) X(i)=(x1(i),x2(i),,xn(i));(i=1,,m),使用前面得到的 x x x的概率密度函数,得其样本对数似然估计:
ℓ ( H ) = ∑ i = 1 m ( ∑ j = 1 n log ⁡ g ′ ( h j T x ( i ) ) + log ⁡ ∣ H ∣ ) \ell(H)=\sum_{i=1}^{m}\left(\sum_{j=1}^{n} \log g^{\prime}\left(h_{j}^{T} x^{(i)}\right)+\log |H|\right) (H)=i=1m(j=1nlogg(hjTx(i))+logH)
其中,括号里的一大堆为 p ( x ( i ) ) p(x^{(i)}) p(x(i)),然后再对 H H H进行求导操作。在上式中包含有行列式,对行列式|W|进行求导的方法可参考这里。

最终得到的求导结果公式(很复杂很繁琐–心情):
H : = H + α ( [ 1 − 2 g ( h 1 T x ( i ) ) 1 − 2 g ( h 2 T x ( i ) ) ⋮ 1 − 2 g ( h n T x ( i ) ) ] x ( i ) T + ( H T ) − 1 ) H:=H+\alpha\left(\left[\begin{array}{c} 1-2 g\left(h_{1}^{T} x^{(i)}\right) \\ 1-2 g\left(h_{2}^{T} x^{(i)}\right) \\ \vdots \\ 1-2 g\left(h_{n}^{T} x^{(i)}\right) \end{array}\right] x^{(i)^{T}}+\left(H^{T}\right)^{-1}\right) H:=H+α12g(h1Tx(i))12g(h2Tx(i))12g(hnTx(i))x(i)T+(HT)1
其中 α \alpha α表示的是梯度上升速率,可自定义。

当通过多次迭代后,可求出 H H H,便可得到 s ( i ) = H x ( i ) s^{(i)}=Hx^{(i)} s(i)=Hx(i)来还原出原始信号。

举个Paper的栗子

下面是 s = 2 s=2 s=2的原始信号:
在这里插入图片描述
下面为我们观测到的信号:
在这里插入图片描述
然后,再通过ICA还原后的信号为:
在这里插入图片描述

MATLAB代码实现

MATLAB代码:
Fast ICA

% Input:X 行变量维数,列采样个数;需要对原始矩阵转置
% Output:Sources重构的原信号, Q白化矩阵, P白化信号解混矩阵
function [Sources, Q, P] = FastICA(X, P)
% 白化处理
[dim, numSample] = size(X);
Xcov = cov(X');
[U, lambda] = eig(Xcov);
Q = lambda^(-1/2)*U';
Z = Q*X;
% FastICA
maxiteration = 10000; %最大迭代次数
error = 1e-5; % 收敛误差
% P = randn(dim,dim); % 随机初始化P,并按照列更新for k = 1:dimPk = P(:,k);Pk = Pk./norm(Pk); % 向量归一化lastPk = zeros(dim,1); % 0不需要再归一化count = 0;while abs(Pk - lastPk)&abs(Pk + lastPk) > errorcount = count + 1;lastPk = Pk;g = tanh(lastPk'*Z); % g(y)函数dg = 1 - g.^2; % g(y)的一阶导函数
%-------------------------------核心公式------------------------------------        Pk = mean(Z.*repmat(g,dim,1), 2) - repmat(mean(dg),dim,1).*lastPk;Pk = Pk - sum(repmat(Pk'*P(:,1:k-1),dim,1).*P(:,1:k-1),2);Pk = Pk./norm(Pk);
%--------------------------------------------------------------------------       if count == maxiterationfprintf('第%d个分量在%d次迭代内不收敛!\n',k,maxiteration);break;endendP(:,k) = Pk;
endSources = P'*Z;
% end

此外还有基于故障诊断的ICA算法代码实现->在这里

下面给出部分代码:

% 基于ICA的故障诊断
clear;clc;close all;
load('MPD2000.mat');Xnormal = MPD0';
% 数据归一化
[dim, numSample] = size(Xnormal);
XnormalMean = mean(Xnormal, 2);
XnormalStd = std(Xnormal, 0, 2);
XnormalNorm = normalization(Xnormal, XnormalMean, XnormalStd);% 正常数据计算 解混矩阵W
% P = rand(dim,dim)*100;
load('P.mat');
[S, Q, P] = FastICA(XnormalNorm, P);
W = P'*Q;
% ------------------------利用2范数大小对W的行重新排列---------------------
Wnorm = zeros(dim,1);
for k = 1:dimWnorm(k) = norm(W(k,:));
end
[Wnorm, indices] = sort(Wnorm, 'descend');% -------------------------确定主导成分Sd与参与成分Se----------------------
threshold = 0.80;
percentage = cumsum(Wnorm)./sum(Wnorm);
for k = 1:dimif percentage(k) > thresholdbreak;end
end

效果如下:


References

  • https://www.cnblogs.com/jerrylead/archive/2011/04/19/2021071.html
  • https://baike.baidu.com/item/ICA/4972405?fr=aladdin
  • https://spaces.ac.cn/archives/2383
  • A. Hyva¨rinen, E. Oja*. Independent component analysis: algorithms and applications.

❤坚持读Paper,坚持做笔记,坚持学习❤!!!
To Be No.1

⚡⚡


创作不易⚡,过路能❤关注收藏点个赞三连就最好不过了

ღ( ´・ᴗ・` )


Four short words sum up what has lifted most successful individuals above the crowd: a little bit more.


http://chatgpt.dhexx.cn/article/poCQEOue.shtml

相关文章

清理vdbench后台进程

当我们打开一个终端&#xff0c;用nohup运行vdbench程序。断开连接后&#xff0c;你发现你写的配置文件有误&#xff0c;想关闭已有的vdbench进程。你重新连接上终端&#xff0c;咦&#xff0c;我的jobs命令怎么没有显示我的nohup任务呢&#xff1f;这是因为你的nohup任务的sh进…

Nas性能测试工具-vdbench

版本&#xff1a; vdbench50406 简介&#xff1a; vdbench是一个 I/O 工作负载生成器&#xff0c;用于验证数据完整性和度量直接附加和网络连接的存储的性能。它是一个免费的工具&#xff0c;容易使用&#xff0c;而且常常用于测试和基准测试。 配置参数&#xff1a; 大文…

Linux中vdbench的安装与使用

vdbench是一个 I/O 工作负载生成器&#xff0c;用于验证数据完整性和度量直接附加和网络连接的存储的性能。它是一个免费的工具&#xff0c;容易使用&#xff0c;而且常常用于测试和基准测试。 可以使用vdbench测试磁盘和文件系统的读写性能。 环境&#xff1a;Ubuntu 16.04 …

vdbench和fio测试磁盘性能的对比总结

vdbench和fio测试磁盘性能的对比总结 一、安装 1、安装vdbench&#xff0c;首先安装java&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 其次下载vdbench安装包并进行安装&#xff1a;http://pan.baidu.com/s/1b7XooY&am…

vdbench使用

简介 vdbench是一个 I/O 工作负载生成器&#xff0c;用于验证数据完整性和度量直接附加和网络连接的存储的性能。它是一个免费的工具&#xff0c;容易使用&#xff0c;而且常常用于测试和基准测试。 可以使用vdbench测试磁盘和文件系统的读写性能。 名词解释 vdbench中常用的…

vdbench测试SSD快速入门

介绍 vdbench是一个I/O工作负载生成器&#xff0c;通常用于验证数据完整性和度量直接附加&#xff08;或网络连接&#xff09;存储性能。它可以运行在windows、linux环境&#xff0c;可用于测试文件系统或块设备基准性能。我们下面主要以块设备为介绍对象。 下载及安装 下载…

vdbench多主机运行指导

测试工具之vdbench多主机运行 本文介绍vdbench在多机环境下的操作和配置,以及本人在配置过程中遇到的问题和解决方法。 文章目录 测试工具之vdbench多主机运行前言一、vdbench在linux环境下多机运行1.环境参数2.配置说明二、vdbench在windows环境下多机运行1.环境参数2.配置…

Vdbench工具安装使用

一、 概述 1.1 内容简介 Vdbench 是一个命令行使用程序&#xff0c;旨在帮助工程师和客户生成用于验证存储性能和存储数据完 整性的磁盘 I/O 负载。还可通过输入文本文件指定 Vdbench 执行参数。它是一个免费的工具&#xff0c;容 易使用&#xff0c;而且常常用于测试和基准测试…

Vdbench工具的安装及使用

Vdbench工具的安装 Vdbench的运行依赖java环境&#xff0c;请务必先安装java运行环境安装java&#xff0c;Ubuntu OS环境安装java: apt-get install openjdk-8-jdkCentos OS环境安装: yum install openjdk-8-jdk检查是否安装成功 安装vdbench,下载vdbench50407.zip包&#…

Java jre的安装与卸载

文章目录 1. jre安装2. 卸载 Java JDK安装教程 Idea Java开发环境配置教程&#xff1a; https://tangxing.blog.csdn.net/article/details/112392218 1. jre安装 java下载网址&#xff1a; https://www.java.com/zh-CN/download/manual.jsp 这里有联机版和脱机版&#xff0c;…

彻底卸载jdk,jdk安装 ,javaa安装,jdk删除干净

标签&#xff1a; 一.备份安装好的绿色版JDK a.重新安装JDK到任意目录&#xff0c;假设这个目录是C:\java。 b.将装好的JDK,JRE拷贝到任意一个其他目录&#xff0c;如D:\bak,这样做的目的主要是为了备份JDK。(建议打成zip压缩包奔备用)二.彻底卸载JDK1.第一步,首先卸载或删除J…

Java如何卸载?怎么删掉Windows计算机上的Java?Java卸载流程详解!

大家都知道Java版本不是一成不变的&#xff0c;Java会朝着功能增加、漏洞修复和性能优化的方向一直进步。而公布新版Java之后&#xff0c;我们需要使用它&#xff0c;那么卸载掉旧版的Java很有必要&#xff0c;为什么呢? 这是Java官方给出的回复&#xff1a; 我们强烈建议您…

JAVA安装、配置及卸载

基本上从入门到实用非常全面了。 安装 安装Eclipse先配置jdk jdk下载地址&#xff1a;https://www.oracle.com/technetwork/java/javase/downloads/index.html &#xff08;此处以jdk8为示例&#xff09; 一、安装jdk 此处默认路径即可&#xff0c;单击下一步 安装完成后会…

Java类的卸载机制

类的生命周期 当Sample类被加载、连接和初始化后&#xff0c;它的生命周期就开始了。 当代表Sample类的Class对象不再被引用&#xff0c;即不可触及时&#xff0c;Class对象就会结束生命周期&#xff0c;Sample类在方法区内的数据也会被卸载&#xff0c;从而结束Sample类的生命…

JAVA的安装与卸载

1.java的卸载 1.删除java的安装目录 2.删除系统环境变量里的JAVA_HOME和Path里面的bin目录和jre/bin目录 3.cmd输入java -version 查看是否删除取消 2.java的安装 1.百度搜索jdk1.8找到下载地址 2.双击安装文件安装 3.配置系统环境变量 1.配置环境变量JAVA_HOME&#xff…

教你如何完全卸载Java

有时候卸载Java时真的让人很烦&#xff0c;明明卸载了但重新安装Java时还报错&#xff0c;今天我就把我卸载Java的过程给大家分享一下。 1. 在控制面板中删除。&#xff08;但我这么卸载之后java没有完全卸载&#xff09;。 2.找到java的安装目录&#xff0c;直接将Java文件夹删…

【java基础】Java如何卸载

Java如何卸载 首先右键我的电脑&#xff0c;属性选择高级系统设置&#xff0c;找到环境变量&#xff0c;打开之后在系统变量里找到JAVA_HOME&#xff0c;点击JAVA_HOME复制变量值中的路径 在资源管理器中找到这个目录&#xff0c;将目录删除。 再次打开环境变量&#xff…

Java的安装与卸载方法

Java的安装与卸载方法&#xff08;附图&#xff09; JDK的卸载步骤 我的电脑–>属性–>高级系统设置–>环境变量 删除Java的安装目录–>删除JAVA_HOME 双击path&#xff0c;然后删除path下JAVA_HOME相关的 打开DOS输入java -version检查 JDK的安装步骤 百…

如何卸载干净JAVA

有很多小伙伴下载了JAVA的JDK(java开发工具包)并安装成功运行后&#xff0c;发现自己下错了版本。凉了&#xff0c;半天白搞了。卸载之后又发现在再安装出现安装不了的问题。这往往是因为JAVA并没有卸载完全。今天我们就看看如何完全卸载JAVA。 JAVA卸载有两种方式。手动和用J…

JAVA的卸载与重新安装

1.JAVA的卸载&#xff0c;在系统的添加与删除中删去Java。 2.清理Java有关的缓存文件 到Java安装途径下把Java文件夹删除干净&#xff0c;然后删除Java的缓存文件 一般在C盘Users文件夹下的APPData\LocalLow\Sun下去看看有没有 3.清除注册表 使用电脑管家把无用的注册表清除…