机器学习之PCA

在机器学习的数据预处理中,降维是重要环节,PCA主成分分析法是常见降维方法之一。本文介绍了PCA的概念,即寻找使数据方差最大的一维基;阐述了其原理和计算步骤,还给出了代码实现相关内容,同时说明了协方差的意义。

    在机器学习中,数据预处理极为重要,好的数据预处理往往比模型更为关键,数据预处理中降维是相当重要的一个环节。常见的降维方法有很多种,如:SVD奇异值分解法,PCA主成分分析法等,这里主要针对PCA谈谈自己的看法。

PCA概念

    PCA的思想是寻找一个一维基,使得所有数据变换为这个基上的坐标表示后,方差值最大。二维中用协方差表示数据分散程度,设原始数据矩阵 XXX 对应的协方差矩阵为CCC,而 PPP 是一组基按行组成的矩阵,设Y=PXY=PXY=PX,则YYYXXXPPP做基变换后的数据。设YYY的协方差矩阵为DDD,我们推导一下DDDCCC的关系:
D=1n−1YYT=1n−1(PX)(PX)T=1n−1(PXXTPT)=P(1n−1XXT)PT=PCPT \begin{aligned} D &= \frac{1}{n-1}YY^{T} \\ &= \frac{1}{n-1}(PX)(PX)^{T} \\ &= \frac{1}{n-1}(PXX^{T}P^{T}) \\ &= P(\frac{1}{n-1}XX^{T})P^{T} \\ &= PCP^{T} \end{aligned} D=n11YYT=n11(PX)(PX)T=n11(PXXTPT)=P(n11XXT)PT=PCPT
  这样我们就看清楚了,我们要找的 P 是能让原始协方差矩阵对角化的 P。换句话说,优化目标变成了寻找一个矩阵 P,满足PCPTPCP^{T}PCPT是一个对角矩阵,并且对角元素按从大到小依次排列,那么 P 的前 K 行就是要寻找的基,用 P 的前 K 行组成的矩阵乘以 X 就使得 X 从 N 维降到了 K 维并满足上述优化条件。

PCA原理

    PCA算法流程如下:

  1. 中心化,每一个特征都减去各自的平均值(主要是方便计算);
  2. 计算协方差矩阵(二维的是计算方差,多维的计算协方差);
  3. 计算协方差矩阵的特征值和特征向量;
  4. 将特征值从大到小排序;
  5. 保留最大的k个特征向量;
  6. 将数据转换到k个特征向量构成的新坐标系中。
PCA计算步骤

    假设x=(x1,x2,...,xn)Tx=(x_1, x_2, ..., x_n)^Tx=(x1,x2,...,xn)Tnnn维的随机矢量,我们想要降维指k维(0<k<n)0<k<n)0<k<n)则PCA具体计算步骤如下:

  1. 对每个样本进行中心化处理,xi=xi−1n∑i=1nxix_i = x_i - \frac{1}{n} \sum_{i=1}^n x_ixi=xin1i=1nxi
  2. 计算协方差矩阵
    cov(xi,xj)=E[(xi−E(xi))(xj−E(xj))]=1n−1(xi−x‾)(xj−x‾)T \begin{aligned} cov(x_i, x_j) &= E[(x_i - E(x_i))(x_j - E(x_j))] \\ &=\frac{1}{n-1}(x_i - \overline x)(x_j - \overline x)^T \end{aligned} cov(xi,xj)=E[(xiE(xi))(xjE(xj))]=n11(xix)(xjx)T
  3. 计算特征值和特征向量

    这里首先说明一下特征值与特征向量的概念:假设AAAnnn阶方阵,如果存在一个数λ\lambdaλ和非零nnn维向量,使得 Ax=λxAx = \lambda xAx=λx成立,则称 mmm为矩阵AAA的一个特征值,xxx则称为AAA的对应于特征值λ\lambdaλ的特征向量。
    利用 Ax=λxAx = \lambda xAx=λx变换为: ∣A−λE∣x=0|A - \lambda E| x = 0AλEx=0EEEnnn维的单位向量,解出该方程就可以得到特征值 λ\lambdaλ,将λ\lambdaλ带入,则可求出对应的特征向量。

  1. 将特征值进行排序,选出前k个对应的特征向量,即为我们需要的数据。
PCA代码实现
import numpy as np

def func_pca(input, k):
    """
    这里的input默认都是预处理过的,都是数值类型,维度为 m * n
    """
    m, n = input.shape
    if k > n:
        assert "k 必须小于特征维度!"
    # 中心化
    average = np.mean(input, 0)
    input_average = input - average
    # 计算协方差矩阵
    cov_vec = np.cov(input_average.T)
    # 计算协方差也可以按照公式计算
    # cov_vec = 1/(m-1+1e-6) * np.dot(input_average.T, input_average)
    # 求解特征值和特征向量
    feature_val, feature_vec = np.linalg.eig(cov_vec)
    # 获取前 k 个特征向量
    index_val = np.argsort(-feature_val)
    selected_vec = feature_vec[:, index_val[:k]]
    # 获取data
    data = np.dot(input_average, selected_vec)
    return data
    

    这里顺便说一下协方差的意义:

  1. cov(X, Y) > 0时,表示 X 与 Y正相关;
  2. cov(X, Y) < 0时,表示 X 与 Y负相关;
  3. cov(X, Y) = 0时,表示 X 与 Y不相关;

    这里的相关指的是线性相关,并不能得到他们之间的非线性关系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值