支持向量机SVM----简化版序列最小优化SMO(Sequential Minimal Optimation)

本文介绍了一个基于《机器学习实战》的SMO算法实现,并通过Matlab进行了详细的实验演示。实验中使用了较大的数据集,提供了完整的代码实现过程,包括参数调整、支持向量的选择等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本算法根据《机器学习实战》中Python版的简化版SMO改编而来,所以详细的过程说明请参照原书,这里只给出了改编后的程序及结果。实验数据数量较大放在云盘上,https://pan.baidu.com/s/1cHJKku。

需要注意的问题:因为存在第二个点是随机选择的特征,所以每次实验的结果可能都不会完全一样。

以下为实验Matlab代码:

clc;
clear;
%加载测试数据文件,前两列为坐标值,后两列为类标号
fileID = fopen('D:\matlabFile\SVM\SVM.txt');
DS=textscan(fileID,'%f %f %f');
fclose(fileID);
%将数据转为矩阵形式
DataMat=cat(2,DS{1},DS{2});
[Row,Column]=size(DataMat);
%提取类别矩阵
LabelMat=DS{3};
%设定常数C
C=0.6;
%设定容错率
Toler=0.001;
%设定循环次数
MaxIter=30;
b=0;
Alpha=zeros(Row,1);
%循环计数器
flag=0;
while flag<MaxIter
    alphaPairChanged=0;
    for i=1:Row
        X_i=(Alpha.*LabelMat)'*(DataMat*DataMat(i,:)')+b;
        %计算坐标X的误差
        Err_i=X_i-LabelMat(i);
        if ((LabelMat(i)*Err_i<-Toler)&&(Alpha(i)<C))||((LabelMat(i)*Err_i>Toler)&&(Alpha(i)>0))
            %在Row的范围内,随机选择一个不等于i的数
            Rnd=unidrnd(Row,1,Row);
            j=Rnd(1);
            if i==j
                j=Rnd(2);
            end
            X_j=(Alpha.*LabelMat)'*(DataMat*DataMat(j,:)')+b;
            %计算坐标Y的误差
            Err_j=X_j-LabelMat(j);
            %备份第i,j个Alpha
            Alpha_i_old=Alpha(i);
            Alpha_j_old=Alpha(j);
            %寻找最大最小值,保证Alpha在0到C之间
            if LabelMat(i)~=LabelMat(j)
                Low=max([0,Alpha(j)-Alpha(i)]);
                High=min([C,C+Alpha(j)-Alpha(i)]);
            else
                Low=max([0,Alpha(j)+Alpha(i)-C]);
                High=min([C,Alpha(j)+Alpha(i)]);
            end
            %如果最大最小相等,循环步进
            if Low==High
                continue;
            end
            Eta=2*DataMat(i,:)*DataMat(j,:)'-DataMat(i,:)*DataMat(i,:)'-DataMat(j,:)*DataMat(j,:)';
            if Eta>0
                continue;
            end
            Alpha(j)=Alpha(j)-LabelMat(j)*(Err_i-Err_j)/Eta;
            if Alpha(j)>High
                Alpha(j)=High;
            end
            if Alpha(j)<Low
                Alpha(j)=Low;
            end
            %判断Alpha的误差是否足够小,如果否则进行更新
            if abs(Alpha(j)-Alpha_j_old)<0.00001
                continue;
            end
            Alpha(i)=Alpha(i)+LabelMat(j)*LabelMat(i)*(Alpha_j_old-Alpha(j));         
            b1=b-Err_i-LabelMat(i)*(Alpha(i)-Alpha_i_old)*DataMat(i,:)*DataMat(i,:)'-LabelMat(j)*(Alpha(j)-Alpha_j_old)*DataMat(i,:)*DataMat(j,:)';
            b2=b-Err_j-LabelMat(i)*(Alpha(i)-Alpha_i_old)*DataMat(i,:)*DataMat(j,:)'-LabelMat(j)*(Alpha(j)-Alpha_j_old)*DataMat(j,:)*DataMat(j,:)';
            if (0<Alpha(i))&&(Alpha(i)<C)
                b=b1;
            elseif (0<Alpha(j))&&(Alpha(j)<C)
                b=b2;
            else
                b=(b1+b2)/2;
            end                     
            alphaPairChanged=alphaPairChanged+1;         
        end
    end
    if alphaPairChanged==0
        flag=flag+1;
    else
        flag=0;
    end   
end
%显示原始数据
scatter(DataMat(:,1),DataMat(:,2),'filled');
hold on
%显示支持向量
Index=find(Alpha>0);
Sup=DataMat(Index,:);
scatter(Sup(:,1),Sup(:,2),'r');
实验结果仅供参考:








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值