clear
clc
load normal.mat
X = normal % X训练数据集
[Xrow, Xcol] = size(X)% Xrow:样本个数 Xcol:样本属性个数
%% 数据预处理,进行标准化出理,处理后均值为0方差为1
Xc = mean(X)% 求原始数据的均值
Xe = std(X) % 求原始数据的方差
X0 = (X-ones(Xrow,1)*Xc) ./ (ones(Xrow,1)*Xe)% 标准阵X0,标准化为均值0,方差1
c = 20000 %此参数可调
%% 求核矩阵
for i = 1 : Xrow
for j = 1 : Xrow
K(i,j) = exp(-(norm(X0(i,:) - X0(j,:)))^2/c)%求核矩阵,采用径向基核函数,参数c
end
end
%% 中心化矩阵
n1 = ones(Xrow, Xrow)
N1 = (1/Xrow) * n1
Kp = K - N1*K - K*N1 + N1*K*N1% 中心化矩阵
%% 特征值分解
[V, D] = eig(Kp)% 求协方差矩阵的特征向量(V)和特征值(D)
lmda = real(diag(D)) % 将主对角线上为特征值的对角阵变换成特征值列向量
[Yt, index] = sort(lmda, 'descend')% 特征值按降序排列,t是排列后的数组,index是序号
%% 确定主元贡献率 记下累计贡献率大于85%的特征值的序号放入 mianD中
rate = Yt / sum(Yt)% 计算各特征值的贡献率
sumrate = 0 % 累计贡献率
mpIndex = [] % 记录主元所在特征值向量中的序号
for k = 1 : length(Yt)% 特征值个数
sumrate = sumrate + rate(k) % 计算累计贡献率
mpIndex(k) = index(k)% 保存主元序号
if sumrate >0.85
break
end
end
npc = length(mpIndex)% 主元个数
%% 计算负荷向量
for i = 1 : npc
zhuyuan_vector(i) = lmda(mpIndex(i))% 主元向量
P(:, i) = V(:, mpIndex(i)) % 主元所对应的特征向量(负荷向量)
end
zhuyuan_vector2 = diag(zhuyuan_vector)% 构建主元对角阵
恰好我也在做kpca相关的内容,可以交流一下。我觉得关键问题是你没理解核函数的概念。我理解上核函数是本质是两个空间之间的映射,具体可以参看一个关键定理:mercer定理。这个定理是描述了一个函数满足何种条件才能等价于向希尔伯特空间上的内积运算,这里的空间维度就是我们专业术语里的特征(机器学习里面的特征概念,而非数学上的特征值特征向量)。既然它是一个空间向另一个空间的映射,那么映射以后的维度当然不一定和原空间相等,类比高斯径向基核,它就是一个升维映射,甚至再类比傅里叶变换或者小波变换,是向1组或者几组无限维的正交基上映射。
样本在经过映射(通常是升维)以后,本身它的维度就会发生很大变化,比如描述一个人,原来表示身高、体重、胸围等等这些特征经过升维以后不再具有物理意义,但是在分类过程中,升维可以把原本非线性的特征转化的较为接近线性,这就是核函数存在的价值。你原本特征维度是20,经过映射以后变成了500,后续的pca *** 作是针对映射后的这500个新特征进行的,当然会和原来不相同。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)