首页 > 编程语言 >Python实现核主成分分析(KPCA)降维算法

Python实现核主成分分析(KPCA)降维算法

时间:2024-08-26 18:53:59浏览次数:12  
标签:kernel 核主 Python self 矩阵 降维 KPCA 数据

目录

Python实现核主成分分析(KPCA)降维算法的博客

引言

在高维数据分析中,主成分分析(PCA)是一种常用的线性降维技术。然而,PCA的局限在于它只能发现线性结构,对于非线性分布的数据效果不佳。为了处理非线性数据,我们可以通过引入核函数的方式来扩展PCA的能力,这就是核主成分分析(Kernel PCA,简称KPCA)。KPCA通过将数据映射到高维空间来捕捉数据的非线性结构,然后在高维空间中应用PCA进行降维。本文将详细介绍KPCA算法的原理,并通过Python实现该算法,展示其在实际场景中的应用。

KPCA算法原理

核主成分分析的核心思想是利用核技巧(Kernel Trick)将数据从原始空间映射到高维特征空间,在高维空间中应用PCA来提取主要成分,从而实现降维。核技巧的引入,使得KPCA能够捕捉数据中的非线性结构,这使得KPCA比传统的PCA更为灵活和强大。

1. 核函数与核技巧

核函数是KPCA的核心。常见的核函数包括:

  • 线性核: k ( x , y ) = x T y k(x, y) = x^T y k(x,y)=xTy
  • 多项式核: k ( x , y ) = ( x T y + c ) d k(x, y) = (x^T y + c)^d k(x,y)=(xTy+c)d
  • 高斯径向基核(RBF核): k ( x , y ) = exp ⁡ ( − ∥ x − y ∥ 2 2 σ 2 ) k(x, y) = \exp\left(-\frac{\|x - y\|^2}{2\sigma^2}\right) k(x,y)=exp(−2σ2∥x−y∥2​)

核技巧的思想是通过核函数计算输入空间中点之间的相似度,而不显式地计算映射后的高维特征。这种方法避免了直接处理高维数据带来的计算复杂度。

2. 中心化核矩阵

在进行PCA之前,需要对核矩阵进行中心化。假设核矩阵为 K K K,则中心化后的核矩阵 K ′ K' K′可以通过以下公式得到:

K ′ = K − 1 n K − K 1 n + 1 n K 1 n K' = K - \mathbf{1}_n K - K \mathbf{1}_n + \mathbf{1}_n K \mathbf{1}_n K′=K−1n​K−K1n​+1n​K1n​

其中, 1 n \mathbf{1}_n 1n​是一个所有元素均为 1 n \frac{1}{n} n1​的矩阵, n n n是样本数量。

3. 特征分解

在得到中心化的核矩阵后,KPCA通过对其进行特征分解,提取前 d d d 个特征向量作为主要成分。这些特征向量对应的特征值表示了相应主成分的方差。

Python中的KPCA实现

接下来我们将通过Python实现KPCA算法,并将其封装到一个面向对象的类中,方便复用。

1. 创建KPCA类
import numpy as np
from scipy.linalg import eigh

class KernelPCA:
    def __init__(self, n_components=2, kernel='rbf', gamma=None, degree=3, coef0=1):
        """
        初始化KPCA类
        :param n_components: 降维后的维度
        :param kernel: 核函数类型 ('linear', 'poly', 'rbf')
        :param gamma: RBF核函数中的γ参数
        :param degree: 多项式核中的度数
        :param coef0: 多项式核中的常数项
        """
        self.n_components = n_components
        self.kernel = kernel
        self.gamma = gamma
        self.degree = degree
        self.coef0 = coef0
        self.alphas = None  # 特征向量
        self.lambdas = None  # 特征值
        self.X_fit = None  # 训练数据

    def _kernel_function(self, X, Y):
        """
        计算核函数
        :param X: 输入数据矩阵X
        :param Y: 输入数据矩阵Y
        :return: 核矩阵
        """
        if self.kernel == 'linear':
            return np.dot(X, Y.T)
        elif self.kernel == 'poly':
            return (np.dot(X, Y.T) + self.coef0) ** self.degree
        elif self.kernel == 'rbf':
            if self.gamma is None:
                self.gamma = 1.0 / X.shape[1]
            K = -2 * np.dot(X, Y.T)
            K += np.sum(X**2, axis=1)[:, np.newaxis]
            K += np.sum(Y**2, axis=1)
            return np.exp(-self.gamma * K)
        else:
            raise ValueError("未定义的核函数类型。")

    def fit(self, X):
        """
        训练KPCA模型
        :param X: 训练数据
        """
        self.X_fit = X
        K = self._kernel_function(X, X)
        
        # 中心化核矩阵
        n_samples = K.shape[0]
        one_n = np.ones((n_samples, n_samples)) / n_samples
        K = K - one_n @ K - K @ one_n + one_n @ K @ one_n
        
        # 特征分解
        eigvals, eigvecs = eigh(K)
        eigvals = eigvals[::-1]
        eigvecs = eigvecs[:, ::-1]
        
        self.alphas = eigvecs[:, :self.n_components]
        self.lambdas = eigvals[:self.n_components]

    def transform(self, X):
        """
        将新数据映射到KPCA的特征空间
        :param X: 输入数据矩阵
        :return: 映射后的低维数据矩阵
        """
        K = self._kernel_function(X, self.X_fit)
        return K @ self.alphas / self.lambdas

    def fit_transform(self, X):
        """
        训练KPCA模型并返回降维后的数据
        :param X: 输入数据矩阵
        :return: 映射后的低维数据矩阵
        """
        self.fit(X)
        return self.transform(X)
2. 在瑞士卷数据集上应用KPCA

我们将使用瑞士卷数据集来展示KPCA的效果,该数据集是一个非线性结构的三维数据集。我们将采用RBF核来对数据进行降维。

from sklearn.datasets import make_swiss_roll
import matplotlib.pyplot as plt

# 生成瑞士卷数据集
X, color = make_swiss_roll(n_samples=1000, noise=0.2)

# 使用KPCA进行降维
kpca = KernelPCA(n_components=2, kernel='rbf', gamma=0.1)
X_kpca = kpca.fit_transform(X)

# 绘制降维前后的数据分布
fig = plt.figure(figsize=(12, 6))

ax = fig.add_subplot(121, projection='3d')
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=color, cmap=plt.cm.Spectral)
ax.set_title("Original 3D data")

ax = fig.add_subplot(122)
ax.scatter(X_kpca[:, 0], X_kpca[:, 1], c=color, cmap=plt.cm.Spectral)
ax.set_title("2D embedding by KPCA")

plt.show()
3. 结果分析

通过在瑞士卷数据集上的实验,我们可以看到KPCA成功地将数据从三维映射到二维,同时保留了数据的非线性结构。与传统PCA不同,KPCA能够有效地捕捉数据的曲面结构,使得降维后的数据分布更加紧凑和清晰。

总结

核主成分分析(KPCA)是一种强大的非线性降维工具,通过引入核技巧,KPCA可以将数据映射到高维特征空间并在该空间中应用PCA,从而捕捉数据的非线性结构。在本文中,我们详细介绍了KPCA的原理,并通过Python实现了KPCA算法的面向对象版本。此外,我们还展示了KPCA在瑞士卷数据集上的应用,验证了其有效性和实用性。KPCA适用于各种高维和非线性数据的降维需求,是数据预处理和特征提取的重要工具。

标签:kernel,核主,Python,self,矩阵,降维,KPCA,数据
From: https://blog.csdn.net/qq_42568323/article/details/141571097

相关文章

  • python学习—redis入门,新手小白轻松学
    目录一.安装redis-py库二.连接redis服务器三.基本操作(1)字符串1.一次添加一个键值对2.一次添加多个键值对3.设置存在秒数4.设置过期时间(秒)5.设置存在天数 完整代码(2)列表1.添加数据2.从右侧删除数据3.从左侧删除数据4.获取列表的长度5.根据索引查找数......
  • 基于Python语言快速批量运行DSSAT模型及交叉融合、扩展
    随着数字农业和智慧农业的发展,基于过程的作物生长模型(Process-basedCropGrowthSimulationModel)在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农业碳中和、农田固碳减排等领域扮演着越来越重要的作用。DecisionSupportSystemsforAgrotechnolog......
  • 计算机毕业设计选题-基于python的医院预约挂号系统
    精彩专栏推荐订阅:在下方专栏......
  • PyInstaller 打包 Python 程序
    使用PyInstaller打包Python程序是一个相对简单直接的过程。PyInstaller允许你将Python程序及其所有依赖项打包成一个独立的可执行文件,这样用户就可以在没有安装Python解释器的系统上运行你的程序了。以下是一个基本的步骤指南,用于使用PyInstaller打包Python程......
  • Python 多线程编程技巧举例
    Python多线程(Multithreading)是一种编程技术,允许在同一程序中同时执行多个独立的逻辑流,即线程。每个线程都有自己的程序计数器、栈空间和局部变量,它们共享同一进程的全局变量、文件描述符和其他系统资源。线程是操作系统调度的基本单位,能够在单个进程中并发运行,从而实现任务......
  • Python未来五年的风口,抓住了未来就是你的!
    Python在未来五年的风口依然强劲,这主要得益于其在多个领域的广泛应用和持续增长的需求。以下是对Python未来五年风口的详细分析:1.人工智能与大数据领域主导地位:Python在人工智能(AI)和大数据领域已经占据主导地位,并且这一趋势在未来五年将持续加强。随着AI技术的不断发展和普......
  • 学会Python基础制作简单计算器(附源码)
    在Python中,我们可以使用tkinter库来制作一个具有图形用户界面的简单计算器。以下是一个完整的教程,包括设计思路、代码实现以及运行效果说明。设计思路在设计计算器程序时,我们需要考虑以下几个方面:界面设计:计算器需要一个简单的用户界面,用户可以通过该界面输入数字和运算符......
  • 数模国赛冲刺 | 数据预处理方法合集(特征工程、数据降维、数据划分、数据平衡)
    ​数据预处理方法合集(特征工程、数据降维、数据划分、数据平衡)本文继续介绍数据预处理中的特征工程、数据降维、数据划分、数据平衡的内容,接下来我们将详细地介绍具体的方法,文末可获得预处理方法合集PDF!目录特征工程特征选择(FeatureSelection)特征提取数据降维线性降......
  • Python学习-[numpy库]-初级
    创建数组:np.array([1,2,3,4,5])使用zeros创建全零数组:np.zeros((3,2))代表一个三行二列的数组:array([0.,0.], [0.,0.], [0.,0.])获取数组的尺寸:a=np.zeros((3,2))a.shape#输出结果为:(3,2)第一个数据展示数组第一维的长度,第二个数据展示数......
  • Python分布式任务处理库之dramatiq使用详解
    概要在现代Web应用和数据处理任务中,异步任务处理是一个至关重要的部分。Dramatiq是一个用于分布式任务处理的Python库,旨在提供简单、可靠的任务队列解决方案。与其他任务队列库相比,Dramatiq更加轻量级,且易于上手。它的设计目标是帮助开发者轻松地将耗时的任务放到后台......