如何在Python項(xiàng)目中使用Sklearn?相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括邳州網(wǎng)站建設(shè)、邳州網(wǎng)站制作、邳州網(wǎng)頁制作以及邳州網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,邳州網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到邳州省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!Scikit-learn(sklearn)是機(jī)器學(xué)習(xí)中常用的第三方模塊,對常用的機(jī)器學(xué)習(xí)方法進(jìn)行了封裝,包括回歸(Regression)、降維(Dimensionality Reduction)、分類(Classfication)、聚類(Clustering)等方法。當(dāng)我們面臨機(jī)器學(xué)習(xí)問題時(shí),便可根據(jù)下圖來選擇相應(yīng)的方法。Sklearn具有以下特點(diǎn):
簡單高效的數(shù)據(jù)挖掘和數(shù)據(jù)分析工具
讓每個人能夠在復(fù)雜環(huán)境中重復(fù)使用
建立NumPy、Scipy、MatPlotLib之上
Sklearn安裝要求Python(>=2.7 or >=3.3)
、NumPy (>= 1.8.2)
、SciPy (>= 0.13.3)
。如果已經(jīng)安裝NumPy和SciPy,安裝scikit-learn可以使用pip install -U scikit-learn
。
Sklearn中包含眾多機(jī)器學(xué)習(xí)方法,但各種學(xué)習(xí)方法大致相同,我們在這里介紹Sklearn通用學(xué)習(xí)模式。首先引入需要訓(xùn)練的數(shù)據(jù),Sklearn自帶部分?jǐn)?shù)據(jù)集,也可以通過相應(yīng)方法進(jìn)行構(gòu)造,4.Sklearn datasets
中我們會介紹如何構(gòu)造數(shù)據(jù)。然后選擇相應(yīng)機(jī)器學(xué)習(xí)方法進(jìn)行訓(xùn)練,訓(xùn)練過程中可以通過一些技巧調(diào)整參數(shù),使得學(xué)習(xí)準(zhǔn)確率更高。模型訓(xùn)練完成之后便可預(yù)測新數(shù)據(jù),然后我們還可以通過MatPlotLib
等方法來直觀的展示數(shù)據(jù)。另外還可以將我們已訓(xùn)練好的Model進(jìn)行保存,方便移動到其他平臺,不必重新訓(xùn)練。
from sklearn import datasets#引入數(shù)據(jù)集,sklearn包含眾多數(shù)據(jù)集 from sklearn.model_selection import train_test_split#將數(shù)據(jù)分為測試集和訓(xùn)練集 from sklearn.neighbors import KNeighborsClassifier#利用鄰近點(diǎn)方式訓(xùn)練數(shù)據(jù) ###引入數(shù)據(jù)### iris=datasets.load_iris()#引入iris鳶尾花數(shù)據(jù),iris數(shù)據(jù)包含4個特征變量 iris_X=iris.data#特征變量 iris_y=iris.target#目標(biāo)值 X_train,X_test,y_train,y_test=train_test_split(iris_X,iris_y,test_size=0.3)#利用train_test_split進(jìn)行將訓(xùn)練集和測試集進(jìn)行分開,test_size占30% print(y_train)#我們看到訓(xùn)練數(shù)據(jù)的特征值分為3類 ''' [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 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2] ''' ###訓(xùn)練數(shù)據(jù)### knn=KNeighborsClassifier()#引入訓(xùn)練方法 knn.fit(X_train,y_train)#進(jìn)行填充測試數(shù)據(jù)進(jìn)行訓(xùn)練 ###預(yù)測數(shù)據(jù)### print(knn.predict(X_test))#預(yù)測特征值 ''' [1 1 1 0 2 2 1 1 1 0 0 0 2 2 0 1 2 2 0 1 0 0 0 0 0 0 2 1 0 0 0 1 0 2 0 2 0 1 2 1 0 0 1 0 2] ''' print(y_test)#真實(shí)特征值 ''' [1 1 1 0 1 2 1 1 1 0 0 0 2 2 0 1 2 2 0 1 0 0 0 0 0 0 2 1 0 0 0 1 0 2 0 2 0 1 2 1 0 0 1 0 2] '''
Sklearn提供一些標(biāo)準(zhǔn)數(shù)據(jù),我們不必再從其他網(wǎng)站尋找數(shù)據(jù)進(jìn)行訓(xùn)練。例如我們上面用來訓(xùn)練的load_iris
數(shù)據(jù),可以很方便的返回?cái)?shù)據(jù)特征變量和目標(biāo)值。除了引入數(shù)據(jù)之外,我們還可以通過load_sample_images()
來引入圖片。
除了sklearn提供的一些數(shù)據(jù)之外,還可以自己來構(gòu)造一些數(shù)據(jù)幫助我們學(xué)習(xí)。
from sklearn import datasets#引入數(shù)據(jù)集 #構(gòu)造的各種參數(shù)可以根據(jù)自己需要調(diào)整 X,y=datasets.make_regression(n_samples=100,n_features=1,n_targets=1,noise=1) ###繪制構(gòu)造的數(shù)據(jù)### import matplotlib.pyplot as plt plt.figure() plt.scatter(X,y) plt.show()
數(shù)據(jù)訓(xùn)練完成之后得到模型,我們可以根據(jù)不同模型得到相應(yīng)的屬性和功能,并將其輸出得到直觀結(jié)果。假如通過線性回歸訓(xùn)練之后得到線性函數(shù)y=0.3x+1
,我們可通過_coef
得到模型的系數(shù)為0.3,通過_intercept
得到模型的截距為1。
from sklearn import datasets from sklearn.linear_model import LinearRegression#引入線性回歸模型 ###引入數(shù)據(jù)### load_data=datasets.load_boston() data_X=load_data.data data_y=load_data.target print(data_X.shape) #(506, 13)data_X共13個特征變量 ###訓(xùn)練數(shù)據(jù)### model=LinearRegression() model.fit(data_X,data_y) model.predict(data_X[:4,:])#預(yù)測前4個數(shù)據(jù) ###屬性和功能### print(model.coef_) ''' [ -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] ''' print(model.intercept_) #36.4911032804 print(model.get_params())#得到模型的參數(shù) #{'copy_X': True, 'normalize': False, 'n_jobs': 1, 'fit_intercept': True} print(model.score(data_X,data_y))#對訓(xùn)練情況進(jìn)行打分 #0.740607742865
數(shù)據(jù)集的標(biāo)準(zhǔn)化對于大部分機(jī)器學(xué)習(xí)算法來說都是一種常規(guī)要求,如果單個特征沒有或多或少地接近于標(biāo)準(zhǔn)正態(tài)分布,那么它可能并不能在項(xiàng)目中表現(xiàn)出很好的性能。在實(shí)際情況中,我們經(jīng)常忽略特征的分布形狀,直接去均值來對某個特征進(jìn)行中心化,再通過除以非常量特征(non-constant features)的標(biāo)準(zhǔn)差進(jìn)行縮放。
例如, 許多學(xué)習(xí)算法中目標(biāo)函數(shù)的基礎(chǔ)都是假設(shè)所有的特征都是零均值并且具有同一階數(shù)上的方差(比如徑向基函數(shù)、支持向量機(jī)以及L1L2正則化項(xiàng)等)。如果某個特征的方差比其他特征大幾個數(shù)量級,那么它就會在學(xué)習(xí)算法中占據(jù)主導(dǎo)位置,導(dǎo)致學(xué)習(xí)器并不能像我們說期望的那樣,從其他特征中學(xué)習(xí)。例如我們可以通過Scale將數(shù)據(jù)縮放,達(dá)到標(biāo)準(zhǔn)化的目的。
from sklearn import preprocessing import numpy as np a=np.array([[10,2.7,3.6], [-100,5,-2], [120,20,40]],dtype=np.float64) print(a) print(preprocessing.scale(a))#將值的相差度減小 ''' [[ 10. 2.7 3.6] [-100. 5. -2. ] [ 120. 20. 40 [[ 0. -0.85170713 -0.55138018] [-1.22474487 -0.55187146 -0.852133 ] [ 1.22474487 1.40357859 1.40351318]] '''
我們來看下預(yù)處理前和預(yù)處理預(yù)處理后的差別,預(yù)處理之前模型評分為0.511111111111
,預(yù)處理后模型評分為0.933333333333
,可以看到預(yù)處理對模型評分有很大程度的提升。
from sklearn.model_selection import train_test_split from sklearn.datasets.samples_generator import make_classification from sklearn.svm import SVC import matplotlib.pyplot as plt ###生成的數(shù)據(jù)如下圖所示### plt.figure X,y=make_classification(n_samples=300,n_features=2,n_redundant=0,n_informative=2, random_state=22,n_clusters_per_class=1,scale=100) plt.scatter(X[:,0],X[:,1],c=y) plt.show() ###利用minmax方式對數(shù)據(jù)進(jìn)行規(guī)范化### X=preprocessing.minmax_scale(X)#feature_range=(-1,1)可設(shè)置重置范圍 X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3) clf=SVC() clf.fit(X_train,y_train) print(clf.score(X_test,y_test)) #0.933333333333 #沒有規(guī)范化之前我們的訓(xùn)練分?jǐn)?shù)為0.511111111111,規(guī)范化后為0.933333333333,準(zhǔn)確度有很大提升
交叉驗(yàn)證的基本思想是將原始數(shù)據(jù)進(jìn)行分組,一部分做為訓(xùn)練集來訓(xùn)練模型,另一部分做為測試集來評價(jià)模型。交叉驗(yàn)證用于評估模型的預(yù)測性能,尤其是訓(xùn)練好的模型在新數(shù)據(jù)上的表現(xiàn),可以在一定程度上減小過擬合。還可以從有限的數(shù)據(jù)中獲取盡可能多的有效信息。
機(jī)器學(xué)習(xí)任務(wù)中,拿到數(shù)據(jù)后,我們首先會將原始數(shù)據(jù)集分為三部分:訓(xùn)練集、驗(yàn)證集和測試集。 訓(xùn)練集用于訓(xùn)練模型,驗(yàn)證集用于模型的參數(shù)選擇配置,測試集對于模型來說是未知數(shù)據(jù),用于評估模型的泛化能力。不同的劃分會得到不同的最終模型。
以前我們是直接將數(shù)據(jù)分割成70%的訓(xùn)練數(shù)據(jù)和測試數(shù)據(jù),現(xiàn)在我們利用K折交叉驗(yàn)證分割數(shù)據(jù),首先將數(shù)據(jù)分為5組,然后再從5組數(shù)據(jù)之中選擇不同數(shù)據(jù)進(jìn)行訓(xùn)練。
from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier ###引入數(shù)據(jù)### iris=load_iris() X=iris.data y=iris.target ###訓(xùn)練數(shù)據(jù)### X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3) #引入交叉驗(yàn)證,數(shù)據(jù)分為5組進(jìn)行訓(xùn)練 from sklearn.model_selection import cross_val_score knn=KNeighborsClassifier(n_neighbors=5)#選擇鄰近的5個點(diǎn) scores=cross_val_score(knn,X,y,cv=5,scoring='accuracy')#評分方式為accuracy print(scores)#每組的評分結(jié)果 #[ 0.96666667 1. 0.93333333 0.96666667 1. ]5組數(shù)據(jù) print(scores.mean())#平均評分結(jié)果 #0.973333333333
那么是否n_neighbor=5便是好呢,我們來調(diào)整參數(shù)來看模型最終訓(xùn)練分?jǐn)?shù)。
from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import cross_val_score#引入交叉驗(yàn)證 import matplotlib.pyplot as plt ###引入數(shù)據(jù)### iris=datasets.load_iris() X=iris.data y=iris.target ###設(shè)置n_neighbors的值為1到30,通過繪圖來看訓(xùn)練分?jǐn)?shù)### k_range=range(1,31) k_score=[] for k in k_range: knn=KNeighborsClassifier(n_neighbors=k) scores=cross_val_score(knn,X,y,cv=10,scoring='accuracy')#for classfication k_score.append(scores.mean()) plt.figure() plt.plot(k_range,k_score) plt.xlabel('Value of k for KNN') plt.ylabel('CrossValidation accuracy') plt.show() #K過大會帶來過擬合問題,我們可以選擇12-18之間的值
我們可以看到n_neighbor在12-18之間評分比較高,實(shí)際項(xiàng)目之中我們可以通過這種方式來選擇不同參數(shù)。另外我們還可以選擇2-fold Cross Validation
,Leave-One-Out Cross Validation
等方法來分割數(shù)據(jù),比較不同方法和參數(shù)得到最優(yōu)結(jié)果。
我們將上述代碼中的循環(huán)部分改變一下,評分函數(shù)改為neg_mean_squared_error
,便得到對于不同參數(shù)時(shí)的損失函數(shù)。
for k in k_range: knn=KNeighborsClassifier(n_neighbors=k) loss=-cross_val_score(knn,X,y,cv=10,scoring='neg_mean_squared_error')# for regression k_score.append(loss.mean())
什么是過擬合問題呢?例如下面這張圖片,黑色線已經(jīng)可以很好的分類出紅色點(diǎn)和藍(lán)色點(diǎn),但是在機(jī)器學(xué)習(xí)過程中,模型過于糾結(jié)準(zhǔn)確度,便形成了綠色線的結(jié)果。然后在預(yù)測測試數(shù)據(jù)集結(jié)果的過程中往往會浪費(fèi)很多時(shí)間并且準(zhǔn)確率不是太好。
我們先舉例如何辨別overfitting問題。Sklearn.learning_curve中的learning curve可以很直觀的看出Model學(xué)習(xí)的進(jìn)度,對比發(fā)現(xiàn)有沒有過擬合。
from sklearn.model_selection import learning_curve from sklearn.datasets import load_digits from sklearn.svm import SVC import matplotlib.pyplot as plt import numpy as np #引入數(shù)據(jù) digits=load_digits() X=digits.data y=digits.target #train_size表示記錄學(xué)習(xí)過程中的某一步,比如在10%,25%...的過程中記錄一下 train_size,train_loss,test_loss=learning_curve( SVC(gamma=0.1),X,y,cv=10,scoring='neg_mean_squared_error', train_sizes=[0.1,0.25,0.5,0.75,1] ) train_loss_mean=-np.mean(train_loss,axis=1) test_loss_mean=-np.mean(test_loss,axis=1) plt.figure() #將每一步進(jìn)行打印出來 plt.plot(train_size,train_loss_mean,'o-',color='r',label='Training') plt.plot(train_size,test_loss_mean,'o-',color='g',label='Cross-validation') plt.legend('best') plt.show()
如果我們改變gamma的值,那么會改變相應(yīng)的Loss函數(shù)。損失函數(shù)便在10左右停留,此時(shí)便能直觀的看出過擬合。
下面我們通過修改gamma參數(shù)來修正過擬合問題。
from sklearn.model_selection import validation_curve#將learning_curve改為validation_curve from sklearn.datasets import load_digits from sklearn.svm import SVC import matplotlib.pyplot as plt import numpy as np #引入數(shù)據(jù) digits=load_digits() X=digits.data y=digits.target #改變param來觀察Loss函數(shù)情況 param_range=np.logspace(-6,-2.3,5) train_loss,test_loss=validation_curve( SVC(),X,y,param_name='gamma',param_range=param_range,cv=10, scoring='neg_mean_squared_error' ) train_loss_mean=-np.mean(train_loss,axis=1) test_loss_mean=-np.mean(test_loss,axis=1) plt.figure() plt.plot(param_range,train_loss_mean,'o-',color='r',label='Training') plt.plot(param_range,test_loss_mean,'o-',color='g',label='Cross-validation') plt.xlabel('gamma') plt.ylabel('loss') plt.legend(loc='best') plt.show()
通過改變不同的gamma值我們可以看到Loss函數(shù)的變化情況。從圖中可以看到,如果gamma的值大于0.001便會出現(xiàn)過擬合的問題,那么我們構(gòu)建模型時(shí)gamma參數(shù)設(shè)置應(yīng)該小于0.001。
我們花費(fèi)很長時(shí)間用來訓(xùn)練數(shù)據(jù),調(diào)整參數(shù),得到最優(yōu)模型。但如果改變平臺,我們還需要重新訓(xùn)練數(shù)據(jù)和修正參數(shù)來得到模型,將會非常的浪費(fèi)時(shí)間。此時(shí)我們可以先將model保存起來,然后便可以很方便的將模型遷移。
from sklearn import svm from sklearn import datasets #引入和訓(xùn)練數(shù)據(jù) iris=datasets.load_iris() X,y=iris.data,iris.target clf=svm.SVC() clf.fit(X,y) #引入sklearn中自帶的保存模塊 from sklearn.externals import joblib #保存model joblib.dump(clf,'sklearn_save/clf.pkl') #重新加載model,只有保存一次后才能加載model clf3=joblib.load('sklearn_save/clf.pkl') print(clf3.predict(X[0:1])) #存放model能夠更快的獲得以前的結(jié)果
看完上述內(nèi)容,你們掌握如何在Python項(xiàng)目中使用Sklearn的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!