sklearn 1.4發佈:引入重要新功能

2024年2月6日 22点热度 0人点赞

升級方法

scikit-learn 1.4版本已經正式發佈,在這個版本中,不僅修復了許多bug,還進行了一些改進,並引入了一些重要的新功能。

https://scikit-learn.org/stable/whats_new/v1.4.html

通過pip或conda升級到最新版:

pip install --upgrade scikit-learn
conda install -c conda-forge scikit-learn

特性1:HistGradientBoosting支持Categorical類型

集成學習的
HistGradientBoostingClassifier和
HistGradientBoostingRegressor現在直接支持包含分類特征的數據框(dataframes)。

下面我們有一個包含混合分類和數值特征的數據集:

from sklearn.datasets import fetch_openml
X_adult, y_adult = fetch_openml("adult", version=2, return_X_y=True)
# Remove redundant and non-feature columns
X_adult = X_adult.drop(["education-num", "fnlwgt"], axis="columns")
X_adult.dtypes

數據字段類型如下:

  age                  int64
  workclass         category
  education         category
  marital-status    category
  occupation        category
  relationship      category
  race              category
  sex               category
  capital-gain         int64
  capital-loss         int64
  hours-per-week       int64
  native-country    category
  dtype: object

通過將categorical_features參數設置為"from_dtype",梯度提升分類器會將具有分類數據類型的列視為算法中的分類特征。下面是一個使用這一特性的示例代碼:

from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
X_train, X_test, y_train, y_test = train_test_split(X_adult, y_adult, random_state=0)
hist = HistGradientBoostingClassifier(categorical_features="from_dtype")
hist.fit(X_train, y_train)
y_decision = hist.decision_function(X_test)
print(f"ROC AUC score is {roc_auc_score(y_test, y_decision)}")

特性2:支持 Polars 格式輸出

scikit-learn的轉換器現在通過set_output API支持Polars輸出。

現在已經在預處理模塊、聚類、降維、特征篩選的API中支持:

import polars as pl
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import OneHotEncoder
from sklearn.compose import ColumnTransformer
df = pl.DataFrame(
    {"height": [120, 140, 150, 110, 100], "pet": ["dog", "cat", "dog", "cat", "cat"]}
)
preprocessor = ColumnTransformer(
    [
        ("numerical", StandardScaler(), ["height"]),
        ("categorical", OneHotEncoder(sparse_output=False), ["pet"]),
    ],
    verbose_feature_names_out=False,
)
preprocessor.set_output(transform="polars")
df_out = preprocessor.fit_transform(df)
df_out

特性3:支持缺失值


ensemble.RandomForestClassifier和
ensemble.RandomForestRegressor現在支持缺失值。在訓練每個獨立的樹時,分裂器將評估每個潛在閾值,同時將缺失值分配到左右節點。

import numpy as np
from sklearn.ensemble import RandomForestClassifier
X = np.array([0, 1, 6, np.nan]).reshape(-1, 1)
y = [0, 0, 1, 1]
forest = RandomForestClassifier(random_state=0).fit(X, y)
forest.predict(X)

DecisionTreeClassifier和DecisionTreeRegressor在splitter='best'且criterion為'gini'、'entropy'、'log_loss'(分類)或 'squared_error'、 'friedman_mse'、 'poisson'(回歸)時,內建支持缺失值。

from sklearn.tree import DecisionTreeClassifier
import numpy as np
X = np.array([0, 1, 6, np.nan]).reshape(-1, 1)
y = [0, 0, 1, 1]
tree = DecisionTreeClassifier(random_state=0).fit(X, y)
tree.predict(X)

特征4:添加樹模型的單調約束

雖然在 scikit-learn 0.23 中添加了對基於直方圖的梯度提升的單調約束的支持,但我們現在支持所有其他基於樹的模型(如樹、隨機森林、額外樹和精確梯度提升)的此功能。在這裡,我們在回歸問題上展示了隨機森林的這一功能。

單調約束指的是在統計或機器學習模型中對預測變量與目標變量之間關系的限制。具體而言,單調約束規定了這種關系的方向性,即目標變量在預測變量變化時是增加還是減少。

對應的樹模型參數為monotonic_cst:

  • 1: monotonically increasing
  • 0: no constraint
  • -1: monotonically decreasing
import matplotlib.pyplot as plt
from sklearn.inspection import PartialDependenceDisplay
from sklearn.ensemble import RandomForestRegressor
n_samples = 500
rng = np.random.RandomState(0)
X = rng.randn(n_samples, 2)
noise = rng.normal(loc=0.0, scale=0.01, size=n_samples)
y = 5 * X[:, 0]   np.sin(10 * np.pi * X[:, 0]) - noise
rf_no_cst = RandomForestRegressor().fit(X, y)
rf_cst = RandomForestRegressor(monotonic_cst=[1, 0]).fit(X, y)
disp = PartialDependenceDisplay.from_estimator(
    rf_no_cst,
    X,
    features=[0],
    feature_names=["feature 0"],
    line_kw={"linewidth": 4, "label": "unconstrained", "color": "tab:blue"},
)
PartialDependenceDisplay.from_estimator(
    rf_cst,
    X,
    features=[0],
    line_kw={"linewidth": 4, "label": "constrained", "color": "tab:orange"},
    ax=disp.axes_,
)
disp.axes_[0, 0].plot(
    X[:, 0], y, "o", alpha=0.5, zorder=-1, label="samples", color="tab:green"
)
disp.axes_[0, 0].set_ylim(-3, 3)
disp.axes_[0, 0].set_xlim(-1, 1)
disp.axes_[0, 0].legend()
plt.show()

特征5:增加稀疏數據的PCA性能

PCA(Principal Component Analysis)現在原生支持對稀疏矩陣的處理,特別是對於使用arpack求解器的情況。它通過利用
scipy.sparse.linalg.LinearOperator來避免在執行數據集協方差矩陣的特征值分解時生成大型稀疏矩陣。

這一改進的主要優勢在於,對於稀疏數據,不再需要顯式地構建稀疏協方差矩陣,從而節省了內存和計算資源。

from sklearn.decomposition import PCA
import scipy.sparse as sp
from time import time
X_sparse = sp.random(m=1000, n=1000, random_state=0)
X_dense = X_sparse.toarray()
t0 = time()
PCA(n_components=10, svd_solver="arpack").fit(X_sparse)
time_sparse = time() - t0
t0 = time()
PCA(n_components=10, svd_solver="arpack").fit(X_dense)
time_dense = time() - t0
print(f"Speedup: {time_dense / time_sparse:.1f}x")
# Speedup: 2.7x