Scikit-Learn最新更新简介

Scikit-Learn应该是最著名的基于Python的机器学习库了。在深度学习火之前,直接应用Scikit-Learn应该就可以解决大多数机器学习问题了。但是,它对深度学习架构的算法支持不太好,因此这几年的风头略有欠缺。但是并不是所有的问题都需要深度学习,它支持的经典的算法非常易于使用,效果也很好。

Scikit-Learn最新更新简介

Scikit-Learn的官方文档非常值得阅读,它不仅告诉我们如何使用,还在关键的地方告诉这些技术的原理。非常通俗易懂,还有实例。

Scikit-Learn有很优秀的机器学习处理思想,包括TensorFlow等新框架都借鉴了它的设计思想。最近的更新也让Scikit-Learn更加强大。在描述这个更新之前我们先简单看一下历史,然后让我们一起看看都有什么新内容吧。

  • Scikit-Learn历史简介
  • Scikit-Learn v0.22新特性基于Stacking的分类/回归算法基于排列的特征重要性计算多分类问题支持ROC-AUC计算基于kNN方法的缺失值填补对树进行剪枝

Scikit-Learn历史简介

Scikt-Learn是2007年Google Summer of Code的一个产物。后来经过大神的重写,在2010年重新发布。它集成了很多经典的机器学习算法。当然,Scikit-Learn不仅包含很多优秀的机器学习编程的设计思想,它的能力也很强,由于很多最底层的实现都是基于C语言的程序,因此Scikit-Learn在执行速度上也非常快。

Scikit-Learn v0.22新特性

在2019年12月3日发布的0.22版本除了修复了很多bug以外还有一些非常优秀的新特性。ANKIT CHOUDHARY已经帮我们总结了一些内容,主要如下:

基于Stacking的分类/回归算法

参加过Kaggle比赛的童鞋都知道,模型的stacking是必不可少的技能。将多个优秀的单个模型进行混合会在原有的基础上有所提升。这也是很多排名靠前的团队“调优”的重要方向。

在v0.22版本中,Scikt-Learn新增了stacking的方法,与之前的用法类似,我们很容易就能实现。以下是一个简单的示例:

<code>from sklearn.linear_model import LogisticRegressionfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.ensemble import StackingClassifierfrom sklearn.model_selection import train_test_splitX, y = load_iris(return_X_y=True)estimators = [  ('rf', RandomForestClassifier(n_estimators=10, random_state=42)),                  ('dt', DecisionTreeClassifier(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)/<code>

基于排列的特征重要性计算

As the name suggests, this technique provides a way to assign importance to each feature by permuting each feature and capturing the drop in performance.

简单解释一下,有时候我们需要了解每个特征在分类或者回归问题上的重要性。一般采用的方法是对某一个特征随机shuffle,然后使用模型进行预测,看这个shuffle特征之后的预测结果与原来的结果的差距。多次计算就能得到一个平均值,用这个值来表示特征重要性。

简单解释一下这个原理,其实也很简单。比如有两个特征预测收入,性别和身高。假如我们在身高不变的基础上,把性别特征打乱,比如把所有人的性别重新随机分。然后用新数据进行预测,得到的结果如果和打乱之前差不多,证明这个性别对预测作用不大。

基于这个原理我们可以知道每种特征的重要性。原来这种方式需要我们自己实现,在最新的Scikit-Learn中已经带有了这个功能。我们看一个示例:

<code>from sklearn.ensemble import RandomForestClassifierfrom sklearn.inspection import permutation_importancefrom sklearn.datasets import make_classification# Use Sklearn make classification to create a dummy dataset with 3 important variables out of 7X, y = make_classification(random_state=0, n_features=7, n_informative=3)rf = RandomForestClassifier(random_state=0).fit(X, y)result = permutation_importance(rf, X, y,                                n_repeats=10, # Number of times for which each feature must be shuffled                                random_state=0, # random state fixing for reproducability                                n_jobs=-1) # Parallel processing using all coresfig, 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()/<code>

结果如下:

Scikit-Learn最新更新简介

多分类问题支持ROC-AUC计算

ROC-AUC是一种评估二分类问题的经典指标。ROC曲线描述的是模型区分能力,它的线条表示不论真实样本是0还是1,模型会预测成1的概率。其中横坐标表示0预测成1的概率,纵坐标表示1预测成1的概率。显然,如果这个线条是y=x的时候,不管真实样本是0还是1,模型预测成1的概率都一样,这就没有区分能力。显然最好的是真实结果是1,预测1的概率高一点最好。AUC就是ROC去线下方的面积,等于0.5就是y=x情况,最坏。我们希望它是1,这是最好的情况。

现在,Scikit-Learn将这个指标扩展到了多分类问题上。计算是采用两种方式:

  1. 对任意两个类别计算ROC AUC,然后取平均值
  2. 计算一个类别,剩下都是负类。取所有的平均值

基于kNN方法的缺失值填补

这个容易理解,就是对于缺失值的处理。采用kNN找最相似的点,然后把缺失值用最像的数据的值补上。一个简单示例:

<code>import numpy as npfrom sklearn.impute import KNNImputerX = [[4, 6, np.nan], [3, 4, 3], [np.nan, 6, 5], [8, 8, 9]]imputer = KNNImputer(n_neighbors=2)print(imputer.fit_transform(X))/<code>

对树进行剪枝

剪枝就是通过某种技术降低决策树的大小,防止过拟合,并且加速模型。是一种非常重要且流行的技术。在最新的版本中Scikit-Learn提供了手工剪枝的方式(XGBoost或者LightGBM都已经包含了剪枝)。也就是树模型一旦建立,就可以利用这个技术降低模型大小。

一个简单示例:

<code>from sklearn.ensemble import RandomForestClassifier from sklearn.datasets import make_classificationX, 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.1).fit(X, y)print("Average number of nodes with pruning {:.1f}".format(      np.mean([e.tree_.node_count for e in rf.estimators_])))/<code>

原文:https://www.analyticsvidhya.com/blog/2020/02/everything-you-should-know-scikit-learn/


分享到:


相關文章: