您好,登錄后才能下訂單哦!
這篇文章主要介紹“Python Sklearn中超實用的隱藏功能有哪些”,在日常操作中,相信很多人在Python Sklearn中超實用的隱藏功能有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Python Sklearn中超實用的隱藏功能有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
通常,在我們的所處理的數據分布中有異常值是很常見的,并且許多算法都可以處理離群值,而 EllipticalEnvelope 就是 Sklearn 中直接內置的一個例子。該算法的優勢在于,它在檢測正態分布(高斯)特征中的異常點時表現得非常好:
import numpy as np from sklearn.covariance import EllipticEnvelope # 創建一個樣本正態分布 X = np.random.normal(loc=5, scale=2, size=50).reshape(-1, 1) # 擬合估計量 ee = EllipticEnvelope(random_state=0) _ = ee.fit(X) # 測試 test = np.array([6, 8, 20, 4, 5, 6, 10, 13]).reshape(-1, 1) # Predict返回1作為內嵌值,返回-1作為異常值 >>> ee.predict(test) array([ 1, 1, -1, 1, 1, 1, -1, -1])
為了檢驗評估結果,我們創建了一個均值為5,標準差為2的正態分布。訓練完成后,將一些隨機數傳遞給它的預測方法。該方法返回-1表示測試中的異常值,即20、10、13。
我們在做數據挖掘,做特征工程時,選擇對預測最有幫助的特征是防止過擬合和降低模型復雜性的必要步驟。Sklearn提供的最健壯的算法之一是遞歸特征消除(RFE)。它通過使用交叉驗證自動找到最重要的特性,并丟棄其余的。
這個評估器的一個優點是它是一個包裝器——它可以用于返回特征重要性或系數分數的任何 Sklearn 算法。下面是一個關于合成數據集的例子:
from sklearn.datasets import make_regression from sklearn.feature_selection import RFECV from sklearn.linear_model import Ridge # 構建一個合成數據集 X, y = make_regression(n_samples=10000, n_features=15, n_informative=10) # 初始化和擬合選擇器 rfecv = RFECV(estimator=Ridge(), cv=5) _ = rfecv.fit(X, y) # 轉換特性陣列 >>> rfecv.transform(X).shape (10000, 10)
數據集有 15 個特征,其中 10 個特征是信息豐富的,其余都是冗余的。我們用嶺回歸擬合 5-fold RFECV 作為評估器。訓練后,可以使用變換方法丟棄冗余特征。最后調用 .shape
查看評估器刪除了所有 5 個冗余的特性。
我們都知道,盡管隨機森林非常強大,但過度擬合的風險非常高。因此,Sklearn提供了稱為 ExtraTrees(分類器和回歸器) 的 RF 替代方案。
"Extra"
這個詞并不是指更多的樹,而是指更多的隨機性。該算法使用了另一種類似于決策樹的樹。唯一的區別是,不同于在構建每棵樹時計算分割閾值,這些閾值是為每個特征隨機繪制的,并選擇最佳閾值作為分割規則。這允許以偏差略微增加的代價來降低方差:
from sklearn.ensemble import ExtraTreesRegressor, RandomForestRegressor from sklearn.model_selection import cross_val_score from sklearn.tree import DecisionTreeRegressor X, y = make_regression(n_samples=10000, n_features=20) # 決策樹 clf = DecisionTreeRegressor(max_depth=None, min_samples_split=2, random_state=0) scores = cross_val_score(clf, X, y, cv=5) >>> scores.mean() 0.6376080094392635 # 隨機森林 clf = RandomForestRegressor( n_estimators=10, max_depth=None, min_samples_split=2, random_state=0 ) scores = cross_val_score(clf, X, y, cv=5) >>> scores.mean() 0.8446103607404536 # ExtraTrees clf = ExtraTreesRegressor( n_estimators=10, max_depth=None, min_samples_split=2, random_state=0 ) scores = cross_val_score(clf, X, y, cv=5) >>> scores.mean() 0.8737373931608834
如結果所示,ExtraTreesRegressor 在合成數據集上的表現優于隨機森林。
如果你正在尋找比 SimpleImputer
更健壯、更先進的 imputation
技術,Sklearn再次為你提供了支持。impute 子包包括兩個基于模型的 impute 算法 KNNImputer
和 IterativeImputer
。
顧名思義,KNNImputer
使用 k-Nearest-Neighbors
算法來尋找缺失值的最佳替代:
from sklearn.impute import KNNImputer # 代碼取自Sklearn用戶指南 X = [[1, 2, np.nan], [3, 4, 3], [np.nan, 6, 5], [8, 8, 7]] imputer = KNNImputer(n_neighbors=2) imputer.fit_transform(X)
輸出:
array([[1. , 2. , 4. ],
[3. , 4. , 3. ],
[5.5, 6. , 5. ],
[8. , 8. , 7. ]])
另一個更健壯的算法是 IterativeImputer
。它通過將每個特征的缺失值建模為其他特征的函數來尋找缺失值。 這個過程是按循序漸進的循環方式完成的。在每一步中,選擇一個具有缺失值的特征作為目標(y),其余的作為特征數組(X)。然后,使用回歸函數預測 y 中的缺失值,并對每個特征繼續這個過程,直到 max_iter
次數 (IterativeImputer的一個參數)。
因此,會為一個缺失的值生成多個預測。這樣做的好處是,可以將每個缺失的值視為隨機變量,并將其與固有的不確定性聯系起來:
from sklearn.experimental import enable_iterative_imputer from sklearn.impute import IterativeImputer from sklearn.linear_model import BayesianRidge imp_mean = IterativeImputer(estimator=BayesianRidge()) imp_mean.fit([[7, 2, 3], [4, np.nan, 6], [10, 5, 9]]) X = [[np.nan, 2, 3], [4, np.nan, 6], [10, np.nan, 9]] imp_mean.transform(X)
輸出:
array([[ 6.95847623, 2. , 3. ],
[ 4. , 2.6000004 , 6. ],
[10. , 4.99999933, 9. ]])
結果表明,使用 IterativeImputer
缺失值填補算法的 BayesianRidge
和 ExtraTree
算法性能效果變現更加優秀。
雖然正常情況下,數據分布中存在異常值是非常常見的, 但異常值的存在會嚴重破壞任何模型的預測。許多異常值檢測算法會丟棄異常值并將其標記為缺失。雖然這有助于模型的學習,但它完全消除了異常值對分布的影響。
另一種算法是 HuberRegressor
回歸算法。它不是完全去除它們,而是在擬合數據期間給予異常值更小的權重。它有超參數 epsilon
來控制樣本的數量,這些樣本應該被歸類為異常值。參數越小,對異常值的魯棒性越強。它的API與任何其他線性回歸函數相同。下面,你可以看到它與貝葉斯嶺回歸器在一個有大量異常值的數據集上的比較:
可以看到,設置參數 epsilon 為 1.35 1.5, 1.75 的 huberregressionor
算法設法捕獲不受異常值影響的最佳擬合線。
Sklearn 中可以使用 plot_tree
函數繪制單個決策樹的結構。這個特性可能對剛開始學習基于樹的模型和集成模型的初學者很方便,通過該方法,對決策樹的決策過程可視化,對其決策過程和原理更加一目了然。
from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier, plot_tree iris = load_iris() X, y = iris.data, iris.target clf = DecisionTreeClassifier() clf = clf.fit(X, y) plt.figure(figsize=(15, 10), dpi=200) plot_tree(clf, feature_names=iris.feature_names, class_names=iris.target_names);
還有其他繪制樹的方法,比如 Graphviz。
盡管感知機是一個奇特的名字,但它是一個簡單的線性二進制分類器。算法的定義特征是適合大規模學習,默認為:
它不需要學習速率。
不要實現正則化。
它只在分類錯誤的情況下更新模型。
它等價于 SGDClassifier
,loss='perceptron'
, eta0=1
, learning_rate="constant"
, penalty=None
,但略快:
from sklearn.datasets import make_classification from sklearn.linear_model import Perceptron # 創建一個更大的數據集 X, y = make_classification(n_samples=100000, n_features=20, n_classes=2) # Init/Fit/Score clf = Perceptron() _ = clf.fit(X, y) clf.score(X, y)
輸出:
0.91928
Sklearn 中另一個基于模型的特征選擇模型是 SelectFromModel。它不像RFECV那樣健壯,但由于它具有較低的計算成本,可以作為大規模數據集的一個很好的選擇。它也是一個包裝器模型,適用于任何具有 .feature_importance_
或 .coef_
屬性的模型:
from sklearn.feature_selection import SelectFromModel # 創建一個包含40個無信息特征的數據集 X, y = make_regression(n_samples=int(1e4), n_features=50, n_informative=10) # 初始化選擇器并轉換特性數組 selector = SelectFromModel(estimator=ExtraTreesRegressor()).fit(X, y) selector.transform(X).shape
輸出:
(10000, 8)
如結果所示,算法成功地刪除了所有40個冗余特征。
總所周知,混淆矩陣是用于評估分類問題的常用方法。我們通常使用的大多數指標都來自于它,如精度、召回率、F1、ROC AUC等等。Sklearn中可以計算和繪制一個默認的混淆矩陣:
from sklearn.metrics import plot_confusion_matrix from sklearn.model_selection import train_test_split # 創建一個二元分類問題 X, y = make_classification(n_samples=200, n_features=5, n_classes=2) X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.5, random_state=1121218 ) clf = ExtraTreeClassifier().fit(X_train, y_train) fig, ax = plt.subplots(figsize=(5, 4), dpi=100) plot_confusion_matrix(clf, X_test, y_test, ax=ax);
老實說,我不喜歡默認的混淆矩陣。它的格式是固定的—行是true labels
,列是predictions label
。第一行和第一列是負類,第二行和第二列是正類。有些人可能更喜歡不同格式的矩陣,可能是轉置或翻轉的。
例如,我喜歡將正類作為第一行和第一列。這有助于我更好地隔離 4 矩陣項 -- TP, FP, TN, FN
。幸運的是,你可以用另一個函數 ConfusionMatrixDisplay
繪制自定義矩陣:
from sklearn.metrics import ConfusionMatrixDisplay, confusion_matrix clf = ExtraTreeClassifier().fit(X_train, y_train) y_preds = clf.predict(X_test) fig, ax = plt.subplots(figsize=(5, 4), dpi=100) cm = confusion_matrix(y_test, y_preds) cmp = ConfusionMatrixDisplay(cm, display_labels=["Positive", "Negative"]) cmp.plot(ax=ax);
在傳遞給 ConfusionMatrixDisplay
之前,可以把 混淆矩陣cm 放在任何格式中。
一般情況下,如果有可用于其他類型分布的替代方案,則將目標(y)轉換為正態分布是沒有意義的。
例如,Sklearn 為目標變量提供了3種廣義線性模型,分別是泊松、Tweedie或Gamma分布 ,而不是所期望的正態分布,poissonregressionor, TweedieRegressor 和 GammaRegressor
可以生成具有各自分布的目標的穩健結果。
除此之外,他們的api與任何其他Sklearn模型一樣。為了找出目標的分布是否與上述三個相匹配,可以將它們的PDF(概率密度函數)繪制在相同軸上。
例如,要查看目標是否遵循泊松分布,可以使用 Seaborn 的 kdeploy
繪制它的 PDF,并在相同的軸上使用 np.random_poisson
從 Numpy 中采樣,繪制完美的泊松分布。
一般情況下,基于樹的模型和集合模型通常產生更穩健的結果,它們在異常點檢測方面也被證明是有效的。Sklearn 中的 IsolationForest 使用一個極端隨機樹 (tree.ExtraTreeRegressor) 來檢測異常值。每棵樹試圖通過選擇一個單一的特征,并在所選特征的最大值和最小值之間隨機選擇一個分裂值來隔離每個樣本。
這種隨機分區會在每棵樹的根節點和終止節點之間產生明顯更短的路徑。
因此,當隨機樹組成的森林為特定樣本共同產生更短的路徑長度時,它們極有可能是異常——Sklearn用戶指南。
from sklearn.ensemble import IsolationForest X = np.array([-1.1, 0.3, 0.5, 100]).reshape(-1, 1) clf = IsolationForest(random_state=0).fit(X) clf.predict([[0.1], [0], [90]])
輸出:
array([ 1, 1, -1])
許多線性模型需要在數值特征上進行一些轉換才能使其服從正態分布。StandardScaler
和 MinMaxScaler
在大多數發行版中都比較適用。然而,當數據存在高偏度時,分布的核心指標,如平均值、中位數、最小值和最大值,就會受到影響。因此,簡單的標準化和標準化對傾斜分布不起作用。
相反,Sklearn 實現中提供了一個名為 PowerTransformer
的方法,它使用對數變換將任何傾斜的特征盡可能地轉化為正態分布。考慮 Diamonds 數據集中的兩個特征:
import seaborn as sns diamonds = sns.load_dataset("diamonds") diamonds[["price", "carat"]].hist(figsize=(10, 5));
兩者都嚴重傾斜。我們用對數變換 PowerTransformer
來解決這個問題:
from sklearn.preprocessing import PowerTransformer pt = PowerTransformer() diamonds.loc[:, ["price", "carat"]] = pt.fit_transform(diamonds[["price", "carat"]]) diamonds[["price", "carat"]].hist(figsize=(10, 5));
Sklearn 中的另一個數字轉換器是 RobustScaler
,我們可以從它的名稱猜出它的用途——可以以一種健壯到異常值的方式轉換特性。如果一個特征中存在異常值,就很難使其服從正態分布,因為它們會嚴重扭曲均值和標準差。
與使用均值/標準不同,RobustScaler 使用中值和IQR(四分位數范圍)來衡量數據,因為這兩個指標都不會因為異常值而有偏差。
在 Sklearn 中,有一個用 make_pipeline
函數創建 Pipeline 實例的簡寫。該函數不需要為Pipeline中的每一步命名,而是只接受變形器和估計器并執行它的工作,從而不需要使代碼那么長:
from sklearn.impute import SimpleImputer from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler pipeline = make_pipeline(SimpleImputer(), StandardScaler(), ExtraTreesRegressor()) pipeline
Pipeline(steps=[('simpleimputer', SimpleImputer()), ('standardscaler', StandardScaler()), ('extratreesregressor', ExtraTreesRegressor())])
對于更復雜的場景,使用 ColumnTransformer
,這有相同的問題——每個預處理步驟都應該命名,這會使代碼變得冗長且不可讀。Sklearn提供了與 make_pipeline
類似的函數:
import seaborn as sns from sklearn.compose import make_column_transformer from sklearn.preprocessing import OneHotEncoder # 負載鉆石數據集 diamonds = sns.load_dataset("diamonds") X, y = diamonds.drop("price", axis=1), diamonds.price.values.reshape(-1, 1) # 拆分數字和類別標簽 num_cols = X.select_dtypes(include=np.number).columns cat_cols = X.select_dtypes(exclude=np.number).columns make_column_transformer((StandardScaler(), num_cols), (OneHotEncoder(), cat_cols))
ColumnTransformer( transformers=[('standardscaler', StandardScaler(), Index(['carat', 'depth', 'table', 'x', 'y', 'z'], dtype='object')), ('onehotencoder', OneHotEncoder(), Index(['cut', 'color', 'clarity'], dtype='object'))] )
如上所示,使用 make_column_transformer
要短得多,并且它自己負責命名每個轉換器步驟。
上文中,我們使用 select_dtypes
函數和 pandas DataFrames
的 columns
屬性來拆分數值列和分類列。雖然這當然有效,但使用 Sklearn 有一個更靈活、更優雅的解決方案。
make_column_selector
函數創建一個可以直接傳遞到 ColumnTransformer 實例中的列選擇器。它的工作原理與 select_dtypes
類似,甚至更好。它有 dtype_include
和 dtype_exclude
參數,可以根據數據類型選擇列。如果需要自定義列篩選器,可以將正則表達式傳遞給 pattern,同時將其他參數設置為 None。下面是它的工作原理:
from sklearn.compose import make_column_selector make_column_transformer( (StandardScaler(), make_column_selector(dtype_include=np.number)), (OneHotEncoder(), make_column_selector(dtype_exclude=np.number)), )
只是傳遞一個實例 make_column_selector 與由你設置相關參數,而不是傳遞一個列名稱列表!
在我們剛學習機器學習時,常見的一個錯誤是使用 LabelEncoder 來編碼有序的分類特征。注意到,LabelEncoder 一次只允許轉換一個列,而不是像 OneHotEncoder 那樣同時轉換。你可能會認為 Sklearn 犯了一個錯誤!
實際上,LabelEncoder
應該只用于按照 LabelEncoder 文檔中指定的方式對響應變量(y)進行編碼。要編碼特征數組(X),應該使用 OrdinalEncoder
,它將有序分類列轉換為具有(0, n_categories - 1)
類的特性。它在一行代碼中跨所有指定列執行此操作,使得在管道中包含它成為可能。
from sklearn.preprocessing import OrdinalEncoder oe = OrdinalEncoder() X = [ ["class_1", "rank_1"], ["class_1", "rank_3"], ["class_3", "rank_3"], ["class_2", "rank_2"], ] oe.fit_transform(X)
輸出:
array([[0., 0.],
[0., 2.],
[2., 2.],
[1., 1.]])
Sklearn 內置了 50 多個指標,它們的文本名稱可以在 Sklearn.metrics.scores.keys
中看到。在單個項目中,如果單獨使用它們,則可能需要使用多個指標并導入它們。
從 sklearn.metrics
中導入大量指標可能會污染你的名稱空間,使其變得不必要的長。一種解決方案是可以使用 metrics.get_scorer
函數使用其文本名稱訪問任何度量,而不需要導入它:
from sklearn.metrics import get_scorer >>> get_scorer("neg_mean_squared_error") make_scorer(mean_squared_error, greater_is_better=False) >>> get_scorer("recall_macro") make_scorer(recall_score, pos_label=None, average=macro) >>> get_scorer("neg_log_loss") make_scorer(log_loss, greater_is_better=False, needs_proba=True)
在 sklearn 的 0.24 版本中,引入了兩個實驗性超參數優化器:HalvingGridSearchCV
和 HalvingRandomSearchCV
類。
與它們詳盡的同類 GridSearch
和 RandomizedSearch
不同,新類使用了一種稱為連續減半的技術。 不是在所有數據上訓練所有候選集,而是只將數據的一個子集提供給參數。通過對更小的數據子集進行訓練,篩選出表現最差的候選人。每次迭代后,訓練樣本增加一定的因子,而可能的候選個數減少盡可能多的因子,從而獲得更快的評估時間。
快多少呢?在我做過的實驗中,HalvingGridSearch
比普通 GridSearch
快11倍,HalvingRandomSearch
甚至比 HalvingGridSearch
快10倍。
Sklearn在 sklearn.utils
中有一整套實用程序和輔助功能。Sklearn本身使用這個模塊中的函數來構建我們使用的所有變形器transformers和估計器transformers。
這里有許多有用的方法,如 class_weight.compute_class_weight
、estimator_html_repr
、shuffle
、check_X_y
等。你可以在自己的工作流程中使用它們,使你的代碼更像 Sklearn,或者在創建適合 Sklearn API 的自定義轉換器和評估器時,它們可能會派上用場。
到此,關于“Python Sklearn中超實用的隱藏功能有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。