利用鸢尾花数据集介绍PCA算法

PCA:

主成分分析(PCA, Principal Component Analysis)是一种常用的数据降维技术,它可以将高维数据转换为较低维数据,同时尽可能保留数据的主要信息。PCA通过寻找数据的主要方向,即方差最大的方向,来完成降维。PCA的主要思想是将n维特征映射到k维上,这k维是全新的正交特征也被称为主成分,是在原有n维特征的基础上重新构造出来的k维特征。

降维:

  • 降维就是一种对高维度特征数据预处理方法。降维是将高维度的数据保留下最重要的一些特征,去除噪声和不重要的特征,从而实现提升数据处理速度的目的。在实际的生产和应用中,降维在一定的信息损失范围内,可以为我们节省大量的时间和成本。降维也成为应用非常广泛的数据预处理方法。

  • 数据降维,直观地好处是维度降低了,便于计算和可视化,其更深层次的意义在于有效信息的提取综合及无用信息的摈弃。

擒贼先擒王: 

  1. PCA(Principal Components Analysis)即主成分分析,是图像处理中经常用到的降维方法。它不仅仅是对高维数据进行降维,更重要的是经过降维去除了噪声,发现了数据中的模式。PCA把原先的n个特征用数目更少的m个特征取代,新特征是旧特征的线性组合,这些线性组合最大化样本方差,尽量使新的m个特征互不相关。

  2. PCA方法通过消除数据的相关性,找到一个空间,使得各个类别的数据在该空间上能够很好地分离。在下图中,有一些离散的二维分布点,其中棕色表示一类集合,黄色表示另一类集合,假设这两个类别可以用特征X和特征Y进行描述,由图可知,在X轴和Y轴上这两个类别的投影是重叠的,表明这些点的两个特征X和Y没有表现出突出的识别性。但是两个类的投影在Z轴上区分度较大,显示出很好的识别性。PCA就是这样的一个工具,它可以产生非常好的降维效果。

示例:

二维数据降到一维:

PCA算法在二维数据集上的可视化图示,展示了如何将数据从二维降维到一维。图中显示了原始数据点、主成分向量以及数据点投影到第一个主成分上的过程。 

使用numpy实现PCA:

import numpy as np

# 定义PCA函数
def pca(X, num_components):
    # 1. 数据标准化(均值归一化)
    X_meaned = X - np.mean(X, axis=0)

    # 2. 计算协方差矩阵
    cov_matrix = np.cov(X_meaned, rowvar=False)

    # 3. 计算协方差矩阵的特征值和特征向量
    eigen_values, eigen_vectors = np.linalg.eigh(cov_matrix)

    # 4. 对特征值排序
    sorted_index = np.argsort(eigen_values)[::-1]
    sorted_eigenvalue = eigen_values[sorted_index]
    sorted_eigenvectors = eigen_vectors[:, sorted_index]

    # 5. 选择前num_components个特征向量(主成分)
    eigenvector_subset = sorted_eigenvectors[:, 0:num_components]

    # 6. 将数据投影到新空间
    X_reduced = np.dot(X_meaned, eigenvector_subset)

    return X_reduced, sorted_eigenvalue, sorted_eigenvectors

# 示例数据
X = 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]])

# 执行PCA
X_reduced, eigen_values, eigen_vectors = pca(X, 1)

print("降维后的数据:\n", X_reduced)
print("特征值:\n", eigen_values)
print("特征向量:\n", eigen_vectors)

运行结果分析:  

降维后的数据:
 [[ 0.82797019]
 [-1.77758033]
 [ 0.99219749]
 [ 0.27421042]
 [ 1.67580142]
 [ 0.9129491 ]
 [-0.09910944]
 [-1.14457216]
 [-0.43804614]
 [-1.22382056]]

特征值:
 [0.0490834  1.28402771]

特征向量:
 [[-0.73517866 -0.6778734 ]
 [-0.6778734   0.73517866]]

 解释

  1. 降维后的数据:原本二维数据集现在被降到了1维。每个样本在新的主成分方向上都有一个值,数据被映射到了这个新的空间。
  2. 特征值:两个特征值中,1.28402771对应的主成分解释了数据中的大部分方差(信息量)。特征值越大,表明该方向上的方差越大,信息量越多。
  3. 特征向量:每个特征向量表示PCA找到的主成分方向。第一个向量是方向,它解释了最多的方差。

 使用sklearn实现PCA:

from sklearn.decomposition import PCA

pca = PCA(n_components=1)
X_reduced_sklearn = pca.fit_transform(X)
print("降维后的数据:\n", X_reduced_sklearn)
print("解释方差比:\n", pca.explained_variance_ratio_)

运行结果分析: 

降维后的数据:
 [[-0.82797019]
 [ 1.77758033]
 [-0.99219749]
 [-0.27421042]
 [-1.67580142]
 [-0.9129491 ]
 [ 0.09910944]
 [ 1.14457216]
 [ 0.43804614]
 [ 1.22382056]]
解释方差比:
 [0.96318131]

 

解释

  1. 降维后的数据sklearn的结果和numpy的实现相同。
  2. 解释方差比:第一个主成分解释了大约96.32%的数据方差。这意味着几乎所有的主要信息都保留在这个一维空间中。

 

三维数据降到二维:

使用numpy实现PCA:

import numpy as np

# 定义PCA函数
def pca(X, num_components):
    # 1. 数据标准化(均值归一化)
    X_meaned = X - np.mean(X, axis=0)

    # 2. 计算协方差矩阵
    cov_matrix = np.cov(X_meaned, rowvar=False)

    # 3. 计算协方差矩阵的特征值和特征向量
    eigen_values, eigen_vectors = np.linalg.eigh(cov_matrix)

    # 4. 对特征值排序
    sorted_index = np.argsort(eigen_values)[::-1]
    sorted_eigenvalue = eigen_values[sorted_index]
    sorted_eigenvectors = eigen_vectors[:, sorted_index]

    # 5. 选择前num_components个特征向量(主成分)
    eigenvector_subset = sorted_eigenvectors[:, 0:num_components]

    # 6. 将数据投影到新空间
    X_reduced = np.dot(X_meaned, eigenvector_subset)

    return X_reduced, sorted_eigenvalue, sorted_eigenvectors

# 示例数据
X_3D = np.array([[2.5, 2.4, 1.5],
                 [0.5, 0.7, 0.9],
                 [2.2, 2.9, 2.1],
                 [1.9, 2.2, 1.8],
                 [3.1, 3.0, 2.9],
                 [2.3, 2.7, 1.9],
                 [2.0, 1.6, 1.5],
                 [1.0, 1.1, 0.6],
                 [1.5, 1.6, 1.1],
                 [1.1, 0.9, 0.7]])
X_reduced_3D, eigen_values_3D, eigen_vectors_3D = pca(X_3D, 2)
print("降维后的数据:\n", X_reduced_3D)
print("特征值:\n", eigen_values_3D)
print("特征向量:\n", eigen_vectors_3D)

 运行结果分析:

降维后的数据:
 [[-0.70889453 -0.46108745]
 [ 1.83196957  0.42891188]
 [-1.16005691  0.12212606]
 [-0.38989499  0.15041607]
 [-2.15763363  0.25019311]
 [-0.98864791 -0.06737495]
 [ 0.08538904 -0.06151523]
 [ 1.4447941  -0.15563484]
 [ 0.58162174 -0.10471513]
 [ 1.46135351 -0.10131952]]
特征值:
 [1.7286401  0.06116445 0.04775101]
特征向量:
 [[-0.57953314 -0.5637771  -0.58846981]
 [-0.63064625 -0.14710458  0.76200102]
 [-0.51616533  0.81272112 -0.27029193]]

解释:

  • 降维后的数据:原本三维的数据集现在降到了二维,表示数据在新的两个主成分方向上的投影。
  • 特征值:第一个特征值1.7286401远大于另外两个,意味着第一个主成分解释了绝大部分的数据方差。第二个主成分解释了少量的方差,而第三个几乎没有方差,因此可以忽略。
  • 特征向量:这些向量表示主成分的方向,第一个向量是解释方差最多的方向

 使用sklearn实现PCA:

from sklearn.decomposition import PCA

pca_3D = PCA(n_components=2)
X_reduced_3D_sklearn = pca_3D.fit_transform(X_3D)
print("降维后的数据:\n", X_reduced_3D_sklearn)
print("解释方差比:\n", pca_3D.explained_variance_ratio_)

运行结果分析: 

降维后的数据:
 [[ 0.70889453  0.46108745]
 [-1.83196957 -0.42891188]
 [ 1.16005691 -0.12212606]
 [ 0.38989499 -0.15041607]
 [ 2.15763363 -0.25019311]
 [ 0.98864791  0.06737495]
 [-0.08538904  0.06151523]
 [-1.4447941   0.15563484]
 [-0.58162174  0.10471513]
 [-1.46135351  0.10131952]]
解释方差比:
 [0.94072807 0.03328577]

 解释: 

  • 降维后的数据:与numpy的实现结果一致。
  • 解释方差比:两个主成分一共解释了约97.40%的方差,其中第一个主成分解释了绝大部分数据方差(约94.07%),第二个主成分解释了少量方差(约3.30%)。

鸢尾花数据集:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

# 1. 加载数据集
iris = datasets.load_iris()
X = iris.data
y = iris.target
target_names = iris.target_names

# 2. 标准化数据
X_standardized = StandardScaler().fit_transform(X)

# 3. 执行PCA
pca = PCA(n_components=2)  # 选择前两个主成分
X_pca = pca.fit_transform(X_standardized)

# 4. 绘制PCA散点图
plt.figure(figsize=(8, 6))
colors = ['navy', 'turquoise', 'darkorange']
lw = 2

for color, i, target_name in zip(colors, [0, 1, 2], target_names):
    plt.scatter(X_pca[y == i, 0], X_pca[y == i, 1], color=color, alpha=.8, lw=lw,
                label=target_name)

plt.title('PCA of IRIS Dataset')
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.legend(loc='best', shadow=False, scatterpoints=1)
plt.grid()
plt.show()

# 5. 绘制投影图
plt.figure(figsize=(10, 6))
plt.scatter(X_standardized[:, 0], X_standardized[:, 1], alpha=0.5)
plt.quiver(0, 0, pca.components_[0, 0], pca.components_[0, 1], angles='xy', scale_units='xy', scale=1, color='r')
plt.quiver(0, 0, pca.components_[1, 0], pca.components_[1, 1], angles='xy', scale_units='xy', scale=1, color='g')
plt.xlim(-3, 3)
plt.ylim(-3, 3)
plt.title('PCA Projection of IRIS Dataset')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.grid()
plt.show()

# 6. 解释方差图
plt.figure(figsize=(8, 4))
plt.bar(range(1, len(pca.explained_variance_ratio_) + 1), pca.explained_variance_ratio_, alpha=0.7)
plt.ylabel('Explained Variance Ratio')
plt.xlabel('Principal Components')
plt.title('Explained Variance by Principal Components')
plt.xticks(range(1, len(pca.explained_variance_ratio_) + 1))
plt.show()

# 7. 降维效果图
plt.figure(figsize=(8, 6))
plt.scatter(X_pca[:, 0], X_pca[:, 1], alpha=0.7, c=y, edgecolor='k', cmap=plt.cm.Paired)
plt.xlabel('Principal Component 1')
plt.ylabel('Principal Component 2')
plt.title('PCA Result on IRIS Dataset')
plt.colorbar()
plt.grid()
plt.show()

PCA(主成分分析)图示通常包括以下几种代表性的图:

  1. 原始数据点与主成分向量:显示数据点和主成分方向的二维散点图。主成分向量通常以箭头表示,显示数据方差最大的方向。

  2. 数据投影到主成分上的图:显示原始数据点投影到主成分上后的图形,展示如何从高维数据降维到低维空间。

  3. 特征值与主成分的解释方差:条形图或饼图显示各主成分解释的方差比例,帮助理解每个主成分在数据中所占的比重。

  4. 降维后的数据分布:数据在降维后的低维空间中的分布图,通常用于可视化降维效果。

下面是这些图的描述:

  1. 原始数据点与主成分向量

    • 散点图显示原始数据点,主成分方向作为箭头,通常两个主成分向量互相垂直。
  2. 数据投影图

    • 显示数据点如何沿主成分方向投影到低维空间,突出显示主成分方向和投影后的数据点。
  3. 特征值图

    • 条形图或饼图展示每个主成分的解释方差比例,说明主成分对数据总方差的贡献。
  4. 降维后数据分布图

    • 降维后(例如从三维到二维)的数据点分布,通常用散点图展示,显示数据的结构和分布。

PCA散点图:

投影图: 

方差图: 

降维效果图: 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值