在本篇内容中,我们展开讲解SKLearn的进阶与核心内容。
SKLearn 中有六大任务模块,如下图所示:分别是分类、回归、聚类、降维、模型选择和预处理。

SKLearn官网:https://scikit-learn.org/stable/[2]SKLearn的快速利用方法也推举大家查看ShowMeAI的文章和速查手册 AI建模工具速查|Scikit-learn利用指南[3]

在SKLearn中,由于做了上层的封装,分类模型、回归模型、聚类与降维模型、预处理器等等都叫做估计器(estimator),就像在Python里『万物皆工具』,在SKLearn里『万物皆估计器』。

在本篇内容中,我们将给大家进一步深入讲解scikit-learn工具库的利用方法,力求完全覆盖SKLearn工具库运用的方方面面。
本文的内容板块包括:

① 机器学习根本知识:机器学习定义与四要素:数据、任务、性能度量和模型。
机器学习观点,以便和SKLearn对应匹配上。

scikitlearn保姆级入门教程

② SKLearn讲解:API设计事理,SKLearn几大特点:同等性、可考验、标准类、可组合和默认值,以及SKLearn自带数据以及储存格式。

③ SKLearn三大核心API讲解:包括估计器、预测器和转换器。
这个板块很主要,大家实际运用时紧张是借助于核心API落地。

④ SKLearn高等API讲解:包括简化代码量的流水线(Pipeline估计器),集成模型(Ensemble估计器)、有多种别-多标签-多输出分类模型(Multiclass 和 Multioutput 估计器)和模型选择工具(Model Selection估计器)。

1.机器学习简介

关于本节内容,强烈推举大家阅读ShowMeAI文章 图解机器学习 | 机器学习根本知识[4] 和 图解机器学习 | 模型评估方法与准则[5] ,ShowMeAI对干系知识内容展开做了详细讲解。

定义和构成元素

作甚机器学习?大师汤姆米切尔(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)

数据

数据(data)是信息的载体。
数据可以有以下划分办法:

从『数据详细类型』维度划分:构造化数据和非构造化数据。
构造化数据(structured data)是由二维表构造来逻辑表达和实现的数据。
非构造化数据是没有预定义的数据,不便用数据库二维表来表现的数据。
非构造化数据包括图片,笔墨,语音和视频等。
从『数据表达形式』维度划分:原始数据和加工数据。
从『数据统计性子』维度划分:样本内数据和样本外数据。

对付非构造数据,常日神经网络有更好的效果,可以参考 ShowMeAI 的文章Python机器学习算法实践[6]中的图像建模例子。

机器学习模型很多时候利用的是构造化数据,即二维的数据表。
我们这里以 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)』。

任务

根据学习的任务模式(演习数据是否有标签),机器学习可分为几大类。
上图画出机器学习各种之间的关系。

监督学习(有标签)无监督学习(无标签)半监督学习(有部分标签)强化学习(有延迟的标签)

性能度量

回归和分类任务中最常见的偏差函数以及一些有用的性能度量如下,详细内容可以参考ShowMeAI文章 机器学习评估与度量准则[7]。

2. SKLearn数据

SKLearn作为通用机器学习建模的工具包,包含六个任务模块和一个数据导入模块:

监督学习:分类任务[8]监督学习:回归任务[9]无监督学习:聚类任务[10]无监督学习:降维任务[11]模型选择任务[12]数据预处理任务[13]数据导入模块[14]

首先看看 SKLearn 默认数据格式和自带数据集。

SKLearn默认数据格式

Sklearn 里模型能直策应用的数据有两种形式:

Numpy二维数组(ndarray)的稠密数据(dense data),常日都是这种格式。
SciPy矩阵(scipy.sparse.matrix)的稀疏数据(sparse data),比如文本分析每个单词(字典有100000个词)做独热编码得到矩阵有很多0,这时用ndarray就不得当了,太耗内存。

自带数据集

SKLearn 里面有很多自带数据集供用户利用。

比如在之前文章Python机器学习算法实践中用到的鸢尾花数据集,包含四个特色(萼片长/宽和花瓣长/宽)和三个种别。

我们可以直接从SKLearn里面的datasets模块中引入,代码如下(代码可以在 线上Jupyter环境[15] 中运行):

# 导入工具库from sklearn.datasets import load_irisiris = load_iris()# 数据因此『字典』格式存储的,看看 iris 的键有哪些。
print(iris.keys())

输出如下:

dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])

读取数据集的信息:

#输出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]

输出如下:

dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])(150, 4)['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'](150,)['setosa' 'versicolor' 'virginica']

构建Dataframe格式的数据集:

# 将X和y合并为Dataframe格式数据import pandas as pdiris_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))print(iris_data)

输出如下:

sepal length (cm) sepal width (cm) ... petal width (cm) species0 5.1 3.5 ... 0.2 setosa1 4.9 3.0 ... 0.2 setosa2 4.7 3.2 ... 0.2 setosa3 4.6 3.1 ... 0.2 setosa4 5.0 3.6 ... 0.2 setosa.. ... ... ... ... ...145 6.7 3.0 ... 2.3 virginica146 6.3 2.5 ... 1.9 virginica147 6.5 3.0 ... 2.0 virginica148 6.2 3.4 ... 2.3 virginica149 5.9 3.0 ... 1.8 virginica[150 rows x 5 columns]

我们利用 seaborn 来做一些数据剖析,查看一下数据的分布特性。
这里利用到的是成对维度的关联剖析,关于seaborn的利用方法可以参阅ShowMeAI的文章 seaborn工具与数据可视化教程[16]。

import seaborn as snsfrom matplotlib import pyplot as plt# 利用Seaborn的pairplot查看两两特色之间的关系sns.pairplot(iris_data, hue='species', palette='husl')plt.show()

数据集引入办法

前面提到的是鸢尾花iris数据集,我们通过load_iris加载进来,实际上SKLearn有三种引入数据形式。

打包好的数据:对付小数据集,用sklearn.datasets.load_分流下载数据:对付大数据集,用sklearn.datasets.fetch_随机创建数据:为了快速展示,用sklearn.datasets.make_

上面这个星号指代详细文件名,如果大家在Jupyter这种IDE环境中,可以通过tab制表符自动补全和选择。

datasets.load_datasets.fetch_datasets.make_

比如我们调用load_iris

from sklearn import datasetsdatasets.load_iris

输出如下:

<function sklearn.datasets._base.load_iris(, return_X_y=False, as_frame=False)>

我们调用load_digits加载手写数字图像数据集

digits = datasets.load_digits()digits.keys()

输出:

dict_keys(['data', 'target', 'frame', 'feature_names', 'target_names', 'images', 'DESCR'])

我们再来看看通过fetch拉取数据的示例:

#加州房屋数据集california_housing = datasets.fetch_california_housing() california_housing.keys()

输出:

dict_keys(['data', 'target', 'frame', 'target_names', 'feature_names', 'DESCR'])3.SKLearn核心API

我们前面提到SKLearn里万物皆估计器。
估计器是个非常抽象的叫法,不严谨的一个理解,我们可以视其为一个模型(用来回归、分类、聚类、降维),或一套流程(预处理、网格搜索交叉验证)。

本节三大API实在都是估计器:

估计器(estimator)常日是用于拟合功能的估计器。
预测器(predictor)是具有预测功能的估计器。
转换器(transformer)是具有转换功能的估计器。

估计器

任何可以基于数据集对一些参数进行估计的工具都被称为估计器,它有两个核心点:

① 须要输入数据。
② 可以估计参数。

估计器首先被创建,然后被拟合。

创建估计器:须要设置一组超参数,比如线性回归里超参数normalize=TrueK均值里超参数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()model

输出:

创建完后的估计器会显示所有的超参数(比如刚才设置的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 )

输出为:

拟合完后的估计器和创建完彷佛没有差别,但我们已经可以用model.param_访问到拟合完数据的参数了,如下代码。

print(model.coef_)print(model.intercept_)# 输出结果# [2.]0.9999999999999982

(2) K均值

我们来看看聚类[17]的例子,先从SKLearn的cluster中导入KMeans,初始化模型工具命名为model,设置超参数n_cluster为3(为了展示方便而我们知道用的iris数据集有3类,实际上可以设置不同数量的n_cluster)。

虽然iris数据里包含标签y,但在无监督的聚类中我们不会利用到这个信息。

from sklearn.cluster import KMeansmodel = KMeans(n_clusters=3)model

输出为:

iris数据集包含四维特色(萼片长、萼片宽、花瓣长、花瓣宽),不才面的例子中我们希望可视化,这里我们大略选取两个特色(萼片长、萼片宽)来做聚类并且可视化结果。

把稳下面代码X = iris.data[:,0:2]实在便是提取特色维度。

from sklearn.datasets import load_irisiris = load_iris()X = iris.data[:, 0:2]model.fit(X)

输出为:

拟合完后的估计器和创建完彷佛没有差别,但我们已经可以用model.param_访问到拟合完数据的参数了,如下代码。

print(model.cluster_centers_, '\n')print(model.labels_, '\n')print(model.inertia_, '\n')print(iris.target)

输出为:

[[5.006 3.428 ] [6.81276596 3.07446809] [5.77358491 2.69245283]] [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 2 1 2 1 2 1 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 1 1 1 1 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 1 1 2 1 1 1 1 1 1 2 2 1 1 1 1 2 1 2 1 2 1 1 2 2 1 1 1 1 1 2 2 1 1 1 2 1 1 1 2 1 1 1 2 1 1 2] 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)

预测器

预测器是估计器做的一个延展,具备对数据进行预测的功能。

预测器最常见的是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_irisiris = load_iris()from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(iris['data'], iris['target'], test_size=0.2, random_state=42)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()。

from sklearn.linear_model import LogisticRegression# 演习逻辑回归模型clf = LogisticRegression(random_state=42)clf.fit(X_train, y_train)# 预测并输出结果y_pred = clf.predict(X_test)p_pred = clf.predict_proba(X_test)print(y_test, '\n')print(y_pred, '\n')print(p_pred)

输出为:

[2 0 1 2 0 2 1 2 1 1 2 0 1 0 1 1 1 2 0 0 0 1 1 2 0 2 0 0 2 0] [2 0 1 2 0 2 1 2 1 1 2 0 1 0 1 2 1 2 0 0 0 1 1 2 0 2 0 0 2 0] [[5.84963046e-08 4.96117097e-03 9.95038771e-01] [9.71672786e-01 2.83271495e-02 6.40401092e-08] [2.53663405e-03 7.50077887e-01 2.47385478e-01] [1.15877033e-06 7.78044433e-03 9.92218397e-01] [9.83970209e-01 1.60297543e-02 3.66791074e-08] [8.04755568e-04 1.82375270e-01 8.16819974e-01] [1.25437262e-02 7.10497126e-01 2.76959148e-01] [1.94079178e-05 4.27933017e-02 9.57187290e-01] [1.80584275e-01 8.14585269e-01 4.83045658e-03] [5.84488653e-03 7.95860503e-01 1.98294611e-01] [7.57223966e-05 6.14486740e-02 9.38475604e-01] [9.61296248e-01 3.87035912e-02 1.60329912e-07] [1.30146442e-02 9.64248450e-01 2.27369057e-02] [9.65720575e-01 3.42791404e-02 2.84868855e-07] [2.12979534e-02 9.04287017e-01 7.44150292e-02] [5.91582281e-04 3.10399507e-01 6.89008911e-01] [7.71812321e-02 9.11937138e-01 1.08816299e-02] [1.83162197e-05 2.11439580e-02 9.78837726e-01] [9.83997195e-01 1.60027584e-02 4.62150789e-08] [9.69181057e-01 3.08188845e-02 5.80897527e-08] [9.94617424e-01 5.38257293e-03 3.40606259e-09] [2.80522888e-03 7.81463368e-01 2.15731403e-01] [2.40149429e-02 9.16835184e-01 5.91498731e-02] [3.26994050e-04 1.51003221e-01 8.48669785e-01] [9.46376509e-01 5.36230480e-02 4.42746065e-07] [8.94084091e-06 2.79665472e-02 9.72024512e-01] [9.81344974e-01 1.86550062e-02 1.93952662e-08] [9.76763867e-01 2.32360873e-02 4.56820412e-08] [1.72445556e-06 2.93413411e-02 9.70656934e-01] [9.60437629e-01 3.95622134e-02 1.57401313e-07]]

score & decision_function

预测器里还有额外的两个函数可以利用。
在分类问题中:

score()返回的是分类准确率。
decision_function()返回的是每个样例在每个类下的分数值。

from sklearn.svm import SVC# 打算准确率accuracy = clf.score(X_test, y_test)print("Accuracy:", accuracy)# 利用SVM模型svc = SVC(probability=True, random_state=42)svc.fit(X_train, y_train)# 获取每个样本在每个类下的分数值decision_scores = svc.decision_function(X_test)print("Decision Function Scores:", decision_scores)

Accuracy: 0.9666666666666667Decision Function Scores: [[-0.21354919 0.81327918 2.25115765] [ 2.23169288 1.16431173 -0.25493274] [-0.23173658 2.21556256 1.10354143] [-0.22176414 0.83548245 2.24920544] [ 2.23352788 1.11529919 -0.24717049] [-0.23723586 1.163352 2.20040945] [-0.22443193 2.21584876 1.06091779] [-0.23324846 0.94961946 2.23832758] [-0.13768142 2.23536216 0.79018497] [-0.22724648 2.21909847 1.06102765] [-0.23566482 1.04835818 2.23055457] [ 2.22438466 1.18795538 -0.25674756] [-0.21064144 2.24067251 0.84392292] [ 2.22389429 1.17852713 -0.25395059] [-0.215283 2.23287749 0.88969875] [-0.23809459 1.17426253 2.19470283] [-0.17365556 2.23470521 0.81208984] [-0.23418257 0.92509474 2.24205248] [ 2.23399014 1.13529377 -0.25079519] [ 2.2315122 1.17064842 -0.25622041] [ 2.24294709 1.0593895 -0.2479655 ] [-0.22676008 2.20955701 1.10099822] [-0.2129543 2.23495842 0.8725085 ] [-0.23942305 1.14842522 2.21197955] [ 2.21922601 1.18732399 -0.25404726] [-0.23196582 0.90666121 2.24268675] [ 2.23682688 1.13632807 -0.25293461] [ 2.23344891 1.15955883 -0.25500122] [-0.22633456 0.87512674 2.24359076] [ 2.22636148 1.16967315 -0.25306669]]

小结

估计器都有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)

转换器

转换器是一种估计器,也有拟合功能,比拟预测器做完拟合来预测,转换器做完拟合来转换。
核心点如下:

估计器里fit + predict转换器里fit + transform

本节先容两大类转换器:

将种别型变量(categorical)编码成数值型变量(numerical)规范化(normalize)或标准化(standardize)数值型变量

(1) 种别型变量编码

① LabelEncoder&OrdinalEncoder

LabelEncoder和OrdinalEncoder都可以将字符转成数字,但是:

LabelEncoder的输入是一维,比如1d ndarrayOrdinalEncoder的输入是二维,比如 DataFrame

# 首先给出要编码的列表 enc 和要解码的列表 dec。
enc = ['red', 'blue', 'yellow', 'red']dec = ['blue', 'blue', 'red']# 从sklearn下的preprocessing中引入LabelEncoder,再创建转换器起名LE,不须要设置任何超参数。
from sklearn.preprocessing import LabelEncoderLE = LabelEncoder()print(LE.fit(enc))print(LE.classes_)print(LE.transform(dec))LabelEncoder()

输出为:

LabelEncoder()['blue' 'red' 'yellow'][0 0 1]

除了LabelEncoder,OrdinalEncoder也可以完成编码。
如下代码所示:

from sklearn.preprocessing import OrdinalEncoderOE = 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()[array(['blue', 'red', 'yellow'], dtype=object)][[0.] [0.] [1.]]

上面这种编码的问题是,在编码过后会带来不同类别的大小关系,比如这里3种颜色实在实质上是平等的,没有大小关系。

我们的其余一种种别型数据编码办法,独热向量编码(one-hot encoding)可以办理这个问题,大家连续往下看。

② OneHotEncoder

独热向量编码实在便是把一个整数用向量的形式表现。
上图右侧便是对颜色做独热向量编码。
转换器OneHotEncoder可以接管两种类型的输入:

① 用LabelEncoder编码好的一维数组② DataFrame

一、用LabelEncoder编码好的一维数组(元素为整数),重塑(用reshape(-1,1))成二维数组作为OneHotEncoder输入。

from sklearn.preprocessing import OneHotEncoderOHE = OneHotEncoder()num = LE.fit_transform(enc)print(num)OHE_y = OHE.fit_transform(num.reshape(-1, 1))OHE_y

输出为:

[1 0 2 1]

<4x3 sparse matrix of type '<class 'numpy.float64'>'with 4 stored elements in Compressed Sparse Row format>

上面结果阐明如下:

第4行打印出编码结果[2 0 1 2]。
第6行将其转成独热心势,输出是一个『稀疏矩阵』形式,由于实操中常日种别很多,因此就一步到位用稀疏矩阵来节省内存。

想看该矩阵里详细内容,用toarray()函数。

OHE_y.toarray()

输出为:

二、用DataFrame作为OneHotEncoder输入。

OHE = OneHotEncoder()OHE.fit_transform(enc_DF).toarray()

输出为:

(2) 特色缩放

数据要做的最主要的转换之一是特色缩放(feature scaling)。
类似逻辑回归,神经网络这种打算型模型,对付不同特色的幅度大小差异是敏感的。

详细来说,对付某个特色,我们有两种变换方法:

标准化(standardization):每个维度的特色减去该特色均值,除以该维度的标准差。
规范化(normalization):每个维度的特色减去该特色最小值,除以该特色的最大值与最小值之差。

① MinMaxScaler

如上图所示,MinMaxScaler会根据特色的最大最小取值,对数据进行幅度缩放。

from sklearn.preprocessing import MinMaxScalerX = np.array([0, 0.5, 1, 1.5, 2, 100])X_scale = MinMaxScaler().fit_transform(X.reshape(-1, 1))X_scale

输出为:

② StandardScaler

StandardScaler做的事情是调度数据分布,只管即便靠近正态分布。

from sklearn.preprocessing import StandardScalerX_scale = StandardScaler().fit_transform(X.reshape(-1, 1))X_scale

输出为:

把稳:

fit()函数只能浸染在演习集上,如果希望对测试集变换,只要用演习集上fit好的转换器去transform即可。
不能在测试集上fit再transform,否则演习集和测试集的变换规则不一致,模型学习到的信息就无效了。

4.高等API

我们在这节中给大家先容SKLearn的『高等API』,即五大元估计器(集成功能的Ensemble,多分类和多标签的Multiclass,多输出的Multioutput,选择模型的Model Selection,流水线的Pipeline)。

ensemble.BaggingClassifierensemble.VotingClassifiermulticlass.OneVsOneClassifiermulticlass.OneVsRestClassifiermultioutput.MultiOutputClassifiermodel_selection.GridSearchCVmodel_selection.RandomizedSearchCVpipeline.Pipeline

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_irisiris = load_iris()from sklearn.model_selection import train_test_splitfrom sklearn import metricsX_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 RandomForestClassifierRF = RandomForestClassifier(n_estimators=4, max_depth=5)RF.fit(X_train, y_train)

输出为:

元估计器和预估器一样也有fit()。
下面看看随机森林里包含的估计器个数和其本身。

rint( RF.n_estimators ) RF.estimators_

输出为:

4[DecisionTreeClassifier(max_depth=5, max_features='sqrt', random_state=999750908), DecisionTreeClassifier(max_depth=5, max_features='sqrt', random_state=897325070), DecisionTreeClassifier(max_depth=5, max_features='sqrt', random_state=693132726), DecisionTreeClassifier(max_depth=5, max_features='sqrt', random_state=1637950645)]

拟合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): 0.9667RF - Accuracy (Test): 0.9667

和随机森林由同质分类器『决策树』不同,投票分类器由多少个异质分类器组成。
下面我们用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)

结果如下:

看看Ensemble集成模型里包含的估计器个数和其本身。

print(len(Ensemble.estimators_))Ensemble.estimators_

结果如下:

3[LogisticRegression(multi_class='multinomial'), RandomForestClassifier(n_estimators=5), GaussianNB()]

比拟元估计器和它三个组成元素的表现,下过表现如下:

# 拟合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.9917GNB - Accuracy (Train): 0.95Ensemble - Accuracy (Train): 0.9833LR - Accuracy (Test): 1RF - Accuracy (Test): 1GNB - Accuracy (Test): 1Ensemble - Accuracy (Test): 1

Multiclass 估计器

sklearn.multiclass可以处理多种别(multi-class) 的多标签(multi-label) 的分类问题。
下面我们会利用数字数据集digits作为示例数据来讲解。
我们先将数据分成 80:20 的演习集和测试集。

# 导入数据from sklearn.datasets import load_digitsdigits = load_digits()digits.keys()

输出如下:

# 输出结果dict_keys(['data', 'target', 'frame', 'feature_names', '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)# 109/2=45,10类统共45个OvO分类器。
print(len(ovo_lr.estimators_))ovo_lr.estimators_

结果如下:

45(LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200), LogisticRegression(max_iter=200))

演习集分类全对,测试集准确率98%。

print("OvO LR - Accuracy (Train): %.4g" % metrics.accuracy_score(y_train, ovo_lr.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.9833

② 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)

10类统共10个OvA分类器。

print(len(ova_lr.estimators_))ova_lr.estimators_

结果如下:

10[LogisticRegression(max_iter=800), LogisticRegression(max_iter=800), LogisticRegression(max_iter=800), LogisticRegression(max_iter=800), LogisticRegression(max_iter=800), LogisticRegression(max_iter=800), LogisticRegression(max_iter=800), LogisticRegression(max_iter=800), LogisticRegression(max_iter=800), LogisticRegression(max_iter=800)]

演习集准确率险些100%,测试集准确率96%。
代码与结果如下:

print("OvA LR - Accuracy (Train): %.4g" % metrics.accuracy_score(y_train, ova_lr.predict(X_train)))print("OvA LR - Accuracy (Test): %.4g" % metrics.accuracy_score(y_test, ova_lr.predict(X_test)))

OvA LR - Accuracy (Train): 0.9965OvA LR - Accuracy (Test): 0.9611

(2) 多标签分类

到目前为止,所有的样例都总是被分配到仅一个类。
有些情形下,你大概想让分类器给一个样例输出多个种别。
在无人驾驶的运用中,不才图识别出有车和指示牌,没有交通灯和人。

物体识别是一个繁芜的深度学习问题,我们在这里暂且不深入磋商。
我们先看一个大略点的例子,在手写数字的例子上,我们特意为每个数字设计了两个标签:

标签1:奇数、偶数标签2:小于即是4,大于4

我们构建多标签y_train_multilabel,代码如下(OneVsRestClassifier也可以用来做多标签分类):

from sklearn.multiclass import OneVsRestClassifiery_train_multilabel = np.c_[y_train % 2 == 0, y_train <= 4]print(y_train_multilabel)

看下图演习集第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)

有两个估计器,每个对应一个标签。

print(len(ova_ml.estimators_))ova_ml.estimators_

运行结果如下:

2[LogisticRegression(max_iter=800), LogisticRegression(max_iter=800)]

展示一下测试集上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([])

第一张图片是数字4,它是偶数(标签1为true),小于4(标签2为false)。

print(y_test[:1])print(ova_ml.predict(X_test[:1, :]))

[4][[1 0]]

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_1st[y_train >= 7] = 2y_train_multioutput = np.c_[y_train_1st, y_train]y_train_multioutput

MO = MultiOutputClassifier(RandomForestClassifier(n_estimators=100))MO.fit(X_train, y_train_multioutput)

看看这个模型在测试集前五张照片上的预测。

MO.predict(X_test[: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] = 0y_test_1st[np.logical_and(y_test > 4, y_test < 7)] = 1y_test_1st[y_test >= 7] = 2y_test_multioutput = np.c_[y_test_1st, y_test]y_test_multioutput[:5]

比拟参考绩果标签,模型预测的结果还是很不错的。

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 RandomizedSearchCVfrom 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 7.06 seconds for 20 candidates,parameter settings.{'criterion': 'gini', 'max_depth': 5, 'max_features': 6, 'min_samples_split': 3}0.8920597338285361GridSearchcv took 3.95 seconds for 36 candidate parameter settings.{'criterion': 'entropy', 'max_depth': 5, 'max_features': 10, 'min_samples_split': 2}0.8208372021046116

这里我们对代码做一个阐明:

前5行引入相应工具库。
第7-8行准备好数据X和y,创建一个含20个决策树的随机森林模型。
第11-16和27-32行为对随机森林的超参数『最大树深、最多特色数、最小可分裂样本数、分裂标准』构建候选参数分布与参数网格。
第17-20行是运行随机搜索。
第20-36行是运行网格搜索。

运行结果里:

第一行输出每种追踪法运行的多少次和花的韶光。
第二行输出最佳超参数的组合。
第三行输出最高得分。

在本例中,随机搜索比网格搜索用更短韶光内找到一组超参数,得到了更高的得分。

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-6行创建了流水线,利用办法非常大略,在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

X_normalize = MinMaxScaler().fit_transform(X_impute)X_normalize

如果我们想在一个节点同时运行几个估计器,我们可用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用涌现最多的值来添补NoneOneHotEncoder来编码返回非稀疏矩阵numeric_pipe处理数值型变量DataFrameSelector用来获取SimpleImputer用均值来添补NaNnormalize来规范化数值

代码如下:

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_output=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工具库运用知识做一个总结。

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给大多超参数供应了合理的默认值,大大降落了建模的难度。

SKLearn框架流程

sklearn的建模运用流程框架大概如下:

(1) 确定任务

是『有监督』的分类或回归?还是『无监督』的聚类或降维?确定好后基本就能知道用Sklearn里哪些模型了。

(2) 数据预处理

这步最繁琐,要处理缺失落值、非常值;要编码种别型变量;要正规化或标准化数值型变量,等等。
但是有了Pipeline神器统统变得大略高效。

(3) 演习和评估

这步最大略,演习用估计器fit()先拟合,评估用预测器predict()来评估。

(4) 选择模型

启动ModelSelection估计器里的GridSearchCV和RandomizedSearchCV,选择得分最高的那组超参数(即模型)。

参考资料

[1]SKLearn入门与大略运用案例: https://www.showmeai.tech/article-detail/202

[2]SKLearn官网: https://scikit-learn.org/stable/

[3]AI建模工具速查|Scikit-learn利用指南: https://www.showmeai.tech/article-detail/108

[4]图解机器学习 | 机器学习根本知识: https://www.showmeai.tech/article-detail/185

[5]图解机器学习 | 模型评估方法与准则: https://www.showmeai.tech/article-detail/186

[6]Python机器学习算法实践: https://www.showmeai.tech/article-detail/201

[7]机器学习评估与度量准则: https://www.showmeai.tech/article-detail/186

[8]监督学习:分类任务: https://scikit-learn.org/stable/supervised_learning.html#supervised-learning

[9]监督学习:回归任务: https://scikit-learn.org/stable/supervised_learning.html#supervised-learning

[10]无监督学习:聚类任务: https://scikit-learn.org/stable/modules/clustering.html#clustering

[11]无监督学习:降维任务: https://scikit-learn.org/stable/modules/decomposition.html#decompositions

[12]模型选择任务: https://scikit-learn.org/stable/model_selection.html#model-selection

[13]数据预处理任务: https://scikit-learn.org/stable/modules/preprocessing.html#preprocessing

[14]数据导入模块: https://scikit-learn.org/stable/datasets.html

[15]线上Jupyter环境: https://jupyter.org/try

[16]seaborn工具与数据可视化教程: https://www.showmeai.tech/article-detail/151

[17]聚类: https://www.showmeai.tech/article-detail/19