最近在学习浙江大学胡浩基老师的机器学习一课程,以下内容也是围绕该课程而写的课程笔记,原课程可直接在中国慕课上搜索。
编写程序之前很重要的一个原则是要先知道所要解决的问题是什么,尽管是在入门学习的时候也不能够只分析代码而忽略问题的本质。
利用支持向量机判断兵王问题即是白方胜还是和棋,属于二分类问题,首先需要有标注好的训练数据,在UCI MACHINE LEARNING中可以下载到兵王问题的数据https://archive.ics.uci.edu/ml/index.php(搜索文件krkopt.data)
很不幸的是不知道是网站问题还是我的电脑或者浏览器之类的有问题,当我搜索krkopt.data时总是会出现“你的连接不是专用连接”de1错误提示,机智的我按着百度上面的各种提示,先是在出现“你的连接不是专用连接”时用键盘敲打thisisunsafe后>>>>就出现了下图所示的“找不到此www.google.com 页面”的提示。
???
机智的我怎么可能被打倒!然后凭着我的高端(小学)英语阅读水平,在页面右上角你们猜我找到了什么!!没错!是所有数据集!
然后又凭着我尖锐的眼光在几百几百条数据集中找到了!chess!!
好吧 其实并不难找,页面往下划不用多久就能见到了,krkopt.data文件就在其中一个链接当中。
下载网址:https://www.csie.ntu.edu.tw/~cjlin/libsvm/
打开后点击如图所示下载压缩包即可
LIBSVM 的主要功能包括:
其实呢,在慕课的这门课程里这节课对应的章节就有所有要用到的资料的压缩包,第二章的第12节,但是当我欣喜雀跃的时候发现下载不了!换了个浏览器我才真正获得。
为了方便大家使用我把资源上传到了百度云,供有需要学习的人参考
链接:https://pan.baidu.com/s/1pRvw7CB87utJJn1wASYaSw
提取码:560m
这么一来二去,看起来像是瞎折腾,把过程写下来看起来也很没必要,但是呢,起码我学会了如何在UCI MACHINE LEARNING和LIBSVM的网站上查找资料呀!顺便提一下把遇到的问题po出来是为了如果有像我这样遇到同样问题的人能够找到方案,而不是在小白启航之路上被不值得成为绊脚石的石头绊倒。(虽然遇到我这种低级问题的人估计也不多了,请跳过!)
在兵王问题的训练集中,训练样本是六维的,代表了三颗棋子在棋盘上的位置。
其中:
p = randperm(M); %直接打乱了训练样本
numberOfSamplesForTraining = 5000;
for i = 1:numVec%归一化操作,每个训练集上的样本,每个维度都减掉了均值再除以这个维度相应的方差
xTraining(i,:) = (xTraining(i,:)-avgX)./stdX;
end;
表示选择了目标函数为:
他用于选择支持向量机的核函数K(X1,X2),数字0、1、2、3分别代表以下四种支持向量机最经常使用的核函数,4表示的是自定义的核函数。
clear all;
% Read the data.
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;
fclose(fid);
[N,M] = size(xapp);
p = randperm(M); %直接打乱了训练样本
numberOfSamplesForTraining = 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';
%%%%%%%%%%%%%%%%%%%%%%%%
%Normalization
[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;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%SVM Gaussian kernel
%Search for the optimal C and gamma, K(x1,x2) = exp{-||x1-x2||^2/gamma} to
%make the recognition rate maximum.
%首先需要对C和Gamma两个参数的取值进行搜索,c的取值范围是:2^-5--2^15,gamma的取值范围:2^-15--2^3,该范围是基于人工的经验;
%对数据进行交叉验证,初步找出识别率最高的c与gamma的组合
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;
%进一步缩小搜索范围,再次进行交叉验证,找出识别率最高的更精确的c与gamma的组合
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;
%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;