OpenCV-Python教程:60.scikit-learn

機器學習:問題設置

一般的,一個學習問題考慮一個n個樣本集合的數據,然后嘗試預測未知數據的屬性。如果每個樣本都超過一個數,比如是多維度條目。被叫做有多個特征或者屬性。

我們可以把學習問題分成幾個大類:

·監督學習,數據有我們要預測的額外的屬性。問題可以是:

·分類:樣本屬于兩個或更多的類別,我們要從已經標記過的數據學習如果預測未分類數據的類別。一個分類的例子是手寫數字識別,目標是給每個輸入向量分配一個分類的數字。

·回歸:如果期望的輸出包含一個或多個連續變量,任務就被叫做回歸,一個回歸的例子是根據鮭魚的年齡和重量預測它的長度。

·無監督學習,訓練數據不包括任何對應目標值得輸入向量x 的集合組成。這種問題的目標是發現數據里的相似數據的分組,這被叫做聚類。或者是在輸入空間里決定數據的分布,被叫做密度估計。或者從一個高緯度空間投射數據到2維或者3維空以顯示

訓練集合和測試集合

機器學習是關于學習數據集的一些屬性,并應用到其他數據上。這就是為什么機器學習里通常評估算法的方式是把手里的數據拆分成兩個集合,一個我們叫做訓練集,用來學習數據的屬性,另一個叫做測試集,我們用來測試這些屬性。

加載一個數據集

scikit-learn自帶一些標準數據集,比如iris和digits數據集用來做分類,boston house prices dataset用來做回歸。

下面我們啟動一個python解釋器,并加載iris和digits數據集。

$ python

>>> from sklearn import datasets

>>> iris = datasets.load_iris()

>>> digits = datasets.load_digits()

一個數據集是一個字典類的對象,里面有所有的數據還有關于數據的元數據。這些數據存在.data成員里,是n_samples,k n_features 數組,在監督學習問題里,一個或多個相應變量存在.target成員里。

例如,對于digits數據集,digits.data可以訪問用來對數字樣本分類的特征:

>>> 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給出數據集的真實情況。是我們要學習的每個數字圖像對應的數字

>>>digits.target
array([0, 1, 2, ..., 8, 9, 8])

數據數字的形狀

數據都是2D數組,雖然原始數據可能有不同的形狀,在這個數字的例子里,每個原始樣本都是一個8x8的圖像,可以通過下面方式訪問:

>>> 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.]])

學習和預測

在數字數據集的例子里,任務是預測,給定一個圖像,它表示的數字是啥,我們給10個可能的類別(0到9)每個一些樣本來讓我們適配估計量,使之有能力預測未來的樣本的類別。

在scikit-learn里,分類的估計量是一個Python對象,實現了fit(X, y)和predict(T)方法。

估計量的一個例子是sklearn.svm.SVC。實現了支持向量分類。估計量構造函數把模型的參數作為參數

>>> from sklearn import svm

>>> clf = svm.SVC(gamma=0.001, C=100.)

選擇模型參數

我們手動設置gamma的值,如果用類似于grid search或者cross validation這樣的工具可以自動找到好的值。

我們把估計量實例叫clf,因為它是一個分類器,它現在必須適合模型,也就是說必須從模型學習。這個通過給fit方法傳我們的訓練數據實現。作為訓練集合,讓我們使用數據集合里除了最后一個的其他所有圖像。我們使用Python的[:-1]語法,產生一個新的數組,包含除了最后一個之外的digits.data:

>>>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)

現在你可以預測新值了,我們可以問分類器最后一張圖像里的數字是什么

>>>clf.predict(digits.data[-1:])

array([8])

模型持久化

可以用Python內置的持久化模塊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:1])

array([0])

>>> y[0]

0

在scikit的特殊例子里,可以用joblib的替代pickle的工具(joblib.dump和joblib.load)。在大數據上更有效,但是只能保存到磁盤上,而不能到字符串。

>>> from sklearn.externals import joblib

>>> joblib.dump(clf, 'filename.pkl')

之后你可以把pickle了的模型加載回來。

>>>clf=joblib.load('filename.pkl')

注意:joblib.dump返回一個文件列表。clf對象里包含的每個單獨的numpy數組被串行化到文件系統的單獨文件里。當joblib.load加載模型的時候所有文件都需要在同一個目錄里。

慣例

scikit-learn 估計量遵循下屬原則以使其行為更可預測。

type casting

除非另外指明,否則輸入會被轉換到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)

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)

>>> list(clf.predict(iris.data[:3]))

[0, 0, 0]

>>> clf.fit(iris.data, iris.target_names[iris.target])

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)

>>> list(clf.predict(iris.data[:3]))

['setosa', 'setosa', 'setosa']

這里,由于iris.target(整數數組)被fit使用,第一個predict()返回了整數數組,第二個predict返回字符串數組,因為iris.target_names 被調用。

更新參數

估計量的參數可以在構造完以后通過sklearn.pipeline.Pipeline.set_params方法修改。調用fit()會覆蓋之前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])

這里,默認核rbf在通過SVC()構造后被改變為linear,然后變回rbf來重新適應估計量。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,634評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,653評論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,063評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,835評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,235評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,459評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,000評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,819評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,004評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,257評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,676評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,937評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,717評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,003評論 2 374

推薦閱讀更多精彩內容