Python机器学习库笔记(4)——scikit-learn:快速入门

scikit-learn是用python进行机器学习项目的最重要的模块,它对主要的机器学习模型进行了封装,支持分类、回归、聚类、降维等机器学习任务,涵盖了树、支持向量机、神经网络等主流机器学习模型,并且提供了特征缩放、模型评估等功能。一个优秀的数据科学工作者应当熟练掌握它。

scikit-learn的官方文档地址官方中文文档地址

scikit-learn内容较多,将分为5篇文章分步阐述:

  • 数据载入、预处理(标准化、归一化、特征转换)、保存与恢复
  • 回归(线性模型,树回归,SVM回归,KNN回归,集成回归模型)
  • 分类(逻辑回归,决策树,贝叶斯分类器,神经网络,SVM,KNN,集成分类模型)
  • 聚类(K-Means、DBSCAN)、降维(PCA、LDA)
  • 模型评估与优化

数据集

为了帮助新手快速入门机器学习项目,scikit-learn内建了许多经典的机器学习数据集。注意有部分较大的数据集在首次使用时需要联网下载。

列举其中一些数据集如下:

数据集 说明 类型
datasets.load_boston 波士顿房价数据集 回归
datasets.load_breast_cancer 威斯康辛州乳腺癌数据集 二分类
datasets.load_digits 8×8手写数字数据集 多分类
datasets.load_iris 鸢尾花数据集 多分类
1
2
3
4
5
6
7
8
# 导入内建数据集
from sklearn import datasets
iris = datasets.load_iris()
# 获得ndarray格式的变量X和标签y
X = iris.data
y = iris.target
# 获得数据维度
n_samples, n_features = iris.data.shape

数据预处理

《Python机器学习库笔记(3)——pandas》一节中,已经利用pandas库对数据集完成去重、填充缺失值等工作。此外还需使用scikit-learn中的preprocessing模块来对数据做进一步的处理。

数据标准化

数据标准化和归一化是将数据映射到一个小的浮点数范围内,以便模型能快速收敛。

标准化有多种方式,常用的一种是min-max标准化(对象名为MinMaxScaler),该方法使数据落到[0,1]区间:

$$x’=\frac{x-x_{min}}{x_{max}-x_{min}}$$

1
2
3
4
5
# min-max标准化
from sklearn.preprocessing import MinMaxScaler
sc = MinMaxScaler()
sc.fit(X)
sc.transform(X)

另一种是Z-score标准化(对象名为StandardScaler),该方法使数据满足标准正态分布:

$$x’=\frac{x-\bar{X}}{S}$$

1
2
3
# Z-score标准化
from sklearn.preprocessing import StandardScaler
StandardScaler().fit_transform(X) #将fit和transform组合执行

归一化(对象名为Normalizer,默认为L2归一化):

$$x’=\frac{x}{\sqrt{\Sigma^m_jx[j]^2}}$$

1
2
3
# L2归一化
from sklearn.preprocessing import Normalizer
Normalizer().fit_transform(X)

数据二值化

使用阈值过滤器将数据转化为布尔值,即为二值化。使用Binarizer对象实现数据的二值化:

1
2
3
# 二值化,阈值设置为3
from sklearn.preprocessing import Binarizer
Binarizer(threshold=3).fit_transform(X)

标签编码

使用LabelEncoder将不连续的数值或文本变量转化为有序的数值型变量:

1
2
3
# 标签编码
from sklearn.preprocessing import LabelEncoder
LabelEncoder().fit_transform(['apple','pear','orange','banana'])

独热编码

对于无序的离散型特征,其数值大小并没有意义,需要对其进行one-hot编码,将其特征的m个可能值转化为m个二值化特征。可以利用OneHotEncoder对象实现:

1
2
3
# 独热编码
from sklearn.preprocessing import OneHotEncoder
OneHotEncoder().fit_transform(y.reshape(-1,1)).toarray()

注意OneHotEncoder无法对字符串类型进行转换,须先进行LabelEncoder将其转化为数字,或者尝试用pandas.get_dummies()来完成这一步工作。

数据集拆分

为了进行模型评估,将训练数据集拆分成训练集和测试集,可使用train_test_split,它接收如下参数:

  • train_data:用于拆分的数据集的特征集X。
  • train_target:用于拆分的数据集的标签y。
  • test_size:如果是浮点数,表示测试集样本占比;如果是整数,表示测试集样本的数量。
  • random_state:随机数种子。
1
2
3
# 随机拆分20%数据作为测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

定义模型

在scikit-learn中,所有模型都是BaseEstimator的子类,他们都有同样的接口供调用。监督学习模型都具有以下的方法:

  • fit:对数据进行拟合。
  • set_params:设定模型参数。
  • get_params:返回模型参数。
  • predict:在指定的数据集上预测。
  • score:返回预测器的得分。

鸢尾花数据集是一个分类任务,故以决策树模型为例,采用默认参数拟合模型,并对验证集预测。

1
2
3
4
5
6
7
8
9
# 决策树分类器
from sklearn.tree import DecisionTreeClassifier
model = DecisionTreeClassifier()
# 训练模型
model.fit(X_train, y_train)
# 在测试集上预测
model.predict(X_test)
# 测试集上的得分(默认为准确率)
model.score(X_test, y_test)

scikit-learn中所有模型的调用方式都类似。关于其他模型以及模型的参数用法,可参阅我的相关文章:

模型评估

评估模型的常用方法为K折交叉验证,它将数据集划分为K个大小相近的子集(K通常取10),每次选择其中(K-1)个子集的并集做为训练集,余下的做为测试集,总共得到K组训练集&测试集,最终返回这K次测试结果的得分,取其均值可作为选定最终模型的指标。

1
2
3
# 交叉验证
from sklearn.model_selection import cross_val_score
cross_val_score(model, X, y, scoring=None, cv=10)

注意:由于之前采用了train_test_split分割数据集,它默认对数据进行了洗牌,所以这里可以直接使用cv=10来进行10折交叉验证(cross_val_score不会对数据进行洗牌)。如果之前未对数据进行洗牌,则要搭配使用KFold模块:

1
2
3
4
from sklearn.model_selection import KFold
n_folds = 10
kf = KFold(n_folds, shuffle=True).get_n_splits(X)
cross_val_score(model, X, y, scoring=None, cv = kf)

关于模型评估的更多信息,详见这篇文章

保存模型

在训练模型后可将模型保存,以免下次重复训练。一种方法是采用python标准库中的pickle,另一种是使用sklearn的joblib

1
2
3
4
5
from sklearn.externals import joblib
# 保存模型
joblib.dump(model,'myModel.pkl')
# 载入模型
model=joblib.load('myModel.pkl')