作者:韩信子@ShowMeAI
教程地址:http://www.showmeai.tech/tutorials/41
本文地址:http://www.showmeai.tech/article-detail/203
申明:版权所有,转载请分割平台与作者并注明出处
珍藏ShowMeAI查看更多精彩内容
引言
咱们在上一篇SKLearn入门与简略利用案例里给大家讲到了SKLearn工具的根本板块与应用办法,在本篇内容中,咱们开展解说SKLearn的进阶与核心内容。SKLearn中有六大工作模块,如下图所示:别离是分类、回归、聚类、降维、模型抉择和预处理。
- SKLearn官网:https://scikit-learn.org/stable/
- SKLearn的疾速应用办法也举荐大家查看ShowMeAI的文章和速查手册 AI建模工具速查|Scikit-learn使用指南
在SKLearn中,因为做了下层的封装,分类模型、回归模型、聚类与降维模型、预处理器等等都叫做预计器(estimator),就像在Python里「万物皆对象」,在SKLearn里「万物皆预计器」。
在本篇内容中,咱们将给大家进一步深刻解说scikit-learn工具库的应用办法,力求残缺笼罩sklearn工具库利用的方方面面。本文的内容板块包含:
- ① 机器学习基础知识:机器学习定义与四因素:数据、工作、性能度量和模型。机器学习概念,以便和SKLearn对应匹配上。
- ② SKLearn解说:API设计原理,sklearn几大特点:一致性、可测验、规范类、可组合和默认值,以及SKLearn自带数据以及贮存格局。
- ③ SKLearn三大外围API解说:包含预计器、预测器和转换器。这个板块很重要,大家理论利用时次要是借助于外围API落地。
- ④ SKLearn高级API解说:包含简化代码量的流水线(Pipeline预计器),集成模型(Ensemble预计器)、有多类别-多标签-多输入分类模型(Multiclass 和 Multioutput 预计器)和模型抉择工具(Model Selection预计器)。
1.机器学习简介
对于本节内容,强烈推荐大家浏览ShowMeAI文章 图解机器学习 | 机器学习基础知识 和 图解机器学习 | 模型评估办法与准则 ,ShowMeAI对相干常识内容开展做了具体解说。
1.1 定义和形成元素
何为机器学习?巨匠汤姆米切尔(Tom Mitchell)对机器学习定义的原话是:
A computer program is said to learn from experience E with respect to some class of tasks T and performance measure P if its performance at tasks in T, as measured by P, improves with experience E.
这段英文中有两个词computer program和learn,翻译成中文就是机器(计算机程序)和学习,整体翻译下来就是说:如果计算机程序在T工作上的性能(由P掂量)随着教训E而进步,则称计算机程序从教训E中学习某类工作T。
由上述机器学习的定义可知机器学习蕴含四个元素:
- 数据(Data)
- 工作(Task)
- 性能度量(Quality Metric)
- 算法(Algorithm)
1.2 数据
数据(data)是信息的载体。数据能够有以下划分形式:
从「数据具体类型」维度划分:结构化数据和非结构化数据。
- 结构化数据(structured data)是由二维表构造来逻辑表白和实现的数据。
- 非结构化数据是没有预约义的数据,不便用数据库二维表来体现的数据。非结构化数据包含图片,文字,语音和视频等。
- 从「数据表达形式」维度划分:原始数据和加工数据。
- 从「数据统计性质」维度划分:样本内数据和样本外数据。
对于非构造数据,通常神经网络有更好的成果,能够参考ShowMeAI的文章[Python机器学习算法实际]()中的图像建模例子。
机器学习模型很多时候应用的是结构化数据,即二维的数据表。咱们这里以iris花瓣数据集举例,如下图。
上面术语大家在深刻理解机器学习前肯定要弄清楚:
- 每行的记录(这是一朵鸢尾花的数据统计),称为一个「样本(sample)」。
- 反映样本在某方面的性质,例如萼片长度(Sepal Length)、花瓣长度(Petal Length),称为「特色(feature)」。
- 特色上的取值,例如「样本1」对应的5.1、3.5称为「特征值(feature value)」。
- 对于样本后果的信息,例如Setosa、Versicolor,称为「类别标签(class label)」。
- 蕴含标签信息的示例,则称为「样例(instance)」,即
样例=(特色,标签)
。 - 从数据中学得模型的过程称为「学习(learning)」或「训练(training)」。
- 在训练数据中,每个样例称为「训练样例(training instance)」,整个汇合称为「训练集(training set)」。
1.3 工作
依据学习的工作模式(训练数据是否有标签),机器学习可分为几大类:
- 监督学习(有标签)
- 无监督学习(无标签)
- 半监督学习(有局部标签)
- 强化学习(有提早的标签)
下图画出机器学习各类之间的关系。
1.4 性能度量
回归和分类工作中最常见的误差函数以及一些有用的性能度量如下,具体内容能够参考ShowMeAI文章 机器学习评估与度量准则。
2. SKLearn数据
SKLearn作为通用机器学习建模的工具包,蕴含六个工作模块和一个数据导入模块:
- 监督学习:分类工作
- 监督学习:回归工作
- 无监督学习:聚类工作
- 无监督学习:降维工作
- 模型抉择工作
- 数据预处理工作
- 数据导入模块
首先看看SKLearn默认数据格式和自带数据集。
2.1 SKLearn默认数据格式
Sklean里模型能间接应用的数据有两种模式:
- Numpy二维数组(ndarray)的浓密数据(dense data),通常都是这种格局。
- SciPy矩阵(scipy.sparse.matrix)的稠密数据(sparse data),比方文本剖析每个单词(字典有100000个词)做独热编码失去矩阵有很多0,这时用ndarray就不适合了,太耗内存。
2.2 自带数据集
SKLearn外面有很多自带数据集供用户应用。
比方在之前文章Python机器学习算法实际中用到的鸢尾花数据集,蕴含四个特色(萼片长/宽和花瓣长/宽)和三个类别。
咱们能够间接从SKLearn外面的datasets模块中引入,代码如下(代码能够在 线上Jupyter环境 中运行):
# 导入工具库from sklearn.datasets import load_iris iris = load_iris()#数据是以「字典」格局存储的,看看 iris 的键有哪些。iris.keys()
输入如下:
dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names', 'filename'])
读取数据集的信息:
#输入iris 数据中特色的大小、名称等信息和前五个样本。n_samples, n_features = iris.data.shape print((n_samples, n_features)) print(iris.feature_names) print(iris.target.shape) print(iris.target_names)iris.data[0:5]
输入如下:
(150, 4)['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'](150,)['setosa' 'versicolor' 'virginica']array([[5.1, 3.5, 1.4, 0.2], [4.9, 3. , 1.4, 0.2], [4.7, 3.2, 1.3, 0.2], [4.6, 3.1, 1.5, 0.2], [5. , 3.6, 1.4, 0.2]])
构建Dataframe格局的数据集:
# 将X和y合并为Dataframe格局数据 import pandas as pdimport seaborn as snsiris_data = pd.DataFrame( iris.data, columns=iris.feature_names ) iris_data['species'] = iris.target_names[iris.target] iris_data.head(3).append(iris_data.tail(3))
输入如下:
sepal length (cm) | sepal width (cm) | petal length (cm) | petal width (cm) | species | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | setosa |
1 | 4.9 | 3.0 | 1.4 | 0.2 | setosa |
2 | 4.7 | 3.2 | 1.3 | 0.2 | setosa |
147 | 6.5 | 3.0 | 5.2 | 2.0 | virginica |
148 | 6.2 | 3.4 | 5.4 | 2.3 | virginica |
149 | 5.9 | 3.0 | 5.1 | 1.8 | virginica |
咱们应用seaborn来做一些数据分析,查看一下数据的散布个性。这里应用到的是成对维度的关联剖析,对于seaborn的应用办法能够参阅ShowMeAI的文章 seaborn工具与数据可视化教程。
# 应用Seaborn的pairplot查看两两特色之间的关系sns.pairplot( iris_data, hue='species', palette='husl' )
2.3 数据集引入形式
后面提到的是鸢尾花iris数据集,咱们通过load_iris加载进来,实际上SKLearn有三种引入数据模式。
- 打包好的数据:对于小数据集,用
sklearn.datasets.load_*
- 分流下载数据:对于大数据集,用
sklearn.datasets.fetch_*
- 随机创立数据:为了疾速展现,用
sklearn.datasets.make_*
下面这个星号*
指代具体文件名,如果大家在Jupyter这种IDE环境中,能够通过tab制表符主动补全和抉择。
- datasets.load_<TAB>
- datasets.fetch_<TAB>
- datasets.make_<TAB>
比方咱们调用load_iris
from sklearn import datasetsdatasets.load_iris
输入如下:
<function sklearn.datasets.base.load_iris(return_X_y=False)>
咱们调用load_digits
加载手写数字图像数据集
digits = datasets.load_digits()digits.keys()
输入:
dict_keys(['data', 'target', 'target_names', 'images', 'DESCR'])
咱们再来看看通过fetch拉取数据的示例:
#加州屋宇数据集california_housing = datasets.fetch_california_housing() california_housing.keys()
输入:
dict_keys(['data', 'target', 'feature_names', 'DESCR'])
3.SKLearn外围API
咱们后面提到SKLearn里万物皆预计器。预计器是个十分形象的叫法,不谨严的一个了解,咱们能够视其为一个模型(用来回归、分类、聚类、降维),或一套流程(预处理、网格搜寻穿插验证)。
本节三大API其实都是预计器:
- 预计器(estimator)通常是用于拟合性能的预计器。
- 预测器(predictor)是具备预测性能的预计器。
- 转换器(transformer)是具备转换性能的预计器。
3.1 预计器
任何能够基于数据集对一些参数进行预计的对象都被称为预计器,它有两个外围点:
- ① 须要输出数据。
- ② 能够预计参数。
预计器首先被创立,而后被拟合。
创立预计器:须要设置一组超参数,比方
- 线性回归里超参数
normalize=True
- K均值里超参数
n_clusters=5
- 线性回归里超参数
拟合预计器:须要训练集
- 在监督学习中的代码范式为
model.fit(X_train, y_train)
- 在无监督学习中的代码范式为
model.fit(X_train)
- 在监督学习中的代码范式为
拟合之后能够拜访model里学到的参数,比方线性回归里的特色系数coef,或K均值里聚类标签labels,如下(具体的能够在SKLearn文档的每个模型页查到)。
model.coef_
model.labels_
上面看看监督学习的「线性回归」和无监督学习的「K均值聚类」的具体例子。
(1) 线性回归
首先从SKLearn工具库的linear_model
中引入LinearRegression
;创立模型对象命名为model,设置超参数normalize
为True
(在每个特征值上做标准化,这样能保障拟合的稳定性,减速模型拟合速度)。
from sklearn.linear_model import LinearRegressionmodel = LinearRegression(normalize=True)model
输入:
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=True)
创立完后的预计器会显示所有的超参数(比方方才设置的normalize=True
),未设置的超参数都应用默认值。
本人创立一个简略数据集(一条直线上的数据点),简略解说一下预计器外面的特色。
import numpy as npimport matplotlib.pyplot as pltx = np.arange(10) y = 2 * x + 1 plt.plot( x, y, 'o' )
在咱们生成的数据里,X是一维,咱们做一点小小的调整,用np.newaxis
加一个维度,把[1,2,3]转成[[1],[2],[3]],这样的数据状态能够合乎sklearn的要求。接着把X和y送入fit()
函数来拟合线性模型的参数。
X = x[:, np.newaxis] model.fit( X, y )
输入为:
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=True)
拟合完后的预计器和创立完仿佛没有差异,但咱们曾经能够用model.param_
拜访到拟合完数据的参数了,如下代码。
print( model.coef_ ) print( model.intercept_ )# 输入后果# [2.]# 0.9999999999999982
(2) K均值
咱们来看看聚类的例子,先从SKLearn的cluster中导入KMeans,初始化模型对象命名为model,设置超参数n_cluster
为3(为了展现不便而咱们晓得用的iris数据集有3类,实际上能够设置不同数量的n_cluster
)。
尽管iris数据里蕴含标签y,但在无监督的聚类中咱们不会应用到这个信息。
from sklearn.cluster import KMeans model = KMeans( n_clusters=3 ) model
输入为:
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300, n_clusters=3, n_init=10, n_jobs=None, precompute_distances='auto', random_state=None, tol=0.0001, verbose=0)
iris数据集蕴含四维特色(萼片长、萼片宽、花瓣长、花瓣宽),在上面的例子中咱们心愿可视化,这里咱们简略选取两个特色(萼片长、萼片宽)来做聚类并且可视化后果。
留神上面代码X = iris.data[:,0:2]
其实就是提取特色维度。
from sklearn.datasets import load_iris iris = load_iris()X = iris.data[:,0:2] model.fit(X)
输入为:
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300, n_clusters=3, n_init=10, n_jobs=None, precompute_distances='auto', random_state=None, tol=0.0001, verbose=0)
拟合完后的预计器和创立完仿佛没有差异,但咱们曾经能够用model.param_
拜访到拟合完数据的参数了,如下代码。
print( model.cluster_centers_, '\n') print( model.labels_, '\n' ) print( model.inertia_, '\n') print(iris.target)[[5.77358491 2.69245283] [6.81276596 3.07446809] [5.006 3.428 ]] [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 0 1 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 1 0 1 0 1 0 1 1 0 0 1 1 1 1 1 0 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 0] 37.05070212765958 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
这里解释一下KMeans模型这几个参数:
model.clustercenters
:簇核心。三个簇意味着有三个坐标。model.labels_
:聚类后的标签。model.inertia_
:所有点到对应的簇核心的间隔平方和(越小越好)
小结
尽管下面以有监督学习的Linear Regression和无监督学习的KMeans举例,但实际上你能够将它们替换成其余别的模型,比方监督学习的Logistic Regression和无监督学习的DBSCAN。它们都是「预计器」,因而都有fit()
办法。
应用它们的通用伪代码如下:
# 有监督学习from sklearn.xxx import SomeModel# xxx 能够是 linear_model 或 ensemble 等model = SomeModel( hyperparameter )model.fit( X, y )# 无监督学习from sklearn.xxx import SomeModel# xxx 能够是 cluster 或 decomposition 等model = SomeModel( hyperparameter )model.fit( X )
3.2 预测器
预测器是预计器做的一个延展,具备对数据进行预测的性能。
预测器最常见的是predict()
函数:
model.predict(X_test)
:评估模型在新数据上的体现。model.predict(X_train)
:确认模型在老数据上的体现。
为了进行新数据评估,咱们先将数据分成80:20的训练集(X_train, y_train)
和测试集(X_test, y_test)
,再用从训练集上拟合fit()的模型在测试集上预测predict()
。
from sklearn.datasets import load_iris iris = load_iris()from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split( iris['data'], iris['target'], test_size=0.2 ) print( 'The size of X_train is ', X_train.shape ) print( 'The size of y_train is ', y_train.shape ) print( 'The size of X_test is ', X_test.shape ) print( 'The size of y_test is ', y_test.shape )The size of X_train is (120, 4)The size of y_train is (120,)The size of X_test is (30, 4)The size of y_test is (30,)
predict & predict_proba
对于分类问题,咱们不仅想晓得预测的类别是什么,有时咱们还心愿获取预测概率等信息。前者用 predict()
,后者用predict_proba()
。
y_pred = model.predict( X_test )p_pred = model.predict_proba( X_test )print( y_test, '\n' )print( y_pred, '\n' )print( p_pred )
score & decision_function
预测器里还有额定的两个函数能够应用。在分类问题中:
score()
返回的是分类准确率。decision_function()
返回的是每个样例在每个类下的分数值。
print( model.score( X_test, y_test ) )print( np.sum(y_pred==y_test)/len(y_test) )decision_score = model.decision_function( X_test )print( decision_score )
小结
预计器都有fit()
办法,预测器都有predict()
和score()
办法,话中有话不是每个预测器都有predict_proba()
和decision_function()
办法,这个在用的时候查查官网文档就分明了(比方RandomForestClassifier
就没有decision_function()
办法)。
应用它们的通用伪代码如下:
# 有监督学习from sklearn.xxx import SomeModel# xxx 能够是 linear_model 或 ensemble 等model = SomeModel( hyperparameter )model.fit( X, y )y_pred = model.predict( X_new )s = model.score( X_new )# 无监督学习from sklearn.xxx import SomeModel# xxx 能够是 cluster 或 decomposition 等model = SomeModel( hyperparameter )model.fit( X )idx_pred = model.predict( X_new )s = model.score( X_new )
3.3 转换器
转换器是一种预计器,也有拟合性能,比照预测器做完拟合来预测,转换器做完拟合来转换。外围点如下:
- 预计器里
fit + predict
- 转换器里
fit + transform
本节介绍两大类转换器:
- 将类别型变量(categorical)编码成数值型变量(numerical)
- 规范化(normalize)或标准化(standardize)数值型变量
(1) 类别型变量编码
① LabelEncoder&OrdinalEncoder
LabelEncoder和OrdinalEncoder都能够将字符转成数字,然而:
- LabelEncoder的输出是一维,比方1d ndarray
- OrdinalEncoder的输出是二维,比方 DataFrame
# 首先给出要编码的列表 enc 和要解码的列表 dec。enc = ['red','blue','yellow','red'] dec = ['blue','blue','red']# 从sklearn下的preprocessing中引入LabelEncoder,再创立转换器起名LE,不须要设置任何超参数。from sklearn.preprocessing import LabelEncoder LE = LabelEncoder() print(LE.fit(enc)) print( LE.classes_ ) print( LE.transform(dec) )LabelEncoder()['blue' 'yellow' 'red'][0 1 2]
除了LabelEncoder,OrdinalEncoder也能够实现编码。如下代码所示:
from sklearn.preprocessing import OrdinalEncoder OE = OrdinalEncoder() enc_DF = pd.DataFrame(enc) dec_DF = pd.DataFrame(dec) print( OE.fit(enc_DF) ) print( OE.categories_ ) print( OE.transform(dec_DF) )OrdinalEncoder(categories='auto', dtype=<class 'numpy.float64'>)[array(['blue', 'yellow', 'red'], dtype=object)][[0.] [1.] [2.]]
下面这种编码的问题是,在编码过后会带来不同类别的大小关系,比方这里3种颜色其实实质上是平等的,没有大小关系。
咱们的另外一种类别型数据编码形式,独热向量编码(one-hot encoding)能够解决这个问题,大家持续往下看。
② OneHotEncoder
独热向量编码其实就是把一个整数用向量的模式体现。上图右侧就是对色彩做独热向量编码。转换器OneHotEncoder能够承受两种类型的输出:
- ① 用LabelEncoder编码好的一维数组
- ② DataFrame
一、用LabelEncoder编码好的一维数组(元素为整数),重塑(用reshape(-1,1))成二维数组作为OneHotEncoder输出。
from sklearn.preprocessing import OneHotEncoder OHE = OneHotEncoder() num = LE.fit_transform( enc ) print( num ) OHE_y = OHE.fit_transform( num.reshape(-1,1) ) OHE_y[2 0 1 2]
输入为:
<4x3 sparse matrix of type '<class 'numpy.float64'>' with 4 stored elements in Compressed Sparse Row format>
下面后果解释如下:
- 第3行打印出编码后果[2 0 1 2]。
- 第5即将其转成独热模式,输入是一个「稠密矩阵」模式,因为实操中通常类别很多,因而就一步到位用稠密矩阵来节俭内存。
想看该矩阵里具体内容,用toarray()
函数。
OHE_y.toarray()
输入为:
array([[0., 0., 1.], [1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])
二、用DataFrame作为OneHotEncoder输出。
OHE = OneHotEncoder() OHE.fit_transform( enc_DF ).toarray()
输入为:
array([[0., 0., 1.], [1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])
(2) 特色缩放
数据要做的最重要的转换之一是特色缩放(feature scaling)。相似逻辑回归,神经网络这种计算型模型,对于不同特色的幅度大小差别是敏感的。
具体来说,对于某个特色,咱们有两种变换办法:
- 标准化(standardization):每个维度的特色减去该特色均值,除以该维度的标准差。
- 规范化(normalization):每个维度的特色减去该特色最小值,除以该特色的最大值与最小值之差。
① MinMaxScaler
如上图所示,MinMaxScaler会依据特色的最大最小取值,对数据进行幅度缩放。
from sklearn.preprocessing import MinMaxScaler X = np.array( [0, 0.5, 1, 1.5, 2, 100] ) X_scale = MinMaxScaler().fit_transform( X.reshape(-1,1) ) X_scale
输入为:
array([[0. ], [0.005], [0.01 ], [0.015], [0.02 ], [1. ]])
② StandardScaler
StandardScaler做的事件是调整数据分布,尽量靠近正态分布。
from sklearn.preprocessing import StandardScaler X_scale = StandardScaler().fit_transform( X.reshape(-1,1) ) X_scale
输入为:
array([[-0.47424487], [-0.46069502], [-0.44714517], [-0.43359531], [-0.42004546], [ 2.23572584]])
留神:fit()
函数只能作用在训练集上,如果心愿对测试集变换,只有用训练集上fit好的转换器去transform即可。不能在测试集上fit再transform,否则训练集和测试集的变换规定不统一,模型学习到的信息就有效了。
4.高级API
咱们在这节中给大家介绍SKLearn的「高级API」,即五大元预计器(集成性能的Ensemble,多分类和多标签的Multiclass,多输入的Multioutput,抉择模型的Model Selection,流水线的Pipeline)。
ensemble.BaggingClassifier
ensemble.VotingClassifier
multiclass.OneVsOneClassifier
multiclass.OneVsRestClassifier
multioutput.MultiOutputClassifier
model_selection.GridSearchCV
model_selection.RandomizedSearchCV
pipeline.Pipeline
4.1 Ensemble 预计器
如上图:分类器统计每个子分类器的预测类别数,再用「少数投票」准则失去最终预测。回归器计算每个子回归器的预测平均值。
最罕用的Ensemble预计器排列如下:
AdaBoostClassifier
:逐渐晋升分类器AdaBoostRegressor
:逐渐晋升回归器BaggingClassifier
:Bagging分类器BaggingRegressor
:Bagging回归器GradientBoostingClassifier
:梯度晋升分类器GradientBoostingRegressor
:梯度晋升回归器RandomForestClassifier
:随机森林分类器RandomForestRegressor
:随机森林回归器VotingClassifier
:投票分类器VotingRegressor
:投票回归器
咱们用鸢尾花数据iris,拿以下estimator来举例:
- 含同质预计器
RandomForestClassifier
- 含异质预计器
VotingClassifier
首先将数据分成80:20的训练集和测试集,并引入metrics来计算各种性能指标。
from sklearn.datasets import load_iris iris = load_iris()from sklearn.model_selection import train_test_split from sklearn import metrics X_train, X_test, y_train, y_test = train_test_split(iris['data'], iris['target'], test_size=0.2)
(1) RandomForestClassifier
随机森林RandomForestClassifier通过管制n_estimators
超参数来决定基预计器的个数,在这里是4棵决策树(森林由树组成);此外每棵树的最大树深为5(max_depth=5
)。
from sklearn.ensemble import RandomForestClassifier RF = RandomForestClassifier( n_estimators=4, max_depth=5 ) RF.fit( X_train, y_train )
输入为:
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini', max_depth=5, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, n_estimators=4, n_jobs=None, oob_score=False, random_state=None, verbose=0, warm_start=False)
元预计器和预估器一样也有fit()
。上面看看随机森林里蕴含的预计器个数和其自身。
print( RF.n_estimators ) RF.estimators_
输入为:
4[DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=5, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, presort=False, random_state=705712365, splitter='best'), DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=5, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, presort=False, random_state=1026568399, splitter='best'), DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=5, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, presort=False, random_state=1987322366, splitter='best'), DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=5, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, presort=False, random_state=1210538094, splitter='best')]
拟合RF完再做预测,用metrics外面的accuracy_score来计算准确率。训练准确率98.33%,测试准确率100%。
print ( "RF - Accuracy (Train): %.4g" % metrics.accuracy_score(y_train, RF.predict(X_train)) ) print ( "RF - Accuracy (Test): %.4g" % metrics.accuracy_score(y_test, RF.predict(X_test)) )
RF - Accuracy (Train): 1RF - Accuracy (Test): 0.9667
(2) VotingClassifier
和随机森林由同质分类器「决策树」不同,投票分类器由若干个异质分类器组成。上面咱们用VotingClassifier建设个含有逻辑回归(Logistic regression)、随机森林(RandomForest)和高斯奢侈贝叶斯(GNB)三个分类器的集成模型。
RandomForestClassifier的基分类器只能是决策树,因而只用通过管制n_estimators
超参数来决定树的个数,而VotingClassifier的基分类器要输出每个异质分类器。
from sklearn.linear_model import LogisticRegressionfrom sklearn.naive_bayes import GaussianNBfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.ensemble import VotingClassifierLR = LogisticRegression( solver='lbfgs', multi_class='multinomial' )RF = RandomForestClassifier( n_estimators=5 )GNB = GaussianNB()Ensemble = VotingClassifier( estimators=[('lr', LR), (‘rf', RF), ('gnb', GNB)], voting='hard' )Ensemble. fit( X_train, y_train )
后果如下:
VotingClassifier(estimators=[('lr', LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,intercept_scaling=1, max_iter=100, multi_class='multinomial',n_jobs=None, penalty='12', random_state=None, solver='lbfgs',tol=0.0001, verbose=6, warm_start=False)), ('rf', ...e, verbose=0,warm_start=False)), ('gnb', GaussianNB(priors=None, var_smoothing=1e-09))],flatten_transform=None, n_jobs=None, voting='hard', weights=None)
看看Ensemble集成模型里蕴含的预计器个数和其自身。
print( len(Ensemble.estimators_) ) Ensemble.estimators_
后果如下:
3[LogisticRegression(C=1.0, class_weight-None, dual-False, fit_intercept=True,intercept_scaling=1, max_iter=100, multi_class='multinomial',n_jobs-None, penalty="12", random_state-None, solver='1bfgs',t01=0.0001, verbose=0, warm_start=False),RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',max_depth=None, max_features='auto', max_leaf_nodes=None,min_impurity_decrease-0.0, min_impurity_splitmin_samples_leaf=1, min_samples_split=2,min_weight_fraction_leaf=0.0, n_estimator:oob_score=False, random_state-None, verbose=warm_start=False),GaussianNB(priors-None, var_smoothing=1e-9)]
比照元预计器和它三个组成元素的体现,下过体现如下:
# 拟合LR.fit( X_train, y_train ) RF.fit( X_train, y_train ) GNB.fit( X_train, y_train )
# 评估成果print ( "LR - Accuracy (Train): %.4g" % metrics.accuracy_score(y_train, LR.predict(X_train)) )print ( "RF - Accuracy (Train): %.4g" % metrics.accuracy_score(y_train, RF.predict(X_train)) )print ( "GNB - Accuracy (Train): %.4g" % metrics.accuracy_score(y_train, GNB.predict(X_train)) )print ( "Ensemble - Accuracy (Train): %.4g" % metrics.accuracy_score(y_train, Ensemble.predict(X_train)) )print ( "LR - Accuracy (Test): %.4g" % metrics.accuracy_score(y_test, LR.predict(X_test)) )print ( "RF - Accuracy (Test): %.4g" % metrics.accuracy_score(y_test, RF.predict(x_test)) )print ( "GNB - Accuracy (Test): %.4g" % metrics.accuracy_score(y_test, RF.predict(X_test)) )print ( "Ensemble - Accuracy (Test): %.4g" % metrics.accuracy_score(y test, Ensemble.predict(X_test)) )
# 运行后果LR - Accuracy (Train): 0.975RF - Accuracy (Train): 0.9833GNB - Accuracy (Train): 0.95Ensemble - Accuracy (Train): 0.9833 LR - Accuracy (Test): 1RF - Accuracy (Test): 1GNB - Accuracy (Test): 1Ensemble - Accuracy (Test): 1
4.2 Multiclass 预计器
sklearn.multiclass
能够解决多类别(multi-class) 的多标签(multi-label) 的分类问题。上面咱们会应用数字数据集digits作为示例数据来解说。咱们先将数据分成 80:20 的训练集和测试集。
# 导入数据from sklearn.datasets import load_digits digits = load_digits() digits.keys()
输入如下:
# 输入后果dict_keys(['data', 'target', 'target_names','images', 'DESCR'])
上面咱们切分数据集:
# 数据集切分X_train, X_test, y_train, y_test = train_test_split( digits['data'], digits['target'], test_size=0.2 ) print( 'The size of X_train is ', X_train.shape ) print( 'The size of y_train is ', y_train.shape ) print( 'The size of X_test is ', X_test.shape ) print( 'The size of y_test is ', y_test.shape )
输入如下
The size of X_train is (1437, 64)The size of y_train is (1437,)The size of X_test is (360, 64)The size of y_test is (360,)
训练集和测试集别离有1437和360张图像。每张照片是蕴含8×8的像素,咱们用flatten操作把2维的8×8展平为1维的64。
看看训练集中前100张图片和对应的标签(如下图)。像素很低,但基本上还是能看清。
fig, axes = plt.subplots( 10, 16, figsize=(8, 8) )fig.subplots_adjust( hspace=0.1, wspace=0.1 )for i, ax in enumerate( axes.flat ): ax.imshow( X_train[i,:].reshape(8,8), cmap='binary’, interpolation='nearest’) ax.text( 0.05, 0.05, str(y_train[i]), transform=ax.transAxes, color='blue') ax.set_xticks([]) ax.set_yticks([])
(1) 多类别分类
手写数字有0-9十类,但手头上只有二分类预计器(比方像撑持向量机)怎么用呢?咱们能够采取以下策略解决:
- 一对一(One vs One,OvO):一个分类器用来解决数字0和数字1,一个用来解决数字0和数字2,一个用来解决数字1和2,以此类推。N个类须要N(N-1)/2个分类器。
- 一对其余(One vs All,OvA):训练10个二分类器,每一个对应一个数字,第一个分类「1」和「非1」,第二个分类「2」和「非2」,以此类推。N个类须要N个分类器。
① OneVsOneClassifier
思考一个具体天气多分类问题,天气能够是晴天、阴天和雨天,在OvO中,三个分类器为f1、f2和f3。
- f1负责辨别橙色和绿色样本
- f2负责辨别橙色和紫色样本
- f3负责辨别绿色和紫色样本
在下图的例子中,f1和f2都预测为橙色,f3预测为紫色。依据少数准则失去的联合预测为橙色,如下图所示。
回到数字分类问题上,代码及后果如下:
from sklearn.multiclass import OneVsOneClassifierfrom sklearn.linear_model import LogisticRegressionovo_lr = OneVsOneClassifier( LogisticRegression(solver='lbfgs', max_iter=200) )ovo_lr.fit( X_train, y_train )
OnevsOneClassifier(estimator=LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,intercept_scaling=1, max_iter=200, multi_class=‘warn’,n_jobs=None, penalty='12', random_state=None, solver='lbfgs’,tol=0.0001, verbose=6, warm_start=False),n_jobs=None)
10*9/2=45,10类总共45个OvO分类器。
print( len(ovo_lr.estimators_) ) ovo_lr.estimators_
后果如下:
45(LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,intercept_scaling=1, max_iter=200, multi_class='warn',n_jobs=None, penalty='12', random_state=None, solver='lbfgs',tol=60.0001, verbose=0, warm_start=False),LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, max_iter=200, multi_class='warn', n_jobs=None, penalty='l2', random_state=None, solver='lbfgs',tol=0.0001, verbose=0, warm_start=False),LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, max_iter=200, multi_class='warn', n_jobs=None, penalty='12', random_state=None, solver='lbfgs', tol=60.0001, verbose=0, warm_start=False),LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, max_iter=200, multi_class='warn', n_jobs=None, penalty="12", random_state=None, solver='lbfgs', tol=0.0001, verbose=0, warm_start=False),LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,...
训练集分类全对,测试集准确率98%。
print ( “OvO LR - Accuracy (Train): %.4g" % metrics.accuracy_score(y_train, ovo_Ir.predict(X_train)) )print ( "OvO LR - Accuracy (Test): %.4g" % metrics.accuracy_score(y_test, ovo_lr.predict(X_test}) )
# 运行后果OvO LR - Accuracy (Train): 1OvO LR - Accuracy (Test): 0.9806
② OneVsRestClassifier
在OvA中,把数据分成“某个”和“其余”
- 图一,某个=橙色,其余=绿色和紫色
- 图二,某个=绿色,其余=橙色和紫色
- 图三,某个=紫色,其余=橙色和绿色
三分类分解成三个二分类,对应的分类器为f1、f2和f3。
- f1预测负类,即预测绿色和紫色
- f2预测负类,即预测橙色和紫色
- f3预测正类,即预测紫色
三个分类器都预测了紫色,依据少数准则失去的预测是紫色,即阴天。
回到数字分类问题上,代码和后果如下:
from sklearn.multiclass import OneVsRestClassifierova_lr = OneVsRestClassifier( LogisticRegression(solver='lbfgs', max_iter=800) )ova_lr.fit( X_train, y_train )
OnevsRestClassifier(estimator=LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, max_iter=800, multi_class=‘warn’, n_jobs=None, penalty='12', random_state=None, solver='lbfgs’, tol=0.0001, verbose=6, warm_start=False), n_jobs=None)
10类总共10个OvA分类器。
print( len(ova_lr.estimators_) ) ova_lr.estimators_
后果如下:
10[LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, max_iter=800, multi_class='warn', n_jobs=None, penalty='12', random_state=None, solver='lbfgs',tol=0.0001, verbose=0, warm_start=False),LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, max_iter=800, multi_class='warn', n_jobs=None, penalty='12', random_state=None, solver='lbfgs', tol=0.0001, verbose=0, warm_start=False),LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,intercept_scaling=1, max_iter=800, multi_class=‘warn',n_jobs=None, penalty='12', random_state=None, solver="lbfgs',tol=0.0001, verbose=0, warm_start=False),LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,intercept_scaling=1, max_iter=800, multi_class='warn', n_jobs=None, penalty='12', random_state=None, solver='lbfgs', tol=0.0001, verbose=0, warm_start=False),LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,...
训练集准确率简直100%,测试集准确率96%。代码与后果如下:
print ( “OvA LR - Accuracy (Train): %.4g" % metrics.accuracy_score(y_train, ova_Ir.predict(X_train)) )print ( "OvA LR - Accuracy (Test): %.4g" % metrics.accuracy_score(y_test, ova_lr.predict(X_test}) )
OvA LR - Accuracy (Train): 6.9993OvA LR - Accuracy (Test}: 6.9639
(2) 多标签分类
到目前为止,所有的样例都总是被调配到仅一个类。有些状况下,你兴许想让分类器给一个样例输入多个类别。在无人驾驶的利用中,在下图辨认出有车和指示牌,没有交通灯和人。
物体辨认是一个简单的深度学习问题,咱们在这里暂且不深入探讨。咱们先看一个简略点的例子,在手写数字的例子上,咱们特意为每个数字设计了两个标签:
- 标签1:奇数、偶数
- 标签2:小于等于4,大于4
咱们构建多标签y_train_multilabel
,代码如下(OneVsRestClassifier也能够用来做多标签分类):
from sklearn.multiclass import OneVsRestClassifier y_train_multilabel = np.c_[y_train%2==0, y_train<=4 ] print(y_train_multilabel)
[[ True True] [False False] [False False] ... [False False] [False False] [False False]]
看下图训练集第1和2个图片是数字4和5,对应下面两种标签后果为:
- [True True]:4是偶数,小于等于4
- [False False]:5不是偶数,大于4
咱们这次用y_train_multilabel
来训练模型。代码如下
ova_ml = OneVsRestClassifier( LogisticRegression(solver='lbfgs', max_iter=800) )ova_ml.fit( X_train, y_train_multilabel )
# 运行后果OnevsRestClassifier(estimator=LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, max_iter=800, multi_class=‘warn’, n_jobs=None, penalty='12', random_state=None, solver='lbfgs', tol=0.0001, verbose=6, warm_start=False), n_jobs=None)
有两个预计器,每个对应一个标签。
print( len(ova_ml.estimators_) ) ova_ml.estimators_
运行后果如下:
2[LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, max_iter=800, multi_class=‘warn', n_jobs=None, penalty='12°, random_state=None, solver='lbfgs', tol=0.0001, verbose=0, warm_start=False),LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, max_iter=800, multi_class='warn', n_jobs=None, penalty='l2', random_state=None, solver='lbfgs', tol=0.0001, verbose=0, warm_start=False) ]
展现一下测试集上100张图片。
fig, axes = plt.subplots( 10, 10, figsize=(8, 8) )fig.subplots_adjust( hspace=0.1, wspace=0.1 )for i, ax in enumerate( axes.flat ): ax.imshow( X_test[i,:].reshape(8,8), cmap='binary', interpolation='nearest') ax.text( 6.05, 0.05, str(y_test[i]), transform=ax.transAxes, color='blue') ax.set_xticks([]) ax.set_yticks([])
第一张图片是数字2,它是偶数(标签1为true),小于等于4(标签2为true)。
print( y_test[:1] ) print( ova_ml.predict(X_test[:1,:]) )
[2][[1 1]]
4.3 Multioutput 预计器
sklearn.multioutput
能够解决多输入(multi-output)的分类问题。
多输入分类是多标签分类的泛化,在这里每一个标签能够是多类别(大于两个类别)的。一个例子就是预测图片每一个像素(标签)的像素值是多少(从0到255的256个类别)。
Multioutput预计器有两个:
MultiOutputRegressor
:多输入回归MultiOutputClassifier
:多输入分类
这里咱们只关注多输入分类。
(1) MultiOutputClassifier
首先引入MultiOutputClassifier和RandomForestClassifier。
from sklearn.multioutput import MultiOutputClassifierfrom sklearn.ensemble import RandomForestClassifier
在手写数字的例子上,咱们也为特意每个数字设计了多标签而且每个标签的类别都大于二。
- 标签1:小于等于4,4和7之间,大于等于7(三类)
- 标签2:数字自身(十类)
代码如下:
y_train_1st = y_train.copy()y_train_1st[ y_train<=4 ] = 0y_train_1st[ np.logical_and{y_train>4, y_train<7) ] = 1y_train_ist[ y_train>=7 ] = 2y_train_multioutput = np.c_[y_train_1st, y_train]y_train_multioutput
# 运行后果array( [[0, 4], [1, 5], [2, 7], [1, 5], [2, 9], [2, 9]])
用含有100棵决策树的随机森林来解决这个多输出分类问题。
MO = MultiOutputClassifier( RandomForestClassifier(n_estimators=100) )MO.fit( X_train, y_train_multioutput )
# 后果MultiOutputClassifier(estimator=RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini', max_depth=None, max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, n_estimators=100, n_jobs=None, oob_score=False, random_state=None, verbose=0, warm_start=False), n_jobs=None)
看看这个模型在测试集前五张照片上的预测。
MO.predict( X_test[:5,:] )
array([[0, 2],[0, 2],[0, 0],[2, 9],[1, 5]])
这个ndarray第一列是标签1的类别,第二列是标签2的类别。预测后果是这五张照片别离显示数字2、2、0、9、5(标签2),它们前三个数2、2、0都小于等于4(标签1第一类),第四个数9大于等于7(标签1第二类),而第五个数5在4和7之间(标签1第三类)。
再看看实在标签。
y_test_1st = y_test.copy() y_test_1st[ y_test<=4 ] = 0 y_test_1st[ np.logical_and(y_test>4, y_test<7) ] = 1 y_test_1st[ y_test>=7 ] = 2 y_test_multioutput = np.c_[ y_test_1st, y_test ] y_test_multioutput[:5]
array([[0, 2],[0, 2],[0, 0],[2, 9],[1, 5]])
比照参考后果标签,模型预测的后果还是很不错的。
4.4 Model Selection 预计器
模型抉择(Model Selction)在机器学习十分重要,它次要用于评估模型体现,常见的Model Selection预计器有以下几个:
cross_validate
:评估穿插验证的后果。learning_curve
:构建与绘制学习曲线。GridSearchCV
:用穿插验证从超参数候选网格中搜寻出最佳超参数。RandomizedSearchCV
:用穿插验证从一组随机超参数搜寻出最佳超参数。
这里咱们只关注调节超参数的两个预计器,即GridSearchCV
和RandomizedSearchCV
。咱们先回顾一下穿插验证(更具体的解说请查看ShowMeAI文章 图解机器学习 | 模型评估办法与准则)。
(1) 穿插验证
K-折穿插验证(K-fold cross validation set),指的是把整个数据集均匀但随机分成K份,每份大略蕴含m/K个数据(m 是总数据数)。
在这K份,每次选K-1份作为训练集拟合参数,在剩下1份验证集上进行评估计算。因为遍历了这K份数据,因而该操作称为穿插验证。操作如下图所示
下图展现了两个调参的预计器:「网格搜寻」和「随机搜寻」。
网格搜寻调参:参数1在[1,10,100,1000]中取值,参数2在[0.01, 0.1, 1 10] 中取值,留神并不是等间距取值。模型在所有16组超参数上试验,选取穿插验证误差最小的参数。
随机搜寻调参:依据指定散布随机搜寻,能够抉择独立于参数个数,比方log(参数1)遵从0到3的均匀分布,log(参数2)遵从-2到1的均匀分布。
利用形式与参考代码如下:
from time import timefrom scipy.stats import randintfrom sklearn.model_selection import GridSearchCvfrom sklearn.model_selection import RandomizedSearchcCvfrom sklearn.ensemble import RandomForestClassifierX, y = digits.data, digits.targetRFC = RandomForestClassifier(n_estimators=20)# 随机搜寻/Randomized Searchparam_dist = { "max_depth": [3, 5], "max_features": randint(1, 11), "min_samples_split": randint(2, 11), "criterion": ["gini", "entropy"]}n_iter_search = 20random_search = RandomizedSearchCv( RFC, param_distributions=param_dist, n_iter=n_iter_search, cv=5 )}start = time()random_search.fit(X, y)print("RandomizedSearchCv took %.2f seconds for %d candidates,parameter settings." % ((time() - start), n_iter_search))print( random_search.best_params_ )print( random_search.best_score_ )# 网格搜寻/Grid Searchparam_grid = { "max_depth": [3, 5], "max_features": [1, 3, 10], "min_samples_ split": [2, 3, 10], "criterion": ["gini", "entropy"]}grid_search = GridSearchCV( RF, param_grid=param_grid, cv=5 )start = time()grid_search.fit(X, y)print("\nGridSearchcv took %.2f seconds for %d candidate parameter settings." % (time() - start, len(grid_search.cv_results_['params'])))print( grid_search.best_params_ )print( grid_search.best_score_ )
输入后果如下:
RandomizedSearchCv took 3.73 seconds for 20 candidates parameter settings.{'criterion': 'entropy', '*max_depth': 5, 'max_features': 6, 'min_samples_split': 4}0.8898163606010017GridSearchCV took 2.30 seconds for 36 candidate parameter settings.{'criterion': 'entropy', 'max_depth': 5, 'max_features': 10, 'min_samples_ split': 10}0.841402337228714S5
这里咱们对代码做一个解释:
- 前5行引入相应工具库。
- 第7-8行筹备好数据X和y,创立一个含20个决策树的随机森林模型。
- 第10-14和23-27行为对随机森林的超参数「最大树深、最多特色数、最小可决裂样本数、决裂规范」构建候选参数散布与参数网格。
- 第15-18行是运行随机搜寻。
- 第18-30行是运行网格搜寻。
运行后果里:
- 第一行输入每种追踪法运行的多少次和花的工夫。
- 第二行输入最佳超参数的组合。
- 第三行输入最高得分。
在本例中,随机搜寻比网格搜寻用更短时间内找到一组超参数,取得了更高的得分。
4.5 Pipeline 预计器
Pipeline预计器又叫流水线,把各种预计器串联(Pipeline)或并联(FeatureUnion)的形式组成一条龙服务。用好了它真的能大大提高效率。
(1) Pipeline
Pipeline将若干个预计器按程序连在一起,比方:特征提取 → 降维 → 拟合 → 预测
Pipeline的属性永远和最初一个预计器属性一样:
- 如果最初一个预计器是预测器,那么Pipeline是预测器。
- 如果最初一个预计器是转换器,那么Pipeline是转换器。
上面是一个简略示例,应用Pipeline来实现「填补缺失值-标准化」这两步的。咱们先构建含缺失值NaN的数据X。
X = np.array([[56,40,30,5,7,10,9,np.NaN,12], [1.68,1.83,1.77,np.NaN,1.9,1.65,1.88,np.NaN,1.75]])X = np.transpose(X)
咱们用以下流程组件构建Pipeline:
- 解决缺失值的转换器SimpleImputer。
- 做布局化的转换器MinMaxScaler。
from sklearn.pipeline import Pipelinefrom sklearn.impute import SimpleImputerfrom sklearn.preprocessing import MinMaxScalerpipe = Pipeline([ ('impute', SimpleImputer(missing_values=np.nan, strategy='mean')), ('normalize', MinMaxScaler())])
第5-7行创立了流水线,应用形式非常简单,在Pipeline()
里输出(名称,预计器)
这个元组构建的流水线列表。在本例中SimpleImputer起名叫impute,MinMaxScaler起名叫normalize。
因为最初一个预计器是转换器,因而pipeline也是个转换器。上面咱们来运行一下,咱们发现值都被填满了,而且两列也被标准化了。
X_proc = pipe.fit_transform( X )
来验证下面流水线的参数,咱们能够按程序来运行这两个转换器,后果是一样的。
X_impute = SimpleImputer(missing values=np.nan, strategy='mean').fit_transform( X )X_impute
# 运行后果array( [[50, 1.68], [40, 1.83], [30, 1.77], [5, 1.78], [7, 1.9 ], [10, 1.65], [9, 1.88], [20.375, 1.78], [12, 1.75 ]])
X_normalize = MinMaxScaler().fit_transform( X_impute )X_normalize
运行后果
array( [[1., 0.12 ], [0.77777778, 0.72], [0.55555556, 6.48], [0.52, 1], [0.04444444, 1.], [0.11111111, 9.], [0.08888889, 6.92], [0.34166667, 6.52], [0.15555556, 0.4 ]])
(2) FeatureUnion
如果咱们想在一个节点同时运行几个预计器,咱们可用FeatureUnion。在上面的例子中,咱们首先建设一个DataFrame数据,它有如下特点:
- 前两列字段「智力IQ」和「脾气temper」都是类别型变量。
- 后两列字段「支出income」和「身高height」都是数值型变量。
- 每列中都有缺失值。
d= { 'IQ' : ['high','avg','avg','low', high', avg', 'high', 'high',None],'temper' : ['good', None,'good', 'bad', 'bad','bad', 'bad', None, 'bad'],'income' : [50,40,30,5,7,10,9,np.NaN,12],'height' : [1.68,1.83,1.77,np.NaN,1.9,1.65,1.88,np.NaN,1.75]}X = pd.DataFrame( d )X
后果如下:
咱们当初按下列步骤来荡涤数据。
- 对类别型变量:获取数据 → 中位数填充 → 独热编码
- 对数值型变量:获取数据 → 均值填充 → 标准化
下面两步是并行进行的。
首先咱们本人定义一个从DataFrame外面获取数据列的类,起名叫DataFrameSelector
。
from sklearn.base import BaseEstimator, TransformerMixinclass DataFrameSelector( BaseEstimator, TransformerMixin ): def _init_( self, attribute_names ): self.attribute_names = attribute_names def fit( self, X, y=None ): return self def transform( self, X ): return X[self.attribute_names].values
上述代码在transform函数中,咱们将输出的DataFrame X依据属性名称来获取其值。
接下来建设流水线full_pipe
,它并联着两个流水线
categorical_pipe解决分类型变量
- DataFrameSelector用来获取
- SimpleImputer用呈现最多的值来填充None
- OneHotEncoder来编码返回非稠密矩阵
numeric_pipe解决数值型变量
- DataFrameSelector用来获取
- SimpleImputer用均值来填充NaN
- normalize来规范化数值
代码如下:
from sklearn.pipeline import Pipelinefrom sklearn.pipeline import FeatureUnionfrom sklearn.impute import SimpleImputerfrom sklearn.preprocessing import MinMaxScalerfrom sklearn.preprocessing import OneHotEncodercategorical features = ['IQ', 'temper']numeric_features = ['income', 'height']categorical pipe = Pipeline([ ('select', DataFrameSelector(categorical_features)), ('impute', SimpleImputer(missing values=None, strategy='most_frequent')), ('one_hot_encode', OneHotEncoder(sparse=False))])numeric_pipe = Pipeline([ ('select', DataFrameSelector(numeric_features)), ('impute', SimpleImputer(missing values=np.nan, strategy='mean')), ('normalize', MinMaxScaler())])full_pipe = FeatureUnion( transformer_list=[ ('numeric_pipe', numeric_pipe), ('categorical_pipe', categorical_pipe)])
咱们打印后果如下:
X_proc = full_pipe.fit_transform( X ) print( X_proc )
[[1. 0.12 0. 1. 0. 0. 1. ] [0.77777778 0.72 1. 0. 0. 1. 0. ] [0.55555556 0.48 1. 0. 0. 0. 1. ] [0. 0.52 0. 0. 1. 1. 0. ] [0.04444444 1. 0. 1. 0. 1. 0. ] [0.11111111 0. 1. 0. 0. 1. 0. ] [0.08888889 0.92 0. 1. 0. 1. 0. ] [0.34166667 0.52 0. 1. 0. 1. 0. ] [0.15555556 0.4 0. 1. 0. 1. 0. ]]
5.总结
上面咱们对下面解说到的sklearn工具库利用常识做一个总结。
5.1 SKLearn五大准则
SKLearn的设计下,它的次要API遵循五大准则
(1) 一致性
所有对象的接口统一且简略,在「预计器」中
- 创立:
model = Constructor(hyperparam)
拟参:
- 有监督学习:
model.fit(X_train, y_train)
- 无监督学习:
model.fit(X_train)
- 有监督学习:
在「预测器」中
- 有监督学习里预测标签:
y_pred = model.predict(X_test)
- 无监督学习里识别模式:
idx_pred = model.predict( Xtest)
在「转换器」中
- 创立:
trm = Constructor(hyperparam)
- 获参:
trm.fit(X_train)
- 转换:
X_trm = trm.transform(X_train)
(2) 可测验
所有预计器里设置的超参数和学到的参数都能够通过实例的变量间接拜访来测验其值,区别是超参数的名称最初没有下划线_,而参数的名称最初有下划线_。举例如下:
- 通例:
model.hyperparameter
- 特例:
SVC.kernel
- 通例:
model.parameter_
- 特例:
SVC.support_vectors_
(3) 规范类
SKLearn模型承受的数据集的格局只能是「Numpy数组」和「Scipy稠密矩阵」。超参数的格局只能是「字符」和「数值」。
不承受其余的类!
(4) 可组成
模块都能反复「连在一起」或「并在一起」应用,比方两种模式流水线(pipeline)
- 任意转换器序列
- 任意转换器序列+预计器
(5) 有默认
SKLearn给大多超参数提供了正当的默认值,大大降低了建模的难度。
5.2 SKLearn框架流程
sklearn的建模利用流程框架大略如下:
(1) 确定工作
是「有监督」的分类或回归?还是「无监督」的聚类或降维?确定好后根本就能晓得用Sklearn里哪些模型了。
(2) 数据预处理
这步最繁琐,要解决缺失值、异样值;要编码类别型变量;要正规化或标准化数值型变量,等等。然而有了Pipeline神器所有变得简略高效。
(3) 训练和评估
这步最简略,训练用预计器fit()
先拟合,评估用预测器predict()
来评估。
(4) 抉择模型
启动ModelSelection预计器里的GridSearchCV和RandomizedSearchCV,抉择得分最高的那组超参数(即模型)。
参考资料
- 图解机器学习算法 | 从入门到精通系列
- SKLearn官网:https://scikit-learn.org/stable/
- AI建模工具速查|Scikit-learn使用指南
ShowMeAI系列教程举荐
- 图解Python编程:从入门到精通系列教程
- 图解数据分析:从入门到精通系列教程
- 图解AI数学根底:从入门到精通系列教程
- 图解大数据技术:从入门到精通系列教程
- 图解机器学习算法:从入门到精通系列教程
- 机器学习实战:手把手教你玩转机器学习系列
相干文章举荐
- Python机器学习算法利用实际
- SKLearn入门与简略利用案例
- SKLearn最全利用指南
- XGBoost建模利用详解
- LightGBM建模利用详解
- Python机器学习综合我的项目-电商销量预估
- Python机器学习综合我的项目-电商销量预估<进阶计划>
- 机器学习特色工程最全解读
- 自动化特色工程工具Featuretools利用
- AutoML自动化机器学习建模