关于机器学习理论方面的研究,最好阅读英文原版的学术论文。PCA主要作用是数据降维,而ICA主要作用是盲信号分离。在讲述理论依据之前,先思考以下几个问题:真实的数据训练总是存在以下几个问题:

①特征冗余情况,比如建立文档-词频矩阵过程中,"learn"和"study"两个特征,从VSM(计算文档向量间的相似度,Lucene评分机制由此推导而来)角度来看,两者独立,但是从语义角度看,是冗余的……

②特征强相关性,两个特征间具有很强的相关性,需要去除其中一个……

③训练样本数远小特征数,容易造成过拟合……

还有一类情况:在鸡尾酒宴会上,有n个嘉宾,在会场的不同角落里,布置n个麦克风。源信号是每个人的声音,n个麦克风接收到的信号混合声音,如何把声音还原分离出来?

以上两类大的情况,第一大类,涉及到数据降维,第二类涉及到盲信号分离。先谈第一类,关于理论上的深入论述,不探讨(能够搞理论创新的人,都是很少的),只说明个人理解。PCA的计算步骤:①计算各个特征维度的均值;②更新x = x - u,就是去均值化,让均值为0;③计算各个特征的variance④归一化处理:x = x / variance;⑤计算协方差矩阵(方阵)⑥计算协方差矩阵的特征值和特征向量,把特征值按照降序排列,依次对应特征vector,取前k个列特征向量;⑦把归一化处理后的矩阵数据投影到列特征向量,就是最终结果。整个过程非常简单,求协方差矩阵的特征向量就是最后理想的结果。理论依据:①最大方差理论②最小平方误差理论③坐标轴相关度理论。说白了,PCA就是找出所有两两相互正交的坐标轴(投影轴的方向向量,对应协方差矩阵的特征向量),这些坐标轴具有这样的特性,样本点在坐标轴上的投影(由于均值已经去零化,所以投影在轴上的点均值也为零)距离最远(均值为0的情况下,就是具有最高的方差,对应协方差矩阵的特征值)。这是从几何角度来理解,从数学角度理解,就是找出协方差矩阵的特征值(对角阵),按降序排列,取前k个对应的特征向量,剔除不重要的特征。关于PCA最经典的解读,可以观看吴恩达的公开课,或者下载讲义和学习笔记。按照第一种理论来理解:

在信号处理中认为信号具有较大的方差,噪声有较小的方差,信噪比就是信号与噪声的方差比,越大越好 。因此我们认为,最好的k为特征是将n为样本点转换成k为后,每一维上的样本方差都很大。比如下图有5个样本点:(已经做过预处理,均值为0,特征方差归一)

下面将样本点投影到某一维上,这里用一条过原点的直线表示(前处理的过程实质是将原点移到样本点的中心点)。

假设我们选择两条不同的直线作投影,那么左右两条中哪个好呢?根据我们之前的方差最大化理论,左边的好,因为投影后样本点之间的方差最大。这里先解释一下投影的概念:

红色表示样例,蓝色表示在u上的投影,u是直线的斜率也是直线的方向向量,而且是单位向里。蓝色点是在u上的投影点,离原点的距离是<,u>.由于这些样本点的每一维度均值都为0,因此投影到u上的样本点(只有一个到原点的距离)的均值仍然是0。由于投影后均值为0,因此方差为:

中间的部分正是协方差矩阵(一般协方差矩阵除以m-1,这里用m)!。

今天试着用Python写一个PCA算法,然后加载到numpy模块中,以后就可以直接使用了:

# encoding: utf-8
#PCA.py
from numpy import *;
import numpy as np;
import numpy.linalg as nl; '''用PCA对数据降维,实现步骤:
1.零均值化;
2.归一化;
3.计算协方差矩阵;
4.对上述特征值分解;
5.按照特征值降序排列选取特征向量组成矩阵;
6.把第一步得到的矩阵投影到5中返回最后的结果.
''' def zeromean(dataMat):
meanVal = np.mean(dataMat,axis=0);
newData = dataMat - meanVal;
return meanVal,newData; def pca(dataMat,k):
meanVal,newData = zeromean(dataMat);
varData = np.std(newData,axis=0);
normData = newData / varData; covMat = np.cov(normData,rowvar=0);
eigVals,eigVector = nl.eig(np.mat(covMat));
eigValIndice = np.argsort(eigVals);
eigValIndice = eigValIndice[-1:-(k+1):-1];
n_eigVect = eigVector[:,eigValIndice];
lowDDataMat = normData * n_eigVect;
return lowDDataMat; def main():
data = np.mat(np.arange(6).reshape(3,2));
returnMat = pca(data,1);
print(returnMat); if __name__ == "__main__":
main(); 把这个文件加载到Python35\Lib\site-packages\numpy目录下,然后在修改numpy的__init__.py文件,加上如下语句:

就是第172行的语句,意思是把pca函数变为numpy包下可以直接使用的函数。使用时这样用:import numpy as np;np.pca(data,k);如果用from numpy import *的话,需要在__init__.py中修改__all__变量,把PCA加入进去就行了。

 

重点研究ICA,他的难度大于PCA。本人之前研究了FastICA算法,花了好长时间算是弄明白了。为了不误人子弟,直接上传原始的学术论文。写这篇博客的目的,更多的是为了方便更多的人学习,关于这方面理论的研究,本人没有什么建树,因此不能像之前写的kmeans算法那篇博客那样详细。

以下为matlab实现的源代码:

function Z = ICA(X)
%----------去均值--------------
[M,T] = size(X);
average = mean(X')'
for i = 1:M
    X(i,:) = X(i,:) - average(i,:)*ones(1,T);
end
%--------白化/球化---------
Cx = cov(X',1)%----协方差矩阵------
[eigvector,eigvalue] = eig(Cx);%----计算Cx的特征值和特征向量------
W = eigvalue^(-1/2)*eigvector';
Z = W*X %正交矩阵

%-------迭代--------
MaxCount = 10000;
W = rand(m);
Critical = 0.00001
m = M;%-----分量-------
for n = 1:m
    WP = W(:,n)
    LastWP = zeros(m,1)
    count = 0;
    W(:,n) = W(:,n) / norm(W(:,n))
    while abs(WP-LastWP)&abs(WP+LastWP) > Critical
        LastWP = WP;
        count = count + 1;
        for i = 1:m
            WP(i) = mean(Z(i,:)*(tanh(LastWP*Z))) - mean(1-(tanh(LastWP*Z))^2)*LastWP(i)
        end
        WPP = zeros(m,1)
        for j = 1:n-1
            WPP = WPP + (WP'*W(:,j))W(:,j)
        end
        WP = WP - WPP;
        WP = WP / (norm(WP))
        
        if count = MaxCount
            fprintf('未找到相应的信号)
            return;
        end
    end
    W(n,:) = WP;
end
Z = W*Z

下面为python代码实现:

#!/usr/bin/env python

#FastICA from ICA book, table 8.4

import math
import random
import matplotlib.pyplot as plt
from numpy import *

n_components = 2

def f1(x, period = 4):
    return 0.5*(x-math.floor(x/period)*period)

def create_data():
    #data number
    n = 500
    #data time
    T = [0.1*xi for xi in range(0, n)]
    #source
    S = array([[sin(xi)  for xi in T], [f1(xi) for xi in T]], float32)
    #mix matrix
    A = array([[0.8, 0.2], [-0.3, -0.7]], float32)
    return T, S, dot(A, S)

def whiten(X):
    #zero mean
    X_mean = X.mean(axis=-1)
    X -= X_mean[:, newaxis]
    #whiten
    A = dot(X, X.transpose())
    D , E = linalg.eig(A)
    D2 = linalg.inv(array([[D[0], 0.0], [0.0, D[1]]], float32))
    D2[0,0] = sqrt(D2[0,0]); D2[1,1] = sqrt(D2[1,1])
    V = dot(D2, E.transpose())
    return dot(V, X), V

def _logcosh(x, fun_args=None, alpha = 1):
    gx = tanh(alpha * x, x); g_x = gx ** 2; g_x -= 1.; g_x *= -alpha
    return gx, g_x.mean(axis=-1)

def do_decorrelation(W):
    #black magic
    s, u = linalg.eigh(dot(W, W.T))
    return dot(dot(u * (1. / sqrt(s)), u.T), W)

def do_fastica(X):
    n, m = X.shape; p = float(m); g = _logcosh
    #black magic
    X *= sqrt(X.shape[1])
    #create w
    W = ones((n,n), float32)
    for i in range(n):
        for j in range(i):
            W[i,j] = random.random()

#compute W
    maxIter = 200
    for ii in range(maxIter):
        gwtx, g_wtx = g(dot(W, X))
        W1 = do_decorrelation(dot(gwtx, X.T) / p - g_wtx[:, newaxis] * W)
        lim = max( abs(abs(diag(dot(W1, W.T))) - 1) )
        W = W1
        if lim < 0.0001:
            break
    return W

def show_data(T, S):
    plt.plot(T, [S[0,i] for i in range(S.shape[1])], marker="*")
    plt.plot(T, [S[1,i] for i in range(S.shape[1])], marker="o")
    plt.show()

def main():
    T, S, D = create_data()
    Dwhiten, K = whiten(D)
    W = do_fastica(Dwhiten)
    #Sr: reconstructed source
    Sr = dot(dot(W, K), D)
    show_data(T, D)
    show_data(T, S)
    show_data(T, Sr)

if __name__ == "__main__":
    main()

PCA与ICA的更多相关文章

  1. PCA主成分分析 ICA独立成分分析 LDA线性判别分析 SVD性质

    机器学习(8) -- 降维 核心思想:将数据沿方差最大方向投影,数据更易于区分 简而言之:PCA算法其表现形式是降维,同时也是一种特征融合算法. 对于正交属性空间(对2维空间即为直角坐标系)中的样本点 ...

  2. 统计学方法(PCA、ICA、RCA、LCA)

    ---------------------------------------------------------------------------------------------------- ...

  3. 机器学习 —— 基础整理(四)特征提取之线性方法:主成分分析PCA、独立成分分析ICA、线性判别分析LDA

    本文简单整理了以下内容: (一)维数灾难 (二)特征提取--线性方法 1. 主成分分析PCA 2. 独立成分分析ICA 3. 线性判别分析LDA (一)维数灾难(Curse of dimensiona ...

  4. 主成分分析(PCA)原理及R语言实现

    原理: 主成分分析 - stanford 主成分分析法 - 智库 主成分分析(Principal Component Analysis)原理 主成分分析及R语言案例 - 文库 主成分分析法的原理应用及 ...

  5. 对于利用pca 和 cca 进行fmri激活区识别的理解

    1.pca 抛开fmri研究这个范畴,我们有一个超长向量,这个超长向量在fmri研究中,就是体素数据.向量中的每个数值,都代表在相应坐标轴下的坐标值.这些坐标轴所组成的坐标系,其实是标准单位坐标系.向 ...

  6. Python机器学习笔记 使用scikit-learn工具进行PCA降维

    之前总结过关于PCA的知识:深入学习主成分分析(PCA)算法原理.这里打算再写一篇笔记,总结一下如何使用scikit-learn工具来进行PCA降维. 在数据处理中,经常会遇到特征维度比样本数量多得多 ...

  7. 主成分分析(PCA)原理及R语言实现 | dimension reduction降维

    如果你的职业定位是数据分析师/计算生物学家,那么不懂PCA.t-SNE的原理就说不过去了吧.跑通软件没什么了不起的,网上那么多教程,copy一下就会.关键是要懂其数学原理,理解算法的假设,适合解决什么 ...

  8. 机器学习之PCA主成分分析

    前言            以下内容是个人学习之后的感悟,转载请注明出处~ 简介 在用统计分析方法研究多变量的课题时,变量个数太多就会增加课题的复杂性.人们自然希望变量个数较少而得到的 信息较多.在很 ...

  9. PCA算法 | 数据集特征数量太多怎么办?用这个算法对它降维打击!

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是机器学习专题的第27文章,我们一起来聊聊数据处理领域的降维(dimensionality reduction)算法. 我们都知道,图片 ...

随机推荐

  1. NSMutableArray 删除可变数组元素

    平时使用 NSMutableArray 中经常用到遍历删除数组元素的问题.一般第一个想法是使用一下 forin 就解决了,但是老司机都会知道使用 forin 做删除操作的时候会 crash.报错的原因 ...

  2. 用vue-cli搭建vue项目

    首先需要明确的是:Vue.js 不支持 IE8 及其以下 IE 版本,一般用与移动端,基础:开启最高权限的DOS命令(否则会出现意外的错误提示) 一.安装node.js,检测版本node -v,还要检 ...

  3. Integer装箱拆箱、参数传递

    拆箱装箱 举个例子 @Test public void testEquals() { int int1 = 12; int int2 = 12; Integer integer1 = new Inte ...

  4. Java -- springboot 配置 freemarker

    1.添加依赖 org.springframework.boot spring-boot-starter-freemarker 2.配置application.properties spring.fre ...

  5. 使用sudo进行Linux权限升级技巧

    0x00 前言 在我们之前的文章中,我们讨论了如何使用SUID二进制文件和/etc/passwd 文件的Linux权限提升技巧,今天我们发布了另一种“使用Sudoers文件进行Linux权限提示技巧” ...

  6. 实战AudioToolbox--在iOS平台上播放音频

    上午看了关于AudioToolbox.framework相关的资料,结合网上的资料对AudioToolbox的基本使用有了整体上的认识,上一篇文章 笔谈AudioToolbox(一) 中提到使用Aud ...

  7. PB连接数据库

    SQLCA.DBMS = "ODBC" SQLCA..AutoCommit = False SQLCA.DBParm = "ConnectString='DSN=fire ...

  8. Oracle 数据块

    以emp表为例 SYS@ prod>select * from scott.emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO --------- ...

  9. Docker06-仓库

    目录 仓库介绍 阿里云仓库介绍 案例:推送redis镜像到阿里云 仓库介绍 仓库(Repository)是集中存放镜像的地方,仓库分为公开仓库和私有仓库两种形式. 最大的公开仓库是 Docker Hu ...

  10. echarts 饼状图调节 label和labelLine的位置

    原理 使用一个默认颜色为透明的,并且只显示labelLine的饼状图 然后通过调节这个透明的饼状图 以达到修改labelLine的位置 echarts地址 https://gallery.echart ...