基于LibSVM的兵王问题实现
本文最后更新于:2023年12月20日 晚上
纸上得来终觉浅,绝知此事要躬行。为了将 LibSVM 库的学习赋予实践,博主在这里基于 Python 的 LibSVM 对浙江大学《机器学习》课程中的兵王问题进行了复现,并以此博客来记录自己的学习过程。
一、问题背景
国际象棋的兵王问题:棋盘上黑方只剩一个王,白方剩一个王 一个兵,棋局只有两个结果:“白方将死黑方获胜”或者“和棋”,这个问题属于二分类的问题。这里要利用支持向量机解决这个问题,实现在不告诉计算机国际象棋规则的前提下,让计算机可以根据棋子位置判断棋局的结果。
二、数据集
本次用到的数据集为 UCI Machine Learning Repository: Chess (King-Rook vs. King) Data Set
数据集一共包含28056个数据,其中“和棋”样本2796个,“白方胜”样本25260个。数据集的解释如下
三、LibSVM工具包
LibSVM是由台湾大学林智仁教授等开发设计的SVM工具包,支持C, C++, Java,Python , R 和 Matlab 等
1. 为Python安装LibSVM
利用pip运行如下安装命令:
1 |
|
2. LibSVM的使用
LibSVM的使用非常简单,只需调用其为我们提供的接口即可,这里我们只需了解其常用的几个接口:
- svm_problem
- svm_parameter
- svm_train
- svm_predict
- svm_save_model
- svm_load_model
具体用法可以参考博主 finley 写的这篇博客:LibSVM for Python 使用,个人觉得很详细。
四、实现流程
1. 预处理数据
首先,尝试加载数据,并观察其内容与分布等基本信息,便于我们后续处理
1 |
|
1 |
|
1 |
|
可以发现数据中存在的字符类型,这显然是不行的,我们需要对其进行数值化处理。a,b,c等代表的是棋子的横坐标位置,不妨用1代表a,2代表b,以此类推;同样对于结果而言,利用+1替代draw(正样本),其他则用-1代替(负样本),代码如下:
1 |
|
为了消除指标之间的量纲影响,而对训练造成影响,需要进行数据标准化处理:
$$
Xtraining = \frac{Xtraining - meanX}{stdX}
$$
1 |
|
到这里,数据的预处理已经完成,下面我们就可以正式开始构建我们自己的 SVM 模型了。
2. 超参数选择
我们选择 RBF 内核的支持向量机,有两个超参数 $C$,$\gamma$ 进行确定。LibSVM 的帮助文档中建议 $C\in [2^{-5}, 2^{15}]$,$\gamma\in[2^{-15},2^{3}]$。这里我们遵循文档规定,在此范围内进行粗略搜索;同时这里采用五折交叉验证方法对超参数的优劣进行判断
1 |
|
经过粗略的搜索,发现 $C=2048$,$\gamma=0.3125$ 时,验证集的准确率较高;这就完了?当然没有。也许会有更好结果,说不准呢。我们可以考虑在目前得到的最优值附近进行进一步搜索,期望可以得到意外收获。
1 |
|
到这里,我们的超参数的搜索结束了,确定 $C=1176.267$,$\gamma=0.041235$;利用此参数再次训练得到最终的 SVM 模型,并将其存为【model_file】文件,再调用该模型进行测试集的分类,结果显示准确率达到 99.41%
1 |
|
五、完整代码展示
1 |
|