PCA
主要从两个角度考虑问题,
一个是最大投影方差,
一个是最小重构距离。
KPCA
拍下来字真难看,复习KPCA的时候有点疑惑的地方,证明完了写成Latex把,自己看着也舒服点。
KPCA更多细节可以参考:https://blog.csdn.net/zhangping1987/article/details/30492433,写的十分的详细。
代码
经上述原理,按照如下步骤完成代码:
1)、对数据进行中心化处理,即减去均值。
2)、构造协方差矩阵。
3)、求解协方差矩阵的值与特征向量。
4)、将特征值从大到小排列,截取所需的K个,并得到其对应的特征向量
5)、.将数据投影在这K个特征向量上。
import numpy as np
from scipy.spatial.distance import pdist,squareform
def pca(X, threshold):
#将X中心化
X_mean = np.mean(X, axis = 0)
X_cen = X - X_mean
#构造散度矩阵并且求解特征值与特征向量
X_sca = np.dot(X_cen.T, X_cen)
X_eigenval, X_eigenvect = np.linalg.eig(X_sca)
#按照阈值排序
indexs = X_eigenval.argsort()[::-1]
indexs = indexs[:threshold]
X_eigenvect_TopK = X_eigenvect[:,indexs]
#将X投影到特征向量上
X_proj = np.dot(X_cen, X_eigenvect_TopK)
#计算重构数据 X * X_proj* X_proj.T
X_restore = np.dot(X_proj, X_eigenvect_TopK.T) + X_mean
return X_proj, X_restore
#kernel_pca
def KPCA(X, gamma, k):
#计算L2距离
dist_arr = sqdist(X, metric='sqeuclidean')
dist_mat = squareform(sq_dists)
#计算径向基散度矩阵,并将其归一化
K_diag = np.exp(-gamma * dist_mat)
N = X.shape[0]
one_N = np.ones((N, N))/N
K = K-one_N.dot(K)-K.dot(one_N)+one_N.dot(K).dot(one_N)
#计算特征值与特征向量
K_eigenval, K_eigevector = np.linalg.eigh(K)
K_eigevector_proj = np.column_stack((K_eigevector[:, -i]for i in range(1, 1+k)))
K_eigenval_proj = [K_eigenval[-i] for i in range(1, k+1)]
return K_eigevector_proj, K_eigenval_proj
#计算新来的样本的投影
#模型构建完毕后,至于观测样本有关。
def proj_new(X_new, X, gamma, K_eigevector_proj, K_eigenval_proj):
k = np.exp(-gamma*np.sum((X-X_new)**2, 1))
return k.dot(K_eigevector_proj/K_eigenval_proj)