MATLAB 支持向量机(SVM)

2023-11-15

基础

线性可分

简单来讲就是如何将两个数据用点、直线、平面分开。。。。。
在这里插入图片描述
二维空间中,要分开两个线性可分的点集合,我们需要找到一条分类直线即可,

最大间隔超平面

通俗来讲,在这个二维平面中,可以把两类点的分开的直线有很多条,那么这些直线中,哪一条才是最好的呢?也就是如何选择出一条最好的直线呢?
在这里插入图片描述
先看橙色的点,如果这些点到分类直线的距离越大,分类直线也就越远离橙色的点,那么再来一个新的点,如果这个点是依照橙色点集合的特性产生的(也就是它不是一个相对于橙色点集合很奇异的点),那么这个点也很可能和橙色的点集合一样,分布在直线的同一侧。分布在同一侧,表明它和橙色集合点属于同一个类别。用同样的思想,图4中,对于灰色的集合点,这条分类直线离它们的距离也要越远越好。所以找最优分类线,就是要找到这条一条直线,使它到两个类别点的距离越大越好。
在这里插入图片描述

因此便可得到某根距离离两边都累计最远的直线,即最大分隔超平面。

在这里插入图片描述
上述也叫硬间隔最最大化,能够用直线将两者分开。

SVM分类

基本代码和工具

工具:1、MATLAB 2020a;2、fitcsvm

二分类

fitcsvm:fitcsvm训练或交叉验证支持向量机(SVM)模型在低维或中维预测数据集上的一类和二类(binary)分类。fitcsvm支持使用核函数映射预测数据,并支持通过二次规划实现目标函数最小化的顺序最小优化(SMO,sequential minimal optimization)、迭代单数据算法(ISDA,iterative single data algorithm)或L1软边界最小化。
代码:

线性

clc
clear all
%设置两类不同数据
A = [3,7;6,6;4,6;5,6.5];
B = [1,2;3,5;7,3;3,4;6,2.7;4,3;2,7];
C = [A;B];%两类数据合并

%设置不同类别标签
table = [true true true true false false false false false false false];
D = nominal(table);


%%数据集和标签
sd=C;
Y=D;

%% 原始数据图像
subplot(1,2,1)
gscatter(sd(:,1),sd(:,2),Y,'rg','+*');

%%  SVM
SVMModel=fitcsvm(sd,Y,'KernelFunction','linear');
[lable,score]=predict(SVMModel,sd);

%% 画图
subplot(1,2,2)
h = nan(3,1); 
h(1:2) = gscatter(sd(:,1),sd(:,2),Y,'rg','+*'); 
hold on
h(3) =plot(sd(SVMModel.IsSupportVector,1),sd(SVMModel.IsSupportVector,2), 'ko');%画出支持向量

%画出决策边界
w=-SVMModel.Beta(1,1)/SVMModel.Beta(2,1);%斜率
b=-SVMModel.Bias/SVMModel.Beta(2,1);%截距
x_ = 0:0.01:10;
y_ = w*x_+b;
plot(x_,y_)
hold on
legend(h,{'-1','+1','Support Vectors'},'Location','Southeast');
axis equal
hold off



实验结果:
在这里插入图片描述

上述实验得到一个硬间隔最大化的分隔超平面

非线性

clc
clear all
%设置两类不同数据
A = [0.9,1;0.8,1.8;0.79,1.7;0.7,3;0.8,3.9;0.9,4.5;1.2,5.7;1.6,5.6;2.5,6.1;2.9,5.8; 2.9,1;3.1,1.4;3.6,1.2;5,2;5.5,3.9;4.9,4.5;4.2,5.9;3.6,5.6;2.5,5.1;2.9,5.3];
B = [2.5,3.1;3.5,2.6;4.5,3.2;3.5,2;2.4,2;3.5,2.5;4.3,3.7;2.6,2.8;2.4,3;3.6,3.1;4.4,3.3; 2.5,4.0;3.5,4.1;4.5,4.2;1.5,4;2.4,4;3.5,4.5;4.3,3.7;3.6,3.8;2.4,3.5;3.6,3.7;4.4,3.3];
C = [A;B];%两类数据合并

%设置不同类别标签
table = [true true true true true true true true true true true true true true true true true true true true false false false false false false false false false false false false false false false false false false false false false false];
D = nominal(table);


%%数据集和标签
sd=C;
Y=D;

%% 原始数据图像
subplot(1,2,1)
gscatter(sd(:,1),sd(:,2),Y,'rg','+*');

%% 原始数据图像
subplot(1,2,1)
gscatter(sd(:,1),sd(:,2),Y,'rg','+*');
%% SVM
SVMModel=fitcsvm(sd,Y,'BoxConstraint',10,'KernelFunction','rbf','KernelScale',2^0.5*2);%使用高斯核函数

%%SVMModel=fitcsvm(sd,Y,'KernelFunction','rbf','OptimizeHyperparameters',{'BoxConstraint','KernelScale'},  'HyperparameterOptimizationOptions',struct('ShowPlots',false));%使用超参数优化

%% 画图
subplot(1,2,2)
h = nan(3,1); 
h(1:2) = gscatter(sd(:,1),sd(:,2),Y,'rg','+*'); 
hold on
h(3) = plot(sd(SVMModel.IsSupportVector,1),sd(SVMModel.IsSupportVector, 2),'ko'); %画出支持向量

%画出决策边界
h = 0.2; 
[X1,X2] = meshgrid(min(sd(:,1)):h:max(sd(:,1)),min(sd(:,2)):h:max(sd(:,2)));
%得到所有取点的矩阵
[lable,score]=predict(SVMModel,[X1(:),X2(:)]);
scoreGrid = reshape(score(:,2),size(X1,1),size(X2,2));
contour(X1,X2,scoreGrid,[0 0]);%绘制等高线
hold on
legend('-1','+1','Support Vectors','分界线');
axis equal
hold off


实验结果:
在这里插入图片描述

上述实验进行非线性的数据分类

多分类

详细解释

一对多法(one-versus-rest,简称OVR SVMs)

训练时依次把某个类别的样本归为一类,其他剩余的样本归为另一类,这样k个类别的样本就构造出了k个SVM。分类时将未知样本分类为具有最大分类函数值的那类。

假如我有四类要划分(也就是4个Label),他们是A、B、C、D。
于是我在抽取训练集的时候,分别抽取
  (1)A所对应的向量作为正集,B,C,D所对应的向量作为负集;
  (2)B所对应的向量作为正集,A,C,D所对应的向量作为负集;
  (3)C所对应的向量作为正集,A,B,D所对应的向量作为负集;
  (4)D所对应的向量作为正集,A,B,C所对应的向量作为负集;
  使用这四个训练集分别进行训练,然后的得到四个训练结果文件。在测试的时候,把对应的测试向量分别利用这四个训练结果文件进行测试。最后每个测试都有一个结果f1(x),f2(x),f3(x),f4(x)。于是最终的结果便是这四个值中最大的一个作为分类结果。
  数据链接: [https://pan.baidu.com/s/1QUNknb-AV-cPt0hM_jSs_Q ]提取码:http
  代码:

clc;
clear;
close all;
%%导入数据:训练集、测试集、训练标签、测试标签
train_data=xlsread('train_data.xls');
group_train=xlsread('group_train.xls');
test_data=xlsread('test_data.xls');
test_labels=xlsread('test_labels.xls');

%%绘数据分布图
gscatter(train_data(:,1),train_data(:,2),group_train);
title('数据分布');
xlabel('Fea1');
ylabel('Fea2');

%%
% 训练数据分为5% 类别i的 正样本 选择类别i的全部,负样本 从其余类别中随机选择(个数与正样本相同)
%%
% 类别1
class1_p = train_data(1:12,:);
% randperm(n,k)是从1到n的序号中随机返回k个
index1 = randperm(48,12);
train_data_c = train_data;
train_data_c(1:12,:) = [];%正样本
class1_n = train_data_c(index1,:);%负样本
train_features1 = [class1_p;class1_n];
% 正类表示为1,负类表示为-1
train_labels1 = [ones(12,1);-1*ones(12,1)];

%% 类别2
class2_p = train_data(13:24,:);
% randperm(n,k)是从1到n的序号中随机返回k个
index1 = randperm(48,12);
train_data_c = train_data;
train_data_c(13:24,:) = [];%正样本
class2_n = train_data_c(index1,:);%负样本
train_features2 = [class2_p;class2_n];
% 正类表示为1,负类表示为-1
train_labels2 = [ones(12,1);-1*ones(12,1)];


%% 类别3
class3_p = train_data(25:36,:);
% randperm(n,k)是从1到n的序号中随机返回k个
index1 = randperm(48,12);
train_data_c = train_data;
train_data_c(25:36,:) = [];%正样本
class3_n = train_data_c(index1,:);%负样本
train_features3 = [class3_p;class3_n];
% 正类表示为1,负类表示为-1
train_labels3 = [ones(12,1);-1*ones(12,1)];


%% 类别4
class4_p = train_data(37:48,:);
% randperm(n,k)是从1到n的序号中随机返回k个
index1 = randperm(48,12);
train_data_c = train_data;
train_data_c(37:48,:) = [];%正样本
class4_n = train_data_c(index1,:);%负样本
train_features4 = [class4_p;class4_n];
% 正类表示为1,负类表示为-1
train_labels4 = [ones(12,1);-1*ones(12,1)];


%% 类别5
class5_p = train_data(49:60,:);
% randperm(n,k)是从1到n的序号中随机返回k个
index1 = randperm(48,12);
train_data_c = train_data;
train_data_c(49:60,:) = [];%正样本
class5_n = train_data_c(index1,:);%负样本
train_features5 = [class5_p;class5_n];
% 正类表示为1,负类表示为-1
train_labels5 = [ones(12,1);-1*ones(12,1)];



%%
% 分别训练5个类别的SVM模型
model1 = fitcsvm(train_features1,train_labels1,'ClassNames',{'-1','1'});
model2 = fitcsvm(train_features2,train_labels2,'ClassNames',{'-1','1'});
model3 = fitcsvm(train_features3,train_labels3,'ClassNames',{'-1','1'});
model4 = fitcsvm(train_features4,train_labels4,'ClassNames',{'-1','1'});
model5 = fitcsvm(train_features5,train_labels5,'ClassNames',{'-1','1'});


%%
% label是n*1的矩阵,每一行是对应测试样本的预测标签;
% score是n*2的矩阵,第一列为预测为“负”的得分,第二列为预测为“正”的得分。
% 用训练好的5SVM模型分别对测试样本进行预测分类,得到5个预测标签
[label1,score1] = predict(model1,test_data);
[label2,score2] = predict(model2,test_data);
[label3,score3] = predict(model3,test_data);
[label4,score4] = predict(model4,test_data);
[label5,score5] = predict(model5,test_data);
% 求出测试样本在5个模型中预测为“正”得分的最大值,作为该测试样本的最终预测标签
score = [score1(:,2),score2(:,2),score3(:,2),score4(:,2),score5(:,2)];
% 最终预测标签为k*1矩阵,k为预测样本的个数
final_labels = zeros(20,1);
for i = 1:size(final_labels,1)
    % 返回每一行的最大值和其位置
    [m,p] = max(score(i,:));
    % 位置即为标签
    final_labels(i,:) = p;
end
% 分类评价指标

在这里插入图片描述
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MATLAB 支持向量机(SVM) 的相关文章

  • 如何以编程方式指定 MATLAB 编辑器键绑定

    我想将键盘键绑定设置为Windows 默认设置我想在启动时使用startup m因为我希望在大量系统上设置此设置 首选项对话框中的等效设置是 MATLAB gt Keyboard gt Shortcuts gt Active Setting
  • 类方法的自定义代码完成?

    在 MATLAB 中 可以定义代码建议和完成 如标题为 的文档页面中所述 自定义代码建议和完成 https www mathworks com help matlab matlab prog customize code suggestio
  • 估算缺失数据,同时强制相关系数保持不变

    考虑以下 excel 数据集 m r 2 0 3 3 0 8 4 0 1 3 2 1 5 2 2 3 1 9 2 5 1 2 3 0 2 0 2 6 我的目标是使用以下条件填充缺失值 将上述两列之间的成对相关性表示为 R 大约 0 68 将
  • 整数的十进制表示形式中的分隔数字

    例如 我想将用户输入作为整数输入 45697 并将前两位数字存储在数组 向量或其他内容中 例如 4 5 6 9 7 这样我就可以使用一些函数调用来检查前两个值 4 5 并对它们进行计算 问题 我不知道如何存储恢复前两个值 有没有简单的函数调
  • 通过傅里叶空间填充进行插值

    我最近尝试在 matlab 上实现一个在傅立叶域中使用零填充的插值方法的简单示例 但我无法正常工作 我总是有一个小的频移 在傅里叶空间中几乎不可见 但它在时空上产生了巨大的误差 由于傅里叶空间中的零填充似乎是一种常见 且快速 的插值方法 因
  • python 正弦和余弦精度

    如何提高Python正弦和余弦精度 例如 我想使用以下代码 只需计算随机复向量 x 的 y cos acos x import numpy as np N 100000 x np zeros N 1j np zeros N for k in
  • 在 MATLAB 中创建共享库

    一位研究人员在 MATLAB 中创建了一个小型仿真 我们希望其他人也能使用它 我的计划是进行模拟 清理一些东西并将其变成一组函数 然后我打算将其编译成C库并使用SWIG https en wikipedia org wiki SWIG创建一
  • Matlab Solve():未给出所有解决方案

    我试图找到两条曲线的交点 syms x y g x 20 exp x 30 3 5 1 sol x sol y solve x 22 3097 2 y 16 2497 2 25 y g x x y Real true 它只提供一种解决方案
  • 使用 R2010b 中的符号工具箱来求解和/或 linsolve

    我前几天问了一个问题here https stackoverflow com questions 20317038 matlab linear congruence solver that supports a non prime modu
  • MATLAB 可执行文件太慢

    我使用以下命令将 MATLAB 程序转换为基于控制台的应用程序deploytool在 MATLAB 中 MATLAB m文件执行大约需要 2 秒 但在我将其转换为可执行文件并调用 exe 执行需要45秒 太长了 我想将 MATLAB 程序与
  • Matlab颜色检测

    我试图一致地检测同一场景的图像之间的某种颜色 这个想法是根据颜色配置文件识别一组对象 因此 例如 如果给我一个带有绿色球的场景 并且我选择绿色作为我的调色板的一部分 我想要一个具有反映它检测到球的矩阵的函数 任何人都可以为这个项目推荐一些
  • 平衡两轮机器人而不使其向前/向后漂移

    我正在尝试设计一个控制器来平衡 2 轮机器人 约 13 公斤 并使其能够抵抗外力 例如 如果有人踢它 它不应该掉落 也不应该无限期地向前 向后漂移 我对大多数控制技术 LQR 滑模控制 PID 等 都很有经验 但我在网上看到大多数人使用 L
  • Python 或 C 语言中的 Matlab / Octave bwdist()

    有谁知道 Matlab Octave bwdist 函数的 Python 替代品 此函数返回给定矩阵的每个单元格到最近的非零单元格的欧几里得距离 我看到了一个 Octave C 实现 一个纯 Matlab 实现 我想知道是否有人必须用 AN
  • 从 MATLAB 调用 Java?

    我想要Matlab程序调用java文件 最好有一个例子 需要考虑三种情况 Java 内置库 也就是说 任何描述的here http docs oracle com javase 6 docs api 这些项目可以直接调用 例如 map ja
  • 如何在Matlab中打印带有千位分隔符的整数?

    我想使用逗号作为千位分隔符将数字转换为字符串 就像是 x 120501231 21 str sprintf 0 0f x 但随着效果 str 120 501 231 21 如果内置fprintf sprintf做不到 我想可以使用正则表达式
  • 获取向量幂的有效方法

    我编写了一个代码 在数值上使用勒让德多项式直至某个高 n 阶 例如 case 8 p 6435 x 8 12012 x 6 6930 x 4 1260 x 2 35 128 return case 9 如果向量x太长这会变得很慢 我发现说之
  • FMINCON 的替代方案

    除了 fmincon 之外还有其他更快 更高效的求解器吗 我正在使用 fmincon 来解决特定问题 但对于中等大小的向量变量来说 我的内存不足 我也没有任何超级计算机或云计算选项可供使用 我知道任何替代解决方案仍然会耗尽内存 但我只是想看
  • 将 kinect RGB 和深度值转换为 XYZ 坐标

    我正在寻找一种简单的方法将 kinect RGB 和深度值转换为 XYZ 坐标 使用 MATLAB 我的目标是一个输入为以下内容的函数 每个点的 RGB 和深度值Kinect相机 并输出 每个点的 x y 和 z 值 RGB 深度 RGB
  • 在 MATLAB 中绘图后恢复轴

    从文本文件绘制多种方法的输出后 未显示轴的右侧和上侧 我需要拥有它们并将它们加粗 就像当前的轴一样 绘制的数据来自存储每种方法数据的文件 每个数据文件都是一个 256x2 文件 包含 0 1 之间的值 第一列是精度 第二列是召回率 figu
  • 通过 cuFFT 进行逆 FFT 缩放

    每当我使用 cuFFT 绘制程序获得的值并将结果与 Matlab 的结果进行比较时 我都会得到相同形状的图形 并且最大值和最小值位于相同的点 然而 cuFFT 得到的值比 Matlab 得到的值大得多 Matlab代码是 fs 1000 s

随机推荐