SVM使用与参数优化

来源:互联网 发布:软件什么是架构 编辑:程序博客网 时间:2024/05/21 09:07

转载本文请注明出处:amazingwu:http://blog.csdn.net/u013668852/article/details/75007342

python机器学习库 scikit-learn

对Python语言有所了解的科研人员可能都知道SciPy——一个开源的基于Python的科学计算工具包。基于SciPy,目前开发者们针对不同的应用领域已经发展出了为数众多的分支版本,它们被统一称为Scikits,即SciPy工具包的意思。而在这些分支版本中,最有名,也是专门面向机器学习的一个就是Scikit-learn。

Scikit-learn的六大功能

Scikit-learn的基本功能主要被分为六大部分:分类,回归,聚类,数据降维,模型选择和数据预处理。

  • 分类是指识别给定对象的所属类别,属于监督学习的范畴,最常见的应用场景包括垃圾邮件检测和图像识别等。目前Scikit-learn已经实现的算法包括:支持向量机(SVM),最近邻,逻辑回归,随机森林,决策树以及多层感知器(MLP)神经网络等等。
    需要指出的是,由于Scikit-learn本身不支持深度学习,也不支持GPU加速,因此这里对于MLP的实现并不适合于处理大规模问题。有相关需求的读者可以查看同样对Python有良好支持的Keras和Theano等框架。

  • 回归是指预测与给定对象相关联的连续值属性,最常见的应用场景包括预测药物反应和预测股票价格等。目前Scikit-learn已经实现的算法包括:支持向量回归(SVR),脊回归,Lasso回归,弹性网络(Elastic Net),最小角回归(LARS ),贝叶斯回归,以及各种不同的鲁棒回归算法等。可以看到,这里实现的回归算法几乎涵盖了所有开发者的需求范围,而且更重要的是,Scikit-learn还针对每种算法都提供了简单明了的用例参考。

  • 聚类是指自动识别具有相似属性的给定对象,并将其分组为集合,属于无监督学习的范畴,最常见的应用场景包括顾客细分和试验结果分组。目前Scikit-learn已经实现的算法包括:K-均值聚类,谱聚类,均值偏移,分层聚类,DBSCAN聚类等。

  • 数据降维是指使用主成分分析(PCA)、非负矩阵分解(NMF)或特征选择等降维技术来减少要考虑的随机变量的个数,其主要应用场景包括可视化处理和效率提升。

  • 模型选择是指对于给定参数和模型的比较、验证和选择,其主要目的是通过参数调整来提升精度。目前Scikit-learn实现的模块包括:格点搜索,交叉验证和各种针对预测误差评估的度量函数。

  • 数据预处理是指数据的特征提取和归一化,是机器学习过程中的第一个也是最重要的一个环节。这里归一化是指将输入数据转换为具有零均值和单位权方差的新变量,但因为大多数时候都做不到精确等于零,因此会设置一个可接受的范围,一般都要求落在0-1之间。而特征提取是指将文本或图像数据转换为可用于机器学习的数字变量。

需要特别注意的是,这里的特征提取与上文在数据降维中提到的特征选择非常不同。特征选择是指通过去除不变、协变或其他统计上不重要的特征量来改进机器学习的一种方法。

总结来说,Scikit-learn实现了一整套用于数据降维,模型选择,特征提取和归一化的完整算法/模块,虽然缺少按步骤操作的参考教程,但Scikit-learn针对每个算法和模块都提供了丰富的参考样例和详细的说明文档。

安装运行Scikit-learn

如前所述,Scikit-learn需要NumPy和SciPy等其他包的支持,因此在安装Scikit-learn之前需要提前安装一些支持包. Python、Numpy、Scipy

最后安装scikit-learn

sudo pip install -U scikit-learn

具体的使用方法,可以搜索 scikit user guidance,或者浏览http://scikit-learn.org/stable/user_guide.html
了解使用方法。

交叉验证(CrossValidation)

主要使用K-fold Cross Validation(记为K-CV)。
将原始数据分成K组(一般是均分),将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样会得到K个模型,用这K个模型最终的验证集的分类准确率的平均数作为此K-CV下分类器的性能指标.K一般大于等于2,实际操作时一般从3开始取,只有在原始数据集合数据量小的时候才会尝试取2.K-CV可以有效的避免过学习以及欠学习状态的发生,最后得到的结果也比较具有说服性.
具体的介绍可浏览交叉验证(CrossValidation):

数据准备

程序使用的代码源于UCI的Iris数据集,可在官网下载到:Iris数据集。
使用到了其中的iris.data ,该数据集地址为:iris.data数据集
该数据集的内容如下:

5.1,3.5,1.4,0.2,Iris-setosa4.9,3.0,1.4,0.2,Iris-setosa4.7,3.2,1.3,0.2,Iris-setosa4.6,3.1,1.5,0.2,Iris-setosa5.0,3.6,1.4,0.2,Iris-setosa5.4,3.9,1.7,0.4,Iris-setosa4.6,3.4,1.4,0.3,Iris-setosa5.0,3.4,1.5,0.2,Iris-setosa

对于该数据集的描述,官网给出如下说明:

1. Number of Instances: 150 (50 in each of three classes)2. Number of Attributes: 4 numeric, predictive attributes and the class3. Attribute Information:   1. sepal length in cm   2. sepal width in cm   3. petal length in cm   4. petal width in cm   5. class:       -- Iris Setosa      -- Iris Versicolour      -- Iris Virginica4. Missing Attribute Values: NoneSummary Statistics:             Min  Max   Mean    SD   Class Correlation   sepal length: 4.3  7.9   5.84  0.83    0.7826       sepal width: 2.0  4.4   3.05  0.43   -0.4194   petal length: 1.0  6.9   3.76  1.76    0.9490  (high!)    petal width: 0.1  2.5   1.20  0.76    0.9565  (high!)5. Class Distribution: 33.3% for each of 3 classes.

参数优化

参数优化目前常用的方法是让C和g在一定的范围内取值,对于取定的c和g,把训练集作为原始数据集利用K-CV方法得到在此对c和g组合下验证集的分类准确率,最终取得训练集验证分类准确率最高的那组c和g作为最佳参数。对于可能会有多组的c和g对应着最高的验证分类准备率的情况下,选取能够达到最高验证分类准确率中参数c最小的那对c和g作为最佳的参数,在取最小c的情况下,可能还会存在多组g,那么就选取搜索到的第一组c和g作为最佳参数。因为惩罚系数c值过大,会导致过于拟合的情况,模型泛化能力不好。

这种寻优思想可以用网格参数优化来实现。惩罚参数的变化范围在[2^cmin,2^cmax],即在该范围内寻找最佳的参数c,默认值为cmin=-8,cmax=8,。RBF中的g变化范围也在[2^gmin,2^gmax],,默认值同样为为gmin=-8,gmax=8。c,g分别构成横轴和纵轴,cstep,gstep分别是进行网格参数须有时 c和g的步进太小,即c的取值为 2^cmin,2^(cmin+cstep),…,2^cmax ,同理g,默认步进取值为1,通过这种方法找到最佳的c和g组合。

程序实现

import numpy as npfrom sklearn.model_selection import train_test_splitfrom sklearn import svmfrom sklearn.model_selection import cross_val_scorefr = open('iris.data')lines = fr.readlines()data = []target = []for line in lines:    dt = line.strip('\n').split(',')    dt1 = []    for i in dt[0:4]:        dt1.append(float(i))    target.append(dt[4])    data.append(dt1)target_np = np.array(target)data_np = np.array(data)result =[]for i in (-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5):    C = 2 ** i    for j in (-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5):        G = 2 ** j        rbf_svc = svm.SVC(kernel='rbf', gamma=G, C=C).fit(data_np, target_np) # 高斯kernel        # rbf_svc = svm.LinearSVC(C=C).fit(data_np, target_np)        scores = cross_val_score(rbf_svc, data_np, target_np, cv=10)        result.append([C,G,scores.mean()])result1 = sorted(result, key=lambda x:x[2])for i in result1:    print i

说明:
数据集的特征数量为4,数据集的大小为150,因此,我采用了高斯kernel的SVM,该模型适合特征数量较小数据集大小适中的情况。
c和g我从2^-5 ~ 2^5 寻值,设置了默认的步进大小为1,通过该方法,我将得到的准确率进行了排序,以下是关键部分的情况(结果略大,忽略可以舍弃的部分):

[16, 0.125, 0.97333333333333338][32, 0.03125, 0.97333333333333338][32, 0.0625, 0.97333333333333338][0.5, 0.5, 0.98000000000000009][0.5, 1, 0.98000000000000009][1, 0.125, 0.98000000000000009][1, 0.25, 0.98000000000000009][1, 0.5, 0.98000000000000009][2, 0.0625, 0.98000000000000009][2, 0.125, 0.98000000000000009][2, 0.25, 0.98000000000000009][4, 0.03125, 0.98000000000000009][4, 0.0625, 0.98000000000000009][4, 0.125, 0.98000000000000009][8, 0.03125, 0.98000000000000009][8, 0.125, 0.98000000000000009][16, 0.0625, 0.98000000000000009]

该数据是最后的排序数据,可见c和g最优的值为0.5,0.5

原创粉丝点击