1.说明
最近在B站看了浙江大学胡浩基老师的机器学习课程,完全面向入门人群感觉挺好。其中有关原理的部分讲的很细。其中在第六章-支持向量机的例题兵王问题中课程只给了MATLAB的版本,没有Python语言的优势。所以本文首先根据胡老师的MATLAB版的思路改写成Python版,然后使用Python的优势重新编写一版。
2.问题分析
在国际象棋中,存在着一种残局的现象。剩余三子,分别是黑方的王,白方的王和兵,那么无论这三子在棋盘的布局如何,只有两种结果,白方胜利和逼和。这就是一个二分类问题。
3. 数据集
关于这个问题的数据集krkopt.DATA可以在老师给的代码里面找到,然后老师也推荐了一个网址UCI Machine Learning
数据形式:前面六个就是棋子的位置,draw就是逼和,后面的数字eight就代表,白棋最少用8步就能将死对方。
a,1,b,3,c,2,draw
a,1,c,1,c,2,draw
c,2,c,6,e,1,eight
...
4.代码实现
4.1 MATLAB思想的Python实现
# -*- coding: utf-8 -*-
import numpy as np
from libsvm.svm import *
from libsvm.svmutil import *
def data_read_mat(file_name):
'''
从文件中取出数据
:param file_name: 文件名称
:return: 返回一个n*7的矩阵,前6项是三个坐标,第七项是标签
'''
num_list = []
'''
一下是对数据进行读入并且处理,其中open的参数中encoding之所以设置成UTF-8-sig
是因为如果我们把这个参数设置为UTF-8或者不设置,在读入的开头多出\ufeff这么一串
东西,有时候会以中文字的形式出现。
'''
with open(file_name, "r", encoding='UTF-8-sig') as file:
for l in file:
l = l.split(',')
list_k = []
for j in range(3):
list_k.append(ord(l[j * 2]) - ord('a'))
list_k.append(ord(l[j * 2 + 1]) - ord('0'))
if (l[6][0] == 'd'):
list_k.append(0)
else:
list_k.append(1)
num_list.append(list_k)
num_mat = np.array(num_list, dtype="float")
'''
在此处是以numpy的二维数据矩阵的形式存储的,本以为使用numpy的数据进行运算可以使得
训练的速度快一些。结果发现如果要往libsvm中的函数传入参数只能传入list型不能传入numpy
的数据类型。所以,后面又把数据类型转回了list型。但是,我猜应该是有方法可以把numpy
的数据类型传入使用的。于是我在读取数据后任然返回的是numpy的形式。
'''
return num_mat
def data_deal(mat, len_train, len1, len_test, len2):
'''
将数据进行处理,分出训练数据和测试数据
:param mat: 大矩阵,其中包括训练数据和测试数据
:param len_train:训练数据
:para