全栈工程师开发手册 (作者:栾鹏)
python数据挖掘系列教程
支持向量机svm的相关的知识内容可以参考
https://blog.csdn.net/luanpeng825485697/article/details/78823919
支持向量机的优势在于:
支持向量机的缺点包括:
sklearn.svm模块提供了很多模型供我们使用。
SVC用于分类:支持向量分类,基于libsvm实现的,数据拟合的时间复杂度是数据样本的二次方,这使得他很难扩展到10000个数据集,当输入是多类别时(SVM最初是处理二分类问题的),通过一对一的方案解决,当然也有别的解决办法。
SVC参数说明如下:
C:惩罚项,float类型,可选参数,默认为1.0,C越大,即对分错样本的惩罚程度越大,因此在训练样本中准确率越高,但是泛化能力降低,也就是对测试数据的分类准确率降低。相反,减小C的话,容许训练样本中有一些误分类错误样本,泛化能力强。对于训练样本带有噪声的情况,一般采用后者,把训练样本集中错误分类的样本作为噪声。
kernel:核函数类型,str类型,默认为’rbf’。可选参数为:
degree:多项式核函数的阶数,int类型,可选参数,默认为3。这个参数只对多项式核函数有用,是指多项式核函数的阶数n,如果给的核函数参数是其他核函数,则会自动忽略该参数。
gamma:核函数系数,float类型,可选参数,默认为auto。只对’rbf’ ,’poly’ ,’sigmod’有效。如果gamma为auto,代表其值为样本特征数的倒数,即1/n_features。
coef0:核函数中的独立项,float类型,可选参数,默认为0.0。只有对’poly’ 和,’sigmod’核函数有用,是指其中的参数c。
probability:是否启用概率估计,bool类型,可选参数,默认为False,这必须在调用fit()之前启用,并且会fit()方法速度变慢。
shrinking:是否采用启发式收缩方式,bool类型,可选参数,默认为True。
tol:svm停止训练的误差精度,float类型,可选参数,默认为1e^-3。
cache_size:内存大小,float类型,可选参数,默认为200。指定训练所需要的内存,以MB为单位,默认为200MB。
class_weight:类别权重,dict类型或str类型,可选参数,默认为None。给每个类别分别设置不同的惩罚参数C,如果没有给,则会给所有类别都给C=1,即前面参数指出的参数C。如果给定参数’balance’,则使用y的值自动调整与输入数据中的类频率成反比的权重。
verbose:是否启用详细输出,bool类型,默认为False,此设置利用libsvm中的每个进程运行时设置,如果启用,可能无法在多线程上下文中正常工作。一般情况都设为False,不用管它。
max_iter:最大迭代次数,int类型,默认为-1,表示不限制。
decision_function_shape:决策函数类型,可选参数’ovo’和’ovr’,默认为’ovr’。’ovo’表示one vs one,’ovr’表示one vs rest。
random_state:数据洗牌时的种子值,int类型,可选参数,默认为None。伪随机数发生器的种子,在混洗数据时用于概率估计。
NuSVC(Nu-Support Vector Classification.):核支持向量分类,和SVC类似,也是基于libsvm实现的,但不同的是通过一个参数空值支持向量的个数。
LinearSVC(Linear Support Vector Classification):线性支持向量分类,类似于SVC,但是其使用的核函数是”linear“上边介绍的两种是按照brf(径向基函数计算的,其实现也不是基于LIBSVM,所以它具有更大的灵活性在选择处罚和损失函数时,而且可以适应更大的数据集,他支持密集和稀疏的输入是通过一对一的方式解决的。
LinearSVC 参数解释
C:目标函数的惩罚系数C,用来平衡分类间隔margin和错分样本的,default C = 1.0;
loss:指定损失函数
penalty :
dual :选择算法来解决对偶或原始优化问题。当 nsamples>nfeatures n s a m p l e s > n f e a t u r e s 时dual=false。
tol :(default = 1e - 3): svm结束标准的精度;
multi_class:如果y输出类别包含多类,用来确定多类策略, ovr表示一对多,“crammer_singer”优化所有类别的一个共同的目标 。如果选择“crammer_singer”,损失、惩罚和优化将会被被忽略。
fit_intercept :
intercept_scaling :
class_weight :对于每一个类别i设置惩罚系数 C=classweight[i]∗C C = c l a s s w e i g h t [ i ] ∗ C ,如果不给出,权重自动调整为 nsamples/(nclasses∗np.bincount(y)) n s a m p l e s / ( n c l a s s e s ∗ n p . b i n c o u n t ( y ) )
verbose:跟多线程有关,不大明白啥意思具体。
数据集下载地址:https://github.com/626626cdllp/sklearn/blob/master/SVM_data.txt
import numpy as np # 快速操作结构数组的工具
from sklearn import svm # svm支持向量机
import matplotlib.pyplot as plt # 可视化绘图
data_set = np.loadtxt("SVM_data.txt")
train_data = data_set[:,0:2] # 训练特征空间
train_target = np.sign(data_set[:,2]) # 训练集类标号
test_data = [[3,-1], [1,1], [7,-3], [9,0]] # 测试特征空间
test_target = [-1, -1, 1, 1] # 测试集类标号
plt.scatter(data_set[:,0],data_set[:,1],c=data_set[:,2]) # 绘制可视化图
plt.show()
# 创建模型
clf = svm.SVC()
clf.fit(X=train_data, y=train_target,sample_weight=None) # 训练模型。参数sample_weight为每个样本设置权重。应对非均衡问题
result = clf.predict(test_data) # 使用模型预测值
print('预测结果:',result) # 输出预测值[-1. -1. 1. 1.]
# 获得支持向量
print('支持向量:',clf.support_vectors_)
# 获得支持向量的索引
print('支持向量索引:',clf.support_)
# 为每一个类别获得支持向量的数量
print('支持向量数量:',clf.n_support_)
# # ===============================Linear SVM======================
from sklearn.svm import LinearSVC
clf = LinearSVC() # 创建线性可分svm模型,参数均使用默认值
clf.fit(train_data, train_target) # 训练模型
result = clf.predict(test_data) # 使用模型预测值
print('预测结果:',result) # 输出预测值[-1. -1. 1. 1.]
# # ===============================Linear NuSVC======================
from sklearn.svm import NuSVC
clf = NuSVC() # 创建线性可分svm模型,参数均使用默认值
clf.fit(train_data, train_target) # 训练模型
result = clf.predict(test_data) # 使用模型预测值
print('预测结果:',result) # 输出预测值[-1. -1. 1. 1.]
现在我们再来模拟一下样本不均衡的情况,同时学习下SVM处理多分类问题。
# ===============================样本不平衡、多分类的情况========================
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
# 创建不均衡样本
rng = np.random.RandomState(0)
n_samples_1 = 1000
n_samples_2 = 100
n_samples_3 = 100
X = np.r_[1.5 * rng.randn(n_samples_1, 2), 0.5 * rng.randn(n_samples_2, 2) + [2, 2],0.5 * rng.randn(n_samples_3, 2) + [-3, 3]] # 三类样本点中心为(1.5,1.5)、(2,2)、(-3,3)
y = [0] * (n_samples_1) + [1] * (n_samples_2)+ [2] * (n_samples_3) # 前面的1000个为类别0,后面的100个为类别1,最后100个类别为2
# 创建模型获取分离超平面
clf = svm.SVC(decision_function_shape='ovo',kernel='linear', C=1.0) # decision_function_shape='ovo'为使用1对1多分类处理。会创建n(n-1)/2个二分类。ovr为一对所有的处理方式
clf.fit(X, y)
# 多分类的情况下,获取其中二分类器的个数。
dec = clf.decision_function([[1.5,1.5]]) # decision_function()的功能:计算样本点到分割超平面的函数距离。 包含几个2分类器,就有几个函数距离。
print('二分类器个数:',dec.shape[1])
# 绘制,第一个二分类器的分割超平面
w = clf.coef_[0]
a = -w[0] / w[1] # a可以理解为斜率
xx = np.linspace(-5, 5)
yy = a * xx - clf.intercept_[0] / w[1] # 二维坐标下的直线方程
# 使用类权重,获取分割超平面
wclf = svm.SVC(kernel='linear', class_weight={1: 10})
wclf.fit(X, y)
# 绘制 分割分割超平面
ww = wclf.coef_[0]
wa = -ww[0] / ww[1]
wyy = wa * xx - wclf.intercept_[0] / ww[1] # 带权重的直线
# 绘制第一个二分类器的分割超平面和样本点
h0 = plt.plot(xx, yy, 'k-', label='no weights')
h1 = plt.plot(xx, wyy, 'k--', label='with weights')
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.legend()
plt.show()
支持向量分类的方法可以被扩展用作解决回归问题. 这个方法被称作支持向量回归.
支持向量分类生成的模型(如前描述)只依赖于训练集的子集,因为构建模型的 cost function 不在乎边缘之外的训练点. 类似的,支持向量回归生成的模型只依赖于训练集的子集, 因为构建模型的 cost function 忽略任何接近于模型预测的训练数据.
支持向量分类有三种不同的实现形式: SVR, NuSVR 和 LinearSVR. 在只考虑线性核的情况下, LinearSVR 比 SVR 提供一个更快的实现形式, 然而比起 SVR 和 LinearSVR, NuSVR 实现一个稍微不同的构思(formulation)
与分类的类别一样, fit方法会调用参数向量 X, y, 只在 y 是浮点数而不是整数型.:
# ===============================SVM回归预测========================
X = [[0, 0], [2, 2]]
y = [0.5, 2.5]
clf = svm.SVR()
clf.fit(X, y)
clf.predict([[1, 1]])
避免数据复制: 对于 SVC, SVR, NuSVC 和 NuSVR, 如果数据是通过某些方法而不是用 C 有序的连续双精度,那它先会调用底层的 C 命令再复制。 您可以通过检查它的 flags 属性,来确定给定的 numpy 数组是不是 C 连续的。
对于 LinearSVC (和 LogisticRegression) 的任何输入,都会以 numpy 数组形式,被复制和转换为 用 liblinear 内部稀疏数据去表达(双精度浮点型 float 和非零部分的 int32 索引)。 如果您想要一个适合大规模的线性分类器,又不打算复制一个密集的 C-contiguous 双精度 numpy 数组作为输入, 那我们建议您去使用 SGDClassifier 类作为替代。目标函数可以配置为和 LinearSVC 模型差不多相同的。
内核的缓存大小: 在大规模问题上,对于 SVC, SVR, nuSVC 和 NuSVR, 内核缓存的大小会特别影响到运行时间。如果您有足够可用的 RAM,不妨把它的 缓存大小 设得比默认的 200(MB) 要高,例如为 500(MB) 或者 1000(MB)。
惩罚系数C的设置:在合理的情况下, C 的默认选择为 1 。如果您有很多混杂的观察数据, 您应该要去调小它。 C 越小,就能更好地去正规化估计。
支持向量机算法本身不是用来扩大不变性,所以 我们强烈建议您去扩大数据量. 举个例子,对于输入向量 X, 规整它的每个数值范围为 [0, 1] 或 [-1, +1] ,或者标准化它的为均值为0方差为1的数据分布。请注意, 相同的缩放标准必须要应用到所有的测试向量,从而获得有意义的结果。 请参考章节 预处理数据 ,那里会提供到更多关于缩放和规整。
在 NuSVC/OneClassSVM/NuSVR 内的参数 nu , 近似是训练误差和支持向量的比值。
在 SVC, ,如果分类器的数据不均衡(就是说,很多正例很少负例),设置 class_weight=’balanced’ 与/或尝试不同的惩罚系数 C 。
在拟合模型时,底层 LinearSVC 操作使用了随机数生成器去选择特征。 所以不要感到意外,对于相同的数据输入,也会略有不同的输出结果。如果这个发生了, 尝试用更小的 tol 参数。
使用由 LinearSVC(loss=’l2’, penalty=’l1’, dual=False) 提供的 L1 惩罚去产生稀疏解,也就是说,特征权重的子集不同于零,这样做有助于决策函数。 随着增加 C 会产生一个更复杂的模型(要做更多的特征选择)。可以使用 l1_min_c 去计算 C 的数值,去产生一个”null” 模型(所有的权重等于零)。