什么网站可以做软件有哪些东西,上海公共招聘网手机版,wordpress安装时英文版,国内十大设计公司排名在SKLearn中#xff0c;因为做了上层的封装#xff0c;分类模型、回归模型、聚类与降维模型、预处理器等等都叫做估计器(estimator)#xff0c;就像在Python里『万物皆对象』#xff0c;在SKLearn里『万物皆估计器』。
在本篇内容中#xff0c;我们将给大家进一步深入讲解…在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, columnsiris.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_yFalse)
我们调用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)是具有转换功能的估计器。
估计器
任何可以基于数据集对一些参数进行估计的对象都被称为估计器它有两个核心点
① 需要输入数据。
② 可以估计参数。
图片
估计器首先被创建然后被拟合。
创建估计器需要设置一组超参数比如 线性回归里超参数normalizeTrue K均值里超参数n_clusters5 拟合估计器需要训练集 在监督学习中的代码范式为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(normalizeTrue)model
输出
LinearRegression(copy_XTrue, fit_interceptTrue, n_jobsNone, normalizeTrue)
创建完后的估计器会显示所有的超参数比如刚才设置的normalizeTrue未设置的超参数都使用默认值。
自己创建一个简单数据集一条直线上的数据点简单讲解一下估计器里面的特征。
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_XTrue, fit_interceptTrue, n_jobsNone, normalizeTrue)
拟合完后的估计器和创建完似乎没有差别但我们已经可以用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_clusters3 ) model
输出为
KMeans(algorithm‘auto’, copy_xTrue, init‘k-means’, max_iter300, n_clusters3, n_init10, n_jobsNone, precompute_distances‘auto’, random_stateNone, tol0.0001, verbose0)
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_xTrue, init‘k-means’, max_iter300, n_clusters3, n_init10, n_jobsNone, precompute_distances‘auto’, random_stateNone, tol0.0001, verbose0)
拟合完后的估计器和创建完似乎没有差别但我们已经可以用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 )
预测器
预测器是估计器做的一个延展具备对数据进行预测的功能。 图片 预测器最常见的是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_size0.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_predy_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 )
转换器
转换器是一种估计器也有拟合功能对比预测器做完拟合来预测转换器做完拟合来转换。核心点如下
估计器里fit predict 转换器里fit transform 图片 本节介绍两大类转换器
将类别型变量(categorical)编码成数值型变量(numerical) 规范化(normalize)或标准化(standardize)数值型变量 图片 (1) 类别型变量编码
① LabelEncoderOrdinalEncoder
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]
除了LabelEncoderOrdinalEncoder也可以完成编码。如下代码所示
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’, dtypeclass ‘numpy.float64’) [array([‘blue’, ‘yellow’, ‘red’], dtypeobject)] [[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
Ensemble 估计器 图片 如上图分类器统计每个子分类器的预测类别数再用『多数投票』原则得到最终预测。回归器计算每个子回归器的预测平均值。
最常用的Ensemble估计器排列如下
AdaBoostClassifier逐步提升分类器 AdaBoostRegressor逐步提升回归器 BaggingClassifierBagging分类器 BaggingRegressorBagging回归器 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_size0.2)
(1) RandomForestClassifier 图片 随机森林RandomForestClassifier通过控制n_estimators超参数来决定基估计器的个数在这里是4棵决策树(森林由树组成)此外每棵树的最大树深为5(max_depth5)。
from sklearn.ensemble import RandomForestClassifier RF RandomForestClassifier( n_estimators4, max_depth5 ) RF.fit( X_train, y_train )
输出为
RandomForestClassifier(bootstrapTrue, class_weightNone, criterion‘gini’, max_depth5, max_features‘auto’, max_leaf_nodesNone, min_impurity_decrease0.0, min_impurity_splitNone, min_samples_leaf1, min_samples_split2, min_weight_fraction_leaf0.0, n_estimators4, n_jobsNone, oob_scoreFalse, random_stateNone, verbose0, warm_startFalse)
元估计器和预估器一样也有fit()。下面看看随机森林里包含的估计器个数和其本身。
rint( RF.n_estimators ) RF.estimators_
输出为
4
[DecisionTreeClassifier(class_weightNone, criterion‘gini’, max_depth5, max_features‘auto’, max_leaf_nodesNone, min_impurity_decrease0.0, min_impurity_splitNone, min_samples_leaf1, min_samples_split2, min_weight_fraction_leaf0.0, presortFalse, random_state705712365, splitter‘best’), DecisionTreeClassifier(class_weightNone, criterion‘gini’, max_depth5, max_features‘auto’, max_leaf_nodesNone, min_impurity_decrease0.0, min_impurity_splitNone, min_samples_leaf1, min_samples_split2, min_weight_fraction_leaf0.0, presortFalse, random_state1026568399, splitter‘best’), DecisionTreeClassifier(class_weightNone, criterion‘gini’, max_depth5, max_features‘auto’, max_leaf_nodesNone, min_impurity_decrease0.0, min_impurity_splitNone, min_samples_leaf1, min_samples_split2, min_weight_fraction_leaf0.0, presortFalse, random_state1987322366, splitter‘best’), DecisionTreeClassifier(class_weightNone, criterion‘gini’, max_depth5, max_features‘auto’, max_leaf_nodesNone, min_impurity_decrease0.0, min_impurity_splitNone, min_samples_leaf1, min_samples_split2, min_weight_fraction_leaf0.0, presortFalse, random_state1210538094, 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): 1 RF - Accuracy (Test): 0.9667
(2) VotingClassifier 图片 和随机森林由同质分类器『决策树』不同投票分类器由若干个异质分类器组成。下面我们用VotingClassifier建立个含有逻辑回归(Logistic regression)、随机森林(RandomForest)和高斯朴素贝叶斯(GNB)三个分类器的集成模型。
RandomForestClassifier的基分类器只能是决策树因此只用通过控制n_estimators超参数来决定树的个数而VotingClassifier的基分类器要输入每个异质分类器。
from sklearn.linear_model import LogisticRegression from sklearn.naive_bayes import GaussianNB from sklearn.ensemble import RandomForestClassifier from sklearn.ensemble import VotingClassifier
LR LogisticRegression( solver‘lbfgs’, multi_class‘multinomial’ ) RF RandomForestClassifier( n_estimators5 ) GNB GaussianNB()
Ensemble VotingClassifier( estimators[(‘lr’, LR), (‘rf’, RF), (‘gnb’, GNB)], voting‘hard’ )
Ensemble. fit( X_train, y_train )
结果如下
VotingClassifier(estimators[(‘lr’, LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue,intercept_scaling1, max_iter100, multi_class‘multinomial’,n_jobsNone, penalty‘12’, random_stateNone, solver‘lbfgs’,tol0.0001, verbose6, warm_startFalse)), (‘rf’, …e, verbose0,warm_startFalse)), (‘gnb’, GaussianNB(priorsNone, var_smoothing1e-09))],flatten_transformNone, n_jobsNone, voting‘hard’, weightsNone)
看看Ensemble集成模型里包含的估计器个数和其本身。
print( len(Ensemble.estimators_) ) Ensemble.estimators_
结果如下
3
[LogisticRegression(C1.0, class_weight-None, dual-False, fit_interceptTrue,intercept_scaling1, max_iter100, multi_class‘multinomial’,n_jobs-None, penalty“12”, random_state-None, solver‘1bfgs’,t010.0001, verbose0, warm_startFalse),
RandomForestClassifier(bootstrapTrue, class_weightNone, criterion‘gini’,max_depthNone, max_features‘auto’, max_leaf_nodesNone,min_impurity_decrease-0.0, min_impurity_splitmin_samples_leaf1, min_samples_split2,min_weight_fraction_leaf0.0, n_estimator:oob_scoreFalse, random_state-None, verbose warm_startFalse),
GaussianNB(priors-None, var_smoothing1e-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.975 RF - Accuracy (Train): 0.9833 GNB - Accuracy (Train): 0.95 Ensemble - Accuracy (Train): 0.9833 LR - Accuracy (Test): 1 RF - Accuracy (Test): 1 GNB - Accuracy (Test): 1 Ensemble - Accuracy (Test): 1
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_size0.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( hspace0.1, wspace0.1 ) for i, ax in enumerate( axes.flat ): ax.imshow( X_train[i,:].reshape(8,8), cmapbinary’, interpolationnearest’) ax.text( 0.05, 0.05, str(y_train[i]), transformax.transAxes, color‘blue’) ax.set_xticks([]) ax.set_yticks([]) 图片
(1) 多类别分类
手写数字有0-9十类但手头上只有二分类估计器比如像支撑向量机怎么用呢我们可以采取以下策略处理 图片 一对一(One vs OneOvO)一个分类器用来处理数字0和数字1一个用来处理数字0和数字2一个用来处理数字1和2以此类推。N个类需要N(N-1)/2个分类器。 一对其他(One vs AllOvA)训练10个二分类器每一个对应一个数字第一个分类『1』和『非1』第二个分类『2』和『非2』以此类推。N个类需要N个分类器。
① OneVsOneClassifier
考虑一个具体天气多分类问题天气可以是晴天、阴天和雨天在OvO中三个分类器为f1、f2和f3。
f1负责区分橙色和绿色样本 f2负责区分橙色和紫色样本 f3负责区分绿色和紫色样本
在下图的例子中f1和f2都预测为橙色f3预测为紫色。根据多数原则得到的结合预测为橙色如下图所示。 图片 回到数字分类问题上代码及结果如下
from sklearn.multiclass import OneVsOneClassifier from sklearn.linear_model import LogisticRegression ovo_lr OneVsOneClassifier( LogisticRegression(solver‘lbfgs’, max_iter200) ) ovo_lr.fit( X_train, y_train ) OnevsOneClassifier(estimatorLogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue,intercept_scaling1, max_iter200, multi_class‘warn’,n_jobsNone, penalty‘12’, random_stateNone, solverlbfgs’,tol0.0001, verbose6, warm_startFalse),n_jobsNone)
10*9/24510类总共45个OvO分类器。
print( len(ovo_lr.estimators_) ) ovo_lr.estimators_
结果如下
45
(LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue,intercept_scaling1, max_iter200, multi_class‘warn’,n_jobsNone, penalty‘12’, random_stateNone, solver‘lbfgs’,tol60.0001, verbose0, warm_startFalse),
LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, intercept_scaling1, max_iter200, multi_class‘warn’, n_jobsNone, penalty‘l2’, random_stateNone, solver‘lbfgs’,tol0.0001, verbose0, warm_startFalse),
LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, intercept_scaling1, max_iter200, multi_class‘warn’, n_jobsNone, penalty‘12’, random_stateNone, solver‘lbfgs’, tol60.0001, verbose0, warm_startFalse),
LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, intercept_scaling1, max_iter200, multi_class‘warn’, n_jobsNone, penalty“12”, random_stateNone, solver‘lbfgs’, tol0.0001, verbose0, warm_startFalse),
LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, …
训练集分类全对测试集准确率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): 1 OvO LR - Accuracy (Test): 0.9806
② OneVsRestClassifier
在OvA中把数据分成“某个”和“其他”
图一某个橙色其他绿色和紫色 图二某个绿色其他橙色和紫色 图三某个紫色其他橙色和绿色
三分类分解成三个二分类对应的分类器为f1、f2和f3。
f1预测负类即预测绿色和紫色 f2预测负类即预测橙色和紫色 f3预测正类即预测紫色
三个分类器都预测了紫色根据多数原则得到的预测是紫色即阴天。
图片 回到数字分类问题上代码和结果如下
from sklearn.multiclass import OneVsRestClassifier ova_lr OneVsRestClassifier( LogisticRegression(solver‘lbfgs’, max_iter800) ) ova_lr.fit( X_train, y_train ) OnevsRestClassifier(estimatorLogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, intercept_scaling1, max_iter800, multi_class‘warn’, n_jobsNone, penalty‘12’, random_stateNone, solverlbfgs’, tol0.0001, verbose6, warm_startFalse), n_jobsNone)
10类总共10个OvA分类器。
print( len(ova_lr.estimators_) ) ova_lr.estimators_
结果如下
10
[LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, intercept_scaling1, max_iter800, multi_class‘warn’, n_jobsNone, penalty‘12’, random_stateNone, solver‘lbfgs’,tol0.0001, verbose0, warm_startFalse),
LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, intercept_scaling1, max_iter800, multi_class‘warn’, n_jobsNone, penalty‘12’, random_stateNone, solver‘lbfgs’, tol0.0001, verbose0, warm_startFalse),
LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, intercept_scaling1, max_iter800, multi_class‘warn’, n_jobsNone, penalty‘12’, random_stateNone, solverlbfgs’, tol0.0001, verbose0, warm_startFalse),
LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, intercept_scaling1, max_iter800, multi_class‘warn’, n_jobsNone, penalty‘12’, random_stateNone, solver‘lbfgs’, tol0.0001, verbose0, warm_startFalse),
LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, …
训练集准确率几乎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.9993 OvA 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%20, y_train4 ] 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_iter800) ) ova_ml.fit( X_train, y_train_multilabel )
运行结果
OnevsRestClassifier(estimatorLogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, intercept_scaling1, max_iter800, multi_class‘warn’, n_jobsNone, penalty‘12’, random_stateNone, solver‘lbfgs’, tol0.0001, verbose6, warm_startFalse), n_jobsNone) 有两个估计器每个对应一个标签。 print( len(ova_ml.estimators_) ) ova_ml.estimators_ 运行结果如下 2
[LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, intercept_scaling1, max_iter800, multi_class‘warn’, n_jobsNone, penalty12°, random_stateNone, solver‘lbfgs’, tol0.0001, verbose0, warm_startFalse),
LogisticRegression(C1.0, class_weightNone, dualFalse, fit_interceptTrue, intercept_scaling1, max_iter800, multi_class‘warn’, n_jobsNone, penalty‘l2’, random_stateNone, solver‘lbfgs’, tol0.0001, verbose0, warm_startFalse) ]
展示一下测试集上100张图片。
fig, axes plt.subplots( 10, 10, figsize(8, 8) ) fig.subplots_adjust( hspace0.1, wspace0.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]), transformax.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]]
Multioutput 估计器
sklearn.multioutput可以处理多输出(multi-output)的分类问题。 图片 多输出分类是多标签分类的泛化在这里每一个标签可以是多类别(大于两个类别)的。一个例子就是预测图片每一个像素(标签)的像素值是多少(从0到255的256个类别)。 图片 Multioutput估计器有两个
MultiOutputRegressor多输出回归 MultiOutputClassifier多输出分类
这里我们只关注多输出分类。
(1) MultiOutputClassifier
首先引入MultiOutputClassifier和RandomForestClassifier。
from sklearn.multioutput import MultiOutputClassifier from sklearn.ensemble import RandomForestClassifier
在手写数字的例子上我们也为特意每个数字设计了多标签而且每个标签的类别都大于二。
标签1小于等于44和7之间大于等于7(三类) 标签2数字本身(十类)
代码如下
y_train_1st y_train.copy() y_train_1st[ y_train4 ] 0 y_train_1st[ np.logical_and{y_train4, y_train7) ] 1 y_train_ist[ y_train7 ] 2
y_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_estimators100) ) MO.fit( X_train, y_train_multioutput )
结果
MultiOutputClassifier(estimatorRandomForestClassifier(bootstrapTrue, class_weightNone, criterion‘gini’, max_depthNone, max_features‘auto’, max_leaf_nodesNone, min_impurity_decrease0.0, min_impurity_splitNone, min_samples_leaf1, min_samples_split2, min_weight_fraction_leaf0.0, n_estimators100, n_jobsNone, oob_scoreFalse, random_stateNone, verbose0, warm_startFalse), n_jobsNone)
看看这个模型在测试集前五张照片上的预测。
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_test4 ] 0 y_test_1st[ np.logical_and(y_test4, y_test7) ] 1 y_test_1st[ y_test7 ] 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]])
对比参考结果标签模型预测的结果还是很不错的。
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 time from scipy.stats import randint from sklearn.model_selection import GridSearchCv from sklearn.model_selection import RandomizedSearchcCv from sklearn.ensemble import RandomForestClassifier
X, y digits.data, digits.target RFC RandomForestClassifier(n_estimators20)
随机搜索/Randomized Search
param_dist { “max_depth”: [3, 5], “max_features”: randint(1, 11), “min_samples_split”: randint(2, 11), “criterion”: [“gini”, “entropy”]} n_iter_search 20 random_search RandomizedSearchCv( RFC, param_distributionsparam_dist, n_itern_iter_search, cv5 )} start time() random_search.fit(X, y) print(“RandomizedSearchCv took %.2f seconds for %d candidatesparameter settings.” % ((time() - start), n_iter_search)) print( random_search.best_params_ ) print( random_search.best_score_ )
网格搜索/Grid Search
param_grid { “max_depth”: [3, 5], “max_features”: [1, 3, 10], “min_samples_ split”: [2, 3, 10], “criterion”: [“gini”, “entropy”]} grid_search GridSearchCV( RF, param_gridparam_grid, cv5 ) 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.8898163606010017
GridSearchCV 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行是运行网格搜索。
运行结果里
第一行输出每种追踪法运行的多少次和花的时间。 第二行输出最佳超参数的组合。 第三行输出最高得分。
在本例中随机搜索比网格搜索用更短时间内找到一组超参数获得了更高的得分。
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 Pipeline from sklearn.impute import SimpleImputer from sklearn.preprocessing import MinMaxScaler
pipe Pipeline([ (‘impute’, SimpleImputer(missing_valuesnp.nan, strategy‘mean’)), (‘normalize’, MinMaxScaler())])
第5-7行创建了流水线使用方式非常简单在Pipeline()里输入(名称,估计器)这个元组构建的流水线列表。在本例中SimpleImputer起名叫imputeMinMaxScaler起名叫normalize。 因为最后一个估计器是转换器因此pipeline也是个转换器。下面我们来运行一下我们发现值都被填满了而且两列也被标准化了。
X_proc pipe.fit_transform( X )
来验证上面流水线的参数我们可以按顺序来运行这两个转换器结果是一样的。
X_impute SimpleImputer(missing valuesnp.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, TransformerMixin
class DataFrameSelector( BaseEstimator, TransformerMixin ): def init( self, attribute_names ): self.attribute_names attribute_names def fit( self, X, yNone ): 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 Pipeline from sklearn.pipeline import FeatureUnion from sklearn.impute import SimpleImputer from sklearn.preprocessing import MinMaxScaler from sklearn.preprocessing import OneHotEncoder
categorical features [‘IQ’, ‘temper’] numeric_features [‘income’, ‘height’]
categorical pipe Pipeline([ (‘select’, DataFrameSelector(categorical_features)), (‘impute’, SimpleImputer(missing valuesNone, strategy‘most_frequent’)), (‘one_hot_encode’, OneHotEncoder(sparseFalse))])
numeric_pipe Pipeline([ (‘select’, DataFrameSelector(numeric_features)), (‘impute’, SimpleImputer(missing valuesnp.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选择得分最高的那组超参数(即模型)。