開始使用#

本指南旨在說明 scikit-learn 提供的一些主要功能。它假設您對機器學習實踐 (模型擬合、預測、交叉驗證等) 有非常基本的工作知識。請參考我們的安裝說明 來安裝 scikit-learn

Scikit-learn 是一個支援監督式和非監督式學習的開源機器學習函式庫。它還提供了各種模型擬合、數據預處理、模型選擇、模型評估和許多其他實用工具。

擬合和預測:估算器基礎知識#

Scikit-learn 提供了數十種內建的機器學習演算法和模型,稱為估算器。每個估算器都可以使用其fit 方法來擬合到某些數據。

這是一個簡單的範例,我們將 RandomForestClassifier 擬合到一些非常基礎的數據

>>> from sklearn.ensemble import RandomForestClassifier
>>> clf = RandomForestClassifier(random_state=0)
>>> X = [[ 1,  2,  3],  # 2 samples, 3 features
...      [11, 12, 13]]
>>> y = [0, 1]  # classes of each sample
>>> clf.fit(X, y)
RandomForestClassifier(random_state=0)

fit 方法通常接受 2 個輸入

  • 樣本矩陣(或設計矩陣)XX 的大小通常為 (n_samples, n_features),這表示樣本以列表示,而特徵以欄表示。

  • 目標值 y,對於回歸任務是實數,對於分類任務是整數(或任何其他離散值集合)。對於非監督式學習任務,不需要指定 yy 通常是一個一維陣列,其中第 i 個條目對應於 X 的第 i 個樣本(列)的目標。

Xy 通常都應該是 numpy 陣列或等效的類陣列數據類型,儘管某些估算器可以使用其他格式,例如稀疏矩陣。

一旦估算器擬合完成,它就可以用於預測新數據的目標值。您不需要重新訓練估算器

>>> clf.predict(X)  # predict classes of the training data
array([0, 1])
>>> clf.predict([[4, 5, 6], [14, 15, 16]])  # predict classes of new data
array([0, 1])

您可以查看選擇正確的估算器,了解如何為您的使用案例選擇正確的模型。

轉換器和預處理器#

機器學習工作流程通常由不同的部分組成。典型的管線包括一個預處理步驟,用於轉換或填補數據,以及一個預測目標值的最終預測器。

scikit-learn 中,預處理器和轉換器遵循與估算器對象相同的 API(它們實際上都繼承自相同的 BaseEstimator 類別)。轉換器對象沒有 predict 方法,而是有一個 transform 方法,該方法輸出一個新轉換的樣本矩陣 X

>>> from sklearn.preprocessing import StandardScaler
>>> X = [[0, 15],
...      [1, -10]]
>>> # scale data according to computed scaling values
>>> StandardScaler().fit(X).transform(X)
array([[-1.,  1.],
       [ 1., -1.]])

有時,您希望對不同的特徵應用不同的轉換:ColumnTransformer 專為這些使用案例而設計。

管線:鏈接預處理器和估算器#

轉換器和估算器(預測器)可以組合在一起形成一個單一的統一對象:Pipeline。管線提供與常規估算器相同的 API:它可以使用 fitpredict 進行擬合和預測。正如我們稍後將看到的,使用管線還可以防止數據洩漏,即在您的訓練數據中洩露一些測試數據。

在下面的範例中,我們載入鳶尾花數據集,將其分割為訓練集和測試集,並計算管線在測試數據上的準確度得分

>>> 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
...
>>> # create a pipeline object
>>> pipe = make_pipeline(
...     StandardScaler(),
...     LogisticRegression()
... )
...
>>> # load the iris dataset and split it into train and test sets
>>> X, y = load_iris(return_X_y=True)
>>> X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
...
>>> # fit the whole pipeline
>>> pipe.fit(X_train, y_train)
Pipeline(steps=[('standardscaler', StandardScaler()),
                ('logisticregression', LogisticRegression())])
>>> # we can now use it like any other estimator
>>> accuracy_score(pipe.predict(X_test), y_test)
0.97...

模型評估#

將模型擬合到某些數據並不表示它可以在未見過的數據上做出良好的預測。這需要直接評估。我們剛剛看到了 train_test_split 輔助工具,用於將數據集分割成訓練集和測試集,但 scikit-learn 提供了許多其他用於模型評估的工具,特別是用於交叉驗證

我們在這裡簡要展示如何使用 cross_validate 輔助工具執行 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)  # defaults to 5-fold CV
>>> result['test_score']  # r_squared score is high because dataset is easy
array([1., 1., 1., 1., 1.])

自動參數搜尋#

所有估算器都有可以調整的參數(在文獻中通常稱為超參數)。估算器的泛化能力通常取決於一些參數。例如,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
>>> 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)
...
>>> # define the parameter space that will be searched over
>>> param_distributions = {'n_estimators': randint(1, 5),
...                        'max_depth': randint(5, 10)}
...
>>> # now create a searchCV object and fit it to the data
>>> 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}

>>> # the search object now acts like a normal random forest estimator
>>> # with max_depth=9 and n_estimators=4
>>> search.score(X_test, y_test)
0.73...

注意

實際上,您幾乎總是希望搜尋管線,而不是單個估算器。其中一個主要原因是,如果您在不使用管線的情況下對整個數據集應用預處理步驟,然後執行任何類型的交叉驗證,您將會破壞訓練數據和測試數據之間獨立性的基本假設。事實上,由於您使用整個數據集對數據進行了預處理,因此測試集的一些資訊對訓練集可用。這將導致過度估計估算器的泛化能力(您可以在這篇Kaggle 文章中閱讀更多內容)。

使用管線進行交叉驗證和搜尋將很大程度上避免您陷入這種常見的陷阱。

下一步#

我們簡要介紹了估算器擬合和預測、預處理步驟、管線、交叉驗證工具和自動超參數搜尋。本指南應該讓您大致了解函式庫的一些主要功能,但 scikit-learn 還有更多內容!

請參考我們的使用者指南,以了解我們提供的所有工具的詳細資訊。您還可以在API 參考中找到公共 API 的完整列表。

您也可以參考我們眾多的範例,這些範例展示了 scikit-learn 在各種不同情境下的應用。