scikit-learn 0.22中的发布要点

我们很高兴地宣布发布scikit-learn 0.22,这里许多bug被修复和一些新的功能!我们在下面详细介绍了这个版本的几个主要特性。有关所有更改的详尽清单,请参阅发布说明

若要安装最新版本(使用 pip),请执行以下操作:

pip install --upgrade scikit-learn

或者使用conda安装:

conda install scikit-learn

1.2.1 新的绘图API

一个新的绘图API可用于创建可视化。这个新的API允许快速调整一个情节的视觉,而不涉及任何恢复。还可以在同一画布上添加不同的图。下面的示例说明了 plot_roc_curve,但也支持其他绘图实用程序, plot_partial_dependence,plot_precision_recall_curve, and plot_confusion_matrix.。在用户指南中阅读有关此新API的更多信息。

from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import plot_roc_curve
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
import matplotlib.pyplot as plt

X, y = make_classification(random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

svc = SVC(random_state=42)
svc.fit(X_train, y_train)
rfc = RandomForestClassifier(random_state=42)
rfc.fit(X_train, y_train)

svc_disp = plot_roc_curve(svc, X_test, y_test)
rfc_disp = plot_roc_curve(rfc, X_test, y_test, ax=svc_disp.ax_)
rfc_disp.figure_.suptitle("ROC curve comparison")

plt.show()

1.2.2 Stacking 分类器和回归器

StackingClassifierStackingRegressor 允许您有一堆带有最终分类器或回归器的估计器。叠加泛化是将单个估计器的输出叠加起来,并使用分类器来计算最终的预测。Stacking允许使用每个单独的估计器的强度,使用它们的输出作为最终估计器的输入。基估计器是在全X上拟合的,而最终估计器是使用 cross_val_predict对基估计器进行交叉验证的预测来训练的。

用户指南中阅读更多内容。

from sklearn.datasets import load_iris
from sklearn.svm import LinearSVC
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
from sklearn.ensemble import StackingClassifier
from sklearn.model_selection import train_test_split

X, y = load_iris(return_X_y=True)
estimators = [
    ('rf', RandomForestClassifier(n_estimators=10, random_state=42)),
    ('svr', make_pipeline(StandardScaler(),
                          LinearSVC(random_state=42)))
]
clf = StackingClassifier(
    estimators=estimators, final_estimator=LogisticRegression()
)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, stratify=y, random_state=42
)
clf.fit(X_train, y_train).score(X_test, y_test)

# 输出
0.9473684210526315

1.2.3 基于置换的特征重要性

为了得到每个特征的重要性,可以使用 inspection.permutation_importance,对于任何合适的估计器:

from sklearn.ensemble import RandomForestClassifier
from sklearn.inspection import permutation_importance

X, y = make_classification(random_state=0, n_features=5, n_informative=3)
rf = RandomForestClassifier(random_state=0).fit(X, y)
result = permutation_importance(rf, X, y, n_repeats=10, random_state=0,
                                n_jobs=-1)

fig, ax = plt.subplots()
sorted_idx = result.importances_mean.argsort()
ax.boxplot(result.importances[sorted_idx].T,
           vert=False, labels=range(X.shape[1]))
ax.set_title("Permutation Importance of each feature")
ax.set_ylabel("Features")
fig.tight_layout()
plt.show()

1.2.4 梯度提升的原生缺失值支持

ensemble.HistGradientBoostingClassifierensemble.HistGradientBoostingRegressor现在有了对缺失值(NaNs)的原生支持。这意味着在训练或预测时不需要计算数据。

from sklearn.experimental import enable_hist_gradient_boosting  # noqa
from sklearn.ensemble import HistGradientBoostingClassifier
import numpy as np

X = np.array([012, np.nan]).reshape(-11)
y = [0011]

gbdt = HistGradientBoostingClassifier(min_samples_leaf=1).fit(X, y)
print(gbdt.predict(X))

# 输出
[0 0 1 1]

1.2.5 预计算稀疏近邻图

现在大多数基于最近邻图的估计器都接受预先计算的稀疏图作为输入,以重用相同的图以满足多个估计器的训练。要在管道中使用此特性,可以使用memory参数,以及两个新的转换器之一, neighbors.KNeighborsTransformerneighbors.RadiusNeighborsTransformer。预计算还可以由自定义估计器执行,以使用替代实现,例如近似最近邻方法。请参阅用户指南中的详细信息。

from tempfile import TemporaryDirectory
from sklearn.neighbors import KNeighborsTransformer
from sklearn.manifold import Isomap
from sklearn.pipeline import make_pipeline

X, y = make_classification(random_state=0)

with TemporaryDirectory(prefix="sklearn_cache_"as tmpdir:
    estimator = make_pipeline(
        KNeighborsTransformer(n_neighbors=10, mode='distance'),
        Isomap(n_neighbors=10, metric='precomputed'),
        memory=tmpdir)
    estimator.fit(X)

    # We can decrease the number of neighbors and the graph will not be
    # recomputed.
    estimator.set_params(isomap__n_neighbors=5)
    estimator.fit(X)

1.2.6 基于KNN的估算

我们现在支持使用k近邻来完成缺失值的估算。

每个样本的缺失值都是使用训练集中最近的 n_neighbors个最近邻居的平均值来估算的。如果两个都不缺少的特征接近,则两个样本是接近的。默认情况下,欧氏距离度量支持缺失值的, nan_euclidean_distances距离用于查找最近的邻居。

用户指南中阅读更多内容。

import numpy as np
from sklearn.impute import KNNImputer

X = [[12, np.nan], [343], [np.nan, 65], [887]]
imputer = KNNImputer(n_neighbors=2)
print(imputer.fit_transform(X))

# 输出
[[1.  2.  4. ]
 [3.  4.  3. ]
 [5.5 6.  5. ]
 [8.  8.  7. ]]

1.2.7 树剪枝

现在,一旦树木建成,就可以修剪大多数基于树的估计器了。剪枝是基于最小的成本复杂度。有关详细信息,请参阅用户指南中的更多内容。

X, y = make_classification(random_state=0)

rf = RandomForestClassifier(random_state=0, ccp_alpha=0).fit(X, y)
print("Average number of nodes without pruning {:.1f}".format(
    np.mean([e.tree_.node_count for e in rf.estimators_])))

rf = RandomForestClassifier(random_state=0, ccp_alpha=0.05).fit(X, y)
print("Average number of nodes with pruning {:.1f}".format(
    np.mean([e.tree_.node_count for e in rf.estimators_])))

# 输出
Average number of nodes without pruning 22.3
Average number of nodes with pruning 6.4

1.2.8 从OpenML检索数据

datasets.fetch_openml现在可以返回pandas数据,从而正确处理异构数据集:

from sklearn.datasets import fetch_openml

titanic = fetch_openml('titanic', version=1, as_frame=True)
print(titanic.data.head()[['pclass''embarked']])

# 输出
   pclass embarked
0     1.0        S
1     1.0        S
2     1.0        S
3     1.0        S
4     1.0        S

1.2.9 检验scikit-learn估计器的兼容性

开发人员可以使用check_estimator检查他们的scikit-learn兼容估计器的兼容性。例如,通过check_estimator(LinearSVC)

我们现在提供了一个pytest 特定的装饰器,它允许pytest独立运行所有检查并报告失败的检查。

from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.utils.estimator_checks import parametrize_with_checks


@parametrize_with_checks([LogisticRegression, DecisionTreeRegressor])
def test_sklearn_compatible_estimator(estimator, check):
    check(estimator)
  
# 输出
/home/circleci/project/sklearn/utils/estimator_checks.py:420: FutureWarning: Passing a class is deprecated since version 0.23 and won't be supported in 0.24.Please pass an instance instead.
  warnings.warn(msg, FutureWarning)

1.2.10 ROC AUC 现在支持多类分类

roc_auc_score函数也可用于多类分类。目前支持两种平均策略:one-vs-one算法计算成对的ROC AUC分数的平均值,one-vs-rest算法计算每一类相对于所有其他类的平均分数。在这两种情况下,多类ROC AUC分数是根据该模型从样本属于特定类别的概率估计来计算的。OvO和OvR算法均支持相同加权(average='macro')和根据流行程度的加权(average='weighted')。

用户指南中阅读更多内容。

from sklearn.datasets import make_classification
from sklearn.svm import SVC
from sklearn.metrics import roc_auc_score

X, y = make_classification(n_classes=4, n_informative=16)
clf = SVC(decision_function_shape='ovo', probability=True).fit(X, y)
print(roc_auc_score(y, clf.predict_proba(X), multi_class='ovo'))

# 输出
0.9984000000000001

脚本的总运行时间:(0分4.999秒)