Site Overlay

大数据学习-SVM支持向量机


文章热度: 42 热度

SVM说明

适用范围

  • 分类
  • 回归
  • 异常检测

优劣点

优点

  • 在高维空间中非常高效
  • 即使在数据维度比样本数量大的情况下仍然有效
  • 在决策函数(称为支持向量)中使用训练集的子集,因此它也是高效利用内存的
  • 通用性: 不同的核函数核函数与特定的决策函数一一对应.常见的 kernel 已经提供,也可以指定定制的内核.

缺点

  • 如果特征数量比样本数量大得多,在选择核函数 核函数 时要避免过拟合, 而且正则化项是非常重要的
  • 支持向量机不直接提供概率估计,这些都是使用昂贵的五次交叉验算计算的

代码说明

方法使用了sklearn库,其中数据部分采用常见的花分类。

数据格式:

  • ID
  • Sepal.Length
  • Sepal.Width
  • Petal.Length
  • Petal.Width
  • Species

我们根据代码

print(data.describe)

导出数据信息,如下表

数据描述:
<bound method NDFrame.describe of       ID  Sepal.Length  Sepal.Width  Petal.Length  Petal.Width    Species
0      1           5.1          3.5           1.4          0.2     setosa
1      2           4.9          3.0           1.4          0.2     setosa
2      3           4.7          3.2           1.3          0.2     setosa
3      4           4.6          3.1           1.5          0.2     setosa
4      5           5.0          3.6           1.4          0.2     setosa
..   ...           ...          ...           ...          ...        ...
145  146           6.7          3.0           5.2          2.3  virginica
146  147           6.3          2.5           5.0          1.9  virginica
147  148           6.5          3.0           5.2          2.0  virginica
148  149           6.2          3.4           5.4          2.3  virginica
149  150           5.9          3.0           5.1          1.8  virginica
​
[150 rows x 6 columns]>

因为数据结构大部分采用csv格式,因此我们采用pandas进行文件操作。代码很容易看明白,不再进行解释了。

代码

from sklearn.datasets import load_wine
import numpy as np 
from sklearn.model_selection import *
from sklearn import *
import pandas as pd
from sklearn.externals import joblib

#读取数据集,需要训练的部分在feature,结果在target
data = pd.read_csv("/home/joger/Downloads/iris.csv",sep=",")

print("数据描述:")
print(data.describe)

feature = data.drop(['Species','ID'],axis=1)
target = []
for item in data.Species.values:
    target.append([item])
target = np.array(target)
# print(target)

#*******************可选-数据标准化*******************#
#如果使用svm则不必标准化
#训练数据标准化(数据缩放到0~1之间)
# min_max_scaler = preprocessing.MinMaxScaler()
# feature = min_max_scaler.fit_transform(feature)
#*******************可选-数据标准化*******************#

#将数据的30%作为测试集
x_train, x_test, y_train, y_test = train_test_split(
    feature,            #训练数据
    target,             #结果
    test_size = 0.3,    #测试数据比例=30%
    random_state = True #随机分配
)

#*******************可选-支持向量机*******************#
#支持向量机
clf = svm.SVC(
    C=1.,                              #惩罚系数,C越大更趋向于训练集全对,训练集准确度很高,泛化能力低
                                        #C值小,对分类的惩罚小,容错率高
    cache_size=1024,                     #指定训练所需要的内存,以MB为单位,默认为200MB。
    class_weight=None,                  #给每个类别分别设置不同的惩罚参数C,如果没有给,则会给所有类别都给C=1,即前面参数指出的参数C.
                                        #如果给定参数‘balance’,则使用y的值自动调整与输入数据中的类频率成反比的权重。
    coef0=0.0,                          #核函数中的独立项,只有对‘poly’和‘sigmod’核函数有用,是指其中的参数c
    decision_function_shape='ovo', 
    degree=3,                           #这个参数只对多项式核函数有用,是指多项式核函数的阶数n,如果给的核函数参数是其他核函数,则会自动忽略该参数。
    gamma='auto',                       #核函数系数,只对‘rbf’,‘poly’,‘sigmod’有效。如果gamma为auto,代表其值为样本特征数的倒数,即1/n_features.
    kernel='rbf',                       #核函数,可以是
                                        #‘linear’线性 
                                        #‘poly’多项式
                                        # ‘rbf’径像核函数/高斯核
                                        # ‘sigmoid’sigmod核函数
                                        # ‘precomputed’核矩阵,表示自己提前计算好核函数矩阵,这时候算法内部就不再用核函数去计算核矩阵,而是直接用你给的核矩阵。
    max_iter=-1,                        #最大迭代次数,如果为-1,表示不限制
    probability=True,                   #当probability=True时,开启可能性评估,是否启用概率估计。 这必须在调用fit()之前启用,并且会fit()方法速度变慢。
    random_state=None,                  #伪随机数发生器的种子,在混洗数据时用于概率估计。
    shrinking=True,                     #是否采用启发式收缩方式
    tol=0.001,                          #svm停止训练的误差精度
    verbose=False                       #是否启用详细输出。 此设置利用libsvm中的每个进程运行时设置,如果启用,可能无法在多线程上下文中正常工作。一般情况都设为False,不用管它。
    )
#*******************可选-支持向量机*******************#

#开始拟合
print("开始拟合:" , clf.fit(x_train,y_train))

#预测结果保存在result中
result = [[item] for item in clf.predict(x_test)]
#将预测结果和实际结果比对放到accu中
accu = result == y_test

#计算训练准确度
print("训练结果在测试机预测准确度:" , sum(accu) / y_test.shape[0])

#计算每个测试数据在每个标签下的概率
result_proba = clf.predict_proba(x_test)

joblib.dump(clf, 'clf.model')
print("模型保存成功!")

#如果上面训练准确度合格,则可以下面进行预测

#*******************获得结果*******************#
#读取数据集,需要训练的部分在feature,结果在target
feature = data.drop(['Species','ID'],axis=1)

#读取模型
clf = joblib.load('clf.model')
print("打开模型" , clf)

#训练数据标准化(数据缩放到0~1之间)
min_max_scaler = preprocessing.MinMaxScaler()
feature = min_max_scaler.fit_transform(feature)

#获得预测结果
#预测结果保存在result中
result = clf.predict(feature)               #预测结果列表

#获得预测结果对应的概率
result_rate = []
result_proba = clf.predict_proba(x_test)
for proba in result_proba:
    result_rate.append(max(proba))          #取最高概率的标签的概率
print("result_rate:" , result_rate)
#之后保存

核函数

核函数作用

SVM 的处理方法是选择一个核函数 κ(⋅,⋅) ,通过将数据映射到高维空间,来解决在原始空间中线性不可分的问题。

即,当低维度无法进行区分的时候,通过核函数映射到高纬度上进行划分:

我们通过网上整理的图片进行描述

一维数据经过核函数映射到三维空间,实现可分离
图自(https://blog.csdn.net/wjwfighting/article/details/81487040
一维数据映射到三维空间里
图自(https://blog.csdn.net/wjwfighting/article/details/81487040
动图
图自(https://blog.csdn.net/wjwfighting/article/details/81487040
动图
图自(https://blog.csdn.net/wjwfighting/article/details/81487040

核函数选择

linear kernel

线性可分时,特征数量多时,样本数量多再补充一些特征时,linear kernel可以是RBF kernel的特殊情况

Polynomial kernel

image processing,参数比RBF多,取值范围是(0,inf)

Gaussian radial basis function (RBF)

通用,线性不可分时,特征维数少 样本数量正常时,在没有先验知识时用,取值在[0,1]

Sigmoid kernel

生成神经网络,在某些参数下和RBF很像,可能在某些参数下是无效的。

其中 linear kernel 和 RBF kernel 在线性可分和不可分的对比可视化例子如下:

linear kernelRBF kernel
线性可分
线性不可分

相关系数

  • gamma

gamma 越大,支持向量越少,gamma 越小,支持向量越多。

支持向量的个数影响训练和预测的速度。

  • C

C 越高,容易过拟合。C 越小,容易欠拟合。

3+

说点什么

200
  Subscribe  
提醒
Copyright 王政乔 | 中国. 联系方式:me@zhengqiao.wang