用于计算 PCA 尺度上的点的特征向量和样本
Eigenvectors and samples to calculate the points on PCA scale
我想在 PC1
和 PC2
的新等级上获得新分数。
我计算了特征值、特征向量和贡献。
现在我想计算新尺度(分数)上的点,以对其应用 K-Means 聚类算法。
每当我尝试通过说 z_new = np.dot(v, vectors)
(使用 v = np.cov(x)
)来计算它时,我得到一个错误的分数,PC1 为 [[14. -2. -2. -1. -0. 0. 0. -0. -0. 0. 0. -0. 0. 0.]
,PC2 为 [-3. -1. -2. -1. -0. -0. 0. 0. 0. -0. -0. 0. -0. -0.]
。正确的分数分数(使用 SciKit 的 PCA() 函数计算)应该是 PC1: [ 4 4 -6 3 1 -5]
和 PC2: [ 0 -3 1 -1 5 -4]
这是我的代码:
dataset = pd.read_csv("cands_dataset.csv")
x = dataset.iloc[:, 1:].values
m = x.mean(axis=1);
for i in range(len(x)):
x[i] = x[i] - m[i]
z = x / np.std(x)
v = np.cov(x)
values, vectors = np.linalg.eig(v)
d = np.diag(values)
p = vectors
z_new = np.dot(v, p) # <--- Here is where I get the new scores
z_new = np.round(z_new,0).real
print(z_new)
我得到的结果:
[[14. -2. -2. -1. -0. 0. 0. -0. -0. 0. 0. -0. 0. 0.]
[-3. -1. -2. -1. -0. -0. 0. 0. 0. -0. -0. 0. -0. -0.]
[-4. -0. 3. 3. 0. 0. 0. 0. 0. -0. -0. 0. -0. -0.]
[ 2. -1. -2. -1. 0. -0. 0. -0. -0. 0. 0. -0. 0. 0.]
[-2. -1. 8. -3. -0. -0. -0. 0. 0. -0. -0. -0. 0. 0.]
[-3. 2. -1. 2. -0. 0. 0. 0. 0. -0. -0. 0. -0. -0.]
[ 3. -1. -3. -1. 0. -0. 0. -0. -0. 0. 0. -0. 0. 0.]
[11. 6. 4. 4. -0. 0. -0. -0. -0. 0. 0. -0. 0. 0.]
[ 5. -8. 6. -1. 0. 0. -0. 0. 0. 0. 0. -0. 0. 0.]
[-1. -1. -1. 1. 0. -0. 0. 0. 0. 0. 0. 0. -0. -0.]
[ 5. 7. 1. -1. 0. -0. -0. -0. -0. 0. 0. -0. -0. -0.]
[12. -6. -1. 2. 0. 0. 0. -0. -0. 0. 0. -0. 0. 0.]
[ 3. 6. 0. 0. 0. -0. -0. -0. -0. 0. 0. 0. -0. -0.]
[ 5. 5. -0. -4. -0. -0. -0. -0. -0. 0. 0. -0. 0. 0.]]
数据集(由评论请求):
在我看来,您有 6 个 14 维的样本。 PCA过程如下:
1。去掉均值
从以下数据开始:
data = np.array([[10, 9, 1, 7, 5, 3],
[10, 8,10, 8, 8,10],
[ 4, 6, 8, 9, 8, 9],
[ 9, 9, 6, 6, 8, 7],
[ 4, 9,10, 9, 5, 5],
[ 7, 6, 9, 9,10,10],
[10, 9, 6, 6, 8, 7],
[ 5, 4, 2,10, 9, 1],
[ 4,10, 4, 9, 2, 6],
[ 8, 7, 7, 7, 7, 9],
[ 5, 5, 6, 6, 9, 1],
[ 9,10, 1, 9, 5, 6],
[ 7, 6, 6, 6,10, 4],
[10, 9, 9, 7, 9, 4]])
我们可以通过以下方式去除均值:
centered_data = data - np.mean(data, axis=1)[:, None]
2。创建协方差矩阵
可按如下方式进行:
covar = np.cov(centered_data)
3。获取主成分
这可以使用协方差矩阵的特征值分解来完成
eigen_vals, eigen_vecs = np.linalg.eig(covar)
eigen_vals, eigen_vecs = np.real(eigen_vals), np.real(eigen_vecs)
4。降维
现在我们可以通过选择具有最高匹配特征值(方差)的两个PC来进行降维。在您的示例中,您需要 2 维,因此我们采用两台主要 PC:
eigen_vals =
array([ 3.34998559e+01, 2.26499704e+01, 1.54115835e+01, 9.13166675e+00,
1.27359015e+00, -3.10462438e-15, -1.04740277e-15, -1.04740277e-15,
-2.21443036e-16, 9.33811755e-18, 9.33811755e-18, 6.52780501e-16,
6.52780501e-16, 5.26538300e-16])
可以看出前两个特征值最高:
eigen_vals[:2] = array([33.49985588, 22.64997038])
因此,我们可以将前两台PC上的数据投影如下:
projected_data = eigen_vecs[:, :2].T.dot(centered_data)
现在可以打散了,我们可以看到14维降为2维:
PC1 = [0.59123632, -0.10134531, -0.20795954, 0.1596049 , -0.07354629, 0.19588723, 0.19151677, 0.33847213, 0.22330841, -0.03466414, 0.1001646 , 0.52913917, 0.09633029, 0.16141852]
PC2 = [-0.07551251, -0.07531288, 0.0188486 , -0.01280896, -0.07309957, 0.12354371, -0.01170589, 0.49672196, -0.43813664, -0.09948337, 0.49590461, -0.25700432, 0.38198034, 0.2467548 ]
一般分析
自从我们做了 PCA 之后,现在每个维度都有正交方差(对角协方差矩阵)。为了更好地理解降维的可能性,我们可以看到数据的总方差是如何分布在不同维度上的。这可以通过特征值圆顶:
var_dim_contribution = eigen_vals / np.sum(eigen_vals)
绘制此结果:
我们可以在这里看到,使用 2 个主要 PC,我们可以描述 ~67% 的方差。添加第三个维度将使我们接近 90% 的方差。这是 14 的一个很好的减少。这在累积方差图中看起来更好。
var_cumulative_contribution = np.cumsum(eigen_vals / np.sum(eigen_vals))
与sklearn的比较
与 sklearn.decomposition.PCA
比较时,我们得到以下结果:
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pca.fit(centered_data.T)
print(pca.explained_variance_ratio_) # [0.40870097 0.27633148]
print(pca.explained_variance_) # [33.49985588 22.64997038]
我们看到我们得到了与手动计算相同的解释方差和方差值,此外,结果 PC 为:
print(pca.components_)
[[-0.59123632 0.10134531 0.20795954 -0.1596049 0.07354629 0.19588723 0.19151677 -0.33847213 -0.22330841 0.03466414 -0.1001646 -0.52913917 -0.09633029 -0.16141852]
[-0.07551251 -0.07531288 0.0188486 -0.01280896 -0.07309957 0.12354371 -0.01170589 0.49672196 -0.43813664 -0.09948337 0.49590461 -0.25700432 0.38198034 0.2467548 ]]
而且我们看到我们得到了与 scikit
相同的结果
我想在 PC1
和 PC2
的新等级上获得新分数。
我计算了特征值、特征向量和贡献。
现在我想计算新尺度(分数)上的点,以对其应用 K-Means 聚类算法。
每当我尝试通过说 z_new = np.dot(v, vectors)
(使用 v = np.cov(x)
)来计算它时,我得到一个错误的分数,PC1 为 [[14. -2. -2. -1. -0. 0. 0. -0. -0. 0. 0. -0. 0. 0.]
,PC2 为 [-3. -1. -2. -1. -0. -0. 0. 0. 0. -0. -0. 0. -0. -0.]
。正确的分数分数(使用 SciKit 的 PCA() 函数计算)应该是 PC1: [ 4 4 -6 3 1 -5]
和 PC2: [ 0 -3 1 -1 5 -4]
这是我的代码:
dataset = pd.read_csv("cands_dataset.csv")
x = dataset.iloc[:, 1:].values
m = x.mean(axis=1);
for i in range(len(x)):
x[i] = x[i] - m[i]
z = x / np.std(x)
v = np.cov(x)
values, vectors = np.linalg.eig(v)
d = np.diag(values)
p = vectors
z_new = np.dot(v, p) # <--- Here is where I get the new scores
z_new = np.round(z_new,0).real
print(z_new)
我得到的结果:
[[14. -2. -2. -1. -0. 0. 0. -0. -0. 0. 0. -0. 0. 0.]
[-3. -1. -2. -1. -0. -0. 0. 0. 0. -0. -0. 0. -0. -0.]
[-4. -0. 3. 3. 0. 0. 0. 0. 0. -0. -0. 0. -0. -0.]
[ 2. -1. -2. -1. 0. -0. 0. -0. -0. 0. 0. -0. 0. 0.]
[-2. -1. 8. -3. -0. -0. -0. 0. 0. -0. -0. -0. 0. 0.]
[-3. 2. -1. 2. -0. 0. 0. 0. 0. -0. -0. 0. -0. -0.]
[ 3. -1. -3. -1. 0. -0. 0. -0. -0. 0. 0. -0. 0. 0.]
[11. 6. 4. 4. -0. 0. -0. -0. -0. 0. 0. -0. 0. 0.]
[ 5. -8. 6. -1. 0. 0. -0. 0. 0. 0. 0. -0. 0. 0.]
[-1. -1. -1. 1. 0. -0. 0. 0. 0. 0. 0. 0. -0. -0.]
[ 5. 7. 1. -1. 0. -0. -0. -0. -0. 0. 0. -0. -0. -0.]
[12. -6. -1. 2. 0. 0. 0. -0. -0. 0. 0. -0. 0. 0.]
[ 3. 6. 0. 0. 0. -0. -0. -0. -0. 0. 0. 0. -0. -0.]
[ 5. 5. -0. -4. -0. -0. -0. -0. -0. 0. 0. -0. 0. 0.]]
数据集(由评论请求):
在我看来,您有 6 个 14 维的样本。 PCA过程如下:
1。去掉均值
从以下数据开始:
data = np.array([[10, 9, 1, 7, 5, 3],
[10, 8,10, 8, 8,10],
[ 4, 6, 8, 9, 8, 9],
[ 9, 9, 6, 6, 8, 7],
[ 4, 9,10, 9, 5, 5],
[ 7, 6, 9, 9,10,10],
[10, 9, 6, 6, 8, 7],
[ 5, 4, 2,10, 9, 1],
[ 4,10, 4, 9, 2, 6],
[ 8, 7, 7, 7, 7, 9],
[ 5, 5, 6, 6, 9, 1],
[ 9,10, 1, 9, 5, 6],
[ 7, 6, 6, 6,10, 4],
[10, 9, 9, 7, 9, 4]])
我们可以通过以下方式去除均值:
centered_data = data - np.mean(data, axis=1)[:, None]
2。创建协方差矩阵
可按如下方式进行:
covar = np.cov(centered_data)
3。获取主成分
这可以使用协方差矩阵的特征值分解来完成
eigen_vals, eigen_vecs = np.linalg.eig(covar)
eigen_vals, eigen_vecs = np.real(eigen_vals), np.real(eigen_vecs)
4。降维
现在我们可以通过选择具有最高匹配特征值(方差)的两个PC来进行降维。在您的示例中,您需要 2 维,因此我们采用两台主要 PC:
eigen_vals =
array([ 3.34998559e+01, 2.26499704e+01, 1.54115835e+01, 9.13166675e+00,
1.27359015e+00, -3.10462438e-15, -1.04740277e-15, -1.04740277e-15,
-2.21443036e-16, 9.33811755e-18, 9.33811755e-18, 6.52780501e-16,
6.52780501e-16, 5.26538300e-16])
可以看出前两个特征值最高:
eigen_vals[:2] = array([33.49985588, 22.64997038])
因此,我们可以将前两台PC上的数据投影如下:
projected_data = eigen_vecs[:, :2].T.dot(centered_data)
现在可以打散了,我们可以看到14维降为2维:
PC1 = [0.59123632, -0.10134531, -0.20795954, 0.1596049 , -0.07354629, 0.19588723, 0.19151677, 0.33847213, 0.22330841, -0.03466414, 0.1001646 , 0.52913917, 0.09633029, 0.16141852]
PC2 = [-0.07551251, -0.07531288, 0.0188486 , -0.01280896, -0.07309957, 0.12354371, -0.01170589, 0.49672196, -0.43813664, -0.09948337, 0.49590461, -0.25700432, 0.38198034, 0.2467548 ]
一般分析
自从我们做了 PCA 之后,现在每个维度都有正交方差(对角协方差矩阵)。为了更好地理解降维的可能性,我们可以看到数据的总方差是如何分布在不同维度上的。这可以通过特征值圆顶:
var_dim_contribution = eigen_vals / np.sum(eigen_vals)
绘制此结果:
我们可以在这里看到,使用 2 个主要 PC,我们可以描述 ~67% 的方差。添加第三个维度将使我们接近 90% 的方差。这是 14 的一个很好的减少。这在累积方差图中看起来更好。
var_cumulative_contribution = np.cumsum(eigen_vals / np.sum(eigen_vals))
与sklearn的比较
与 sklearn.decomposition.PCA
比较时,我们得到以下结果:
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pca.fit(centered_data.T)
print(pca.explained_variance_ratio_) # [0.40870097 0.27633148]
print(pca.explained_variance_) # [33.49985588 22.64997038]
我们看到我们得到了与手动计算相同的解释方差和方差值,此外,结果 PC 为:
print(pca.components_)
[[-0.59123632 0.10134531 0.20795954 -0.1596049 0.07354629 0.19588723 0.19151677 -0.33847213 -0.22330841 0.03466414 -0.1001646 -0.52913917 -0.09633029 -0.16141852]
[-0.07551251 -0.07531288 0.0188486 -0.01280896 -0.07309957 0.12354371 -0.01170589 0.49672196 -0.43813664 -0.09948337 0.49590461 -0.25700432 0.38198034 0.2467548 ]]
而且我们看到我们得到了与 scikit