#数据挖掘--第3章:建模调参之支持向量机SVM初体验

#数据挖掘--第3章:建模调参之支持向量机SVM初体验


  序言:本系列博客面向初学者,只讲浅显易懂易操作的知识。
  基础知识准备:
  一、我们在进行训练之前,常常要对样本进行归一化、标准化或正则化,以提高训练效果,这三个概念相近但不一样,归一化是为了消除不同数据之间的量纲,方便数据比较和共同处理,比如在神经网络中,归一化可以加快训练网络的收敛性;标准化是为了方便数据的下一步处理,而进行的数据缩放等变换,并不是为了方便与其他数据一同处理或比较,标准化后的数据更利于使用标准正态分布的性质进行处理;正则化则是利用先验知识,在处理过程中引入正则化因子(regulator),增加引导约束的作用,比如在逻辑回归中使用正则化,可有效降低过拟合的现象。当模型使用梯度下降法求最优解时,归一化或标准化往往非常有必要,否则很难收敛甚至不能收敛。
    (1)正则化
     用一组与原不适定问题相“邻近”的适定问题的解,去逼近原问题的解,这种方法称为正则化方法。使用 sklearn.preprocessing.Normalizer 类即可进行正则化,以下是示例。

from sklearn.preprocessing import Normalizer

X = [[4, 1, 2, 2],
     [1, 3, 9, 3],
     [5, 7, 5, 1]]
X = Normalizer().fit_transform(X) 
print(X)

# array([[0.8, 0.2, 0.4, 0.4],
#       [0.1, 0.3, 0.9, 0.3],
#       [0.5, 0.7, 0.5, 0.1]])

    (2)标准化
     在不知道样本的最大最小值时,将数据按比例缩放,使之落入一个小的特定区间, 即: y = ( x − μ ) σ {y = \frac{(x-μ)}{σ}} y=σ(xμ)

from sklearn import preprocessing
import numpy as np
 
x_train = np.array([[ 1., -1.,  2.],
                    [ 2.,  0.,  0.],
                    [ 0.,  1., -1.]])
x_scaled = preprocessing.scale(x_train)
print(x_scaled)
 
# output:
# [[ 0.         -1.22474487  1.33630621]
#  [ 1.22474487  0.         -0.26726124]
#  [-1.22474487  1.22474487 -1.06904497]]

    (3)归一化
     将训练数据区间缩放到[0-1]之间,即min-max归一化: y = ( x − m i n ) ( m a x − m i n ) {y = \frac{(x-min)}{(max-min)}} y=(maxmin)(xmin)

from sklearn import preprocessing
import numpy as np
 
x_train = np.array([[ 1., -1.,  2.],
                    [ 2.,  0.,  0.],
                    [ 0.,  1., -1.]])
min_max_scaler = preprocessing.MinMaxScaler()
x_train_minmax = min_max_scaler.fit_transform(x_train)
print(x_train_minmax)
 
# output:
# [[ 0.5         0.          1.        ]
#  [ 1.          0.5         0.33333333]
#  [ 0.          1.          0.        ]]

  
  二、在使用SVM之前,需要先熟悉 sklearn.svm.SVC,其中的几个参数尤为重要,我们需要记住:

  (1)C: 目标函数的惩罚系数C,用来平衡分类间隔margin和错分样本的,即对误差的宽容度。C越大,说明误差所带来的损失会越大,尽量避免,故容易过拟合。反之,C越小,容易欠拟合。

  (2)kernel:参数选择有rbf, linear, poly, sigmoid,precomputed或者自定义一个核函数, 默认的是"rbf",即高斯核函数;而linear指的是线性核函数,poly指的是多项式核,sigmoid指的是双曲正切函数tanh核。

  (3)gamma:核函数的系数,具体的意义可自行百度,这里不过多赘述,这个参数没有太多的调整的经验可言,更多的是靠自己去尝试。

  (4)decision_function_shape :详细含义不去探讨,读者只需记住对于二分类问题,常使用 ‘ovr’ 对于多分类问题常使用 ‘ovo’。

  (5)tol:svm 结束迭代的精度标准,若tol=1e - 3,即当1000次分类里出现错误少于等于1次时达到标准,可以结束迭代。
  
  三、下面进入实战

  这里笔者采用兵王问题,详细规则介绍见链接 兵王问题规则介绍 。如果需要数据集,请 点击下载 提取码: 67je 。
  进入实战:
  首先读取兵王问题数据集“krkopt.data”,对其进行如下处理:将 a-h 用 1-8 替换,draw 表示和棋用 1 替换,非 draw 用 0 替换,将替换后的数据进行归一化后保存到 krkopt_fill.csv 中

original_data = pd.read_csv("krkopt.data")
original_data.columns = ["wx", "wy", "wwx", "wwy", "vx", "vy", "outcome"]
original_data.replace(to_replace={'^a$': 1, '^b$': 2, '^c$': 3, '^d$': 4, '^e$': 5, '^f$': 6, '^g$': 7,
                                  '^h$': 8, '^draw$': 1, "(?!draw)": 0}, regex=True, inplace=True)
# 样本均值标准差归一化
original_data[['wx', 'wy', 'wwx', 'wwy', 'vx', 'vy']] = \
    preprocessing.scale(original_data[['wx', 'wy', 'wwx', 'wwy', 'vx', 'vy']])
pd.DataFrame(data=original_data).to_csv("krkopt_fill.csv")

  
随机划分数据集与训练集,训练集大小为 5000,并且将标签和数据分开

train_data, test_data, train_label, test_label = model_selection.train_test_split(
    original_data[['wx', 'wy', 'wwx', 'wwy', 'vx', 'vy']], original_data['outcome'], train_size=5000, random_state=0)

del original_data

  
训练 SVM

classifier = svm.SVC(C=1024, tol=2e-3, gamma=0.0625, kernel='rbf', decision_function_shape='ovr')
classifier.fit(train_data, train_label)

查看训练结果

score = classifier.score(test_data, test_label)
print("test score: ", score)

test score: 0.9937106918238994
  
  
完整代码:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import model_selection
from sklearn import svm
from sklearn import preprocessing
# %% 数据的初步处理,将 a-h 用 1-8 替换,draw 表示和棋用 1 替换,非 draw 表示一方赢兵王赢,用 0 替换
# 将替换后的数据归一化并保存到 krkopt_fill.csv

original_data = pd.read_csv("krkopt.data")
original_data.columns = ["wx", "wy", "wwx", "wwy", "vx", "vy", "outcome"]
original_data.replace(to_replace={'^a$': 1, '^b$': 2, '^c$': 3, '^d$': 4, '^e$': 5, '^f$': 6, '^g$': 7,
                                  '^h$': 8, '^draw$': 1, "(?!draw)": 0}, regex=True, inplace=True)
# 样本均值标准差归一化
original_data[['wx', 'wy', 'wwx', 'wwy', 'vx', 'vy']] = \
    preprocessing.scale(original_data[['wx', 'wy', 'wwx', 'wwy', 'vx', 'vy']])
pd.DataFrame(data=original_data).to_csv("krkopt_fill.csv")
#%% 从 krkopt_fill 中读取处理后的数据

original_data = pd.read_csv("krkopt_fill.csv")
# %% 随机划分数据集与训练集,训练集大小为 5000,并且将标签和数据分开

train_data, test_data, train_label, test_label = model_selection.train_test_split(
    original_data[['wx', 'wy', 'wwx', 'wwy', 'vx', 'vy']], original_data['outcome'], train_size=5000, random_state=0)

del original_data
#%% 训练 SVM
classifier = svm.SVC(C=10, tol=2e-3, gamma=0.8, kernel='rbf', decision_function_shape='ovr')
classifier.fit(train_data, train_label)
#%% 查看训练结果
score = classifier.score(test_data, test_label)
print("test score: ", score)
score = classifier.score(train_data, train_label)
print("train score: ", score)
#%%
print(classifier.n_support_)

参考文献:
https://www.biaodianfu.com/python-normalization-method.html
https://blog.csdn.net/lujiandong1/article/details/46386201
https://blog.csdn.net/dongrixinyu/article/details/79039215

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值