主成分分析(PCA)

主成分分析(Principal Component Analysis, PCA)是一种统计技术,主要用于简化数据集。通过将原始数据投影到较低维的空间,PCA帮助我们发现数据中的主要趋势和结构。本文将介绍PCA的基本概念、应用及其在数据科学中的重要性。

一、PCA的基本概念

PCA的核心思想是通过线性变换,将数据从高维空间转换到低维空间,同时尽可能保留数据的主要特征。具体来说,PCA通过以下几个步骤实现:

1. 数据中心化

在进行PCA之前,我们首先需要对数据进行中心化处理,即将每个特征的均值移至零。这是因为PCA依赖于协方差矩阵,而中心化数据可以确保协方差矩阵更好地反映数据的真实结构。

设原始数据矩阵为 X(维度为 n \times p,其中 n 是样本数, p 是特征数),中心化后的数据矩阵 ​ X_{centered}计算如下:

X_{centered}=X-\mu

其中, \mu 是数据矩阵 X 的均值向量。

2. 计算协方差矩阵

协方差矩阵用于衡量特征之间的相关性。协方差矩阵 \sum 的计算公式如下:

\sum = \frac{1}{n-1}X^{T}X_{centered}

3. 计算特征值和特征向量

协方差矩阵的特征值和特征向量用于确定数据的主要方向和重要性。通过计算协方差矩阵的特征值和特征向量,我们可以找到数据在不同方向上的方差。

特征值(eigenvalue)表示主成分的重要性,而特征向量(eigenvector)表示主成分的方向。设协方差矩阵的特征值为 \lambda _{1},\lambda _{2},...,\lambda _{p}(从大到小排列),对应的特征向量为 \nu _{1},\nu _{2},...,\nu _{p},

4. 选择主成分

选择前 k 个最大的特征值对应的特征向量,构成新的低维空间。这里的 k 通常是通过累积解释方差(cumulative explained variance)来确定的。

累积解释方差定义为:

Explained\ Variance=\frac{\sum_{i=1}^{k}\lambda_{i}}{\sum_{i=1}^{p}\lambda_{i}}

当累积解释方差达到某个阈值(例如95%)时,我们认为选取的主成分已经足够解释数据中的大部分信息。

5. 数据投影

将原始数据投影到选择的主成分方向上,得到降维后的数据。降维后的数据矩阵 ZZZ 计算如下:

Z=X_{centered}\cdot V_{k}

其中, V_{k}​ 是包含前 k 个特征向量的矩阵。

6. PCA的数学直观理解

PCA的目标是找到数据在新的坐标系下的最优表示,使得数据在该坐标系下的投影方差最大化。通过选择最大的特征值对应的特征向量,PCA能够最大限度地保留数据的主要变化趋势,从而实现降维和去噪的目的。

二、PCA实践

代码实现

import numpy as np
import matplotlib.pyplot as plt
from sklearn .datasets import make_blobs
from sklearn.decomposition import PCA

def create_data(num_samples=100, num_features=2, centers=2, random_state=42):
    X, y = make_blobs(n_samples=num_samples,  n_features=num_features, centers=centers, random_state=random_state)
    return X, y

def show_data(X, y):
    plt.scatter(X[:, 0], X[:, 1], c=y)
    plt.show()

def visualize_svm(X, y, svm):
    def get_hyperplane_value(x, w, b, offset):
        return (-w[0] * x + b + offset) / w[1]

    plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)

    ax = plt.gca()
    xlim = ax.get_xlim()
    ylim = ax.get_ylim()

    x = np.linspace(xlim[0], xlim[1], 30)
    y_pred = get_hyperplane_value(x, svm.w, svm.b, 0)
    margin_plus = get_hyperplane_value(x, svm.w, svm.b, 1)
    margin_minus = get_hyperplane_value(x, svm.w, svm.b, -1)

    plt.plot(x, y_pred, 'k-')
    plt.plot(x, margin_plus, 'k--')
    plt.plot(x, margin_minus, 'k--')

    plt.legend()
    plt.show()

class SVM:
    def __init__(self, lr=0.001, lambda_param=0.01, num_step=1000):
        '''

        :param lr: 学习率
        :param lambda_param: 正则化参数
        :param num_step: 步数
        '''
        self.lr = lr
        self.lambda_param = lambda_param
        self.num_step = num_step
        self.w = None
        self.b = None

    def fit(self, X, y):
        #初始化权重和偏置
        num_samples, num_features = X.shape
        self.w = np.zeros(num_features)
        self.b = 0

        #将标签从 0/1 转换为 -1/1。SVM 要求标签为 -1 和 1。
        y_ = np.where(y <= 0, -1, 1)

        #梯度下降
        for _ in range(self.num_step):
            for idx, x_i in enumerate(X):
                #检查样本是否满足分类条件,更新权重和偏置
                if y_[idx] * (np.dot(x_i, self.w) - self.b) >= 1:
                    self.w -= self.lr * (2 * self.lambda_param * self.w)
                else:
                    self.w -= self.lr * (2 * self.lambda_param * self.w - np.dot(x_i, y_[idx]))
                    self.b -= self.lr * y_[idx]

    def predict(self, X):
        pred = np.dot(X, self.w) + self.b
        return np.sign(pred)


X, y = create_data(num_features=10)
y = np.where(y==0, -1, 1)
print(X.shape)
pca = PCA(n_components=2)
X = pca.fit_transform(X)
show_data(X, y)
svm = SVM()
svm.fit(X, y)
visualize_svm(X, y, svm)

生成的数据集的特征维度为10,用PCA将数据集的特征维度降维为2。

生成的数据集形状:

PCA降维后:

之后用SVM(支持向量机)对数据集进行分类

运行结果

三、总结

PCA可以简化数据,减少维度,提高计算效率。在上面的实践中PCA把样本特征维度为10的数据集降维到2,大大简化了后面的SVM相关的计算。在保留主要信息的同时,减少数据冗余,让降维后的数据仍然能正确的分类。

但不足的是PCA是一种线性方法,不能处理非线性数据。特征向量的选择可能会导致信息丢失。对数据的缩放和中心化要求较高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值