入门指南 ======== 本指南旨在展示 ``scikit-learn`` 提供的一些主要功能。它假设读者具有机器学习实践的基本知识(如模型拟合、预测、交叉验证等)。请参考我们的 :ref:`installation instructions ` 来安装 ``scikit-learn`` 。 ``Scikit-learn`` 是一个支持监督学习和无监督学习的开源机器学习库。它还提供了各种工具,用于模型拟合、数据预处理、模型选择、模型评估以及其他许多实用功能。 拟合和预测:估计器基础 ------------------------ ``Scikit-learn`` 提供了数十种内置的机器学习算法和模型,称为 :term:`estimators` 。每个估计器都可以使用其 :term:`fit` 方法拟合到某些数据上。 以下是一个简单示例,我们将一个 :class:`~sklearn.ensemble.RandomForestClassifier` 拟合到一些非常基本的数据上:: >>> from sklearn.ensemble import RandomForestClassifier >>> clf = RandomForestClassifier(random_state=0) >>> X = [[ 1, 2, 3], # 2 个样本, 3 个特征 ... [11, 12, 13]] >>> y = [0, 1] # 每个样本的类别 >>> clf.fit(X, y) RandomForestClassifier(random_state=0) :term:`fit` 方法通常接受 2 个输入: - 样本矩阵(或设计矩阵) :term:`X` 。 ``X`` 的大小通常是 ``(n_samples, n_features)`` ,这意味着样本表示为行,特征表示为列。 - 目标值 :term:`y` ,对于回归任务是实数,对于分类任务是整数(或任何其他离散值集合)。对于无监督学习任务, ``y`` 不需要指定。 ``y`` 通常是一个一维数组,其中第 ``i`` 个条目对应于 ``X`` 的第 ``i`` 个样本(行)的目标。 ``X`` 和 ``y`` 通常期望是 numpy 数组或等效的 :term:`类数组` 数据类型,尽管某些估计器支持其他格式,如稀疏矩阵。 一旦估计器被拟合,它就可以用于预测新数据的目标值。您不需要重新训练估计器:: >>> clf.predict(X) # 预测训练数据的类别 array([0, 1]) >>> clf.predict([[4, 5, 6], [14, 15, 16]]) # 预测新数据的类别 array([0, 1]) 您可以查看 :ref:`ml_map` 来了解如何为您的用例选择合适的模型。 转换器和预处理器 -------------------- 机器学习工作流程通常由不同的部分组成。一个典型的管道包括一个预处理步骤,该步骤转换或填充数据,以及一个最终的预测器,用于预测目标值。 在 ``scikit-learn`` 中,预处理器和转换器遵循与估计器对象相同的 API(实际上它们都继承自同一个 ``BaseEstimator`` 类)。转换器对象没有 :term:`predict` 方法,而是有一个 :term:`transform` 方法,该方法输出一个新的转换样本矩阵 ``X`` :: >>> from sklearn.preprocessing import StandardScaler >>> X = [[0, 15], ... [1, -10]] >>> # 根据计算的缩放值缩放数据 >>> StandardScaler().fit(X).transform(X) array([[-1., 1.], [ 1., -1.]]) 有时,您希望对不同的特征应用不同的转换::ref:`ColumnTransformer` 正是为此类用例设计的。 管道:链接预处理器和估计器 ------------------------------ 转换器和估计器(预测器)可以组合在一起成为一个单一的统一对象::class:`~sklearn.pipeline.Pipeline` 。管道提供的 API 与常规估计器相同:可以使用 ``fit`` 和 ``predict`` 进行拟合和预测。正如我们稍后将看到的,使用管道还可以防止数据泄露,即在训练数据中披露一些测试数据。 在以下示例中,我们 :ref:`load the Iris dataset ` ,将其拆分为训练集和测试集,并在测试数据上计算管道的准确性得分:: >>> 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() ... ) ... >>> # 加载鸢尾花数据集并将其拆分为训练集和测试集 >>> 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) Pipeline(steps=[('standardscaler', StandardScaler()), ('logisticregression', LogisticRegression())]) >>> # 我们现在可以像使用其他估计器一样使用它 >>> accuracy_score(pipe.predict(X_test), y_test) 0.97... 模型评估 -------- 将模型拟合到某些数据并不意味着它将在未见数据上预测良好。这需要直接进行评估。我们刚刚看到了 :func:` ~sklearn.model_selection.train_test_split`助手,它将数据集拆分为训练集和测试集,但 ``scikit-learn`` 还提供了许多其他用于模型评估的工具,特别是用于 :ref:`交叉验证 ` 。 我们在这里简要展示如何使用 :func:`~sklearn.model_selection.cross_validate` 助手执行 5 折交叉验证过程。请注意,也可以手动遍历折叠,使用不同的数据拆分策略,并使用自定义评分函数。请参阅我们的 :ref:`User Guide ` 了解更多详细信息:: >>> 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) # 默认为 5 折交叉验证 >>> result['test_score'] # r_squared 得分高是因为数据集简单 array([1., 1., 1., 1., 1.]) 自动参数搜索 ------------ 所有估计器都有参数(在文献中通常称为超参数),这些参数可以进行调整。估计器的泛化能力通常在很大程度上取决于少数几个参数。例如,:class:`~sklearn.ensemble.RandomForestRegressor` 有一个 ``n_estimators`` 参数,用于确定森林中的树的数量,还有一个 ``max_depth`` 参数,用于确定每棵树的最大深度。通常,这些参数的确切值并不清楚,因为它们取决于手头的数据。 ``Scikit-learn`` 提供了工具来自动找到最佳的参数组合(通过交叉验证)。在以下示例中,我们随机搜索随机森林的参数空间,使用 :class:`~sklearn.model_selection.RandomizedSearchCV` 对象。当搜索结束时, :class:`~sklearn.model_selection.RandomizedSearchCV` 的行为就像一个已经拟合了最佳参数集的 :class:`~sklearn.ensemble.RandomForestRegressor` 。更多详细信息请参阅 :ref:`User Guide ` :: >>> from sklearn.datasets import fetch_california_housing >>> from sklearn.ensemble import RandomForestRegressor >>> from sklearn.model_selection import RandomizedSearchCV >>> from sklearn.model_selection import train_test_split >>> from scipy.stats import randint ... >>> X, y = fetch_california_housing(return_X_y=True) >>> 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)} ... >>> # 现在创建一个 searchCV 对象并将其拟合到数据上 >>> search = RandomizedSearchCV(estimator=RandomForestRegressor(random_state=0), ... n_iter=5, ... param_distributions=param_distributions, ... random_state=0) >>> search.fit(X_train, y_train) RandomizedSearchCV(estimator=RandomForestRegressor(random_state=0), n_iter=5, param_distributions={'max_depth': ..., 'n_estimators': ...}, random_state=0) >>> search.best_params_ {'max_depth': 9, 'n_estimators': 4} >>> # 现在 search 对象表现得像一个普通的随机森林估计器 >>> # 具有 max_depth=9 和 n_estimators=4 >>> search.score(X_test, y_test) 0.73... .. note:: 在实践中,你几乎总是希望对一个管道(pipeline)进行搜索,而不是单个估计器。主要原因之一是,如果你对整个数据集应用预处理步骤而不使用管道,然后进行任何形式的交叉验证,你将破坏训练数据和测试数据之间独立性的基本假设。实际上,由于你使用整个数据集对数据进行了预处理,一些关于测试集的信息已经对训练集可用。这将导致过高估计估计器的泛化能力(你可以在 `Kaggle post `_ 中了解更多信息)。 使用管道进行交叉验证和搜索将大大避免这种常见陷阱。 下一步 ------ 我们已经简要介绍了估计器拟合和预测、预处理步骤、管道、交叉验证工具和自动超参数搜索。本指南应该让您对库的一些主要功能有一个概览,但 ``scikit-learn`` 还有更多内容! 请参阅我们的 :ref:`用户指南` 以获取我们提供的所有工具的详细信息。您还可以在 :ref:`API参考` 中找到公共API的详尽列表。 您还可以查看我们众多的 :ref:`示例 `,这些示例在许多不同的上下文中展示了``scikit-learn``的使用。