網(wǎng)上有很多關于sklearn的學習教程,大部分都是簡單的講清楚某一個方面。其實最好的教程就是官方文檔(http://scikit-learn.org/stable/),本系列筆記試圖系統(tǒng)的介紹sklearn做科學研究和工程項目的基本方法。
本文鏈接:http://www.itdecent.cn/p/3a5a3488dd64
學習資源:
章節(jié)內容
在這個章節(jié)中,我們主要介紹scikit-learn機器學習庫,并且將給出一個學習樣例。
機器學習:問題設置
通常,一個學習問題是通過一系列的n個樣本數(shù)據(jù)來學習然后嘗試預測未知數(shù)據(jù)的屬性。習慣上數(shù)據(jù)以行的形式組織,每行一個樣本的特征,多個樣本逐行堆疊,也就是說一個MxN的矩陣,M是樣本數(shù),N是樣本的特征數(shù)量。
我們可以把學習問題劃分為幾個大的來別:
監(jiān)督學習:
在監(jiān)督學習中,這些數(shù)據(jù)自帶了我們想要預測的附加屬性(scikit-learn監(jiān)督學習鏈接),這個問題包括:
- 分類:樣本屬于屬于兩類或者多類,我們想從已經(jīng)被標記的數(shù)據(jù)中來預測未知數(shù)據(jù)的類別。一個分類問題的例子就是手寫字識別。
- 回歸:如果期望的輸出是由一個或者更多的連續(xù)的變量組成,那么就叫做回歸?;貧w問題的例子將通過一條鮭魚的年齡和重量預測它的長度。
- 無監(jiān)督學習:在無監(jiān)督學習里面,訓練數(shù)據(jù)是由一組沒有任何類別標簽值的一系列輸入向量組成。這種問題的目的是可能可以在這些數(shù)據(jù)里發(fā)現(xiàn)相似的樣例組,這些相似的樣例被稱作聚類?;蛘咴谳斎肟臻g里決定數(shù)據(jù)分布,稱之為密度估計;或者將數(shù)據(jù)從高維空間映射到二維或三維空間中,稱之為數(shù)據(jù)可視化問題。
訓練集和測試集
機器學習是關于學習數(shù)據(jù)集的一些屬性然后將它們應用到新的數(shù)據(jù)上。這就是為什么在機器學習中評價一個算法的通常慣例是把數(shù)據(jù)集切分為兩個數(shù)據(jù)集,其中一個叫做訓練集,用來學習數(shù)據(jù)的屬性;另一個叫做測試集,在測試集上測試那些屬性。
加載樣本數(shù)據(jù)集
scikit-learn帶有一些標準的數(shù)據(jù)集,例如用于分類的iris和digit數(shù)據(jù)集和用于回歸的 boston house prices dataset .
加載IRIS數(shù)據(jù)集
from sklearn import datasets
iris = datasets.load_iris()
加載手寫數(shù)字
from sklearn import datasets
digits = datasets.load_digits()
數(shù)據(jù)集是一個類似字典的對象,包含所有的數(shù)據(jù)和一些和數(shù)據(jù)有關的元數(shù)據(jù)。數(shù)據(jù)存儲在
.data中,是個n_samples, n_features的數(shù)組。在監(jiān)督問題的情況下,一個或多個類別變量存儲在.target成員中。更多有關的不同數(shù)據(jù)集的細節(jié)可以在datasets中查找。
例如,在digits數(shù)據(jù)集情況下,digits.data提供了可用于分類數(shù)字樣本。
>>> print(digits.data)
[[ 0. 0. 5. ..., 0. 0. 0.]
[ 0. 0. 0. ..., 10. 0. 0.]
[ 0. 0. 0. ..., 16. 9. 0.]
...,
[ 0. 0. 1. ..., 6. 0. 0.]
[ 0. 0. 2. ..., 12. 0. 0.]
[ 0. 0. 10. ..., 12. 1. 0.]]
并且digits.target給出了digit數(shù)據(jù)集的真實結果,這些數(shù)字是和我們正在學習的每個數(shù)字圖像相關的數(shù)字。
>>> digits.target
array([0, 1, 2, ..., 8, 9, 8])
數(shù)組的形狀
數(shù)據(jù)總是一些2D數(shù)組,shape(n_samples,n_features),盡管原始數(shù)據(jù)也許有一個不同的形狀,就這個digits而言,每一個原始樣例是一個shape(8,8)的圖像,并且能被訪問使用:
>>> digits.images[0]
array([[ 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.]])
simple example on this dataset 這個數(shù)據(jù)集表明了在scikit-learn中怎樣從原始問題開始著手制作數(shù)據(jù)。
學習和預測
在digits數(shù)據(jù)集中,給定一幅手寫數(shù)字的數(shù)字圖像,任務是預測結果。我們給定的樣本有10種類別(是數(shù)字0到9),基于此我們建立一個估計方法能夠預測我們沒有見過的樣本屬于哪一類。
在scikit-learn中,用于分類的估計模型是一個實現(xiàn)了fit(x,y)方法和predict(T)方法的Python對象。
估計模型的例子是在實現(xiàn)了support vector classification支持向量機的類 sklearn.svm.SVC。估計模型的構造函數(shù)帶有模型參數(shù),但是目前,我們將估計模型當做一個黑盒子。
>>> from sklearn import svm
>>> clf = svm.SVC(gamma=0.001, C=100.)
選擇模型參數(shù)
在這個例子中,我們這設定了gamma值??梢酝ㄟ^使用網(wǎng)格搜索和交叉驗證自動的找出最好的參數(shù)值
我們把我們的評估模型命名為clf,作為一個分類器,它現(xiàn)在必須擬合這個模型,也就是它必須從這個模型學習。我們通過將數(shù)據(jù)集傳遞給fit函數(shù)完成。作為訓練集,除了最后一個樣本,我們選擇其余的所有樣本。通過python語句[:-1]選擇樣本,這條語句將從digits.data中產(chǎn)生一個除了最后一個樣本的新數(shù)組。
clf.fit(digits.data[:-1], digits.target[:-1])
SVC(C=100.0, cache_size=200, class_weight=None, coef0=0.0, degree=3,
gamma=0.001, kernel='rbf', max_iter=-1, probability=False,
random_state=None, shrinking=True, tol=0.001, verbose=False)
現(xiàn)在,我們可以預測新值,尤其是我們可以問分類器在digits數(shù)據(jù)集中的用來訓練分類器時沒有使用的最后一個數(shù)據(jù)是數(shù)字幾:
相應的圖像如下所示:
正如你看到的,這是一個具有挑戰(zhàn)性的任務:圖象的分辨率很低。你認同這個分類器嗎?
一個完整的分類問題實例可以通過下面的鏈接下載,用來作為你運行并且學習的例子 Recognizing hand-written digits
模型持久化
可以通過使用python的built-in持久化模型在scikit中保存一個模型,命名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)
>>> clf2.predict(X[0])
array([0])
>>> y[0]
0
在scikit的特別情況下,使用joblib替換pickle(joblib.dump & joblib.load)會更有趣,它在大數(shù)據(jù)上是更有效的,但是僅僅只能存入的是字典而不是字符串。
>>> from sklearn.externals import joblib
>>> joblib.dump(clf, 'filename.pkl')
然后你就可以讀取上面的pickled模型使用了(通常是在其它的Python程序中):
>>> clf = joblib.load('filename.pkl')