首页 > 其他分享 >学习日记_241025_核主成分分析(KPCA)

学习日记_241025_核主成分分析(KPCA)

时间:2024-10-25 22:47:17浏览次数:3  
标签:dims 矩阵 核主 241025 KPCA eig np 中心化 data

前言

提醒:
文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。
其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展及意见建议,欢迎评论区讨论交流。

相关链接:
KPCA算法:从原理到Python代码实现全面解析
在这里插入图片描述

代码抄录源
在这里插入图片描述

文章目录


代码抄录

from sklearn.datasets import load_iris
from sklearn.decomposition import KernelPCA
import numpy as np
import matplotlib.pyplot as plt
from scipy.spatial.distance import pdist, squareform

def sigmiod(x,coef=0.25):
    x=np.dot(x,x.T)
    return np.tanh(coef*x+1)
def linear(x):
    x=np.dot(x,x.T)
    return x
def rbf(x,gamma=15):
    sq_dists=pdist(x,'sqeuclidean')
    mat_sq_dists=squareform(sq_dists)
    return np.exp(-gamma*mat_sq_dists)
def kpca(data,n_dims=2,kernel=rbf):
    K=kernel(data)
    N=K.shape[0]
    one_n=np.ones((N,1))/N
    eig_values,eig_vector=np.linalg.eig(K)
    idx=eig_values.argsort()[::-1]
    eigval=eig_values[idx][:n_dims]
    eigvector=eig_vector[:,idx][:,:n_dims]
    eigval=eigval**0.5
    vi=eigvector/eigval.reshape(-1,n_dims)
    data_n=np.dot(K,vi)
    return data_n

if __name__=='__main__':
    data=load_iris().data
    Y=load_iris().target
    data_1=kpca(data,kernel=rbf)
    sklearn_kpca=KernelPCA(n_components=2,kernel='rbf',gamma=15)
    data_2=sklearn_kpca.fit_transform(data)


    plt.figure(figsize=(10,6))
    plt.subplot(121)
    plt.title('My KPCA')
    plt.scatter(data_1[:,0],data_1[:,1],c=Y)

    plt.subplot(122)
    plt.title('Sklearn KPCA')
    plt.scatter(data_2[:,0],data_2[:,1],c=Y)
    plt.show()

代码分析

数据集介绍

使用sklearn函数库中自带的数据 “from sklearn.datasets import load_iris”
X X X为数据的特征,形状为(150,4):有150条数据,每条数据有4个特征。
Y Y Y为数据的标签,形状为(150,):有150条,三类标签(“setosa”, “versicolor”, 和 “virginica”)。
以下为 X X X与 Y Y Y的表格(只显示了前四组):
在这里插入图片描述
在这里插入图片描述

sigmiod(x,coef=0.25)

def sigmiod(x,coef=0.25):
    x=np.dot(x,x.T)
    return np.tanh(coef*x+1)

sigmoid函数通常用于激活函数,尤其是在神经网络中。它的数学形式是:
在这里插入图片描述
注意到导数与原函数关系:
在这里插入图片描述
其数学图像为:
在这里插入图片描述

源代码没有使用传统的sigmoid函数,而是使用了双曲正切函数(tanh):
在这里插入图片描述
注意到导数与原函数关系:
在这里插入图片描述
其数学图像为:
在这里插入图片描述

def linear(x)

def linear(x):
    x=np.dot(x,x.T)
    return x

代码展示的结果为:
( X X X是一个 m × n m\times n m×n的矩阵,结果 f ( x ) f(x) f(x)是一个 m × m m\times m m×m的矩阵)
在这里插入图片描述
在这里插入图片描述

rbf(x,gamma=15)

def rbf(x,gamma=15):
    sq_dists=pdist(x,'sqeuclidean')
    mat_sq_dists=squareform(sq_dists)
    return np.exp(-gamma*mat_sq_dists)
  1. sq_dists=pdist(x,‘sqeuclidean’);mat_sq_dists=squareform(sq_dists)
    pdist()计算矩阵 X X X中所有成对数据点之间的平方欧几里得距离,squareform()将这些距离转换成对称的距离矩阵
    得到矩阵 m × m m\times m m×m的 D D D矩阵:
    ( D i j D_{ij} Dij​表示矩阵 X X X中第 i i i行和第 j j j行对应的数据点之间的平方欧几里得距离
    在这里插入图片描述
  2. np.exp(-gamma*mat_sq_dists)
    返回值为:
    在这里插入图片描述
    在这里插入图片描述
  3. 关于径向基函数(Radial Basis Function,RBF),常作为核函数,用于机器学习和数据科学中的核方法。以下是该函数的数学表达:
    设 X X X是一个 m × n m\times n m×n的矩阵,其中每一行代表一个 n − n- n−维数据点。
    在这里插入图片描述

关于核主成分析

核主成分分析(Kernel Principal Component Analysis, KPCA)是主成分分析(PCA)的非线性扩展。它通过使用核技巧(kernel trick)将数据映射到更高维的特征空间,在线性空间中进行PCA,从而有效处理非线性数据结构。以下是KPCA的详细步骤:

1. 核技巧

核技巧的核心思想是通过一个非线性映射 ϕ \phi ϕ 将原始数据从输入空间映射到一个更高维甚至是无限维的特征空间。在这个特征空间中,数据可能呈现线性结构。

2. 选择核函数

常用的核函数包括:

  • 线性核: K ( x , y ) = x ⋅ y K(x, y) = x \cdot y K(x,y)=x⋅y
  • 多项式核: K ( x , y ) = ( x ⋅ y + c ) d K(x, y) = (x \cdot y + c)^d K(x,y)=(x⋅y+c)d
  • 高斯核(RBF核): K ( x , y ) = exp ⁡ ( − ∥ x − y ∥ 2 2 σ 2 ) K(x, y) = \exp(-\frac{\|x - y\|^2}{2\sigma^2}) K(x,y)=exp(−2σ2∥x−y∥2​)
  • sigmoid核: K ( x , y ) = tanh ⁡ ( α x ⋅ y + c ) K(x, y) = \tanh(\alpha x \cdot y + c) K(x,y)=tanh(αx⋅y+c)

3. 构建核矩阵

对于给定的数据集 { x 1 , x 2 , … , x n } \{x_1, x_2, \ldots, x_n\} {x1​,x2​,…,xn​},计算核矩阵 K K K,其中 K i j = K ( x i , x j ) K_{ij} = K(x_i, x_j) Kij​=K(xi​,xj​)。

4. 中心化核矩阵

为了确保数据在特征空间中是中心化的,需对核矩阵进行中心化。中心化后的核矩阵 K ′ K' K′ 由以下公式获得:

K ′ = K − 1 n K − K 1 n + 1 n K 1 n K' = K - 1_n K - K 1_n + 1_n K 1_n K′=K−1n​K−K1n​+1n​K1n​

其中 1 n 1_n 1n​是一个 n × n n \times n n×n的全1矩阵。

中心化详细推导步骤

给定数据集 { x 1 , x 2 , … , x n } \{x_1, x_2, \ldots, x_n\} {x1​,x2​,…,xn​},其核矩阵为 K K K,其中

K i j = K ( x i , x j ) K_{ij} = K(x_i, x_j) Kij​=K(xi​,xj​)

1. 计算平均值向量

首先,计算核矩阵的平均值:

K ˉ i = 1 n ∑ j = 1 n K i j \bar{K}_i = \frac{1}{n} \sum_{j=1}^{n} K_{ij} Kˉi​=n1​∑j=1n​Kij​

K ˉ j = 1 n ∑ i = 1 n K i j \bar{K}_j = \frac{1}{n} \sum_{i=1}^{n} K_{ij} Kˉj​=n1​∑i=1n​Kij​

K ˉ = 1 n 2 ∑ i = 1 n ∑ j = 1 n K i j \bar{K} = \frac{1}{n^2} \sum_{i=1}^{n} \sum_{j=1}^{n} K_{ij} Kˉ=n21​∑i=1n​∑j=1n​Kij​

2. 中心化公式

中心化后的核矩阵 K ′ K' K′的每个元素为:

K i j ′ = K i j − K ˉ i − K ˉ j + K ˉ K'_{ij} = K_{ij} - \bar{K}_i - \bar{K}_j + \bar{K} Kij′​=Kij​−Kˉi​−Kˉj​+Kˉ

3. 矩阵形式

使用矩阵运算,可以将上述过程表示为:

K ′ = K − 1 n K − K 1 n + 1 n K 1 n K' = K - 1_n K - K 1_n + 1_n K 1_n K′=K−1n​K−K1n​+1n​K1n​

其中, 1 n 1_n 1n​ 是一个 n × n n \times n n×n 的全1矩阵,矩阵乘法的结果是对每一行或每一列进行平均。
解释

  • 1 n K 1_n K 1n​K和 K 1 n K 1_n K1n​的作用是计算出每一行和每一列的均值。
  • 1 n K 1 n 1_n K 1_n 1n​K1n​ 计算整个矩阵的均值。
  • 通过这些步骤,确保数据在新的特征空间中是零均值的。

通过这种方式,中心化后的核矩阵 K ′ K' K′ 在特征空间中确保数据的均值为零,从而支持后续的特征分析。

5. 特征分解

对中心化后的核矩阵 K ′ K' K′进行特征值分解,得到特征值和特征向量:

K ′ v = λ v K'v = \lambda v K′v=λv

特征向量 (v) 对应于特征空间中的主成分。

6. 投影到主成分空间

选择前 k k k个最大的特征值对应的特征向量,将数据投影到这个新的特征空间中。

优势

  • 捕捉非线性结构: KPCA可以发现原始数据中的非线性模式。
  • 灵活性: 通过选择不同的核函数,可以适应不同的数据分布。

应用

KPCA常用于降维、特征提取、模式识别和数据预处理,在图像处理、基因数据分析等领域有广泛应用。

通过核技巧,KPCA提供了一种强大的非线性降维方法,能够处理复杂结构的数据。

关于抄录代码中定义的sigmiod(x,coef=0.25),linear(x),rbf(x,gamma=15) 三个函数其实就是定义了三个核函数,在代码中,原作者仅仅使用了rbf(x,gamma=15)。同时,在传统的KPCA中会用到核矩阵去中心化,抄录代码中原作者并没有用到。

kpca(data,n_dims=2,kernel=rbf)

def kpca(data,n_dims=2,kernel=rbf):
    K=kernel(data)
    N=K.shape[0]
    one_n=np.ones((N,1))/N
    eig_values,eig_vector=np.linalg.eig(K)
    idx=eig_values.argsort()[::-1]
    eigval=eig_values[idx][:n_dims]
    eigvector=eig_vector[:,idx][:,:n_dims]
    eigval=eigval**0.5
    vi=eigvector/eigval.reshape(-1,n_dims)
    data_n=np.dot(K,vi)
    return data_n
  1. K=kernel(data)
    在这里插入图片描述
    在这里插入图片描述
    其中, ∥ d a t a [ i ] − d a t a [ j ] ∥ ∥data[i]−data[j]∥ ∥data[i]−data[j]∥是数据点 d a t a [ i ] data[i] data[i]和 d a t a [ j ] data[j] data[j]之间的欧几里得距离。
  2. one_n=np.ones((N,1))/N
    原作者并没有使用这一语句,估计是要做去中心化,但没有做。
  3. eig_values,eig_vector=np.linalg.eig(K)
    idx=eig_values.argsort()[::-1]
    eigval=eig_values[idx][:n_dims]
    eigvector=eig_vector[:,idx][:,:n_dims]

    特征值分解,进行排序,进行查找。
    可参考PCA学习日记_241021_主成分分析(PCA)
  4. eigval=eigval**0.5
    vi=eigvector/eigval.reshape(-1,n_dims)
    data_n=np.dot(K,vi)

    假设特征向量为 V V V和特征值为 λ \lambda λ:
    特征向量集合 V n = [ v 1 , v 2 , … , v n _ d i m s ] V_n = [v_1, v_2, \ldots, v_{n\_dims}] Vn​=[v1​,v2​,…,vn_dims​]
    特征值集合 λ n = [ λ 1 , λ 2 , … , λ n _ d i m s ] \lambda_n = [\lambda_1, \lambda_2, \ldots, \lambda_{n\_dims}] λn​=[λ1​,λ2​,…,λn_dims​]
    归一化的特征向量:
    V i = [ v 1 λ 1 , v 2 λ 2 , … , v n _ d i m s λ n _ d i m s ] V_i = \left[\frac{v_1}{\sqrt{\lambda_1}}, \frac{v_2}{\sqrt{\lambda_2}}, \ldots, \frac{v_{n\_dims}}{\sqrt{\lambda_{n\_dims}}}\right] Vi​=[λ1​ ​v1​​,λ2​ ​v2​​,…,λn_dims​ ​vn_dims​​]
    将数据投影到新的特征空间:
    data n = K ⋅ V i \text{data}_n = K \cdot V_i datan​=K⋅Vi​

python中自带函数实现KPCA

sklearn_kpca=KernelPCA(n_components=2,kernel='rbf',gamma=15)

遗留问题

  1. 关于核函数的具体含义与具体意义,,

标签:dims,矩阵,核主,241025,KPCA,eig,np,中心化,data
From: https://blog.csdn.net/2301_81791289/article/details/143195883

相关文章