0

私たちはプロジェクトに取り組んでおり、KPCA でいくつかの結果を得ようとしています。

データセット (手書きの数字) があり、各数値の最初の 200 桁を取得したので、完全な traindata マトリックスは 2000x784 (784 は次元) です。KPCA を実行すると、新しい低次元データセット (eg2000x100) を含む行列が得られます。しかし、結果はわかりません。pca に対して svd を実行するときのように、他の行列を取得するべきではありませんか? KPCA に使用するコードは次のとおりです。

function data_out = kernelpca(data_in,num_dim)

%% Checking to ensure output dimensions are lesser than input dimension.
if num_dim > size(data_in,1)
    fprintf('\nDimensions of output data has to be lesser than the dimensions of input data\n');
    fprintf('Closing program\n');
    return 
end

%% Using the Gaussian Kernel to construct the Kernel K
% K(x,y) = -exp((x-y)^2/(sigma)^2)
% K is a symmetric Kernel
K = zeros(size(data_in,2),size(data_in,2));
for row = 1:size(data_in,2)
    for col = 1:row
        temp = sum(((data_in(:,row) - data_in(:,col)).^2));
        K(row,col) = exp(-temp); % sigma = 1
    end
end
K = K + K'; 
% Dividing the diagonal element by 2 since it has been added to itself
for row = 1:size(data_in,2)
    K(row,row) = K(row,row)/2;
end
% We know that for PCA the data has to be centered. Even if the input data
% set 'X' lets say in centered, there is no gurantee the data when mapped
% in the feature space [phi(x)] is also centered. Since we actually never
% work in the feature space we cannot center the data. To include this
% correction a pseudo centering is done using the Kernel.
one_mat = ones(size(K));
K_center = K - one_mat*K - K*one_mat + one_mat*K*one_mat;
clear K

%% Obtaining the low dimensional projection
% The following equation needs to be satisfied for K
% N*lamda*K*alpha = K*alpha
% Thus lamda's has to be normalized by the number of points
opts.issym=1;                          
opts.disp = 0; 
opts.isreal = 1;
neigs = 30;
[eigvec eigval] = eigs(K_center,[],neigs,'lm',opts);
eig_val = eigval ~= 0;
eig_val = eig_val./size(data_in,2);
% Again 1 = lamda*(alpha.alpha)
% Here '.' indicated dot product
for col = 1:size(eigvec,2)
    eigvec(:,col) = eigvec(:,col)./(sqrt(eig_val(col,col)));
end
[~, index] = sort(eig_val,'descend');
eigvec = eigvec(:,index);

%% Projecting the data in lower dimensions
data_out = zeros(num_dim,size(data_in,2));
for count = 1:num_dim
    data_out(count,:) = eigvec(:,count)'*K_center';
end

多くの論文を読みましたが、まだ kpca のロジックを理解できていません!

どんな助けでも大歓迎です!

4

1 に答える 1

3

PCAアルゴリズム:


  1. PCA データのサンプル

  2. 平均を計算する

  3. 共分散を計算する

  4. 解決する

: 共分散行列。 : 共分散行列の固有ベクトル。 : 共分散行列の固有値。

最初の n 番目の固有ベクトルを使用して、データの次元を n 次元に減らします。このコードは PCA に使用できます。統合された例があり、簡単です。


KPCA アルゴリズム:


コード内のカーネル関数を選択します。これは次のように指定されます。

K(x,y) = -exp((x-y)^2/(sigma)^2)

高次元空間ホッピングでデータを表現するために、この空間では、データは分類やクラスタリングなどのさらなる目的のために適切に表現されますが、このタスクは最初の特徴空間で解決するのが難しい場合があります。このトリックは、「カーネル トリック」としても知られています。図を見てください。

ここに画像の説明を入力

[ Step1 ] 構成グラム行列

K = zeros(size(data_in,2),size(data_in,2));
for row = 1:size(data_in,2)
    for col = 1:row
        temp = sum(((data_in(:,row) - data_in(:,col)).^2));
        K(row,col) = exp(-temp); % sigma = 1
    end
end
K = K + K'; 
% Dividing the diagonal element by 2 since it has been added to itself
for row = 1:size(data_in,2)
    K(row,row) = K(row,row)/2;
end

ここでは、グラム行列が対称であるため、値の半分が計算され、それまでに計算されたグラム行列とその転置を加算することによって最終結果が得られます。最後に、コメントにあるように 2 で割ります。

[ Step2 ]カーネル行列の正規化

これは、コードの次の部分によって行われます。

K_center = K - one_mat*K - K*one_mat + one_mat*K*one_mat;

コメントが言及しているように、疑似センタリング手順を実行する必要があります。証明についてのアイデアはこちら.

[ Step3 ]固有値問題を解く

For this task this part of the code is responsible.

%% Obtaining the low dimensional projection
% The following equation needs to be satisfied for K
% N*lamda*K*alpha = K*alpha
% Thus lamda's has to be normalized by the number of points
opts.issym=1;                          
opts.disp = 0; 
opts.isreal = 1;
neigs = 30;
[eigvec eigval] = eigs(K_center,[],neigs,'lm',opts);
eig_val = eigval ~= 0;
eig_val = eig_val./size(data_in,2);
% Again 1 = lamda*(alpha.alpha)
% Here '.' indicated dot product
for col = 1:size(eigvec,2)
    eigvec(:,col) = eigvec(:,col)./(sqrt(eig_val(col,col)));
end
[~, index] = sort(eig_val,'descend');
eigvec = eigvec(:,index);

[ Step4 ]各データ点の表現を変更

このタスクでは、コードのこの部分が責任を負います。

%% Projecting the data in lower dimensions
data_out = zeros(num_dim,size(data_in,2));
for count = 1:num_dim
    data_out(count,:) = eigvec(:,count)'*K_center';
end

詳細はこちらをご覧ください。

PS: この著者によって書かれた直観的な例を含むコードを使用することをお勧めします。

于 2014-01-18T19:10:29.720 に答える