https://cloud.tencent.com/developer/news/58202
簡介
今天為大家介紹的是scikit-learn。sklearn是一個Python第三方提供的非常強力的機器學習庫,它包含了從數據預處理到訓練模型的各個方面。在實戰使用scikit-learn中可以極大的節省我們編寫代碼的時間以及減少我們的代碼量,使我們有更多的精力去分析數據分布,調整模型和修改超參。(sklearn為包名)
基本概括
sklearn擁有可以用於監督和無監督學習的方法,一般來說監督學習使用的更多。sklearn中的大部分函數可以歸為估計器(Estimator)和轉化器(Transformer)兩類。
估計器(Estimator)其實就是模型,它用於對數據的預測或回歸。基本上估計器都會有以下幾個方法:
fit(x,y):傳入數據以及標簽即可訓練模型,訓練的時間和參數設置,數據集大小以及數據本身的特點有關
score(x,y)用於對模型的正確率進行評分(范圍0-1)。但由於對在不同的問題下,評判模型優劣的的標准不限於簡單的正確率,可能還包括召回率或者是查准率等其他的指標,特別是對於類別失衡的樣本,准確率並不能很好的評估模型的優劣,因此在對模型進行評估時,不要輕易的被score的得分蒙蔽。
predict(x)用於對數據的預測,它接受輸入,並輸出預測標簽,輸出的格式為numpy數組。我們通常使用這個方法返回測試的結果,再將這個結果用於評估模型。
轉化器(Transformer)用於對數據的處理,例如標准化、降維以及特征選擇等等。同與估計器的使用方法類似:
fit(x,y):該方法接受輸入和標簽,計算出數據變換的方式。
transform(x):根據已經計算出的變換方式,返回對輸入數據x變換后的結果(不改變x)
fit_transform(x,y) :該方法在計算出數據變換方式之后對輸入x就地轉換。
以上僅僅是簡單的概括sklearn的函數的一些特點。sklearn絕大部分的函數的基本用法大概如此。但是不同的估計器會有自己不同的屬性,例如隨機森林會有Feature_importance來對衡量特征的重要性,而邏輯回歸有coef_存放回歸系數intercept_則存放截距等等。並且對於機器學習來說模型的好壞不僅取決於你選擇的是哪種模型,很大程度上與你超參的設置有關。因此使用sklearn的時候一定要去看看官方文檔,以便對超參進行調整。
舉個例子
導入數據及數據預處理
sklearn的datasets中提供一些訓練數據,我們可以使用這些數據來進行分類或者回歸等等,以此熟悉sklearn的使用。
如下面代碼所示我們讀取了鳶尾屬植物的分類數據集。load_iris()返回的是一個類似字典的對象通過關鍵字則可以獲取對應的數據。
現在我們已經讀取了數據,首先第一件事應當是查看數據的特點。我們可以看到標簽總共有三個,所以該數據要解決的是一個三分類問題。接着我們要去查看數據特征,用pandas的DataFrame展示是一個很好選擇。

我們可以看到一條數據對應了4個連續特征,接着應當查看一些數據集的缺失值的比例,這一步非常重要,如果數據集中出現缺失值,在訓練模型的時候就會出現問題。
sklearn的preprocessing中有提供Imputer()處理缺失值的函數,它提供了中位數、均值、眾數等策略填充缺失值。但是不同情況下處理不一定使用填充來處理缺失值。因此在遇到缺失值的時候要慎重處理。幸運的是我們這個數據集中沒有缺失值,這樣節省了我們處理缺失值的時間。接下來要判斷數據集的樣本類別是否均衡。
非常幸運,我們的樣本類別的比例恰好是1:1:1,如果我們樣本比例失衡嚴重,那么我們可能需要對失衡的比例做一些調整,例如重采樣、欠采樣等等。現在數據集看上去沒有什么大的問題了,但是在訓練之前,我們還是應當對數據進行標准化處理。
模型訓練之前,我們要對數據進行預處理。sklearn中的preprocessing模塊提供非常多的數據歸一化的類。
標准化之后的數據不僅可以提高模型的訓練速度,並且不同的標准會帶來不一樣的好處。
例如,z-score 標准化將樣本的特征值轉換到同一量綱下,使得不同特征之間有可比性。以上我們就是使用了z-score標准化,sklearn的preprocessing中還有一些其他的標准化方法,有興趣的朋友可以查看官方文檔。
訓練模型
在處理好數據之后我們就可以訓練模型了,以多元邏輯回歸為例
這里我們的邏輯回歸使用OVR多分類方法,
OvR把多元邏輯回歸,看做二元邏輯回歸。具體做法是,每次選擇一類為正例,其余類別為負例,然后做二元邏輯回歸,得到第該類的分類模型。最后得出多個二元回歸模型。按照各個類別的得分得出分類結果。
模型優化
模型選擇

對於一個分類任務,我們可以按照以上的圖來選擇一個比較合適的解決方法或者模型,但模型的選擇並不是絕對的,事實上很多情況下你會去試驗很多的模型,才能比較出適合該問題的模型。
數據划分
我們可以使用交叉驗證或其他划分數據集的方法對數據集多次划分,以得出模型平均的性能而不是偶然結果。sklearn有很多划分數據集的方法,它們都在model_selection里面,常用的有
K折交叉驗證:
KFold 普通K折交叉驗證
StratifiedKFold(保證每一類的比例相等)
留一法:
LeaveOneOut (留一)
LeavePOut (留P驗證,當P = 1 時變成留一法)
隨機划分法:
ShuffleSplit (隨機打亂后划分數據集)
StratifiedShuffleSplit (隨機打亂后,返回分層划分,每個划分類的比例與樣本原始比例一致)
以上方法除了留一法都有幾個同樣的參數:
n_splits:設置划分次數
random_state:設置隨機種子
以上的划分方法各有各的優點,留一法、K折交叉驗證充分利用了數據,但開銷比隨機划分要高,隨機划分方法可以較好的控制訓練集與測試集的比例。(通過設置train_size參數)。關於划分數據集的使用可以參照上面例子中的ShuffleSplit的用法,其他的函數使用方法大同小異,詳細可查看官方文檔。
超參的搜索
我們上面已經初步得出模型,並且效果看起來還不錯,所以我們現在應該下想辦法進一步優化這一個模型了。
我們在調參的時候需要將數據集分為三部分,分別是:訓練集、驗證集以及測試集。訓練集用於模型的訓練,然后我們根據驗證集的結果去調整出泛化能力較強的模型,最后通過測試集得出模型的泛化能力。如果只把數據分為訓練集和測試集,也許你能調出對於測試集最合適的參數,但模型的泛化能力也許並沒有在測試集上表現的那么強。
由於鳶尾屬植物的數據集並不大,如果將數據分為三部分的話,訓練數據就太少了,可能提高不了模型的性能。在此只是簡單的介紹sklearn中的調參方法。
model_seletion里面還提供自動調參的函數,以格搜索(GridSearchCV)為例。
通過傳入字典,對比使用不同的參數的估計器的效果,得出最優的參數。這里是對邏輯回歸的精度進行調整。另外我們還可以使用不同的指標來選擇參數,不同的指標在sklearn.metrics中
特征選擇
當特征特別多的時候,且有冗余的情況下,對特征進行選擇不僅能使訓練速度加快,還可以排除一些負面特征的干擾。sklearn的feature_seletion提供了它許多特征選取函數,目前包括單變量選擇方法和遞歸特征消除算法。它們均為轉化器,故在此不舉例說明如何使用。
除了使用feature_seletion的方法選取特征外,我們也可以選擇那些帶有特征選擇的模型進行選擇特征,例如隨機森林會根據特征的重要程度對特征打分。
Pineline
使用pineline可以按順序構建從數據處理到和訓練模型的整個過程。pineline中間的步驟必須轉化器(對數據進行處理)。使用pineline的好處就是可以封裝一個學習的過程,使得重新調用這個過程變得更加方便。中間的過程用多個二元組組成的列表表示。
上面的封裝的估計器,會先用PCA將數據降至兩維,在用邏輯回歸去擬合。
小結
本期介紹sklearn只做簡單介紹,還有一些方面沒有涉及,例如特征抽取、降維等等,這些在官方文檔中有詳細使用方法及參數介紹。
參考來源
http://scikit-learn.org/stable/documentation.html 官方文檔
https://www.jianshu.com/p/c6bfc9052325
前言
於sklearn的使用來說,目前只是想成為一名調包俠,但是調包俠起碼也得知道有哪些包可以調,為此找了一些教程想快速入門,通過一番查找,終於找到了一名大佬叫做莫煩寫的教程,教程短小實用,對我想快速了解sklearn來說是再適合不過了。
在教程里完成sklearn的一般使用的教程之后,為了鞏固,為此寫此筆記,加深理解和日后的復習。
通用模板
實例化
對於sklearn這個庫來說,是用面向對象的思想來使用的。
就是每種算法都是一個對象,要使用某種算法解決問題,可以將其import進來,此時它只是個對象,只有在實例化之后才可以對數據學習和預測
from sklearn.neighbors import KNeighborsClassifier obj = KNeighborsClassifier()
此時實例obj可以對數據訓練學習之后再對數據進行預測了,但是此時並沒有數據
不過sklearn中有數據供我們使用
獲取數據
from sklearn import datasets iris = datasets.load_iris() x = iris.data y = iris.target
導入的數據是個訓練集,並不能直接傳遞給實例對其學習,因為實例需要特征和標簽才能開始學習(這個實例是這個情況的,無監督學習現在還不那么清楚是個什么樣的情況)
不過特征和標簽都存儲在data和target標簽中,可以輕松的獲得
開始訓練和預測
這個時候,實例有了,數據也有了,可以開始對數據訓練和學習了
obj.fit(x, y)
y_pred = obj.predict(x[:4, :]
print(y - y_pred)
輸出結果:
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 -1 0 0 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
准確度還是蠻高的,到此已經完成了一個機器學習的基本過程
划分訓練集
一般把訓練集划分為訓練集和測試集,這樣來驗證算法的准確性比較好
from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)
其中參數test_size=0.3代表將把訓練集的30%數據當做測試集使用
現在有了訓練集和測試集,重復之前的步驟,對訓練集訓練:
knn = KNeighborsClassifier()
knn.fit(x_train, y_train)
y_pred = knn.predict(x_test)
print(y_pred - y_test)
輸出結果:
[ 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
注意,每次運行的輸出結果可能不一樣
參數獲取
對於每個學習到的模型,也就是一個假設函數,都有一些參數
還有預測的時候也是有參數設置的
對於這兩個參數的獲取,可以通過實例化后的實例的coef_,intercept_屬性和get_params()獲得
由於分類好像沒有實例的那幾個屬性,換個線性回歸的的模型:
from sklearn import datasets from sklearn.linear_model import LinearRegression loaded_data = datasets.load_boston() data_X = loaded_data.data data_y = loaded_data.target model = LinearRegression() model.fit(data_X, data_y) y_pred = model.predict(data_X[:4, :]) print(model.coef_) print(model.intercept_)
輸出:
[-1.07170557e-01 4.63952195e-02 2.08602395e-02 2.68856140e+00 -1.77957587e+01 3.80475246e+00 7.51061703e-04 -1.47575880e+00 3.05655038e-01 -1.23293463e-02 -9.53463555e-01 9.39251272e-03 -5.25466633e-01] 36.49110328036133
獲得訓練學習時設置的參數:
print(model.get_params()) # {'n_jobs': 1, 'copy_X': True, 'normalize': False, 'fit_intercept': True}
評估模型
最經常用的評估方法,越接近於1的效果越好:
print(model.score(data_X, data_y))