MATLAB 中 SVM 实现
直接上代码
| |
| |
| clear, clc, close all; |
| load('data.mat'); |
| |
| y(y == 0) = -1; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| C = 10; |
| svm = jhsvmtrain(X, y, C, 'Linear'); |
| result = jhsvmtest(svm, X); |
| fprintf('Accuracy: %f\n', mean(double(result.y_pred == y))); |
| jhplotdata(X, y); |
| hold on; |
| x1_min = min(X(:, 1)) - 1; |
| x1_max = max(X(:, 1)) + 1; |
| x2_min = min(X(:, 2)) - 1; |
| x2_max = max(X(:, 2)) + 1; |
| |
| [XX, YY] = meshgrid(x1_min:0.02:x1_max, x2_min:0.02:x2_max); |
| Z = jhsvmtest(svm, [XX(:) YY(:)]); |
| Z = reshape(Z.y_pred, size(XX)); |
| contour(XX, YY, Z); |
| hold off; |
| |
| function [model] = jhsvmtrain(X, y, C, kernel_type) |
| |
| |
| |
| |
| |
| |
| m = length(y); |
| |
| |
| |
| H = y * y' * jhkernels(X', X', kernel_type); |
| f = -ones(m, 1); |
| A = []; |
| b = []; |
| Aeq = y'; |
| beq = 0; |
| lb = zeros(m, 1); |
| |
| |
| ub = C * ones(m, 1); |
| alphas0 = zeros(m, 1); |
| |
| epsilon = 1e-8; |
| options = optimset('LargeScale', 'off', 'Display', 'off'); |
| alphas1 = quadprog(H, f, A, b, Aeq, beq, lb, ub, alphas0, options); |
| |
| logic_vector = abs(alphas1) > epsilon; |
| model.vec_x = X(logic_vector, :); |
| model.vec_y = y(logic_vector); |
| model.alphas = alphas1(logic_vector); |
| |
| end |
| |
| function result = jhsvmtest(model, X) |
| |
| |
| |
| |
| |
| |
| |
| tmp = (model.alphas' .* model.vec_y' * jhkernels(model.vec_x', model.vec_x', 'Linear'))'; |
| |
| total_bias = model.vec_y - tmp; |
| bias = mean(total_bias); |
| |
| |
| |
| |
| w = (model.alphas' .* model.vec_y' * jhkernels(model.vec_x', X', 'Linear'))'; |
| result.w = w; |
| result.y_pred = sign(w + bias); |
| result.b = bias; |
| end |
| |
| function K = jhkernels(X1, X2, kernel_type) |
| |
| switch lower(kernel_type) |
| |
| case 'linear' |
| K = X1' * X2; |
| |
| case 'rbf' |
| K = X1' * X2; |
| fprintf("I am sorry about that the rbg kernel is not implemented yet, here we still use the linear kernel to compute\n"); |
| end |
| |
| end |
| |
| function jhplotdata(X, y, caption, labelx, labely, color1, color2) |
| |
| if ~exist('caption', 'var') || isempty(caption) |
| caption = 'The relationship between X1 and X2'; |
| end |
| |
| if ~exist('labelx', 'var') || isempty(labelx) |
| labelx = 'X1'; |
| end |
| |
| if ~exist('labely', 'var') || isempty(labely) |
| labely = 'X2'; |
| end |
| |
| if ~exist('color1', 'var') || isempty(color1) |
| color1 = 'r'; |
| end |
| |
| if ~exist('color2', 'var') || isempty(color2) |
| color2 = 'r'; |
| end |
| |
| |
| positive = find(y == 1); |
| negative = find(y == -1); |
| |
| plot(X(positive, 1), X(positive, 2), 'ro', 'MarkerFace', color1); |
| hold on; |
| |
| plot(X(negative, 1), X(negative, 2), 'bo', 'MarkerFace', color2); |
| title(caption); |
| xlabel(labelx); |
| ylabel(labely); |
| legend('Positive Data', 'Negative Data'); |
| |
| hold off; |
| end |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步