PCA算法问题 - Python
-
16-10-2019 - |
题
我已经实施了PCA算法,并且非常了解它,但我仍然有一些问题。我的代码在下面,这是非常简单的实现。
import numpy as np
x = np.loadtxt('CCPP', delimiter=',')
row, column = x.shape
# Mean normalization
for i in range(column):
x[:,i] = (x[:,i] - x[:,i].mean()) / (x[:,i].max() - x[:,i].min())
sigma = x.transpose().dot(x) / row
u, s, v = np.linalg.svd(sigma, 0)
z = x.dot(u[:,:3]) ## new features
new_x = z.dot(u[:,:3].transpose()) ##reconstruction
第一个问题
如您在上方我的Sigma变量上方看到的那样
x.transpose()。点(x) /行
它给我一个nxn矩阵(n是功能数量)。但是Sigma的公式为$$ sigma = frac {1} {n} sum_ {i = 1}^nx^^{(i)} {x^{(i)}}^t $$
为什么公式中有一个求和符号?我的意思是,如果我使用此Sigma公式,那么Sigma将是一个数字,而不是矩阵。我必须得到NXN矩阵,对吗?那么我的Sigma实施是否正确?还是我错过了有关该公式的东西?
第二个问题
当我们重建X(在代码的底部)时,new_x应该等于我的第一个x吗?我的意思是,我缩小了数据集的维度,然后重建了数据集,原始数据集和重建数据集必须相同,对吗?这是我的第二个问题。
第三个问题
这个很容易。我应该为每个具有1000、100000或更多功能的数据集使用数据压缩吗?我的意思是,我可以总是使用它吗?每次使用它是一个不错的选择吗?
解决方案
关于第一个问题.
在上面的公式中,如果我没有错,则x是元素的矩阵。因此,公式从您那里想要的是将每条线的所有点产品与其转置总结。这会给您标量。
x = np.array([1, 2, 3, 4])
res = x.dot(x.transpose())
# res = 30
因此,我的建议是将该代码行更改为:
for i in range(row):
sigma += x[i].transpose().dot(x[i])
sigma = sigma/row
第二个问题
因为您降低了维度,所以X_NEW矩阵将不相同。
第三个问题
何时使用PCA是域问题。降低维度的重点是获取新的数据集,这并不难处理,但它会失去一些信息。因此,如果您是“结果”/“处理时间”是好的,我认为您不应该使用它。
其他提示
第一个问题:计算$ sigma $
实际上,您执行相同的计算,但使用矩阵操作而不是标量操作。您可能会被写入$ x $的功能矩阵$ x $的表示法误导,因为实际上$$ x =(x_j^{(i)})_ {i,j} = big(x^{(x^{(x^{) 1)} ... x^{(i)} ... x^{(n)} big) ^{(i)} $ $ i $ -th样本。
因此,当您要计算经验协方差矩阵$ sigma $(确实是$ n times n $矩阵)时,您有:$$ sigma = frac {1} {n} {n} sum_ = i = i = i = i = 1}^nx^{(i)} {x^{(i)}}}^t = frac {1} {n} X^tx $$您可以检查这是完全相同的计算。
在您的代码中,您实际上是在使用矩阵操作(即$ sigma = frac {1} {n} x^tx $)直接计算$ sigma $,这确实给了您一个$ n times n $ matrix。因此,您的实施和公式都是正确的。
第二个问题:重建$ x $
根据您的代码,您的新功能矩阵$ z $是$ n times 3 $矩阵。实际上,由于您的代码没有显示功能空间的原始大小,因此我们将在这里看到这两种情况:
- $ x $也是一个$ n times 3 $矩阵,那么您不执行任何尺寸降低,您应该拥有$ x_ {new} = x $(至少在理论上,实际上您可能有一个很小的数值近似误差,但基本上将是相同的)
- $ x $是带有$ d> 3 $的$ n times d $矩阵,然后您确实执行尺寸缩小,在这种情况下,您会摆脱原始数据中包含的一些信息,在这种情况下为$ x_ {new} neq x $
就您而言,我想您确实有$ d> 3 $,因此您处于第二种情况。
第三个问题:何时应用PCA
好吧,这实际上是...
首先,PCA执行SVD,如果您有很多功能,它可能会变得非常昂贵。实际上,有几种计算PCA的方法,您的方式更接近数学理论,但实际上,在$ x $上直接计算SVD避免计算$ x^tx $,这很昂贵,并且可以检索相同的空间。但是在任何情况下,在某些情况下,它可能是昂贵且耗时的,因此不实用。
当PCA根据特征值的值(即新方向的差异)对新功能空间进行分类,从而删除最后一个方向,在某些情况下可能会消除一些噪音,这可能会有所帮助。但是,与此同时,它可以丢弃有价值的歧视信息,这就是为什么其他方法(例如LDA)会很有趣的原因。
因此,总而言之,问题的答案是否定,每次使用它不是一个不错的选择,而是您的问题。