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/


分享到:


相關文章: