支持向量机(SVM)是一组用于分类、回归和异常值检测的有监督学习方法。
SVMs: LinearSVC, Linear SVR, SVC, Nu-SVC, SVR, Nu-SVR, OneClassSVM
支持向量机的优点是:
高维空间中的有效性。
在维数大于样本数的情况下仍然有效。
在决策函数中使用训练点的子集(称为支持向量),因此它也是内存有效的。
多功能:可以为决策函数指定不同的内核函数。提供了常见核函数,但也可以自定义核函数。
支持向量机的缺点包括:
如果特征数远大于样本数,通过选择核函数和正则项避免过拟合是至关重要的。
支持向量机不直接提供概率估计,这些计算使用计算量大的的5折-交叉验证。
最简单分类超平面,1维:x=0,2维:x1+x2=0
当θTXi与 θTX值大于1时,也就是距离分类边界大于1,此时无损,损失为1 - ||θTXi - θTX||,下限为0无上限。
import time
import numpy as np
import scipy.io as scio
import pandas as pd
from numpy import newaxis
#from pylab import * #包含了NumPy和pyplot常用的函数
from sklearn.cluster import KMeans
from sklearn import svm
from sklearn.svm import SVC
from sklearn.svm import LinearSVC
from sklearn.svm import NuSVC
from sklearn.svm import SVR
from sklearn.svm import LinearSVR
from sklearn.datasets import make_regression
from sklearn.datasets import make_classification
对于多分类问题,SVC采用的是one-vs-one投票机制,需要两两类别建立分类器,训练时间可能比较长。
SVC参数解释:
C: 误差项的惩罚系数C ,用来平衡分类间隔margin (误差距离平方和?cost1和cost2,大于1(-1)时损失为0)和错分样本的 (default=1.0);
kernel: 'linear', 'poly', 'rbf', 'sigmoid', 'precomputed' ,(default='rbf');
degree : 多项式核'poly'的阶数,(default=3);
gamma : 'rbf', 'poly' 及'sigmoid'的核系数,默认时为(1/特征个数),(default='auto');
coef0 : 核函数中的独立项,仅在'poly' 和 'sigmoid'中显著,(default=0.0);
probability : 是否使用概率估计,必须在'fit'前使用,并会减慢速度,(default=False);
shrinking :是否使用shrinking heuristic,(default=True);
tol:停止准则的门槛,(default=1e-3);
cache_size : 核缓存(in MB);在大样本的时候,缓存大小会影响训练速度,因此如果机器内存大,推荐用500MB or 1000MB。默认是200MB;
class_weight :类别权重,设置每个类别权重系数。对于每一个类别i设置惩罚系数C = class_weight[i]*C。如果不给出 (default=1);样本数量不均衡时设置为'balanced',权重自动调整为 n_samples / (n_classes * np.bincount(y)), 此时某种类型样本量越多,则权重越低;样本量越少,则权重越高;np.bincount(y)每个类的样本数;
verbose: 如果启用,可能无法在多线程环境正常工作,(default=False);
max_iter: 最大迭代次数,'-1'时无限制, (default=-1);
decision_function_shape : 返回一对多 'ovr'决策函数(n_samples, n_classes),或原始一对一'ovo'决策函数(n_samples, n_classes * (n_classes - 1) / 2),(default='ovr');
random_state: 设置随机数种子,如果设置了随机数种子,则每次实验都能得到一样的结果,即每次运行取随机数都能得到相同的数 (default=None);
输出:
support_ : 支持向量指数;
support_vectors_ : 支持向量;
n_support_ : 每一类的支持向量个数;
dual_coef_ : 决策函数中支持向量的系数,对于多分类为1-vs-1分类器的系数;
coef_ : 返回每个特征的权重,仅线性核时有效;
intercept_ : 决策函数中的常数,截距;
例子:
#import blabla ,在开始那些先导入
#SVC,基于libsvm,不适用于数量大于10K的数据(时间复杂度高)
#数据准备
data = scio.loadmat("train and test top321.mat") #导入数据
test = data['test'] #待分类数据
testclass = data['testclass']
testclass = np.ravel(testclass)
train = data['train']
trainclass = data['trainclass']
trainclass = np.ravel(trainclass)
#建模分类
clf = SVC(kernel='linear')
clf.fit(train, trainclass)
weight = clf.coef_
print(clf.predict(test))
Pretest = clf.predict(test) #输出分类标签
a = Pretest ^ testclass
acc = (a.size-a.sum())/a.size
print("Accuracy:",acc)
print("支持向量指数:",clf.support_)
print("支持向量",clf.support_vectors_)
print("每一类的支持向量个数",clf.n_support_)
print("支持向量的系数:",clf.dual_coef_)
print("截距:",clf.intercept_)
Nu-SVC的实现基于libsvm,通过一个参数控制支持向量,
Nu-SVC参数解释:
degree : 多项式核'poly'的阶数,(default=3);
gamma : 'rbf', 'poly' 及'sigmoid'的核系数,默认时为(1/特征个数),(default='auto');
coef0 : 核函数中的独立项,仅在'poly' 和 'sigmoid'中显著,(default=0.0);
probability : 是否使用概率估计,必须在'fit'前使用,并会减慢速度,(default=False);
shrinking :是否使用shrinking heuristic,(default=True);
tol:停止准则的门槛,(default=1e-3);
cache_size : 核缓存(in MB);在大样本的时候,缓存大小会影响训练速度,因此如果机器内存大,推荐用500MB or 1000MB。默认是200MB;
class_weight :类别权重,设置每个类别权重系数。对于每一个类别i设置惩罚系数C = class_weight[i]*C。如果不给出 (default=1);样本数量不均衡时设置为'balanced',权重自动调整为 n_samples / (n_classes * np.bincount(y)), 此时某种类型样本量越多,则权重越低;样本量越少,则权重越高;np.bincount(y)每个类的样本数;
verbose: 如果启用,可能无法在多线程环境正常工作,(default=False);
max_iter: 最大迭代次数,'-1'时无限制, (default=-1);
decision_function_shape : 返回一对多 'ovr'决策函数(n_samples, n_classes),或原始一对一'ovo'决策函数(n_samples, n_classes * (n_classes - 1) / 2),(default='ovr');
random_state: 设置随机数种子,如果设置了随机数种子,则每次实验都能得到一样的结果,即每次运行取随机数都能得到相同的数 (default=None);
输出:
support_ : 支持向量指数;
support_vectors_ : 支持向量;
n_support_ : 每一类的支持向量个数;
dual_coef_ : 决策函数中支持向量的系数,对于多分类为1-vs-1分类器的系数;
coef_ : 返回每个特征的权重,仅线性核时有效;
intercept_ : 决策函数中的常数,截距;
#import blabla ,在开始那些先导入
#NuSVC,基于libsvm,通过一个参数控制支持向量
#数据准备
data = scio.loadmat("train and test top321.mat") #导入数据
test = data['test'] #待分类数据
testclass = data['testclass']
testclass = np.ravel(testclass)
train = data['train']
trainclass = data['trainclass']
trainclass = np.ravel(trainclass)
#建模分类
clf = NuSVC(kernel='linear')
clf.fit(train, trainclass)
weight = clf.coef_
print(clf.predict(test))
Pretest = clf.predict(test) #输出分类标签
a = Pretest ^ testclass
acc = (a.size-a.sum())/a.size
print("Accuracy:",acc)
print("支持向量指数:",clf.support_)
print("支持向量",clf.support_vectors_)
print("每一类的支持向量个数",clf.n_support_)
print("支持向量的系数:",clf.dual_coef_)
print("截距:",clf.intercept_)
LinearSVC(Linear Support Vector Classification):线性支持向量分类,类似于SVC,但是其使用的核函数是”linear“,其实现基于LIBLINEAR,所以它具有更大的灵活性在选择penalty和loss时,而且可以适应更大的数据集,他支持密集和稀疏的输入是通过一对一的方式解决的。
LinearSVC 参数解释
C: 误差项的惩罚系数C,用来平衡分类间隔margin和错分样本的 (default=1.0);
loss: 指定损失函数 ,'hinge' 或squared_hinge' (default='squared_hinge');
penalty: 正则项L1或L2 (default='l2');
tol : svm结束标准的精度 (default = 1e - 3);
multi_class:如果y输出类别包含多类,用来确定多类策略, ovr表示一对多,“crammer_singer”优化所有类别的一个共同的目标 ;如果选择“crammer_singer”,损失、惩罚和优化将会被被忽略 (default='ovr');
fit_intercept : 截距设置 (default=True);
intercept_scaling : (default=1);
class_weight :类别权重,设置每个类别权重系数。对于每一个类别i设置惩罚系数C = class_weight[i]*C。如果不给出 (default=1);设置为'balanced'时权重自动调整为 n_samples / (n_classes * np.bincount(y)), 样本数量不均衡时使用,此时某种类型样本量越多,则权重越低;样本量越少,则权重越高;np.bincount(y)每个类的样本数;
verbose: 如果启用,可能无法在多线程环境正常工作,(default=0);
random_state: 设置随机数种子,如果设置了随机数种子,则每次实验都能得到一样的结果,即每次运行取随机数都能得到相同的数 (default=None);
max_iter: 最大迭代次数 (default=1000);
输出:
coef_ : 返回每个特征的权重,仅线性核时有效;class = 2时为m*1,class>2时为n_class*m
intercept_ : 决策函数中的常数,截距;
#LinearSVC 适用于大数据,线性核,等同于Liblinear,比libsvm快得多,dual=False时可以调节penalty和loss
#数据准备
data = scio.loadmat("train and test top321.mat") #导入数据
test = data['test'] #待聚类数据
testclass = data['testclass']
testclass = np.ravel(testclass)
train = data['train']
trainclass = data['trainclass']
trainclass = np.ravel(trainclass)
#建模分类
clf = LinearSVC()
clf.fit(train, trainclass)
weight = clf.coef_
#print(clf.intercept_)
print(clf.predict(test))
Pretest = clf.predict(test)
a = Pretest ^ testclass
acc = (a.size-a.sum())/a.size
print("Accuracy:",acc)
SVR(epsilon-SVR),基于libsvm实现,可以灵活调节惩罚参数C与epsilon
SVR 参数解释
C: 误差项的惩罚系数C, (default=1.0);
epsilon: 距离误差,指定了当没有正则项时的epsilon-tube,(default=0.1);
kernel: 'linear', 'poly', 'rbf', 'sigmoid', 'precomputed' ,(default='rbf');
degree : 多项式核'poly'的阶数,(default=3);
gamma : 'rbf', 'poly' 及'sigmoid'的核系数,默认时为(1/特征个数),(default='auto');
coef0 : 核函数中的独立项,仅在'poly' 和 'sigmoid'中显著,(default=0.0);
shrinking :是否使用shrinking heuristic,(default=True);
tol:停止准则的门槛,(default=1e-3);
cache_size : 核缓存(in MB);在大样本的时候,缓存大小会影响训练速度,因此如果机器内存大,推荐用500MB or 1000MB。默认是200MB;
verbose: 如果启用,可能无法在多线程环境正常工作,(default=False);
max_iter: 最大迭代次数,'-1'时无限制, (default=-1);
输出:
support_ : 支持向量指数;
support_vectors_ : 支持向量;
dual_coef_ : 决策函数中支持向量的系数,对于多分类为1-vs-1分类器的系数;
coef_ : 返回每个特征的权重,仅线性核时有效;
intercept_ : 决策函数中的常数,截距;
sample_weight : 每个样本的权重 (???使用时候显示无此属性 )例子:
X, y = make_regression(n_features=4, random_state=0)
regr = SVR(kernel='linear')
regr.fit(X, y) #x为数据,y为变量,a1x11+a2x12...=y1
print("特征权重:",regr.coef_)
#print("样本权重:",regr.sample_weight)
print("截距:",regr.intercept_)
print(regr.predict([[0,0,0,0]])) #预测
LinearSVR 参数解释
C: 误差项的惩罚系数C,用的squared L2正则项,随着C增大正则项效果减弱,(default=1.0);
loss: 指定损失函数 ,'epsilon_insensitive' (即L1)或squared_epsilon_insensitive' (即L2),(default='epsilon_insensitive');
epsilon: 距离误差,与目标变量y的scale有关,如果不确定设置``epsilon=0``,(default=0.1);
dual: 控制使用对偶形式来优化算法或原始优化问题(default=True) ;当n_samples > n_features 时计算量大推荐dual=false;
tol : svm结束标准的精度 (default = 1e - 3);
fit_intercept : 是否计算该模型的截距。如果设置为False则截距不会被用于计算(当时距被centered时可以设为False), (default=True);
intercept_scaling : 当fit_intercept 为True时,合成的特征被加入,x变为 [x, intercept_scaling], 截距变为intercept_scaling * 合成的特征权重,合成的特征权重受到L1/L2正则化影响,增加intercept_scaling值以减少正则化对合成的特征(即截距)的影响,(default=1);
verbose: 如果启用,可能无法在多线程环境正常工作,(default=0);
random_state: 设置随机数种子,如果设置了随机数种子,则每次实验都能得到一样的结果,即每次运行取随机数都能得到相同的数(default=None);
max_iter: 最大迭代次数 (default=1000);
输出:
coef_ : 返回每个特征的权重,仅线性核时有效;
intercept_ : 决策函数中的常数,截距;
例子:#LinearSVR,是用liblinear实现,可灵活设置惩罚参数C和损失函数,适用于大数据
X, y = make_regression(n_features=4, random_state=0)
regr = LinearSVR(random_state=0)
regr.fit(X, y) #x为数据,y为变量,a1x11+a2x12...=y1
print(regr.coef_) #拟合出的系数
print(regr.intercept_) #截距
print(regr.predict([[0,0,0,0]])) #预测
OneClassSvm,用于异常行为检测,基于libsvm的无监督方法;相似的有基于高斯分布的异常点检测算法
常用SVM算法是通过训练两类样本从而建立模型,而一类SVM则是识别与某一类样本不同的点,这些不同的点可能属于n个其它类别。
类似于svdd,构造一个高维超球,把数据包起来,尽可能紧,又尽可能包括更多的数据。
#OneClassSvm,基于libvm的无监督方法用于检测异常数据]
#nu参数调节很重要
data = scio.loadmat("train and test top321.mat") #导入数据
test = data['test']
testclass = data['testclass']
testclass = np.ravel(testclass)
train = data['train']
trainclass = data['trainclass']
trainclass = np.ravel(trainclass)
train = train[:,0:2]
test = test[:,0:2]
#建模检测
clf = OneClassSVM(kernel='rbf')
print(clf.fit(train))
#print(clf.decision_function(train))
print(clf.predict(test))
Pretest = clf.predict(test)
a = Pretest ^ testclass
acc = (a.size-a.sum())/a.size
print("Accuracy:",acc)
normal = test[Pretest==1]
abnormal = test[Pretest==-1]
plt.plot(normal[:,0],normal[:,1],'bx')
plt.plot(abnormal[:,0],abnormal[:,1],'ro')
SVM解决多分类问题的方法
SVM算法最初是为二值分类问题设计的,当处理多类问题时,就需要构造合适的多类分类器。目前,构造SVM多类分类器的方法主要有两类:一类是直接法,直接在目标函数上进行修改,将多个分类面的参数求解合并到一个最优化问题中,通过求解该最优化问题“一次性”实现多类分类。这种方法看似简单,但其计算复杂度比较高,实现起来比较困难,只适合用于小型问题中;另一类是间接法,主要是通过组合多个二分类器来实现多分类器的构造,常见的方法有one-against-one和one-against-all两种。d.其他多类分类方法。除了以上几种方法外,还有有向无环图SVM(Directed Acyclic Graph SVMs,简称DAG-SVMs)和对类别进行二进制编码的纠错编码SVMs。