背景
继续学习浙大《机器学习》课程。第一部分支持向量机学的差不多了,终于可以整点实践了。课程里展示了用libsvm求解兵王问题。
课程里是用matlab演示的。但我从来没用matlab,所以按照自己的理解用python写了一遍。自己实践的时候也发现一些看视频的时候没想到的问题。这里就讲解下我的实践。
兵王问题
简单搜了下网上居然没什么百科词条专门讲兵王问题。(看来这个问题也不是啥知名的问题啊😓)
兵王问题就是一个国际象棋棋盘上,一方只剩一个王,另一方剩一个王一个兵,需要判断出一王一兵的这方能不能赢得最终的胜利(还是会被对方逼和)。

注意,上图这个局面(现在轮到黑方行动),是黑方逼和成功。
没错,我也不理解。这个和中国象棋不一样。现在黑方是无路可走,所以是和棋。
Anyway,总之问题就是给出三个棋子的位置,判断结果一方是否能赢。
数据集
当然了,我们不用自己去整很多不同的局面出来再自行判断每个局面结果如何。原视频中给出了测试数据下载链接(UCI Machine Learning Repository)。里面已经提供了一组数据,一共有28000+个。每一组数据是三个棋子的位置加上这个局面的结果。
然而,在这个链接上我并没有搜到数据文件。不过在github的这个repo里找到了数据文件。
求解步骤
我看到网上也有很多文章也做了同样的事,大都把整个过程写在了一块。我趋向于把这些步骤分开,可以让我们对每一步的作用更清晰,也可以避免每次运行都要把整个过程都跑一遍。
先大体说一下步骤,再看每一步的细节。
- 将数据集抽出一部分作为训练集,剩下的作为测试集。这个大家也都明白,否则会产生过拟合。相当于拿练习的卷子当作考试的卷子。
- 对数据进行归一化。
- 用训练集训练模型,尝试不同的超参数 C C C 和 γ \gamma γ,以寻找最优超参数。
- 以最优超参数,训练出最终模型。
- 使用最终模型在测试集上进行测试,查看模型的准确率。
分割测试集
课程视频里把28000+个数据中分出了5000个作为训练集。我们也分5000个。
这是第一部分的代码 (dataset_devide.py):
import pandas as pd
TRAIN_DATASET_SIZE = 5000
if __name__ == '__main__':
df = pd.read_csv('krkopt.data', header=None)
shuffled = df.sample(frac=1).reset_index(drop=True)
train_data = shuffled[:TRAIN_DATASET_SIZE]
test_data = shuffled[TRAIN_DATASET_SIZE:]
train_data.to_csv('krkopt_train.data', header=False, index=False)
test_data.to_csv('krkopt_test.data', header=False, index=False)
就是读取krkopt.data,然后打乱,再分成两部分。抽出5000个存入krkopt_train.data。剩下的存入krkopt_test.data。
个人很喜欢用pandas,这里使用pandas非常容易。
寻找最优超参数
两个超参数
回顾一下,支持向量机问题的原问题。最小化:
1 2 ∥ ω ∥ 2 + C ⋅ ∑ i = 1 N δ i \frac{1}{2} \left \| \omega \right \|^{2} + C \cdot \sum_{i=1}^{N}\delta_{i} 21∥ω∥2+C⋅i=1∑Nδi
这里的 C C C是一个需要人为设定的超参数。
另外因为支持向量机问题的求解中用到了核函数戏法并且选择了高斯核函数:
e − γ ( ∥ X − X ′ ∥ 2 ) e^{-\gamma( \left \| X - X' \right \|^2)} e−γ(∥X−X′∥

本文介绍了作者跟随浙江大学《机器学习》课程学习,用Python重写了MATLAB中的兵王问题解决方案,包括数据预处理、划分训练集和测试集、寻找最优C和γ超参数,以及最终模型的训练和测试。作者分享了代码实现和优化过程,模型达到99.38%的识别率。
最低0.47元/天 解锁文章
6098






