scikit-learn
入门
本文主要介绍scikit-learn
入门所需了解的一些特征。scikit-learn
是一个支持监督和非监督学习的开源机器学习库。它同时也提供了许多用于模型拟合、数据预处理、模型选择和验证的工具。
拟合和预测:评估器基础
scikit-learn
提供了许多内置的机器学习算法和模型,称作评估器estimator
。每个评估器能够使用fit
方法来拟合一些数据。
下面是一个RandomForestClassifier
拟合数据的简单例子。
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(random_state=0)
X = [[1, 2, 3], [11, 12, 13]]
y = [0, 1]
clf.fit(X, y)
fit
方法通常接受2个输入:
- 样本矩阵
X
。其大小为 ( n s a m p l e s , n f e a t u r e s ) (n_{samples}, n_{features}) (nsamples,nfeatures),其中,行表示样本,列表示特征; - 目标值
y
。对于回归任务,目标值是实数,对于分类任务,目标值是整数或者其它离散值集合,对于非监督机器学习任务,y
不必指定。y
通常是一个一维数组,每个元素对应每个样本的目标值。
尽管有些评估器可以使用稀疏矩阵作为输入,但X
和y
通常是numpy
数组或类似于数组的数据类型。
评估器拟合后可直接用于预测新数据的目标值,而不需要再次训练。
clf.predict([[4, 5, 6], [14, 15, 16]])
转换器和预处理器
机器学习工作流通常包含不同部分。一个典型的管道pipeline
包括一个预处理步骤(用于转换或填补数据)和一个最终预测器(用于预测目标值)。
在scikit-learn
中,预处理器pre-processors
和转换器transformers
继承于BaseEstimator
类,可以使用与估计器相同的API。转换器对象没有predict
方法但是有transform
方法,用于输出一个转换后的样本矩阵。
from sklearn.preprocessing import StandardScaler
X = [[0, 15], [1, -10]]
# Standardize features by removing the mean and scaling to unit variance z = (x-u)/s
StandardScaler().fit(X).transform(X)
此外,可以使用ColumnTransformer
自定义不同转换器对不同特征进行转换。
管道:链接预处理器和估计器
转换器和估计器能够通过一个统一的对象Pipeline
结合在一起。管道提供了与估计器相同的API,能够使用fit
和predict
来拟合和预测数据。
下面使用Iris
数据集为例,计算管道在测试集的准确率
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import make_pipeline
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
pipe = make_pipeline(
StandardScaler(),
LogisticRegression(random_state=0)
)
X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
pipe.fit(X_train, y_train)
accuracy_score(pipe.predict(X_test), y_test)
模型评价
拟合在给定数据上的模型并不能保证其在未知数据上表现同样好,因此,模型拟合的好坏需要直接被评估。上个例子中使用了train_test_split
将数据集分为了训练集和测试集,但是,scikit-learn
提供了更多其它可用于模型评价的工具,如cross_validation
。
下面将介绍在cross_validation
的帮助下,如何执行5折交叉验证。5折交叉验证实际上是在5次不同数据集分割下,拟合和评价模型。
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_validate
X, y = make_regression(n_samples=1000, random_state=0)
lr = LinearRegression()
result = cross_validate(lr, X, y)
result['test_score']
自动化参数搜索
所有估计器都有需要调整的参数(在文献中称作超参)。评估器的泛化能力通常与一些参数密切相关。例如,RandomForestRegressor
有决定森林中树的数量的参数n_estimators
,有决定每棵树最大深度的参数max_depth
。在实际使用中,由于这些参数的取值依赖于数据集,很难提前设置这些参数的最优取值。
scikit-learn
提供了能够自动寻找最优参数值组合的工具(通过交叉验证)。在下述例子中,使用RandomizedSearchCV
对象随机搜索一颗随机树的参数空间,当搜索完成后,RandomizedSearchCV
可以当作按照已经使用最好参数拟合后的RandomForestRegressor
。
from sklearn.datasets import fetch_california_housing
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import RandomizedSearchCV, train_test_split
from scipy.stats import randint
housing_data = fetch_california_housing()
X, y = housing_data['data'], housing_data['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
param_distributions = {'n_estimators': randint(1, 5),
'max_depth': randint(5, 10)}
search = RandomizedSearchCV(estimator=RandomForestRegressor(random_state=0),
n_iter=5,
param_distributions=param_distributions,
random_state=0)
search.fit(X_train, y_train)
print(search.best_params_)
print(search.score(X_test, y_test))
注意,在实际使用中,通常在一个管道上搜索,而不是单个估计器,这样做是为了避免违背训练集和验证集相互独立的基本假设。