机器学习笔记-01(SVM解决兵王问题MATLAB程序)

机器学习笔记-01(SVM解决兵王问题MATLAB程序)

最近在学习浙江大学胡浩基老师的机器学习一课程,以下内容也是围绕该课程而写的课程笔记,原课程可直接在中国慕课上搜索。

一、国际象棋规则介绍

编写程序之前很重要的一个原则是要先知道所要解决的问题是什么,尽管是在入门学习的时候也不能够只分析代码而忽略问题的本质。

  • 国际象棋规则:8*8棋盘,黑、白兵各有8个,王各有1个。
  • 兵:第一次向前可以走一格或两格,以后只能向前走一格,不能后退;吃对方子的时候可以斜前方走,并落在对方位置。
  • 王:黑白各一个,王被将死即告负,走法是横着、斜着都可以,但是每次只能走一格。
  • 兵的升变:兵走至对方底线,可以升变为除王以外的任意一子。
  • 逼和:一方的王未被将军,但移动到任意地方都会被对方将死,则此时是和棋。
  • 兵王问题:国际象棋的残局中,黑方只剩下一个王,白方剩一个兵和一个王。
  • 两种结局:白方将死黑方,白方获胜,或者和棋。

逼和的情况

二、数据集和LIBSVM工具包的获取

(1)数据集的获取

利用支持向量机判断兵王问题即是白方胜还是和棋,属于二分类问题,首先需要有标注好的训练数据,在UCI MACHINE LEARNING中可以下载到兵王问题的数据https://archive.ics.uci.edu/ml/index.php(搜索文件krkopt.data)

UCI网站
很不幸的是不知道是网站问题还是我的电脑或者浏览器之类的有问题,当我搜索krkopt.data时总是会出现“你的连接不是专用连接”de1错误提示,机智的我按着百度上面的各种提示,先是在出现“你的连接不是专用连接”时用键盘敲打thisisunsafe后>>>>就出现了下图所示的“找不到此www.google.com 页面”的提示。

在这里插入图片描述???
机智的我怎么可能被打倒!然后凭着我的高端(小学)英语阅读水平,在页面右上角你们猜我找到了什么!!没错!是所有数据集!
查看所有数据集!!
然后又凭着我尖锐的眼光在几百几百条数据集中找到了!chess!!
chess
好吧 其实并不难找,页面往下划不用多久就能见到了,krkopt.data文件就在其中一个链接当中。

(2)LIBSVM工具包的获取

下载网址:https://www.csie.ntu.edu.tw/~cjlin/libsvm/
打开后点击如图所示下载压缩包即可
在这里插入图片描述
LIBSVM 的主要功能包括:

  1. 不同的 SVM 配方
  2. 高效的多类分类
  3. 模型选择的交叉验证
  4. 概率估计
  5. 各种内核(包括预计算内核矩阵)
  6. 不平衡数据的加权
  7. SVM 系统C++和 Java源
  8. 演示SVM 分类和回归的 GUI Python, R, MATLAB, Perl, Ruby , Weka,通用 LISP、 CLISP、 Haskell、 OCaml、 LabVIEW和PHP接口。 C#.NET代码和CUDA扩展可用。 它还包含在一些数据挖掘环境中:Rapidminer、PCP和LIONsolver。
  9. 可生成交叉验证精度轮廓的自动模型选择。

其实呢,在慕课的这门课程里这节课对应的章节就有所有要用到的资料的压缩包,第二章的第12节,但是当我欣喜雀跃的时候发现下载不了!换了个浏览器我才真正获得。
为了方便大家使用我把资源上传到了百度云,供有需要学习的人参考
链接:https://pan.baidu.com/s/1pRvw7CB87utJJn1wASYaSw
提取码:560m
谷歌浏览器
这么一来二去,看起来像是瞎折腾,把过程写下来看起来也很没必要,但是呢,起码我学会了如何在UCI MACHINE LEARNING和LIBSVM的网站上查找资料呀!顺便提一下把遇到的问题po出来是为了如果有像我这样遇到同样问题的人能够找到方案,而不是在小白启航之路上被不值得成为绊脚石的石头绊倒。(虽然遇到我这种低级问题的人估计也不多了,请跳过!)

三、程序参数设置

在兵王问题的训练集中,训练样本是六维的,代表了三颗棋子在棋盘上的位置。
其中:

  • 总样本数:28056个
  • 正样本数(yi=+1,和棋):2796个
  • 负样本(yi=-1,白方胜):25260个

(1)第一步:对数据进行预处理

  • 总样本数28056个, 正样本数2796个,负样本数25260个
  • 随机取5000个进行训练,其余用于测试
p = randperm(M); %直接打乱了训练样本
numberOfSamplesForTraining = 5000;
  • 对训练样本归一化
    归一化
    **训练样本归一化(NORMALIZATION OF TRAINING DATA)**是构建机器学习分类器时常用的技术,它可以将输入特征的每个维度限定在一个固定范围内,从而减少不同维度由于动态范围不同导致的训练误差。
for i = 1:numVec%归一化操作,每个训练集上的样本,每个维度都减掉了均值再除以这个维度相应的方差
    xTraining(i,:) = (xTraining(i,:)-avgX)./stdX;
end;

(2)第二步:设置支持向量机的各种参数

在这里插入图片描述
表示选择了目标函数为:
在这里插入图片描述
在这里插入图片描述
他用于选择支持向量机的核函数K(X1,X2),数字0、1、2、3分别代表以下四种支持向量机最经常使用的核函数,4表示的是自定义的核函数。
在这里插入图片描述

  1. 其中Linear是线性核只具有理论意义,因为前面讲过使用线性核函数求解向量机和不使用核函数获得的结果是完全一样的。
  2. 可通过调节d的大小来控制φ(x)的维度,从而控制核函数的复杂度(d越大,复杂度越高)。
  3. Rbf径向基函数核:对应的映射函数φ(x)维度是无限的,含有高斯函数的优良性质,一般最常用。
  4. Tanh:对应的映射函数φ(x)维度也是无限的。

在这里插入图片描述
这里C的取值其实就是原问题中C的值和对偶问题中C的值:在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
gamma值的设定与选择的核函数有关。

四、代码及部分分析

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;




  1. C和Gamma取值问题:根据人工经验,这里的C的取值范围一般是2-5—215,gammma的取值一般是2-15—23,遍历此范围内寻找使识别率最大的C与Gamma,即寻找最适合的参数。
  2. 训练支持向量机的样本不能用来测试识别率,否则会导致出现过拟合情况。
  3. 为了避免上述过拟合情况出现一般采用交叉验证的方法:
    即将5000个样本分为ABCDE五个部分,进行5次训练,称为五折法;
    若将样本分为4999个训练样本和1个测试样本,进行5000次训练则称为留一法,适用于训练样本小的数据集。
  • 10
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值