学习内容来源:https://www.cnblogs.com/wj-1314/p/10179741.html,同时感谢原博主的分享。
一、sklearn官方文档的内容和结构
1.1 sklearn官方文档的内容
scikit-learn简称sklearn,支持包括分类,回归,降维和聚类四大机器学习算法。还包括了特征提取,数据处理和模型评估者三大模块。
机器学习定义:针对经验E和一系列的任务T和一定表现的衡量P,如果随着经验E的积累,针对定义好的任务T可以提高表现P,就说明机器具有学习能力。
1.2 sklearn官方文档结构
库的算法主要有四类:分类,回归,聚类,降维。其中:
常用的分类:线性、决策树、SVM、KNN,朴素贝叶斯;集成分类:随机森林、Adaboost、GradientBoosting、Bagging、ExtraTrees;
常用的回归:线性、决策树、SVM、KNN ;集成回归:随机森林、Adaboost、GradientBoosting、Bagging、ExtraTrees;
常用聚类:k均值(K-means)、层次聚类(Hierarchical clustering)、DBSCAN;
常用降维:LinearDiscriminantAnalysis、PCA;
流程图代表:蓝色圆圈是判断条件,绿色方框是可以选择的算法,我们可以根据自己的数据特征和任务目标去找一条自己的操作路线。
sklearn中包含众多数据预处理和特征工程相关的模块,虽然刚接触sklearn时,大家都会为其中包含的各种算法的广度深度所震惊,但其实sklearn六大板块中有两块都是关于数据预处理和特征工程的,两个板块互相交互,为建模之前的全部工程打下基础。
模块preprocessing:几乎包含数据预处理的所有内容
模块Impute:填补缺失值专用
模块feature_selection:包含特征选择的各种方法的实践
模块decomposition:包含降维算法
二、sklearn的快速使用
传统的机器学习任务从开始到建模的一般流程就是:
获取数据——》数据预处理——》训练模型——》模型评估——》预测,分类。
2.1传统机器学习的流程---鸢尾花识别
鸢尾花识别是一个经典的机器学习分类问题,它的数据样本中包括了4个特征变量,1个类别变量,样本总数为150。
它的目标是为了根据花萼长度(sepal length)、花萼宽度(sepal width)、花瓣长度(petal length)、花瓣宽度(petal width)这四个特征来识别出鸢尾花属于山鸢尾(iris-setosa)、变色鸢尾(iris-versicolor)和维吉尼亚鸢尾(iris-virginica)中的哪一种。
# 引入数据集,sklearn包含众多数据集
from sklearn import datasets
# 将数据分为测试集和训练集
from sklearn.model_selection import train_test_split
# 利用邻近点方式训练数据
from sklearn.neighbors import KNeighborsClassifier
# 引入数据,本次导入鸢尾花数据,iris数据包含4个特征变量
iris = datasets.load_iris()
# 特征变量
iris_X = iris.data
# print(iris_X)
print('特征变量的长度',len(iris_X))
# 目标值 label
iris_y = iris.target
print('鸢尾花的目标值',iris_y)
# 利用train_test_split进行训练集和测试机进行分开,test_size占30%
X_train,X_test,y_train,y_test=train_test_split(iris_X,iris_y,test_size=0.3)
# 训练数据
# 引入训练方法
knn = KNeighborsClassifier()
# 进行填充测试数据进行训练
knn.fit(X_train,y_train)
params = knn.get_params()
print(params)
score = knn.score(X_test,y_test)
print("预测得分为:%s"%score)
# 预测数据,预测特征值
print(knn.predict(X_test))
# 打印真实特征值
print(y_test)
2.2 数据集--展示--创建
klearn中包含了大量的优质的数据集,在我们学习机器学习的过程中,我们可以使用这些数据集实现出不同的模型,从而提高你动手实践能力,同时这个过程也可以加深对理论知识的理解和把握。除了引入数据之外,我们还可以通过load_sample_images()来引入图片。
首先,要使用sklearn中的数据集,必须导入datasets模块:from sklearn import datasets
下面两个图中包含了大部分sklearn中的数据集,调用方式也图中给出:
创建数据集https://scikit-learn.org/stable/datasets/
2.2.1实例:展示digits数据集
from sklearn.datasets import load_digits
import matplotlib.pyplot as plt
digits = load_digits()
print(digits.data.shape)
print(digits.target.shape)
print(digits.images.shape)
# 展示样本图片
plt.matshow(digits.images[9])
plt.show()
2.2.2实例:创建一个自己的训练样本
#我们除了可以使用sklearn自带的数据集,还可以自己去创建训练样本。
from sklearn.datasets.samples_generator import make_classification
X, y = make_classification(n_samples=6, n_features=5, n_informative=2,
n_redundant=2, n_classes=2, n_clusters_per_class=2, scale=1.0,
random_state=20)
# n_samples:指定样本数
# n_features:指定特征数
# n_classes:指定几分类
# random_state:随机种子,使得随机状可重
for x_,y_ in zip(X,y):
print(y_,end=': ')
print(x_)
2.2.3 实例:用sklearn.datasets.make_blobs来生成数据
scikit中的make_blobs方法常被用来生成聚类算法的测试数据,直观地说,make_blobs会根据用户指定的特征数量,中心点数量,范围等来生成几类数据,这些数据可用于测试聚类算法的效果。
dataX ,labelY = make_blobs(n_samples=100,n_features=2,centers=3,
cluster_std=1.0,center_box=(-10.0,10.0),shuffle=True,random_state=None)
# 绘制样本显示
pyplot.scatter(dataX[:,0],dataX[:,1],c=labelY)
pyplot.show()
2.2.4 生成数据集参数详解
sklearn.datasets.make_blobs(n_samples=100, n_features=2, centers=3,
cluster_std=1.0, center_box=(-10.0, 10.0), shuffle=True,random_state=None)
n_samples表示产生多少个数据
n_features表示数据是几维
centers表示数据点中心,可以输入int数字,代表有多少个中心,也可以输入几个坐标(fixed center locations)
cluster_std表示分布的标准差
返回值:
X,[n_samples, n_features]形状的数组,代表产生的样本
y,[n_samples]形状的数组,代表每个点的标签(类别)
sklearn.datasets.make_classification(n_samples=100, n_features=20,
n_informative=2, n_redundant=2,n_repeated=0, n_classes=2,
n_clusters_per_class=2, weights=None,flip_y=0.01, class_sep=1.0,
hypercube=True,shift=0.0, scale=1.0, shuffle=True, random_state=None)
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构成的
sklearn.datasets.make_gaussian_quantiles(mean=None, cov=1.0, n_samples=100,
n_features=2, n_classes=3,shuffle=True, random_state=None)
make_hastie_10_2(n_samples=1000)
生成环线数据,生成半环图
sklearn.datasets.make_circles(n_samples=100, shuffle=True, noise=None,
random_state=None, factor=0.8)
factor:外环和内环的尺度因子<1
sklearn.datasets.make_moons(n_samples=100, shuffle=True, noise=None,
random_state=None)
2.3 数据预处理
数据预处理阶段是机器学习中不可缺少的一环,它会使得数据更加有效的被模型或者评估器识别。下面我们来看一下sklearn中有哪些平时我们常用的函数:
from sklearn import preprocessing
sklearn.preprocessing.scale(X)
为了使得训练数据的标准化规则与测试数据的标准化规则同步,preprocessing中提供了很多的Scaler定标器(StandardScaler、MaxAbsScaler、MinMaxScaler、RobustScaler、Normalizer)
应的有直接的函数使用:scale(),maxabs_scale(),minmax_scale(),robust_scale(),normaizer()
2.4 数据标准化
标准化:在机器学习中,我们可能要处理不同种类的资料,例如,音讯和图片上的像素值,这些资料可能是高纬度的,资料标准化后会使得每个特征中的数值平均变为0(将每个特征的值都减掉原始资料中该特征的平均),标准差变为1,这个方法被广泛的使用在许多机器学习算法中(例如:支持向量机,逻辑回归和类神经网络)。
StandardScaler计算训练集的平均值和标准差,以便测试数据及使用相同的变换。
变换后各维特征有0均值,单位方差,也叫z-score规范化(零均值规范化),计算方式是将特征值减去均值,除以标准差。
fit:用于计算训练数据的均值和方差,后面就会用均值和方差来转换训练数据
fit_transform:不仅计算训练数据的均值和方差,还会基于计算出来的均值和方差来转换训练数据,从而把数据转化成标准的正态分布。
Transform:很显然,它只是进行转换,只是把训练数据转换成标准的正态分布。(一般会把train和test集放在一起做标准化,或者在train集上做标准化后,用同样的标准化器去标准化test集,此时可以使用scaler)。
注意:测试数据和预测数据的标准化的方式要和训练数据标准化的方式一样,必须使用同一个scaler来进行transform
最小-最大规范化、正则化(normalize)、one-hot编码、特征二值化(Binarization)、类别特征编码、标签编码(Label encoding)
2.5 数据集拆分
在得到训练数据集时,通常我们经常会把训练数据进一步拆分成训练集和验证集,这样有助于我们模型参数的选取。train_test_split是交叉验证中常用的函数,功能是从样本中随机的按比例选取train data和testdata。
X_train,X_test, y_train, y_test =
cross_validation.train_test_split(train_data,train_target,test_size=0.4, random_state=0)
train_data:所要划分的样本特征集
train_target:所要划分的样本结果
test_size:样本占比,如果是整数的话就是样本的数量
random_state:是随机数的种子。
随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:
种子不同,产生不同的随机数;种子相同,即使实例不同也产生相同的随机数。
搭建知识体系。画虎画皮难画骨。
2.6 定义模型
首先分析自己数据集的类型,明白自己要用什么模型来做。然后就可以在sklearn中定义模型,sklearn对所有的模型都提供了相似的接口,这样使得我们可以加快熟悉模型的用法。在此之前,我们可以先看看模型的常用属性和功能。
#拟合模型
Model.fit(x_train,y_train)
#模型预测
Model.predict(x_test)
#获得模型参数
Model.get_params()
#为模型进行打分,线性回归:R square; 分类问题: acc
Model.score(data_x,data_y)
举个实例:线性回归模型
From sklearn.liner_model import LinearRegression, LogisticRegression,
from sklearn import naive_bayes,tree,neighbors
from sklearn.svm import SVC
from sklearn.neural_network import MLPClassifier
Model = LinearRegression(fit_intercept=True,normalize=False,copy_x=True,n_jobs=1)
2.7模型评估与选择
评价针对不同机器学习任务有不同指标,同一人物也有不同侧重点的评价指标。
以下方法封装在sklearn的metrics类下(sklearn.metrics)。务必记住哪些指标适合分类,哪些适合回归。
交叉验证,cross_val_score.交叉验证思想是把某种意义下原始数据dataset进行分组,一部分作为训练集trainset,另一部分作为验证集validationset 或者testset,用训练集对分类器进行训练,再利用训练集来测试训练得到的模型model,以此来评价分类器的性能。交叉验证用于评估模型的预测性能,尤其是训练好的模型在新数据上的表现,可以在一定程度上减少过拟合,同时,交叉验证还可以在有限的数据中获取更多的有效信息。
分类:accuracy(准确率)、f1、f1_micro、f1_macro(这两个用于多分类的f1_score)、precision(精确度)、recall(召回率)、roc_auc
回归:neg_mean_squared_error(MSE、均方误差)、r2
聚类:adjusted_rand_score、completeness_score等
# 导入k折交叉验证模块
from sklearn.model_selection import cross_val_score
cross_val_score(model, X, y=None, scoring=None, cv=None, n_jobs=1)
留出法(holdout cross validation):在机器学习任务中,拿到数据后,我们首先会将原始数据集分为三部分:训练集,验证集和测试集。训练集用于训练模型,验证集用于模型的参数选择配置,测试集对于模型来说是未知数据,用于评估模型的泛化能力。此方法操作简单,只需要随机将原始数据分为三组即可。
不过,如果只做一次分割,它对训练集,验证集和测试机的样本比例,还有分割后数据的分布是否和原始数据集的分布相同等因素比较敏感,不同的划分会得到不同的最优模型,而且分成三个集合后,用于训练的数据更少了。于是有了2.k折交叉验证(k-fold cross validation).
K折交叉验证通过对k个不同分组训练的结果进行平均来减少方差,因此模型的性能对数据的划分就不那么敏感。
第一步,不重复抽样将原始数据随机分为 k 份。
第二步,每一次挑选其中 1 份作为测试集,剩余 k-1 份作为训练集用于模型训练。
第三步,重复第二步 k 次,这样每个子集都有一次机会作为测试集,其余机会作为训练集。在每个训练集上训练后得到一个模型,用这个模型在相应的测试集上测试,计算并保存模型的评估指标,
第四步,计算 k 组测试结果的平均值作为模型精度的估计,并作为当前 k 折交叉验证下模型的性能指标。
K一般取10,数据量小的是,k可以设大一点,这样训练集占整体比例就比较大,不过同时训练的模型个数也增多。数据量大的时候,k可以设置小一点。当k=m的时候,即样本总数,出现了留一法。
留一法(Leave one out cross validation):每次的测试集都只有一个样本,要进行m次训练和预测,这个方法用于训练的数据只比整体数据集少一个样本,因此最接近原始样本的分布。但是训练复杂度增加了,因为模型的数量与原始数据样本数量相同。一般在数据缺少时使用。
Bootstrapping:通过自助采样法,即在含有 m 个样本的数据集中,每次随机挑选一个样本,再放回到数据集中,再随机挑选一个样本,这样有放回地进行抽样 m 次,组成了新的数据集作为训练集。这里会有重复多次的样本,也会有一次都没有出现的样本,原数据集中大概有 36.8% 的样本不会出现在新组数据集中。优点是训练集的样本总数和原数据集一样都是 m,并且仍有约 1/3 的数据不被训练而可以作为测试集。 缺点是这样产生的训练集的数据分布和原数据集的不一样了,会引入估计偏差。 (此种方法不是很常用,除非数据量真的很少)
2.8检验曲线
validation_curve:使用检验曲线,可以方便的更改模型参数,获得模型表现。
2.9分类模型
accuracy_score(准确率得分)是模型分类正确的数据除以样本总数 【模型的score方法算的也是准确率】accuracy_score(y_test,y_pre)
classification_report中的各项得分的avg/total 是每一分类占总数的比例加权算出来的。classification_report(y_test,y_log_pre)
confusion_matrix(混淆矩阵),用来评估分类的准确性confusion_matrix(y_true, y_pred)
precision_score(精确度)、recall_score(召回率)、f1_score(后者由前两个推导出的)。这三个不仅适合二分类,也适合多分类。只需要指出参数average=‘micro’/‘macro’/'weighted’。macro:计算二分类metrics的均值,为每个类给出相同权重的分值。当小类很重要时会出问题,因为该macro-averging方法是对性能的平均。另一方面,该方法假设所有分类都是一样重要的,因此macro-averaging方法会对小类的性能影响很大。
micro: 给出了每个样本类以及它对整个metrics的贡献的pair(sample-weight),而非对整个类的metrics求和,它会每个类的metrics上的权重及因子进行求和,来计算整个份额。Micro-averaging方法在多标签(multilabel)问题中设置,包含多分类,此时,大类将被忽略。
weighted: 对于不均衡数量的类来说,计算二分类metrics的平均,通过在每个类的score上进行加权实现。
roc_curve(ROC曲线,用于二分类)
2.10 保存模型
最后,我们可以将我们训练好的模型保存到本地,或者放到线上供用户使用,那么如何保存训练好的model呢?又要方式有两种:
保存为pickle文件:
Import pickle
# 保存模型
With open(‘model.pickle’,’wb’) as f:
Pickle.dump(model,f)
# 读取模型
With open(‘model.pickle’,’rb’) as f:
Model = pickle.load(f)
# 使用模型来预测新数据
Model.predict(X_test)
Sklearn自带保存模型方法:
From sklearn.externals import joblib
# save model
Joblib.dump(model,’model.pickle’)
#load model
Model = joblib.load(‘model.pickle’)
# predict
Model.predict(data_x)
2.11模型评分
1.模型的score方法:最简单的模型评估方法就是调用模型自己的方法。每个模型都封装了自己的评分函数。
# 预测
y_predict = knnClf.predict(x_test)
print("score on the testdata:",knnClf.score(x_test,y_test))
- sklearn的指标函数:库提供的一些计算方法,常用的有classification_report方法
- sklearn也支持自己开发评价方法。
2.12 几种交叉验证(cross validation)方式的比较
模型评价的目的:通过模型评价,我们知道当前训练模型的好坏,泛化能力如何?从而知道是否可以应用在解决问题上,如果不行,那又是哪些问题?
Train_test_split:在分类问题中,我们通常通过训练集进行train_test_split,划分出train和test两部分,其中train用来训练模型,test用来评估模型,模型通过fit方法从train数据集中学习,然后调用score方法在test集上进行评估、打分;从分数上知道模型当前的训练水平如何。
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import matplotlib.pyplot as plt
cancer = load_breast_cancer()
X_train,X_test,y_train,y_test = train_test_split(cancer.data,cancer.target,random_state=0)
logreg = LogisticRegression().fit(X_train,y_train)
print("Test set score:{:.2f}".format(logreg.score(X_test,y_test)))
然而这这方式只进行了一次划分,数据结果具有偶然性,如果在某次划分中,训练集里全是容易学习的数据,测试集里全是复杂的数据,这样的就会导致最终的结果不尽人意。
Standard Cross Validation:
针对上面通过train_test_split划分,从而进行模型评估方式存在的弊端,提出Cross Validation交叉验证。
Cross Validation:进行多次train_test_split划分;每次划分时,在不同的数据集上进行训练,测试评估,从而得到一个评价结果;如果是5折交叉验证,意思就是在原始数据集上,进行五次划分,每次划分进行一次训练,评估,最后得到5次划分后的评估结果,一般在这几次评估结果上取平均得到最后的评分,k-folf cross-validation ,其中K一般取5或10。
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
import warnings
warnings.filterwarnings('ignore')
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
cancer.data , cancer.target, random_state=0
)
logreg = LogisticRegression()
# CV 默认是3折交叉验证,可以修改cv=5,变为5折交叉验证
scores = cross_val_score(logreg,cancer.data , cancer.target, cv=5)
print("Cross validation scores:{}".format(scores))
print("Mean cross validation score:{:2f}".format(scores.mean()))
交叉验证的优点:原始采用的train_test_split方法,数据划分具有偶然性;交叉验证通过多次划分,大大降低了这种由一次随机划分带来的偶然性,同时通过多次划分,多次训练,模型也能遇到各种各样的数据,从而提高其泛化能力。
与原始的train_test_split相比,对数据的使用效率更高,train_test_split,默认训练集,测试集比例为3:1,而对交叉验证来说,如果是5折交叉验证,训练集比测试集为4:1;10折交叉验证训练集比测试集为9:1.数据量越大,模型准确率越高!
交叉验证缺点:这种简答的交叉验证方式,从上面的图片可以看出来,每次划分时对数据进行均分,设想一下,会不会存在一种情况:数据集有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,用来控制划分。
from sklearn.datasets import load_iris
from sklearn.model_selection import StratifiedKFold ,cross_val_score
from sklearn.linear_model import LogisticRegression
import warnings
warnings.filterwarnings('ignore')
iris_data = load_iris()
logreg = LogisticRegression()
strKFold = StratifiedKFold(n_splits=3,shuffle=False,random_state=0)
scores = cross_val_score(logreg,iris_data.data,iris_data.target,cv=strKFold)
print("straitified cross validation scores:{}".format(scores))
print("Mean score of straitified cross validation:{:.2f}".format(scores.mean()))
Leave-one-out Cross-validation 留一法:留一法Leave-one-out Cross-validation:是一种特殊的交叉验证方式。顾名思义,如果样本容量为n,则k=n,进行n折交叉验证,每次留下一个样本进行验证。主要针对小样本数据。
from sklearn.datasets import load_iris
from sklearn.model_selection import LeaveOneOut , cross_val_score
....
loout = LeaveOneOut()
scores = cross_val_score(logreg,iris.data,iris.target,cv=loout)
....
Shuffle-split cross-validation:控制更加灵活,可以控制划分迭代次数,每次划分测试集和训练集的比例(也就说:可以存在机不再训练集也不再测试集的情况)
from sklearn.datasets import load_iris
from sklearn.model_selection import ShuffleSplit,cross_val_score
from sklearn.linear_model import LogisticRegression
import warnings
warnings.filterwarnings('ignore')
iris = load_iris()
# 迭代八次
shufsp1 = ShuffleSplit(train_size=0.5,test_size=0.4,n_splits=8)
logreg = LogisticRegression()
scores = cross_val_score(logreg,iris.data,iris.target,cv=shufsp1)
到这里,笔者认为这是最适合学习机器学习的库。
高效看书,亲自实践,掌握更牢靠,用到的时候才能信手拈来!!!2019.9