gpt4 book ai didi

Scikit-Learn PCA

转载 作者:行者123 更新时间:2023-12-03 23:40:53 30 4
gpt4 key购买 nike

我正在使用来自 here 的输入数据(见第 3.1 节)。

我正在尝试使用 scikit-learn 重现它们的协方差矩阵、特征值和特征向量。但是,我无法重现数据源中显示的结果。我也在别处看到过这个输入数据,但我无法辨别这是 scikit-learn、我的步骤还是数据源的问题。

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.0,1.6],
[1.0,1.1],
[1.5,1.6],
[1.1,0.9],
])

centered_data = data-data.mean(axis=0)
pca = PCA()
pca.fit(centered_data)
print(pca.get_covariance()) #Covariance Matrix

array([[ 0.5549, 0.5539],
[ 0.5539, 0.6449]])

print(pca.explained_variance_ratio_) #Eigenvalues (normalized)

[ 0.96318131 0.03681869]

print(pca.components_) #Eigenvectors

[[-0.6778734 -0.73517866]
[ 0.73517866 -0.6778734 ]]

令人惊讶的是,这些预测与来自上述数据源的结果相匹配。
print(pca.transform(centered_data)) #Projections

array([[-0.82797019, 0.17511531],
[ 1.77758033, -0.14285723],
[-0.99219749, -0.38437499],
[-0.27421042, -0.13041721],
[-1.67580142, 0.20949846],
[-0.9129491 , -0.17528244],
[ 0.09910944, 0.3498247 ],
[ 1.14457216, -0.04641726],
[ 0.43804614, -0.01776463],
[ 1.22382056, 0.16267529]])

这是我不明白的地方:
  • 为什么协方差矩阵不同?
  • 更新 :如何从 scikit-learn 中获取尚未归一化的特征值?
  • 最佳答案

    此数据的正确协方差矩阵:

    numpy.cov(data.transpose())

    array([[ 0.61655556,  0.61544444],
    [ 0.61544444, 0.71655556]])


    有偏差(即“不正确”,使用错误的归一化项,并低估数据集中的方差)协方差矩阵:
    numpy.cov(data.transpose(), bias=1)

    array([[ 0.5549,  0.5539],
    [ 0.5539, 0.6449]])


    Numpy 知道您必须将数据居中 - 所以您不需要 centered_data

    PCA 分量不是 1:1 的特征值。

    正确的特征值分解:
    numpy.linalg.eig(numpy.cov(data.transpose()))

    (array([ 0.0490834 ,  1.28402771]),
    array([[-0.73517866, -0.6778734 ],
    [ 0.6778734 , -0.73517866]]))


    使用有偏估计会产生不同的特征值(再次低估方差),但相同的特征向量:

    (array([ 0.04417506,  1.15562494]), ...


    请注意,特征向量尚未按最大特征值排序。

    正如 pca.explained_variance_ratio_ 的名称所示,这些不是特征值。他们是比例。如果我们采用(有偏的、低估的)特征值,并将它们归一化为总和为 1,我们得到
    s/sum(s)

    array([ 0.03681869,  0.96318131])


    此外,scipy 的 pca.transform 方法显然不适用缩放。恕我直言,在使用 PCA 时,缩放每个组件以具有单位方差也很常见。这显然不适用于此输出。然后结果将是(两列交换,我没有费心去改变这个)
    s, e = numpy.linalg.eig(numpy.cov(data.transpose()))
    o=numpy.argsort(s)[::-1]
    (data-mean).dot(e[:,o]) / numpy.sqrt(s[o])

    array([[-0.73068047, -0.79041795],
    [ 1.56870773, 0.64481466],
    [-0.87561043, 1.73495337],
    [-0.24198963, 0.58866414],
    [-1.47888824, -0.94561319],
    [-0.80567404, 0.79117236],
    [ 0.08746369, -1.57900372],
    [ 1.01008049, 0.20951358],
    [ 0.38657401, 0.08018421],
    [ 1.08001688, -0.73426743]])


    (如您所见,PCA 在 numpy 中只有三行,因此您不需要为此使用函数。)

    为什么我认为这是正确的结果?因为结果数据集具有协方差矩阵是单位矩阵(舍入误差除外)的属性。
    没有缩放,协方差矩阵是 numpy.diag(s[o]) 。但也有人可能会争辩说,通过应用缩放,我“丢失”了方差信息,否则会保留这些信息。

    在我看来, scipy 使用了错误的(有偏差的)协方差。 numpy 是正确的。

    但通常情况下,这并不重要。在上述比率中,偏置抵消。如果你有一个大数据集,使用朴素的 1/n 和无偏见的 1/(n-1) 之间的差异最终变得可以忽略不计。但这种差异实际上是零 CPU 成本,因此您不妨使用无偏方差估计。

    关于Scikit-Learn PCA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27699545/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com