赞
踩
转载自,https://www.cnblogs.com/wj-1314/p/10179741.html
网上有很多关于sklearn的学习教程,大部分都是简单的讲清楚某一方面,其实最好的教程就是官方文档。
官方文档地址:https://scikit-learn.org/stable/
(可是官方文档非常详细,同时许多人对官方文档的理解和结构上都不能很好地把握,我也打算好好学习sklearn,这可能是机器学习的神器),下面先简单介绍一下sklearn。
自2007年发布以来,scikit-learn已经成为Python重要的机器学习库了,scikit-learn简称sklearn,支持包括分类,回归,降维和聚类四大机器学习算法。还包括了特征提取,数据处理和模型评估者三大模块。
sklearn是Scipy的扩展,建立在Numpy和matplolib库的基础上。利用这几大模块的优势,可以大大的提高机器学习的效率。
sklearn拥有着完善的文档,上手容易,具有着丰富的API,在学术界颇受欢迎。sklearn已经封装了大量的机器学习算法,包括LIBSVM和LIBINEAR。同时sklearn内置了大量数据集,节省了获取和整理数据集的时间。
定义:针对经验E和一系列的任务T和一定表现的衡量P,如果随着经验E的积累,针对定义好的任务T可以提高表现P,就说明机器具有学习能力。
由图中,可以看到库的算法主要有四类:分类,回归,聚类,降维。其中:
这个流程图代表:蓝色圆圈是判断条件,绿色方框是可以选择的算法,我们可以根据自己的数据特征和任务目标去找一条自己的操作路线。
sklearn中包含众多数据预处理和特征工程相关的模块,虽然刚接触sklearn时,大家都会为其中包含的各种算法的广度深度所震惊,但其实sklearn六大板块中有两块都是关于数据预处理和特征工程的,两个板块互相交互,为建模之前的全部工程打下基础。
传统的机器学习任务从开始到建模的一般流程就是:获取数据——》数据预处理——》训练模型——》模型评估——》预测,分类。本次我们将根据传统机器学习的流程,看看在每一步流程中都有哪些常用的函数以及他们的用法是怎么样的。那么首先先看一个简单的例子:
鸢尾花识别是一个经典的机器学习分类问题,它的数据样本中包括了4个特征变量,1个类别变量,样本总数为150。
它的目标是为了根据花萼长度(sepal length)、花萼宽度(sepal width)、花瓣长度(petal length)、花瓣宽度(petal width)这四个特征来识别出鸢尾花属于山鸢尾(iris-setosa)、变色鸢尾(iris-versicolor)和维吉尼亚鸢尾(iris-virginica)中的哪一种。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
|
下面,我们开始一步步介绍、
1.1 导入sklearn数据集
sklearn中包含了大量的优质的数据集,在我们学习机器学习的过程中,我们可以使用这些数据集实现出不同的模型,从而提高你动手实践能力,同时这个过程也可以加深对理论知识的理解和把握。除了引入数据之外,我们还可以通过load_sample_images()来引入图片。
首先,要使用sklearn中的数据集,必须导入datasets模块。
1 |
|
下面两个图中包含了大部分sklearn中的数据集,调用方式也图中给出,
这里我们使用iris的数据来举个例子,表示导出数据集:
1 2 3 |
|
1.1.1 手写数字数据集
手写数字数据集包含1797个0-9的手写数字数据,每个数据由8 * 8 大小的矩阵构成,矩阵中值的范围是0-16,代表颜色的深度。
使用sklearn.datasets.load_digits即可加载相关数据集。
1 2 3 4 5 6 7 8 9 10 |
|
展示如下:
1 2 3 4 5 6 7 |
|
1.2 创建数据集
我们除了可以使用sklearn自带的数据集,还可以自己去创建训练样本,
具体用法可以参考: https://scikit-learn.org/stable/datasets/
下面我们拿分类问题的样本生成器举例子:
1 2 3 4 5 6 7 8 9 10 |
|
测试如下:
1 2 3 4 5 6 7 8 9 10 11 |
|
1.2.1 用sklearn.datasets.make_blobs来生成数据
scikit中的make_blobs方法常被用来生成聚类算法的测试数据,直观地说,make_blobs会根据用户指定的特征数量,中心点数量,范围等来生成几类数据,这些数据可用于测试聚类算法的效果。
1 2 3 |
|
输入:
返回值:
例子(生成三类数据用于聚类(100个样本,每个样本2个特征)):
1 2 3 4 5 6 7 8 |
|
结果:
为每个类别设置不同的方差,只需要在上述代码中加入cluster_std参数即可:
1 2 3 4 5 6 7 8 9 10 |
|
1.2.2 用sklearn.datasets.make_classification来生成数据
通常用于分类算法
1 2 3 4 |
|
输入:
n_features :特征个数= n_informative() + n_redundant + n_repeated
n_informative:多信息特征的个数
n_redundant:冗余信息,informative特征的随机线性组合
n_repeated :重复信息,随机提取n_informative和n_redundant 特征
n_classes:分类类别
n_clusters_per_class :某一个类别是由几个cluster构成的
1.2.3 用sklearn.datasets.make_gaussian和make_hastie_10_2来生成数据
1 2 |
|
利用高斯分位点区分不同数据
1 |
|
利用Hastie算法,生成二分类数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
|
结果:
1.2.4 用sklearn.datasets.make_circles和make_moons来生成数据
生成环线数据
1 2 |
|
factor:外环和内环的尺度因子<1
1 2 |
|
生成半环图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
结果:
数据预处理阶段是机器学习中不可缺少的一环,它会使得数据更加有效的被模型或者评估器识别。下面我们来看一下sklearn中有哪些平时我们常用的函数:
1 |
|
为了使得训练数据的标准化规则与测试数据的标准化规则同步,preprocessing中提供了很多的Scaler:
StandardScaler
MaxAbsScaler
MinMaxScaler
RobustScaler
Normalizer
对应的有直接的函数使用:scale(),maxabs_scale(),minmax_scale(),robust_scale(),normaizer()
1 |
|
2.1 数据标准化
标准化:在机器学习中,我们可能要处理不同种类的资料,例如,音讯和图片上的像素值,这些资料可能是高纬度的,资料标准化后会使得每个特征中的数值平均变为0(将每个特征的值都减掉原始资料中该特征的平均),标准差变为1,这个方法被广泛的使用在许多机器学习算法中(例如:支持向量机,逻辑回归和类神经网络)。
StandardScaler计算训练集的平均值和标准差,以便测试数据及使用相同的变换。
变换后各维特征有0均值,单位方差,也叫z-score规范化(零均值规范化),计算方式是将特征值减去均值,除以标准差。
fit
用于计算训练数据的均值和方差,后面就会用均值和方差来转换训练数据
fit_transform
不仅计算训练数据的均值和方差,还会基于计算出来的均值和方差来转换训练数据,从而把数据转化成标准的正态分布。
transform
很显然,它只是进行转换,只是把训练数据转换成标准的正态分布。(一般会把train和test集放在一起做标准化,或者在train集上做标准化后,用同样的标准化器去标准化test集,此时可以使用scaler)。
1 2 3 4 5 |
|
一般来说先使用fit:
1 |
|
这一步可以计算得到scaler,scaler里面存的有计算出来的均值和方差。
再使用transform
1 |
|
这一步再用scaler中的均值和方差来转换X,使X标准化。
最后,在预测的时候,也要对数据做同样的标准化处理,即也要用上面的scaler中的均值和方差来对预测时候的特征进行标准化。
注意:测试数据和预测数据的标准化的方式要和训练数据标准化的方式一样,必须使用同一个scaler来进行transform
2.2 最小-最大规范化
最小最大规范化对原始数据进行线性变换,变换到[0,1]区间(也可以是其他固定最小最大值的区间)。
1 2 3 4 5 |
|
2.3 正则化(normalize)
当你想要计算两个样本的相似度时必不可少的一个操作,就是正则化。其思想是:首先求出样本的p范数,然后该样本的所有元素都要除以该范数,这样最终使得每个样本的范数都是1。规范化(Normalization)是将不同变化范围的值映射到相同的固定范围,常见的是[0,1],也成为归一化。
如下例子,将每个样本变换成unit norm。
1 2 3 4 5 6 7 8 9 |
|
我们可以发现对于每一个样本都有0.4^2+0.4^2+0.81^2=1。这就是L2 norm,变换后每个样本的各维特征的平方和为1.类似的,L1 norm则是变换后每个样本的各维特征的绝对值之和为1.还有max norm,则是将每个样本的各维特征除以该样本各维特征的最大值,
在度量样本之间相似性时,如果使用的是二次型kernel,则需要做Normalization。
2.4 one-hot编码
one-hot编码是一种对离散特征值的编码方式,在LR模型中常用到,用于给线性模型增加非线性能力。
1 2 3 |
|
2.5 特征二值化(Binarization)
给定阈值,将特征转换为0/1.
1 2 3 |
|
2.6 类别特征编码
有时候特征时类别型的,而一些算法的输入必须是数值型,此时需要对其编码,
1 2 3 |
|
上面这个例子,第一维特征有两种值0和1,用两位去编码。第二维用三位,第三维用四位。
2.7 标签编码(Label encoding)
1 2 3 4 5 6 |
|
在得到训练数据集时,通常我们经常会把训练数据进一步拆分成训练集和验证集,这样有助于我们模型参数的选取。
train_test_split是交叉验证中常用的函数,功能是从样本中随机的按比例选取train data和testdata,形式为:
1 2 3 |
|
参数解释
参数说明
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
拆分参数遇到的问题及其解决方法
导入模块
1 |
|
则会报错,代码如下:
1 2 |
|
解决方法:
1 |
|
在这一步我们首先要分析自己数据的类型,明白自己要用什么模型来做,然后我们就可以在sklearn中定义模型了,sklearn为所有模型提供了非常相似的接口,这样使得我们可以更加快速的熟悉所有模型的用法,在这之前,我们先来看看模型的常用属性和功能。
1 2 3 4 5 6 7 8 9 |
|
4.1 线性回归
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
4.2 逻辑回归LR
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
4.3 朴素贝叶斯算法NB(Naive Bayes)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
4.4 决策树DT
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
4.5 支持向量机SVM
1 2 3 4 5 6 7 |
|
4.6 k近邻算法KNN
1 2 3 4 5 6 7 8 9 |
|
4.7 多层感知器(神经网络)
1 2 3 4 5 6 7 8 9 10 |
|
评价指标针对不同的机器学习任务有不同的指标,同一任务也有不同侧重点的评价指标。以下方法,sklearn中都在sklearn.metrics类下,务必记住那些指标适合分类,那些适合回归。
机器学习常用的评估指标请参考博文:Python机器学习笔记:常用评估指标的前世今生
5.1 交叉验证
交叉验证cross_val_score的scoring参数
1 2 3 4 5 6 7 8 |
|
1,导入k折交叉验证模块
1 |
|
2,交叉验证的思想
把某种意义下将原始数据(dataset)进行分组,一部分作为训练集(train set),另一部分作为验证集(validation set or test set),首先用训练集对分类器进行训练,再利用验证集来测试训练得到的模型(model),以此来作为评价分类器的性能指标。
3,为什么使用交叉验证法
4,主要有哪些方法
1,留出法(holdout cross validation)
在机器学习任务中,拿到数据后,我们首先会将原始数据集分为三部分:训练集,验证集和测试集。
训练集用于训练模型,验证集用于模型的参数选择配置,测试集对于模型来说是未知数据,用于评估模型的泛化能力。
这个方法操作简单,只需要随机将原始数据分为三组即可。
不过如果只做一次分割,它对训练集,验证集和测试机的样本比例,还有分割后数据的分布是否和原始数据集的分布相同等因素比较敏感,不同的划分会得到不同的最优模型,,而且分成三个集合后,用于训练的数据更少了。于是又了2.k折交叉验证(k-fold cross validation).
下面例子,一共有150条数据:
1 2 3 4 5 6 7 8 |
|
用train_test_split来随机划分数据集,其中40%用于测试集,有60条数据,60%为训练集,有90条数据:
1 2 3 4 5 6 7 |
|
用train来训练,用test来评价模型的分数。
1 2 3 |
|
2,2. k 折交叉验证(k-fold cross validation)
K折交叉验证通过对k个不同分组训练的结果进行平均来减少方差,因此模型的性能对数据的划分就不那么敏感。
K一般取10,数据量小的是,k可以设大一点,这样训练集占整体比例就比较大,不过同时训练的模型个数也增多。数据量大的时候,k可以设置小一点。当k=m的时候,即样本总数,出现了留一法。
举例,这里直接调用了cross_val_score,这里用了5折交叉验证
1 2 3 4 5 |
|
得到最后平均分数为0.98,以及它的95%置信区间:
1 2 |
|
我们可以直接看一下K-Fold是怎么样划分数据的:X有四个数据,把它分成2折,结构中最后一个集合是测试集,前面的是训练集,每一行为1折:
1 2 3 4 5 6 7 8 9 |
|
同样的数据X,我们来看LeaveOneOut后是什么样子,那就是把它分成4折,结果中最后一个集合是测试集,只有一个元素,前面的是训练集,每一行为1折:
1 2 3 4 5 6 7 8 9 10 |
|
3,留一法(Leave one out cross validation)
每次的测试集都只有一个样本,要进行m次训练和预测,这个方法用于训练的数据只比整体数据集少一个样本,因此最接近原始样本的分布。但是训练复杂度增加了,因为模型的数量与原始数据样本数量相同。一般在数据缺少时使用。
此外:
4,Bootstrapping
通过自助采样法,即在含有 m 个样本的数据集中,每次随机挑选一个样本,再放回到数据集中,再随机挑选一个样本,这样有放回地进行抽样 m 次,组成了新的数据集作为训练集。
这里会有重复多次的样本,也会有一次都没有出现的样本,原数据集中大概有 36.8% 的样本不会出现在新组数据集中。
优点是训练集的样本总数和原数据集一样都是 m,并且仍有约 1/3 的数据不被训练而可以作为测试集。
缺点是这样产生的训练集的数据分布和原数据集的不一样了,会引入估计偏差。
(此种方法不是很常用,除非数据量真的很少)
5.2 检验曲线
使用检验曲线,我们可以更加方便的改变模型参数,获取模型表现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
5.3 分类模型
1 2 |
|
1 2 3 4 5 6 7 8 |
|
1 2 3 4 5 6 7 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
最后,我们可以将我们训练好的model保存到本地,或者放到线上供用户使用,那么如何保存训练好的model呢?主要有下面两种方式:
6.1 保存为pickle文件
1 2 3 4 5 6 7 8 9 10 |
|
6.2 sklearn自带方法joblib
1 2 3 4 5 6 7 |
|
1,模型的score方法:最简单的模型评估方法就是调用模型自己的方法:
1 2 3 |
|
2,sklearn的指标函数:库提供的一些计算方法,常用的有classification_report方法
3,sklearn也支持自己开发评价方法。
模型评价的目的:通过模型评价,我们知道当前训练模型的好坏,泛化能力如何?从而知道是否可以应用在解决问题上,如果不行,那又是那些出了问题?
train_test_split
在分类问题中,我们通常通过对训练集进行triain_test_split,划分出train 和test两部分,其中train用来训练模型,test用来评估模型,模型通过fit方法从train数据集中学习,然后调用score方法在test集上进行评估,打分;从分数上我们知道模型当前的训练水平如何。
1 2 3 4 5 6 7 8 9 10 |
|
结果:
1 |
|
然而这这方式只进行了一次划分,数据结果具有偶然性,如果在某次划分中,训练集里全是容易学习的数据,测试集里全是复杂的数据,这样的就会导致最终的结果不尽人意。
Standard Cross Validation
针对上面通过train_test_split划分,从而进行模型评估方式存在的弊端,提出Cross Validation交叉验证。
Cross Validation:进行多次train_test_split划分;每次划分时,在不同的数据集上进行训练,测试评估,从而得到一个评价结果;如果是5折交叉验证,意思就是在原始数据集上,进行五次划分,每次划分进行一次训练,评估,最后得到5次划分后的评估结果,一般在这几次评估结果上取平均得到最后的评分,k-folf cross-validation ,其中K一般取5或10。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
结果:
1 2 |
|
交叉验证的优点:
交叉验证的缺点:
这种简答的交叉验证方式,从上面的图片可以看出来,每次划分时对数据进行均分,设想一下,会不会存在一种情况:数据集有5类,抽取出来的也正好是按照类别划分的5类,也就是说第一折全是0类,第二折全是1类,等等;这样的结果就会导致,模型训练时。没有学习到测试集中数据的特点,从而导致模型得分很低,甚至为0,为避免这种情况,又出现了其他的各种交叉验证方式。
Stratifid k-fold cross validation
分层交叉验证(Stratified k-fold cross validation):首先它属于交叉验证类型,分层的意思是说在每一折中都保持着原始数据中各个类别的比例关系,比如说:原始数据有3类,比例为1:2:1,采用3折分层交叉验证,那么划分的3折中,每一折中的数据类别保持着1:2:1的比例,这样的验证结果更加可信。
通常情况下,可以设置cv参数来控制几折,但是我们希望对其划分等加以控制,所以出现了KFold,KFold控制划分折,可以控制划分折的数目,是否打乱顺序等,可以赋值给cv,用来控制划分。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
结果:
1 2 |
|
Leave-one-out Cross-validation 留一法
留一法Leave-one-out Cross-validation:是一种特殊的交叉验证方式。顾名思义,如果样本容量为n,则k=n,进行n折交叉验证,每次留下一个样本进行验证。主要针对小样本数据。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
结果:
1 2 3 4 5 6 7 8 |
|
Shuffle-split cross-validation
控制更加灵活,可以控制划分迭代次数,每次划分测试集和训练集的比例(也就说:可以存在机不再训练集也不再测试集的情况)
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
结果:
1 2 3 4 |
|
参考文献:http://www.cnblogs.com/lianyingteng/p/7811126.html
https://www.cnblogs.com/magle/p/5638409.html
https://blog.csdn.net/u014248127/article/details/78885180
https://www.cnblogs.com/ysugyl/p/8707887.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。