首页 > 编程知识 正文

python多线程实现原理,python的原理

时间:2023-05-05 17:31:20 阅读:167239 作者:4850

正如前言所说,制作有追赶性的技术博客。 这仍然不是什么了不起的水平,但总算迈出了第一步。 希望今后每天都有一点点进步。

接触机器学习一年多了,学到了很多算法,PCA数据预处理中的重要算法。 当时学习的时候也在网上看了很多资料,简单的PCA也有严密的数学推导,通过当时的研究生考试我知道了为什么数学这么难

这篇文章主要是对PCA算法的总结,数学原理部分主要来自PCA的数学原理(http://blog.coding labs.org/articles/PCA-tutorial.html ) ),并对其进行总结)了

本文数学概念介绍Scikit-learn用于衡量随机变量与其数学期望(均值)的背离程度。 所述统计中的方差(样本方差)是各数据的各自与其平均值的方差之和的平均值。

33558www.Sina.com/:2:用于测量两个随机变量之间关系的统计量,协方差为0的两个随机变量没有相关性。

方差:在统计学和概率论中,协方差矩阵的每个元素是每个向量元素之间的协方差。 特殊的、矩阵对角线上的元素分别是向量的方差。

摘自——百度百科

特别是协方差的概念非常重要。

PCA介绍了协方差矩阵,是用于探索高维数据的技术。 PCA通常用于高维数据集的搜索和可视化。 也可用于数据压缩、数据预处理等。 PCA可将可能具有线性相关性的高维变量合成为线性无关的低维变量,称为协方差矩阵,新的低维数据集尽可能保留原始数据的变量,同时将高维数据集映射到低维空间

必须明确是主成分分析(Principal Component Analysis)。 在原始数据中模型上没有效果,希望通过降维来改善是不现实的,但是考虑到实际数据本身中经常存在的相关性,可以考虑在降维的同时尽可能减少信息损失的方法。 俊秀的故事给原始数据带来了比较好的结果,但是因为讨厌它太慢,模型太复杂,所以可以降低PCA维度。

PCA数学理论基础的二维空间默认为(1,0 )和(0,1 )为一组基础。

其实两个线性无关的二维向量都可以成为一组基础。 由于正交基团具有良好的性质,所以常用的基团是正交的。

例如,只有一个(3,2 )无法正确表示一个向量。 此处的3实际上表示了向量在x轴上的投影值为3,在y轴上的投影值为2。 也就是说,隐式引入了基于缺省选取(1,0 )和(0,1 )的定义,该定义相对于x轴和y轴的正方向长度为1的向量。

内积向量a和b的内积公式如下。

ab=|a|||b|cos(a ) ab=|a|||b|cos(a ) )。

优选基底的类型为1。 因为从内积的意义上可以知道,如果基底的模型为1的话,在矢量点上与基底相乘就可以很容易地得到新的基底上的坐标,即主成分(principal components)

基变换的矩阵表示将一系列向量的基变换表示为矩阵的乘法。 一般来说,如果我们有m个n维向量,并且想把它转换成由r个n维向量(r个基)表示的新空间,那么,如果先逐行构造r个基,然后逐列构造矩阵p,那么两个矩阵的乘积就是转换结果。 r可以小于n,但是r决定了转换后的数据的维数。 即,可以将第一到第n维的数据转换为较低维度的空间,转换后的维度取决于基数。

因此,该矩阵的乘法可以表示降维变换:

YRM=PRNXNMYRM=PRNXNM

两个矩阵相乘的意义:注意:降维就意味着信息的丢失

优化目标如何选择基础是最好的。 或者,如果我们有一组n维向量,现在把它降低到r维,我们应该如何选择r个基最大限度地保留原始信息?

对于二维空间:要在二维平面中选择方向,请将所有数据投影到方向所在的直线上,并用投影值表示原始记录。 这是实际的二维降一维的问题。 那么,如何选择这个方向才能留下尽可能多的原始信息呢? 作为直观的看法,希望投影后的投影值尽量分散,但该分散的程度在数学上可以表示为向量在基上的投影=向量与基的内积=坐标

关于将上面的二维降阶为一维的问题,找出方差最大的方向即可。 但是,更高维的还有另一个问题。 考虑到三维下降到二维的问题,和以前一样,我想首先找到投影后方差最大的方向。 这样就完成了第一个方向的选择,然后选择第二个投影方向。 如果我们还只是简单地选择方差最大的方向,很明显,这个方向和第一个方向应该“差不多重叠”,很明显这样的维度是没有用的,所以

,应该有其他约束条件。从直观上说,让两个不同维度尽可能表示更多的原始信息,我们是不希望它们之间存在(线性)相关性的,因为相关性意味着两个维度不是完全线性独立,必然存在重复表示的信息。

数学上用协方差表示两个维度的相关性,当协方差为0时,表示两个维度完全独立。为了让协方差为0,我们选择第二个基时只能在与第一个基正交的方向上选择,因此最终选择的两个方向一定是正交的。

降维问题的优化目标:将一组N维向量降为R维,其目标是选择R个单位正交基,使得原始数据变换到这组基上后,各维度两两间的协方差为0,而每个维度的方差则尽可能大(在正交的约束下,取最大的R个方差)。

协方差矩阵

上面推导出优化目标,那么具体该怎么实现呢,下面就用到了协方差矩阵。回顾一下,协方差矩阵的每个元素是各个向量元素之间的协方差,特殊的,矩阵对角线上的元素分别是各个向量的方差。

设原始矩阵为X(N×M),表示M个N维向量,其协方差矩阵为C(N×N);P(R×N)为变换矩阵;Y(R×M)为目标矩阵, 其协方差矩阵为D。我们要求降维后的矩阵Y的每一维包含的数据足够分散,也就是每一行(维)方差足够大,而且要求行之间的元素线性无关,也就是要求行之间的协方差全部为0,这就要求协方差矩阵D的对角线元素足够大,除对角线外元素都为0。
相当于对C进行协方差矩阵对角化

具体推导如下:

 

D=1MYY′=1MPXX′P′=PCP′D=1MYY′=1MPXX′P′=PCP′

 

C是X的协方差矩阵,是实对称矩阵,整个PCA降维过程其实就是一个实对称矩阵对角化的过程

PCA具体算法步骤

设有M个N维数据:

将原始数据按列组成N行M列矩阵X

将X的每一行进行零均值化,即减去每一行的均值

求出X的协方差矩阵C

求出协方差矩阵C的特征值及对应的特征向量,C的特征值就是Y的每维元素的方差,也是D的对角线元素,从大到小沿对角线排列构成D。

将特征向量按对应特征值大小从上到下按行排列成矩阵,根据实际业务场景,取前R行组成矩阵P

Y=PX即为降到R维后的目标矩阵

Scikit-learn PCA实例分析

Scikit-learn是Python下著名的机器学习库,关于它我在这里就不多做介绍了,反正很好很强大。

首先数据选用经典的手写字符数据。

from sklearn import datasetsdigits = datasets.load_digits()x = digits.data #输入数据y = digits.target #输出数据

PCA的调用也很简单。

from sklearn import decompositionpca = decomposition.PCA()pca.fit(x)

可视化,matplotlib是Python下的绘图库,功能也是十分强大。

import matplotlib.pyplot as pltplt.figure()plt.plot(pca.explained_variance_, 'k', linewidth=2)plt.xlabel('n_components', fontsize=16)plt.ylabel('explained_variance_', fontsize=16)plt.show()

pca.explained_variance_ 就是上面协方差矩阵D的对角线元素,如下图所示:

至于到底降到多少维度,主要取决于方差,具体的方法可以采用交叉验证

实现PCA算法

基于Nnmpy, Pandas, Matploylib实现PCA并可视化结果。整体代码很简单,按照上面总结的算法步骤一步一步地计算,Numpy和Pandas的功能很强大,你能想到的运算几乎都有。

首先定义异常类:

class DimensionValueError(ValueError): """定义异常类""" pass

定义PCA类:

class PCA(object): """定义PCA类""" def __init__(self, x, n_components=None): self.x = x self.dimension = x.shape[1] if n_components and n_components >= self.dimension: raise DimensionValueError("n_components error") self.n_components = n_components

接下来就是计算协方差矩阵,特征值,特征向量,为了方便下面的计算,我把特征值和特征向量整合在一个dataframe内,并按特征值的大小降序排列:

def cov(self): """求x的协方差矩阵""" x_T = np.transpose(self.x) #矩阵转置 x_cov = np.cov(x_T) #协方差矩阵 return x_cov def get_feature(self): """求协方差矩阵C的特征值和特征向量""" x_cov = self.cov() a, b = np.linalg.eig(x_cov) m = a.shape[0] c = np.hstack((a.reshape((m,1)), b)) c_df = pd.DataFrame(c) c_df_sort = c_df.sort(columns=0, ascending=False) return c_df_sort

最后就是降维,用了两种方式,指定维度降维和根据方差贡献率自动降维,默认方差贡献率为99%:

def reduce_dimension(self): """指定维度降维和根据方差贡献率自动降维""" c_df_sort = self.get_feature() varience = self.explained_varience_() if self.n_components: #指定降维维度 p = c_df_sort.values[0:self.n_components, 1:] y = np.dot(p, np.transpose(self.x)) return np.transpose(y) varience_sum = sum(varience) varience_radio = varience / varience_sum varience_contribution = 0 for R in xrange(self.dimension): varience_contribution += varience_radio[R] if varience_contribution >= 0.99: break p = c_df_sort.values[0:R+1, 1:] #取前R个特征向量 y = np.dot(p, np.transpose(self.x)) return np.transpose(y)

完整的代码已经push到了 Github, 欢迎star和fork。

后记

根据上面对PCA的数学原理的解释,我们可以了解到一些PCA的能力和限制。PCA本质上是将方差最大的方向作为主要特征,并且在各个正交方向上将数据“离相关”,也就是让它们在不同正交方向上没有相关性。

因此,PCA也存在一些限制,例如它可以很好的解除线性相关,但是对于高阶相关性就没有办法了,对于存在高阶相关性的数据,可以考虑Kernel PCA,通过Kernel函数将非线性相关转为线性相关,关于这点就不展开讨论了。另外,PCA假设数据各主特征是分布在正交方向上,如果在非正交方向上存在几个方差较大的方向,PCA的效果就大打折扣了。

最后需要说明的是,PCA是一种无参数技术,也就是说面对同样的数据,如果不考虑清洗,谁来做结果都一样,没有主观参数的介入,所以PCA便于通用实现,但是本身无法个性化的优化。

希望这篇文章能帮助朋友们了解PCA的数学理论基础和实现原理,借此了解PCA的适用场景和限制,从而更好的使用这个算法。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。