目录
第一节 兵王问题描述
第二节 兵王问题的数据预处理与参数设定
样本的情况
第一步:对数据的预处理
对训练样本归一化
第二步:设置支持向量机的各种参数
参数1:-S 支持向量机不同的形式 此问题中取参数为0
参数2:-t 对于核函数进行选择
参数3: -C 原问题中系数C的值,或对偶问题中的上界C
参数4:-g 与核函数相对应的参数
第三节 程序设计与分析
程序分析
第四节 识别系统的性能量度
混淆矩阵
ROC曲线
AUC
等错误率EER
第五节 多类情况
1类 对 K-1类
1类 对 另1类
树状分类器
兵王问题:
黑方只剩一个王,白方剩一兵一王
有两种可能:
①白方将死黑方,白方获胜 ②和棋
对于黑方而言有一个好消息和一个坏消息
好消息是黑方可以有机会尝试逼和
坏消息是白方的兵如果走到底线就会升变为王后,此时黑方必输无疑
和棋的标签为+1,其他情况(即白方胜)为-1
样本总数为:28056
正样本(y=+1):2796
负样本(y=-1):25260
随机取5000个样本进行训练,剩余的进行测试
在训练样本上,求出每个维度的均值和方差,使用以下公式计算新的X
0-4分别为:
0——Linear(线性内核)
1——Ploy(多项式核)
2——Rbf(高斯径向基函数核)
3——Tanh(sigmoid核)
4——自定义核
以下为几种常用核函数
Linear(线性内核):只具有理论的意义,没有实用价值
Ploy(多项式核):复杂度可以调节。指数d越大,对应的φ维度越高
Rbf(高斯径向基函数核):σ为超参数。对应的φ维度是无限的。最常用的核函数
Tanh(sigmoid核):β和b都是超参数。对于的φ维度是无限的
原问题
对偶问题
第一步,下载libsvm工具包,放入matlab文件夹中
第二步,打开MATLAB,点击:设置路径——添加并包含子文件夹
选中matlab文件夹中的libsvm
可以看到,此时libsvn中的内容已经出现在了下图右侧红色框的位置
打开testSVMChess.m
下面对testSVMChessLibSVM.m进行分析
fid = fopen('krkopt.DATA');
c = fread(fid, 3);%读文件
vec = zeros(6,1);
xapp = [];%接收六维的训练数据
yapp = [];%接收标签
while ~feof(fid)
string = [];
c = fread(fid,1);
flag = flag+1;
while c~=13
string = [string, c];
c=fread(fid,1);
end;
fread(fid,1);
if length(string)>10
vec(1) = string(1) - 96;
vec(2) = string(3) - 48;
vec(3) = string(5) - 96;
vec(4) = string(7) - 48;
vec(5) = string(9) - 96;
vec(6) = string(11) - 48;
xapp = [xapp,vec];
if string(13) == 100
yapp = [yapp,1];
else
yapp = [yapp,-1];
end;
end;
end;
xapp的维度为6,总共有28056个
Yapp的维度为1,总共有28056个
%选取训练样本和测试样本。先进行打乱操作
[N,M] = size(xapp);
p = randperm(M); %直接打乱了训练样本
numberOfSamplesForTraining = 5000;%5000个样本构成训练集
xTraining = [];
yTraining = [];
for i=1:numberOfSamplesForTraining
xTraining = [xTraining,xapp(:,p(i))];
yTraining = [yTraining,yapp(p(i))];
end;
xTraining = xTraining';
yTraining = yTraining';
xTesting = [];
yTesting = [];
for i=numberOfSamplesForTraining+1:M
xTesting = [xTesting,xapp(:,p(i))];
yTesting = [yTesting,yapp(p(i))];
end;
xTesting = xTesting';
yTesting = yTesting';
%接下来进行归一化
[numVec,numDim] = size(xTraining);
avgX = mean(xTraining);
stdX = std(xTraining);
for i = 1:numVec
xTraining(i,:) = (xTraining(i,:)-avgX)./stdX;%对训练集归一化:减去均值,除以方差
end;
[numVec,numDim] = size(xTesting);
for i = 1:numVec
xTesting(i,:) = (xTesting(i,:)-avgX)./stdX;%对测试集归一化:减去均值,除以方差
end;
%选取RBF核函数
%SVM Gaussian kernel
%Search for the optimal C and gamma, K(x1,x2) = exp{-||x1-x2||^2/gamma} to
%make the recognition rate maximum.
%Firstly, search C and gamma in a crude scale (as recommended in 'A practical Guide to Support Vector Classification'))
CScale = [-5, -3, -1, 1, 3, 5,7,9,11,13,15];
gammaScale = [-15,-13,-11,-9,-7,-5,-3,-1,1,3];
C = 2.^CScale;
gamma = 2.^gammaScale;
maxRecognitionRate = 0;%开始进行交叉验证
for i = 1:length(C)
for j = 1:length(gamma)
cmd=['-t 2 -c ',num2str(C(i)),' -g ',num2str(gamma(j)),' -v 5'];%五折交叉验证
recognitionRate = svmtrain(yTraining,xTraining,cmd);
if recognitionRate>maxRecognitionRate
maxRecognitionRate = recognitionRate
maxCIndex = i;
maxGammaIndex = j;
end;
end;
end;
%进一步缩小搜索范围,使用交叉验证
%Then search for optimal C and gamma in a refined scale.
n = 10;
minCScale = 0.5*(CScale(max(1,maxCIndex-1))+CScale(maxCIndex));
maxCScale = 0.5*(CScale(min(length(CScale),maxCIndex+1))+CScale(maxCIndex));
newCScale = [minCScale:(maxCScale-minCScale)/n:maxCScale];
minGammaScale = 0.5*(gammaScale(max(1,maxGammaIndex-1))+gammaScale(maxGammaIndex));
maxGammaScale = 0.5*(gammaScale(min(length(gammaScale),maxGammaIndex+1))+gammaScale(maxGammaIndex));
newGammaScale = [minGammaScale:(maxGammaScale-minGammaScale)/n:maxGammaScale];
newC = 2.^newCScale;
newGamma = 2.^newGammaScale;
maxRecognitionRate = 0;
for i = 1:length(newC)
for j = 1:length(newGamma)
cmd=['-t 2 -c ',num2str(newC(i)),' -g ',num2str(newGamma(j)),' -v 5'];
recognitionRate = svmtrain(yTraining,xTraining,cmd);
if recognitionRate>maxRecognitionRate
maxRecognitionRate = recognitionRate
maxC = newC(i);
maxGamma = newGamma(j);
end;
end;
end;
经过以上步骤,寻找出了使得识别率最大的超参数C和gammer
然后使用此C和gammer训练出最终的到模型
%Train the SVM model by the optimal C and gamma.
cmd=['-t 2 -c ',num2str(maxC),' -g ',num2str(maxGamma)];
model = svmtrain(yTraining,xTraining,cmd);
save model.mat model;%存储最终训练好的模型
save xTesting.mat xTesting;
save yTesting.mat yTesting;
最终获得模型model.mat
220个支持向量
b=39.9485
下面将所得模型在测试集上进行测试
% test the model on the remaining testing data and obtain the recognition rate.
% 加载训练结果并进行测试,保存结果
load model.mat;
[yPred,accuracy,decisionValues] = svmpredict(yTesting,xTesting,model);
save yPred.mat yPred;
save decisionValues.mat decisionValues;
兵王问题在测试样本上的混淆矩阵如下
实际上的正负样本的个数是不变的。按行做进行归一化操作得到
对同一个系统来说,如果TP增加,则FP也增加
显然,上图蓝色线条对应的系统性能最佳,紫色线条的系统性能最差
表示如图蓝色面积。面积越大 系统性能越佳
表示图中交点的横坐标。显然EER越小,系统性能越好
假设总共有K类,我们需要构造K个支持向量机模型
- 类别1 VS 类别2,3,4,...K
- 类别2 VS 类别1,3,4,...K
- 类别3 VS 类别1,2,4,...K
............
- 类别K VS 类别1,2,3,...K-1
对于每个优化问题,左边单一类别的标签为+1,右边K-1个类别的标签为-1
训练K个模型,得到K个α和b的组合
对于一个测试样本,预测其标签为
存在问题:训练样本不平衡
假设有三类,那就构建三个支持向量分类器
- 类别1 VS 类别2
- 类别1 VS 类别3
- 类别2 VS 类别3
对于某个测试样本X,采用投票方式判断其类别
若出现平票情况,如下图
分别计算类别1,类别2和类别3的分数和,选择分数最高的作为最终判断结果
存在问题:当K值较大时,需要训练的支持向量机数量太多
前提条件:需要保证每个分类器区分的两类有较大差别