在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文章 图解机器学习 | 机器学习基础知识[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_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]
构建Dataframe格式的数据集:
将X和y合并为Dataframe格式数据
import pandas as pd
import seaborn as sns
iris_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工具与数据可视化教程[16]。
使用Seaborn的pairplot查看两两特征之间的关系
sns.pairplot( iris_data, hue=‘species’, palette=‘husl’ )
图片
数据集引入方式
前面提到的是鸢尾花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)>
我们调用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)是具有转换功能的估计器。
估计器
任何可以基于数据集对一些参数进行估计的对象都被称为估计器,它有两个核心点:
① 需要输入数据。
② 可以估计参数。
图片
估计器首先被创建,然后被拟合。
创建估计器:需要设置一组超参数,比如
线性回归里超参数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 LinearRegression
model = LinearRegression(normalize=True)model
输出:
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=True)
创建完后的估计器会显示所有的超参数(比如刚才设置的normalize=True),未设置的超参数都使用默认值。
自己创建一个简单数据集(一条直线上的数据点),简单讲解一下估计器里面的特征。
import numpy as np
import matplotlib.pyplot as plt
x = 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均值
图片
我们来看看聚类[17]的例子,先从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.074