本文是《盘一盘 Python 系列 8 - Sklearn》的学习笔记。
文章目录
sklearn 建立在 NumPy,SciPy,Pandas 和 Matplotlib 上,是机器学习任务的通用模块。Sklearn 里面有六大任务模块:分别是分类、回归、聚类、降维、模型选择和预处理,分别位于
sklearn
、
sklearn.linear_model
、
sklearn.ensemble
、
sklearn.cluster
、
sklearn.decomposition
、
sklearn.model_selection
和
sklearn.preprocessing
子模块里。同时 slearn 还带有一些数据集,可以从
sklearn.datasets
载入。
API
sklearn 里的所有对象都是估计器,可以把它近似看成一个机器学习的模型(回归、分类、聚类、降维)或一个流程(预处理、参数网格化)。sklearn 里估计器有三类:
- 估计器(estimator)本身;
- 预测器(predictor):带有预测功能的估计器;
- 转换器(transformer):带有转换功能的估计器。
估计器
任何可以基于数据集对一些参数进行估计的对象都被称为估计器。
- 超参数:创建估计器的时候需要设定超参数,如
- 线性回归里超参数 normalize=True
- K 均值里超参数 n_clusters=3
创建好估计器 model 以后可以直接访问超参数: - model.normalize
- model.n_clusters
- 拟合估计器:需要使用训练集训练估计器。有监督学习的代码为
model.fit(X_train, y_train)
,无监督学习的代码为model.fit(X_train)
。拟合完成以后可以访问 model 里学到的参数,比如
- model.coef_
- model.labels_
拟合以后生成的参数比超参数在结尾多了一个 _
。
预测器
预测器基于学到的知识预测,最常见的是 predict()
函数:
- model.predict(X_test):评估模型在新数据上的表现
- model.predict(X_train):确认模型在老数据上的表现
对于分类问题,有时候我们不仅想知道预测的类别是什么,还想知道预测的信心如何,这时候可以用 predict_proba()
。另外还有一个函数 score()
返回分类准确率。
转换器
估计器用 fit
+ predict
,转换器用 fit
+ transform
。
- 将分类型变量 (categorical) 编码成数值型变量 (numerical)
LabelEncoder
和OrdinalEncoder
都可以将字符转成数字,但是
LabelEncoder
的输入是一维,比如 1dndarray
OrdinalEncoder
的输入是二维,比如DataFrame
首先载入两个函数,创建两个列表:
>>> from sklearn.preprocessing import LabelEncoder
>>> from sklearn.preprocessing import OrdinalEncoder
>>> enc = ["red", "blue", "green"]
>>> dec = ["green", "blue", "red", "blue"]
然后分别使用 LabelEncoder
和 OrdinalEncoder
:
>>> LE = LabelEncoder()
>>> print(LE.fit(enc))
>>> print(LE.classes_)
>>> print(LE.transform(dec))
LabelEncoder()
['blue' 'green' 'red']
[1 0 2 0]
# 使用 OrdinalEncoder 以前要先将列表转化为二维数组或数据框
>>> OE = OrdinalEncoder()
>>> enc_df = pd.DataFrame(enc)
>>> dec_df = pd.DataFrame(dec)
>>> print(OE.fit(enc_df))
>>> print(OE.transform(dec_df))
OrdinalEncoder(categories='auto', dtype=<class 'numpy.float64'>)
[[1.]
[0.]
[2.]
[0.]]
使用数字编码有一个问题:机器会认为 2 到 1 的距离比 2 到 0 的距离更近,其实 “red” 到 “blue” 的距离与 “red” 到 “green” 的距离没法比较。为了解决这个问题,一个常见的方法是独热编码(one hot encoding)。
- 独热编码
转换器 OneHotEncoder
可以接受两种类型的输入:
- 用
LabelEncoder
编码好的一维数组 - 使用
DataFrame
进行机器学习前通常需要进行特征缩放(feature scaleing),通常有两种方法:
- 标准化 (standardization):每个维度的特征减去该特征均值,除以该维度的标准差。
- 规范化 (normalization):每个维度的特征减去该特征最小值,除以该特征的最大值与最小值之差。
高级 API
本篇仅讨论三种高级 API 即元估计器(meta-estimator):带集成功能的 ensemble,选择模型的 model_selection 和流水线的 pipeline。
- ensemble.BaggingClassifier
- ensemble.VotingClassifier
- model_selection.GridSearchCV
- model_selection.RandomizedSearchCV
- pipeline.Pipeline
ensemble 估计器
ensemble 估计器的作用原理是:
- 分类器统计每个子分类器的预测类别数,再用「多数投票」原则得到最终预测。
- 回归器计算每个子回归器的预测平均值。
RandomForestClassifier
随机森林 (random forest) 是决策树 (decision tree) 的一种集成模型,每棵决策树处理的数据用装袋法 (bagging) 生成。随机森林可以减小预测的方差,并且可以评估特征重要性。RandomForestClassifier
通过控制 n_estimators 超参数来决定基估计器的个数,本例是 4 棵决策树 (森林由树组成);此外每棵树的最大树深为 5 (max_depth=5)。
VotingClassifier
和随机森林由同质分类器「决策树」不同,投票分类器由若干个异质分类器组成。RandomForestClassifier
的基分类器只能是决策树,因此只用通过控制 n_estimators 超参数来决定树的个数,而 VotingClassifier 的基分类器要实实在在的输入其本身。
Model Selection 估计器
模型选择 (Model Selction) 在机器学习非常重要,它主要用于评估模型表现,常见的 Model Selection 估计器有以下几个:
- cross_validate: 评估交叉验证的表现。
- learning_curve: 建立学习曲线。
- GridSearchCV: 用交叉验证从网格中一组超参数搜索出最佳超参数。
- RandomizedSearchCV: 用交叉验证从一组随机超参数搜索出最佳超参数。
交叉验证
K-折交叉验证集 (K-fold cross validation set),就是把整个数据集平均但随机分成 K 份,每份大概包含 m/K 个数据 (m 是总数据数)。
在这 K 份,每次选 1 份作为训练集在拟合参数 wλ,把参数用在剩下 K-1 份验证集上计算误差。由于遍历了这 K 份数据,因此该操作称为交叉验证。
如何通过选择交叉验证误差来选择模型描述如下(图片出自《盘一盘 Python 系列 8 - Sklearn》):
网格追踪和随机追踪
(图片出自《盘一盘 Python 系列 8 - Sklearn》)
Pipeline 估计器
- Pipeline 估计器又叫流水线,把各种估计器串联 (Pipeline) 或并联 (FeatureUnion) 的方式组成一条龙服务。Pipeline 将若干个估计器按顺序连在一起,比如
特征提取 -> 降维 -> 拟合 -> 预测
在整个 Pipeline 中,它的属性永远和最后一个估计器属性一样。
-
如果最后一个估计器是预测器,那么 Pipeline 是预测器
-
如果最后一个估计器是转换器,那么 Pipeline 是转换器
-
如果我们想在一个节点同时运行几个估计器,我们可用
FeatureUnion
。
sklearn 主要函数一览
sklearn.cluster
- cluster.KMeans(n_clusters)
sklearn.decomposition
- decomposition.PCA(n_components)
sklearn.ensemble
- ensemble.RandomForestEmbedding(n_estimators, max_depth)
sklearn.impute
- impute.SimpleImputer(missing_values)
sklean.linear_model
- linear_model.Lasso(alpha)
- linear_model.LinearRegression()
- linear_model.Ridge(alpha)
sklearn.model_selection
- model_selection.train_test_split(*aarays, test_size)
- model_selection.GridSearchCV(estimator, param_grid)
- model_selection.RandomizedSearchCV(estimator, param_distributions)
sklearn.naive_bayes
- naive_bayes.GaussianNB(priors)
sklearn.neighbors
- neighbors.NearestNeighbors(n_neighbors)
sklearn.pipline
- pipeline.Pipeline(steps)
- pipeline.make_pipeline(*steps)
sklearn.preprocessing
- preprocessing.LabelEncoder()
- preprocessing.MinMaxScaler()
- preprocessing.standardScaler()
- preprocessing.OrdinalEncoder()
sklearn.svm
- svm.SVC(kernal)
- svm.SVR(kernal)
sklearn.tree
- tree.DecisionTreeClassifier(criterion, max_depth)
- tree.DecisionTreeRegressor(criterion, max_depth)