首頁 > 軟體

sklearn 快速入門

2020-06-16 17:12:10

簡介

sklearn自帶了一些標準資料集,用於分類問題的 irisdigits。用於回歸問題的boston房價資料集。

匯入資料集

from sklearn import datasets

 

自帶的資料都放在datasets裡面

iris = datasets.load_iris()
digits = datasets.load_digits()

 

datasets 是dict型別的物件,包含資料和後設資料資訊。資料放在.data裡,標籤放在.target裡。

type(iris.data)

 

numpy.ndarray

.data裡放的是特徵的資訊

print "iris.data.dtype: ",iris.data.dtype
print "iris.data.shape: ",iris.data.shape
print "iris.data.ndim: ",iris.data.ndim
print "--------------------------------"
print iris.data[0:5]

 

iris.data.dtype:  float64
iris.data.shape:  (150, 4)
iris.data.ndim:  2
--------------------------------
[[ 5.1  3.5  1.4  0.2]
 [ 4.9  3.   1.4  0.2]
 [ 4.7  3.2  1.3  0.2]
 [ 4.6  3.1  1.5  0.2]
 [ 5.   3.6  1.4  0.2]]

.target裡放的是標籤資訊

print "iris.target.dtype: ",iris.target.dtype
print "iris.target.shape: ",iris.target.shape
print "iris.target.ndim: ",iris.target.ndim
print "--------------------------------"
print iris.target[0:5]

 

iris.target.dtype:  int64
iris.target.shape:  (150,)
iris.target.ndim:  1
--------------------------------
[0 0 0 0 0]
type(digits)

 

sklearn.datasets.base.Bunch
print "digits.data.dtype: ",digits.data.dtype
print "digits.data.shape: ",digits.data.shape
print "digits.data.ndim: ",digits.data.ndim
print "--------------------------------"
print digits.data[0:5]

 

digits.data.dtype:  float64
digits.data.shape:  (1797, 64)
digits.data.ndim:  2
--------------------------------
[[  0.   0.   5.  13.   9.   1.   0.   0.   0.   0.  13.  15.  10.  15.
    5.   0.   0.   3.  15.   2.   0.  11.   8.   0.   0.   4.  12.   0.
    0.   8.   8.   0.   0.   5.   8.   0.   0.   9.   8.   0.   0.   4.
   11.   0.   1.  12.   7.   0.   0.   2.  14.   5.  10.  12.   0.   0.
    0.   0.   6.  13.  10.   0.   0.   0.]
 [  0.   0.   0.  12.  13.   5.   0.   0.   0.   0.   0.  11.  16.   9.
    0.   0.   0.   0.   3.  15.  16.   6.   0.   0.   0.   7.  15.  16.
   16.   2.   0.   0.   0.   0.   1.  16.  16.   3.   0.   0.   0.   0.
    1.  16.  16.   6.   0.   0.   0.   0.   1.  16.  16.   6.   0.   0.
    0.   0.   0.  11.  16.  10.   0.   0.]
 [  0.   0.   0.   4.  15.  12.   0.   0.   0.   0.   3.  16.  15.  14.
    0.   0.   0.   0.   8.  13.   8.  16.   0.   0.   0.   0.   1.   6.
   15.  11.   0.   0.   0.   1.   8.  13.  15.   1.   0.   0.   0.   9.
   16.  16.   5.   0.   0.   0.   0.   3.  13.  16.  16.  11.   5.   0.
    0.   0.   0.   3.  11.  16.   9.   0.]
 [  0.   0.   7.  15.  13.   1.   0.   0.   0.   8.  13.   6.  15.   4.
    0.   0.   0.   2.   1.  13.  13.   0.   0.   0.   0.   0.   2.  15.
   11.   1.   0.   0.   0.   0.   0.   1.  12.  12.   1.   0.   0.   0.
    0.   0.   1.  10.   8.   0.   0.   0.   8.   4.   5.  14.   9.   0.
    0.   0.   7.  13.  13.   9.   0.   0.]
 [  0.   0.   0.   1.  11.   0.   0.   0.   0.   0.   0.   7.   8.   0.
    0.   0.   0.   0.   1.  13.   6.   2.   2.   0.   0.   0.   7.  15.
    0.   9.   8.   0.   0.   5.  16.  10.   0.  16.   6.   0.   0.   4.
   15.  16.  13.  16.   1.   0.   0.   0.   0.   3.  15.  10.   0.   0.
    0.   0.   0.   2.  16.   4.   0.   0.]]
print "digits.target.dtype: ",digits.target.dtype
print "digits.target.shape: ",digits.target.shape
print "digits.target.ndim: ",digits.target.ndim
print "--------------------------------"
print digits.target[0:5]

 

digits.target.dtype:  int64
digits.target.shape:  (1797,)
digits.target.ndim:  1
--------------------------------
[0 1 2 3 4]

digits是手寫字資料集,可以通過images選擇載入8*8的矩陣圖片

digits.images[1]

 

array([[  0.,   0.,   0.,  12.,  13.,   5.,   0.,   0.],
       [  0.,   0.,   0.,  11.,  16.,   9.,   0.,   0.],
       [  0.,   0.,   3.,  15.,  16.,   6.,   0.,   0.],
       [  0.,   7.,  15.,  16.,  16.,   2.,   0.,   0.],
       [  0.,   0.,   1.,  16.,  16.,   3.,   0.,   0.],
       [  0.,   0.,   1.,  16.,  16.,   6.,   0.,   0.],
       [  0.,   0.,   1.,  16.,  16.,   6.,   0.,   0.],
       [  0.,   0.,   0.,  11.,  16.,  10.,   0.,   0.]])

學習和預測

在scikit-learn裡面,一個分類模型有兩個主要的方法:fit(X,y)和predict(T)

這裡我們用svm做例子,看怎麼使用。

from sklearn import svm
clf = svm.SVC(gamma=0.001,C=100.)

 

選擇模型的引數
在我們這個例子裡面,我們使用手工設定引數,此外還可以使用網格搜尋(grid search)交叉驗證(cross validation)來選擇引數.

現在我們的模型就是 clf。它是一個分類器。現在讓模型可以進行分類任務,先要讓模型學習。這裡就是把訓練資料集放到fit函數裡,這麼把digits資料集最後一個記錄當作test dataset,前面1796個樣本當作training dataset

clf.fit(digits.data[:-1],digits.target[:-1])

 

SVC(C=100.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma=0.001, kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

現在用學習好的模型預測最後一個樣本的標籤

print "prediction: ", clf.predict(digits.data[-1:])
print "actual: ",digits.target[-1:]

 

prediction:  [8]
actual:  [8]

儲存模型

通過pickle來儲存模型

from sklearn import svm
from sklearn import datasets
clf = svm.SVC()
iris = datasets.load_iris()
X, y = iris.data,iris.target
clf.fit(X,y)

 

SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma='auto', kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)

儲存上面的模型

import pickle
s = pickle.dumps(clf)

 

讀取儲存的模型

clf2 = pickle.loads(s)
print "prediction: ",clf2.predict(X[0:1])
print "actual: ",y[0:1]

 

prediction:  [0]
actual:  [0]

此外,可以使用joblib代替pickle(joblib.dump & joblib.load)。joblib對大的資料很有效,但是只能儲存的硬碟,而不是一個string物件裡。

用joblib儲存模型

from sklearn.externals import joblib
joblib.dump(clf,"filename.pkl")

 

['filename.pkl',
 'filename.pkl_01.npy',
 'filename.pkl_02.npy',
 'filename.pkl_03.npy',
 'filename.pkl_04.npy',
 'filename.pkl_05.npy',
 'filename.pkl_06.npy',
 'filename.pkl_07.npy',
 'filename.pkl_08.npy',
 'filename.pkl_09.npy',
 'filename.pkl_10.npy',
 'filename.pkl_11.npy']

讀取joblib儲存的模型

clf3 = joblib.load("filename.pkl")
print "prediction: ",clf3.predict(X[0:1])
print "actual: ",y[0:1]

 

prediction:  [0]
actual:  [0]

注意:

joblib返回一系列的檔名,是因為模型裡面的每一個numpy矩陣都儲存在獨立的檔案裡,並且要在相同的路徑下面,再次讀取的時候才能成功。

協定

sklearn 有如下幾點規則,保證其能正常工作。

型別轉換

除非特別指定,否則都會自動轉換到 float64

import numpy as np
from sklearn import random_projection

rng = np.random.RandomState(0)
X = rng.rand(10,2000)
X = np.array(X,dtype='float32')
X.dtype

 

dtype('float32')
transformer = random_projection.GaussianRandomProjection()
X_new = transformer.fit_transform(X)
X_new.dtype

 

dtype('float64')

X本來是float32型別,通過fit_transform(X)轉換到float64

回歸的結果被轉換成float64,分類的資料型別不變。

from sklearn import datasets
from sklearn.svm import SVC
iris = datasets.load_iris()
clf = SVC()
# 回歸
clf.fit(iris.data, iris.target)  
print u"回歸結果:",list(clf.predict(iris.data[:3]))
# 分類
clf.fit(iris.data, iris.target_names[iris.target]) 
print u"分類結果:",list(clf.predict(iris.data[:3]))

 

回歸結果: [0, 0, 0]
分類結果: ['setosa', 'setosa', 'setosa']

回歸用的是iris.target,分類用的是iris.target_names

重新訓練和更新超引數

模型的超引數在模型訓練完成以後仍然可以更新,通過sklearn.pipeline.Pipeline.set_params方法。多次呼叫fit會覆蓋前面訓練的模型。

import numpy as np
from sklearn.svm import SVC

rng = np.random.RandomState(0)
X = rng.rand(100, 10)
y = rng.binomial(1, 0.5, 100)
X_test = rng.rand(5, 10)

 

clf = SVC()
clf.set_params(kernel="linear").fit(X,y)

 

SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma='auto', kernel='linear',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)
clf.predict(X_test)

 

array([1, 0, 1, 1, 0])
clf.set_params(kernel='rbf').fit(X, y)

 

SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma='auto', kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)
clf.predict(X_test)

 

array([0, 0, 0, 1, 0])

本文永久更新連結地址http://www.linuxidc.com/Linux/2017-06/144940.htm


IT145.com E-mail:sddin#qq.com