Matlab SVM 自定义核函数

Posted

技术标签:

【中文标题】Matlab SVM 自定义核函数【英文标题】:Matlab SVM custom kernel function 【发布时间】:2015-08-06 10:46:04 【问题描述】:

在 Matlab SVM tutorial 中,它说

您可以通过设置'KernelFunction','kernel'来设置自己的内核函数,例如内核。内核必须具有以下形式:

函数 G = kernel(U,V)

地点:

U 是一个 m×p 矩阵。 V 是一个 n×p 矩阵。 G 是 U 和 V 行的 m×n Gram 矩阵。

当我遵循自定义 SVM 内核 example 时,我在 mysigmoid.m 函数中设置了一个断点。但是,我发现 U 和 V 实际上是 1×p 向量,而 G 是标量。

为什么 MATLAB 不通过矩阵处理内核?

我的自定义核函数是

function G = mysigmoid(U,V)
% Sigmoid kernel function with slope gamma and intercept c
gamma = 0.5;
c = -1;
G = tanh(gamma*U*V' + c);
end

我的 Matlab 脚本是

%% Train SVM Classifiers Using a Custom Kernel

rng(1); % For reproducibility
n = 100; % Number of points per quadrant

r1 = sqrt(rand(2*n,1)); % Random radius
t1 = [pi/2*rand(n,1); (pi/2*rand(n,1)+pi)]; % Random angles for Q1 and Q3
X1 = [r1.*cos(t1), r1.*sin(t1)]; % Polar-to-Cartesian conversion

r2 = sqrt(rand(2*n,1));
t2 = [pi/2*rand(n,1)+pi/2; (pi/2*rand(n,1)-pi/2)]; % Random angles for Q2 and Q4
X2 = [r2.*cos(t2), r2.*sin(t2)];

X = [X1; X2]; % Predictors
Y = ones(4*n,1);
Y(2*n + 1:end) = -1; % Labels

% Plot the data
figure(1);
gscatter(X(:,1),X(:,2),Y);
title('Scatter Diagram of Simulated Data');

SVMModel1 = fitcsvm(X,Y,'KernelFunction','mysigmoid','Standardize',true);

% Compute the scores over a grid
d = 0.02; % Step size of the grid
[x1Grid,x2Grid] = meshgrid(min(X(:,1)):d:max(X(:,1)),...
min(X(:,2)):d:max(X(:,2)));
xGrid = [x1Grid(:),x2Grid(:)]; % The grid
[~,scores1] = predict(SVMModel1,xGrid); % The scores

figure(2);
h(1:2) = gscatter(X(:,1),X(:,2),Y);
hold on;
h(3) = plot(X(SVMModel1.IsSupportVector,1),X(SVMModel1.IsSupportVector,2),...
'ko','MarkerSize',10);
% Support vectors
contour(x1Grid,x2Grid,reshape(scores1(:,2),size(x1Grid)),[0,0],'k');
% Decision boundary
title('Scatter Diagram with the Decision Boundary');
legend('-1','1','Support Vectors','Location','Best');
hold off;

CVSVMModel1 = crossval(SVMModel1);
misclass1 = kfoldLoss(CVSVMModel1);
disp(misclass1);

【问题讨论】:

【参考方案1】:

内核为特征添加维度。例如,如果您有示例x=a 的一项功能,它将扩展为x= a_1... a_q 之类的内容。当您同时对所有数据执行此操作时,您将拥有 M x PM 是训练集中的示例数,P 是特征数)。它要求的第二个矩阵是P x N,其中N 是训练/测试集中示例的数量。

也就是说,您的输出应该是M x N。因为它是1,这意味着你有U = 1XMV=Nx1,其中N=M。要获得M x N 逻辑的输出,您应该简单地转置您的输入。

【讨论】:

内核函数具有固定格式,如“mysigmoid”所示。我不能直接使用内核函数。当我调用 SVMModel1 = fitcsvm(X,Y,'KernelFunction','mysigmoid','Standardize',true) 时,它包含在 MATLAB SVM 框架中。 G = tanh(gamma*U*V' + c);更改为G = tanh(gamma*U'*V + c); 这并不能解决问题。在演示中,我的训练数据是 X,一个 200 x 2 的矩阵,所以 U 和 V 应该正好是 X,G = U*V' 是一个 200 x 200 的矩阵(Gram 矩阵)。但是现在 U 和 V 都是 1 x 2,所以U'*V 只构造了一个 2 x 2 的矩阵,这不是我想要的。 是的,你是对的,当你训练时,U 和 V 是 X(测试时不是这样)。然后你的内核是G= X * X',因为X 是200 x 2 X' 然后是2 x 200,所以你得到预期的200 x 200 作为G 的输出大小。我不知道你从哪里得到“U 和V 是1 x 2 "。 不,不完全是。如果您的输入是200 x 2,那么您的内核函数将获得大小为p x 2q x 2 的输入,并且pq 通常等于1。我在这里做了一些跟踪,在我的情况下是第一个对我的内核函数 p 和 q 的 97 调用是 1,然后在最后 22 次调用中 p 更改为 97。为什么会这样我不能说,因为我的函数是从某个 Java 类调用的,我无法调试到,但这是我能观察到的。

以上是关于Matlab SVM 自定义核函数的主要内容,如果未能解决你的问题,请参考以下文章

scikit-learn 中自定义内核 SVM 的交叉验证

如何为 sklearn.svm.SVC 定义自定义内核函数?

SVM 的自定义内核,何时应用它们?

matlab怎么建立自定义函数

C++ 支持向量机 (SVM) 模板库?

Python中怎样编写混合核函数?