提问人:Abhishek Bhatia 提问时间:8/10/2015 最后编辑:ZahraAbhishek Bhatia 更新时间:7/9/2022 访问量:103767
从 sklearn PCA 获取特征值和向量
Obtain eigen values and vectors from sklearn PCA
问:
如何获取 PCA 应用程序的特征值和特征向量?
from sklearn.decomposition import PCA
clf=PCA(0.98,whiten=True) #converse 98% variance
X_train=clf.fit_transform(X_train)
X_test=clf.transform(X_test)
我在文档中找不到它。
1.我“无法”理解这里的不同结果。
编辑:
def pca_code(data):
#raw_implementation
var_per=.98
data-=np.mean(data, axis=0)
data/=np.std(data, axis=0)
cov_mat=np.cov(data, rowvar=False)
evals, evecs = np.linalg.eigh(cov_mat)
idx = np.argsort(evals)[::-1]
evecs = evecs[:,idx]
evals = evals[idx]
variance_retained=np.cumsum(evals)/np.sum(evals)
index=np.argmax(variance_retained>=var_per)
evecs = evecs[:,:index+1]
reduced_data=np.dot(evecs.T, data.T).T
print(evals)
print("_"*30)
print(evecs)
print("_"*30)
#using scipy package
clf=PCA(var_per)
X_train=data.T
X_train=clf.fit_transform(X_train)
print(clf.explained_variance_)
print("_"*30)
print(clf.components_)
print("__"*30)
- 我希望获得所有特征值和特征向量,而不仅仅是具有收敛条件的约简集。
答:
您的实施
您正在计算相关矩阵的特征向量,即归一化变量的协方差矩阵。
不是经典 PCA 的一部分,我们只将变量居中。
因此,sklearn PCA 不会事先对数据进行缩放。data/=np.std(data, axis=0)
除此之外,如果我们抽象出您提供的代码没有运行的事实,那么您就走在正确的轨道上;)。
您只会对行/列布局感到困惑。老实说,我认为从那里开始只使用 X 要容易得多。我在帖子末尾添加了您的代码“已修复”。X = data.T
获取特征值
您已经注意到,您可以使用 获取特征向量。clf.components_
所以你有主要组成部分。它们是协方差矩阵 XTX 的特征向量。
从那里检索特征值的一种方法是将此矩阵应用于每个主成分,并将结果投影到该成分上。
设 v_1 为第一个主成分,并lambda_1关联的特征值。我们有: 因此:
自 .(x, y) 向量 x 和 y 的标量积。
回到 Python 中,您可以执行以下操作:
n_samples = X.shape[0]
# We center the data and compute the sample covariance matrix.
X -= np.mean(X, axis=0)
cov_matrix = np.dot(X.T, X) / n_samples
for eigenvector in pca.components_:
print(np.dot(eigenvector.T, np.dot(cov_matrix, eigenvector)))
然后你得到与特征向量相关的特征值。 好吧,在我的测试中,结果证明不适用于最后几个特征值,但我认为这是由于我缺乏数值稳定性方面的技能。
现在这不是获取特征值的最佳方法,但很高兴知道它们来自哪里。
特征值表示特征向量方向的方差。因此,您可以通过以下属性获取它们:pca.explained_variance_
eigenvalues = pca.explained_variance_
下面是一个可重现的示例,它打印了使用每种方法获得的特征值:
import numpy as np
from sklearn.decomposition import PCA
from sklearn.datasets import make_classification
X, y = make_classification(n_samples=1000)
n_samples = X.shape[0]
pca = PCA()
X_transformed = pca.fit_transform(X)
# We center the data and compute the sample covariance matrix.
X_centered = X - np.mean(X, axis=0)
cov_matrix = np.dot(X_centered.T, X_centered) / n_samples
eigenvalues = pca.explained_variance_
for eigenvalue, eigenvector in zip(eigenvalues, pca.components_):
print(np.dot(eigenvector.T, np.dot(cov_matrix, eigenvector)))
print(eigenvalue)
您的原始代码,已修复
如果运行它,你会看到值是一致的。它们并不完全相等,因为 numpy 和 scikit-learn 在这里没有使用相同的算法。
最主要的是,如上所述,您使用的是相关矩阵而不是协方差。此外,您还从 numpy 中获得了转置的特征向量,这使得它非常令人困惑。
import numpy as np
from scipy.stats.mstats import zscore
from sklearn.decomposition import PCA
def pca_code(data):
#raw_implementation
var_per=.98
data-=np.mean(data, axis=0)
# data/=np.std(data, axis=0)
cov_mat=np.cov(data, rowvar=False)
evals, evecs = np.linalg.eigh(cov_mat)
idx = np.argsort(evals)[::-1]
evecs = evecs[:,idx]
evals = evals[idx]
variance_retained=np.cumsum(evals)/np.sum(evals)
index=np.argmax(variance_retained>=var_per)
evecs = evecs[:,:index+1]
reduced_data=np.dot(evecs.T, data.T).T
print("evals", evals)
print("_"*30)
print(evecs.T[1, :])
print("_"*30)
#using scipy package
clf=PCA(var_per)
X_train=data
X_train=clf.fit_transform(X_train)
print(clf.explained_variance_)
print("_"*30)
print(clf.components_[1,:])
print("__"*30)
评论
clf.components_
clf.components_
clf.components_
我使用了sklearn PCA函数。返回参数“components_”是特征向量,“explained_variance_”是特征值。下面是我的测试代码。
from sklearn.decomposition import PCA
import numpy as np
def main():
data = np.array([[2.5, 2.4], [0.5, 0.7], [2.2, 2.9], [1.9, 2.2], [3.1, 3.0], [2.3, 2.7], [2, 1.6], [1, 1.1], [1.5, 1.6], [1.1, 0.9]])
print(data)
pca = PCA()
pca.fit(data)
print(pca.components_)
print(pca.explained_variance_)
if __name__ == "__main__":
main()
评论
当您说“特征值”时,您是指 PCA 的“奇异值”吗?只有当应用的矩阵 PCA 是方阵时,特征值才有可能。
如果您尝试使用“特征值”来确定 PCA 所需的适当维度,您实际上应该使用奇异值。你可以只用pca.singular_values_来获取奇异值。
上一个:Conda 激活不起作用?
评论
.explained_variance_
1
PCA
.explained_variance_