目录

PCA转回原特征

例1

例2

scikit-learn中的PCA

PCA的对象

PCA对象的方法

PCA.components_

总结

PCA过程

PCA转回原特征的公式

手刻逆转换

Sklearn逆转换

PCA逆转换实验

sklearn的逆转换

手刻PCA以及逆转换


PCA转回原特征

例1

参考:

https://www.cnpython.com/qa/81148

sklearn的PCA 转换是怎样手算, 如何执行反变换。pca对象的哪个字段包含反变换的相关系数?如何计算反变换?

具体来说,我指的是sklearn.decomposition.PCA package中提供的PCA.inverse_transform()方法调用:如何使用PCA计算的各种系数重现其功能?

1)transform不是data * pca.components_。

首先,*不是numpy数组的点积。这是元素相乘。要执行点积,需要使用np.dot。

其次,PCA.components_的形状是(n个组件,n个特征),而要转换的数据形状是(n个样本,n个特征),因此需要对PCA.components_进行转置才能执行点积。

此外,变换的第一步是减去平均值,因此,如果手动进行,也需要首先减去平均值。

正确的转换方法是

data_reduced = np.dot(data - pca.mean_, pca.components_.T)

2)inverse_transform只是transform的逆过程

data_original = np.dot(data_reduced, pca.components_) + pca.mean_

如果您的数据在每一列中的平均值已经为零,那么您可以忽略上面的pca.mean_

在Scikit中,pca.components_就是P的逆矩阵, 逆转换时PCA.components不用求逆

import numpy as np

from sklearn.decomposition import PCA

pca = PCA(n_components=3)

pca.fit(data)

data_reduced = np.dot(data, pca.components_.T) # transform

data_original = np.dot(data_reduced, pca.components_) # inverse_transform

例2

参考:

https://www.cnblogs.com/okokok/p/6822885.html

在Scikit中运用PCA很简单

import numpy as np

from sklearn import decomposition

from sklearn import datasets

iris = datasets.load_iris()

X = iris.data

y = iris.target

pca = decomposition.PCA(n_components=3)

pca.fit(X)

X = pca.transform(X)

以上代码是将含有4个特征的数据经过PCA压缩为3个特征。PCA的压缩由如下特点:

1.新的3个特征并不是随便删除一个特征后留下的,而是4个特征的线性组合。

2.新的3个特征保留了原有4个特征的绝大部分信息,换句话说就是略有损失。

那么PCA的损失到底是什么? 新特征能否转回旧特征?

首先看PCA过程:

PCA过程

1.均值化矩阵X

2.通过一系列矩阵运算得出  特征矩阵P

3.矩阵运算 Y = P * X

Y 即为原始数据降维后的结果,也就是说,得到矩阵P后,我们还可以通过Y=P * X这个算式, 反推回X

 Y = P * X ==>   P(-1) * Y = P(-1) * P * X,  P(-1)是P的逆矩阵, 即 P(-1) * P = 1

==>   P(-1) * Y = X

需要注意的是,程序一开始就已经将原始数据均值化,所以实际上, P(-1)*Y的结果需要去均值化才是原来的样子

在Scikit中,pca.components_就是P的逆矩阵

转换过程源码:

1    def transform(self, X, y=None):

2         """Apply dimensionality reduction to X.

3

4         X is projected on the first principal components previously extracted

5         from a training set.

6

7         Parameters

8         ----------

9         X : array-like, shape (n_samples, n_features)

10             New data, where n_samples is the number of samples

11             and n_features is the number of features.

12

13         Returns

14         -------

15         X_new : array-like, shape (n_samples, n_components)

16

17         Examples

18         --------

19

20         >>> import numpy as np

21         >>> from sklearn.decomposition import IncrementalPCA

22         >>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])

23         >>> ipca = IncrementalPCA(n_components=2, batch_size=3)

24         >>> ipca.fit(X)

25         IncrementalPCA(batch_size=3, copy=True, n_components=2, whiten=False)

26         >>> ipca.transform(X) # doctest: +SKIP

27         """

28         check_is_fitted(self, ['mean_', 'components_'], all_or_any=all)

29         print self.mean_

30         X = check_array(X)

31         if self.mean_ is not None:

32             X = X - self.mean_

33         X_transformed = fast_dot(X, self.components_.T)

34         if self.whiten:

35             X_transformed /= np.sqrt(self.explained_variance_)

36         return X_transformed

还原降维前数据:

iris = datasets.load_iris()

X = iris.data

y = iris.target

print X[0]

pca = decomposition.PCA(n_components=3)

pca.fit(X)

X = pca.transform(X)

a = np.matrix(X)

b = np.matrix(pca.components_)

c = a * b

mean_of_data = np.matrix([5.84333333, 3.054,       3.75866667,  1.19866667])

print c[0]

print c[0] + mean_of_data

scikit-learn中的PCA

PCA.inverse_transform()

X=pca.inverse_transform(newX)

将降维后的数据转换成原始数据

X=scaler.inverse_transform(X[, copy])

将标准化后的数据转换为标准化之前的原始数据。

参考博文:

https://blog.csdn.net/u012162613/article/details/42192293

scikit-learn官方文档:

https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html#sklearn.decomposition.PCA

PCA的对象

components_ :返回具有最大方差的成分。

explained_variance_ratio_:返回所保留的n个成分各自的方差百分比。即每个成分(新特征)的方差大小

n_components_:返回所保留的成分个数n。

mean_:每个特征的均值

noise_variance_:

PCA对象的方法

fit(X,y=None)

fit()可以说是scikit-learn中通用的方法,每个需要训练的算法都会有fit()方法,它其实就是算法中的“训练”这一步骤。因为PCA是无监督学习算法,此处y自然等于None。

fit(X),表示用数据X来训练PCA模型。

函数返回值:调用fit方法的对象本身。比如pca.fit(X),表示用X对pca这个对象进行训练。

fit_transform(X)

用X来训练PCA模型,同时返回降维后的数据。

newX=pca.fit_transform(X),newX就是降维后的数据。

inverse_transform()

将降维后的数据转换成原始数据,将数据转换回其原始空间X=pca.inverse_transform(newX)

transform(X)

将数据X转换成降维后的数据。当模型训练好后,对于新输入的数据,都可以用transform方法来降维。

例子

>>> pca.n_components

1

>>> pca.explained_variance_ratio_

array([ 0.99910873])

>>> pca.explained_variance_

array([ 2.55427003])

>>> pca.get_params

<bound method PCA.get_params of PCA(copy=True, n_components=1, whiten=False)>

训练的pca对象的n_components值为1,即保留1个特征,该特征的方差为2.55427003,占所有特征的方差百分比为0.99910873,意味着几乎保留了所有的信息。get_params返回各个参数的值。

PCA.components_

核实PCA.components_中数值的意义

看公式推导, components的逆和转置是等价的吗?

PCA算法认为降维就是线性function,输入x与输出z之间是线性变换(linear transform),PCA 目标: 找变换系数W.

z=wx

从n个特征转换到m个特征:

$$ z_{1} = w^{1} \cdot x,\\ z_{2} = w^{2} \cdot x,\\ W = \begin{bmatrix} \left( w^{1} \right)^{T} \\ \left( w^{2} \right)^{T} \\  \vdots \\ \end{bmatrix} \\ \\ \Rightarrow  z = Wx \\ \begin{bmatrix}  z_{1} \\  z_{2} \\  \vdots \\ z_{m}\end{bmatrix} =\begin{bmatrix} \left( w^{1} \right)^{T} \\ \left( w^{2} \right)^{T} \\  \vdots \\ \end{bmatrix} \begin{bmatrix}  x_{1} \\  x_{2} \\  \vdots \\ x_{n}\end{bmatrix} \\ \Rightarrow  \begin{bmatrix}  z_{1} \\  z_{2} \\  \vdots \\ z_{m}\end{bmatrix} =\begin{bmatrix} w^{1}_{1} & w^{1}_{2} & \cdots  & w^{1}_{n} \\w^{2}_{1} & w^{2}_{2} & \cdots &w^{2}_{n}\\ & \vdots \\ w^{m}_{1} & w^{m}_{2} & \cdots &w^{m}_{n}\end{bmatrix} \begin{bmatrix}  x_{1} \\  x_{2} \\  \vdots \\  x_{n}\end{bmatrix}  \\ \Rightarrow  \begin{bmatrix}  z_{1} \\  z_{2} \\  \vdots \\ z_{m}\end{bmatrix} =\begin{bmatrix} w^{1}_{1} x_{1}+ w^{1}_{2}x_{2} + \cdots +w^{1}_{n}x_{n}  \\w^{2}_{1} x_{1}+ w^{2}_{2} x_{2}+ \cdots +w^{2}_{n}x_{n} \\  \vdots \\ w^{m}_{1} x_{1}+ w^{m}_{2} x_{2}+ \cdots   +w^{m}_{n}x_{n}\end{bmatrix}$$

其中每个组件为一个w^i, 考虑x中的所有特征, 形成z中的一个特征

PCA.components_.T的形状是

W(m个组件, n个特征)对应X(n个特征, k个样本)

components的逆和转置等价

因为变换矩阵W是正交阵, 正交阵的逆等于它的转置.

证明

单位正交矩阵:

$$ Q=\left[  \begin{matrix}    \vdots & \vdots &  & \vdots \\    q_1 & q_2& \dots & q_n \\    \vdots & \vdots & & \vdots \\   \end{matrix}   \right] , q_i^Tq_j=\left\{ \begin{aligned} 0 & \ &when \  i\neq j \\ 1 & \ & when \ i=j \end{aligned} \right. \\ Q^TQ=\left[ \begin{matrix}q_1^T \\ q_2^T \\ \vdots \\ q_n^T \end{matrix} \right] \left[ \begin{matrix} q_1^T q_2^T \dots q_n^T\end{matrix} \right]=I $$

总结

PCA过程

1.均值化矩阵X

2.通过一系列矩阵运算得出  特征矩阵P

3.矩阵运算 Y = P * X

PCA转回原特征的公式

Y 即为原始数据降维后的结果,也就是说,得到矩阵P后,我们还可以通过Y=P * X这个算式, 反推回X

 Y = P * X ==>   P(-1) * Y = P(-1) * P * X,  P(-1)是P的逆矩阵, 即 P(-1) * P = 1

==>   P(-1) * Y = X

需要注意的是,程序一开始就已经将原始数据均值化,所以实际上, P(-1)*Y的结果需要去均值化才是原来的样子

手刻逆转换

iris = datasets.load_iris()

X = iris.data

y = iris.target

print X[0]

pca = decomposition.PCA(n_components=3)

pca.fit(X)

X = pca.transform(X)

a = np.matrix(X)

b = np.matrix(pca.components_)

c = a * b

mean_of_data = np.matrix([5.84333333, 3.054,       3.75866667,  1.19866667])

print c[0]

print c[0] + mean_of_data

Sklearn逆转换

X=scaler.inverse_transform(X[, copy])

将标准化后的数据转换为原始数据。

X=pca.inverse_transform(newX)

将降维后的数据转换成原始数据

PCA逆转换实验

创建pcaInverseDemo.py进行尝试

先试一下调包

sklearn的逆转换

建立简单矩阵, PCA转换, 输出值

import numpy as np

from sklearn import decomposition

# 建立简单矩阵

X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])

# 将含有2个特征的数据经过PCA压缩为1个特征

pca = decomposition.PCA(n_components=1)

pca.fit(X)

X_pca = pca.transform(X)

print("X_pca:\n",X_pca)

X_pca:

[[ 1.38340578]

[ 2.22189802]

[ 3.6053038 ]

[-1.38340578]

[-2.22189802]

[-3.6053038 ]]

再逆转换, 输出值

X_origin=pca.inverse_transform(X_pca)

X_origin:

[[-1.15997501 -0.75383654]

[-1.86304424 -1.21074232]

[-3.02301925 -1.96457886]

[ 1.15997501  0.75383654]

[ 1.86304424  1.21074232]

[ 3.02301925  1.96457886]]

如果维度降低, 则会损失信息, 如果进行PCA时维度不变, 则逆转换后值与原来相同

手刻PCA以及逆转换

PCA:

def pca(X, k): # k is the components you want

# mean of each feature

n_samples, n_features = X.shape

mean = np.array([np.mean(X[:, i]) for i in range(n_features)])

# normalization

norm_X = X - mean

# scatter matrix

scatter_matrix = np.dot(np.transpose(norm_X), norm_X)

# Calculate the eigenvectors and eigenvalues

eig_val, eig_vec = np.linalg.eig(scatter_matrix)

eig_pairs = [(np.abs(eig_val[i]), eig_vec[:, i]) for i in range(n_features)]

# sort eig_vec based on eig_val from highest to lowest

eig_pairs = [((np.abs(eig_val[i])), eig_vec[:, i]) for i in range(len(eig_vec))]

eig_pairs.sort(key=lambda x: x[0], reverse=True)

# select the top k eig_vec

feature = np.array([ele[1] for ele in eig_pairs[:k]])

# get new data

new_data = np.dot(norm_X, np.transpose(feature))

return new_data

X_pca = pca(X, 1).real#.real取得复数的实部

print("X_pca:\n",X_pca)

X_pca:

[[-1.38340578]

[-2.22189802]

[-3.6053038 ]

[ 1.38340578]

[ 2.22189802]

[ 3.6053038 ]]

和刚刚结果绝对值相同, 正负相反, 但是和原数据的正负还是保持一致的, 感觉没有大问题(有时间对照包源码找下原因)

逆转换:

def pca(X, k): # k is the components you want

# mean of each feature

n_samples, n_features = X.shape

mean = np.array([np.mean(X[:, i]) for i in range(n_features)])

# normalization

norm_X = X - mean

# scatter matrix

scatter_matrix = np.dot(np.transpose(norm_X), norm_X)

# Calculate the eigenvectors and eigenvalues

eig_val, eig_vec = np.linalg.eig(scatter_matrix)

eig_pairs = [(np.abs(eig_val[i]), eig_vec[:, i]) for i in range(n_features)]

# sort eig_vec based on eig_val from highest to lowest

eig_pairs = [((np.abs(eig_val[i])), eig_vec[:, i]) for i in range(len(eig_vec))]

eig_pairs.sort(key=lambda x: x[0], reverse=True)

# select the top k eig_vec

feature = np.array([ele[1] for ele in eig_pairs[:k]])

# get new data

new_data = np.dot(norm_X, np.transpose(feature))

return new_data,feature,mean

# X_pca = pca(X, 1)#可行

X_pca,X_components,X_mean = pca(X, 1)

print("X_pca:\n",X_pca)

X_origin=np.dot(X_pca, X_components)+X_mean

print("X_origin:\n",X_origin)

X_pca:

[[-1.38340578]

[-2.22189802]

[-3.6053038 ]

[ 1.38340578]

[ 2.22189802]

[ 3.6053038 ]]

X_origin:

[[-1.15997501 -0.75383654]

[-1.86304424 -1.21074232]

[-3.02301925 -1.96457886]

[ 1.15997501  0.75383654]

[ 1.86304424  1.21074232]

[ 3.02301925  1.96457886]]

结果与调包相同, 基本没问题

归因分析笔记4:PCA逆变换相关推荐

  1. 归因分析笔记5:机器学习可解释性

    目录 可解释的机器学习 从宏观业务流程看可解释机器学习 使机器学习可解释两种方法 可解释性的范围 模型不可知的全局方法 排列特征重要性(模型依赖) 模型不可知的局部方法 Shapley 值 Shapl ...

  2. 归因分析笔记13 特征重要度正确性的验证

    目录 SHAP原论文 引言 第五节 计算和用户研究实验 5.2 符合人类直觉 5.3 解释分类差异 引用文献 验证方法总结 数据集选取 Madelon Adult Cross-Domain Indoo ...

  3. 归因分析笔记21 可解释的机器学习-李宏毅讲座

    视频链接: https://www.bilibili.com/video/BV1Wv411h7kN/?p=96&vd_source=7259e29498a413d91ab48c04f93298 ...

  4. 归因分析笔记6:SHAP包使用及源码阅读

    突然发现这篇文章居然被百度文库给盗了, 举报侵权还要我自己打印保证函, 最逗的是, 上传保证函图片还要求开启flash, 其心昭然若揭. 目录 安装 使用示例 shap.kmeans shap_val ...

  5. 多渠道归因分析:python实现马尔可夫链归因(三)

    本篇主要是python实现马尔科夫链归因,关联的文章: 多渠道归因分析(Attribution):传统归因(一) 多渠道归因分析:互联网的归因江湖(二) 多渠道归因分析:python实现马尔可夫链归因 ...

  6. Algorithm:网络广告营销领域之归因分析/归因模型的简介、算法、案例应用之详细攻略

    Algorithm:网络广告营销领域之归因分析/归因模型的简介.算法.案例应用之详细攻略 目录 归因分析/归因模型的简介 1.常见几种归因分析模型 2.单触点归因分析VS多触点归因分析 3.归因模型的 ...

  7. 2.View绘制分析笔记之onMeasure

    今天主要学习记录一下Android View绘制三部曲的第一步,onMeasure,测量. 起源 在Activity中,所有的View都是DecorView的子View,然后DecorView又是被V ...

  8. 用户行为分析笔记(一):概述

    今天有人问我会不会推荐算法,回到家里反复思考了下(其实就是一个会与不会的回答,为啥我还要反复思量下了?),我发现自己从事软件开发工作这么多年,大小项目无数,但是如果从做应用角度换句话说我做了哪些提高人 ...

  9. 重载内核全程分析笔记

    标 题: [原创]重载内核全程分析笔记 作 者: Speeday 时 间: 2013-08-20,20:19:46 链 接: http://bbs.pediy.com/showthread.php?t ...

最新文章

  1. php中删除数组元素的函数,php删除数组中的元素函数用法汇总
  2. tensorflow lstm 预测_图卷积神经网络GCN与递归结构RNN相结合的时间序列预测
  3. JavaScript(十三)面向对象
  4. android 真机 sqlite3,在android真机上使用sqlite3
  5. 在类中用class时数据是共有还是私有_jvm学习笔记之class文件的加载、初始化
  6. 机器找不到 libcudnn.so.6
  7. (74)信号发生器DDS三角波设计(二)(第15天)
  8. 电视开机还要看广告?超80%的人一秒都忍不了
  9. 如何监控 Tomcat?Zabbix 与 Cloud Insight 对比
  10. 2008-2013年工业企业数据库(EXCEL)
  11. 函数调用中的堆栈平衡
  12. fullcalendar日历控件知识点集合
  13. 详谈外部浏览器如何实现复制微信号一键唤起微信号加好友
  14. VS2019新建osgEarth项目时,GL.h文件提示报错
  15. 菠萝V1mini是以太坊唯一的静音机器
  16. KK凯文.凯利:第一届中国社群领袖峰会演讲实录(全部版)
  17. 股票交易接口有什么优势?
  18. 神策数据如何帮助企业实现营销自动化?
  19. Ajax-服务器响应数据详解
  20. Axure RP 9 基础教程

热门文章

  1. 《计算机系统应用》期刊投稿经验
  2. 第5章-CSS盒子模型
  3. 积分等级系统php,积分等级数据结构
  4. rep论文阅读1:ACNet_Strengthening the Kernel Skeletons for Powerful CNN via Asymmetric Convolution Blocks
  5. 基于网络爬虫和SpringBoot框架的晋江文学小说小型网站项目
  6. 第8期-通过晋江爬取小说
  7. 中指无名指收起 其他3个手指伸出来 这种手势是什么意思?
  8. Microsoft Build 发布丨开发者关注的7大方向技术更新
  9. OTRS中国版 快速安装
  10. Java通道(Channel)的实现及优势