scikit_learn 中文說明入門

scikit_learn 中文說明入門

原文:http://www.cnblogs.com/taceywong/p/4568806.htmljavascript

原文地址:http://scikit-learn.org/stable/tutorial/basic/tutorial.html
翻譯:Tacey Wongcss


概要
該章節,咱們將介紹貫穿scikit-learn使用中的「機器學習(Machine Learning)」這個詞彙,並給出一些簡單的學習示例。html

1、機器學習:問題設定

一般,一個學習問題是經過分析一些數據樣原本嘗試預測未知數據的屬性。若是每個樣本不只僅是一個單獨的數字,好比一個多維的實例(multivariate data),也就是說有着多個屬性特徵java

咱們能夠把學習問題分紅以下的幾個大類:python

  • (1)有監督學習
    數據帶有咱們要預測的屬性。這種問題主要有以下幾種:nginx

    • ①分類
      樣例屬於兩類或多類,咱們想要從已經帶有標籤的數據學習以預測未帶標籤的數據。識別手寫數字就是一個分類問題,這個問題的主要目標就是把每個輸出指派到一個有限的類別中的一類。另外一種思路去思考分類問題,其實分類問題是有監督學習中的離散形式問題。每個都有一個有限的分類。對於樣例提供的多個標籤,咱們要作的就是把未知類別的數據劃分到其中的一種。git

    • ②迴歸
      去過預期的輸出包含連續的變量,那麼這樣的任務叫作迴歸。根據三文魚的年紀和中聯預測其長度就是一個迴歸樣例。算法

  • (2)無監督學習
    訓練數據包含不帶有目標值的輸入向量x。對於這些問題,目標就是根據數據發現樣本中類似的羣組——聚類。或者在輸入空間中斷定數據的分佈——密度估計,或者把數據從高維空間轉換到低維空間以用於可視化shell

訓練集和測試集
機器學習是學習一些數據集的特徵屬性並將其應用於新的數據。這就是爲何在機器學習用來評估算法時通常把手中的數據分紅兩部分。一部分咱們稱之爲訓練集,用以學習數據的特徵屬性。一部分咱們稱之爲測試集,用以檢驗學習到的特徵屬性。數組

2、加載一個樣本數據集

scikit-learn帶有一些標準數據集。好比用來分類的iris數據集、digits數據集;用來回歸的boston house price 數據集。

接下來,咱們咱們從shell開啓一個Python解釋器並加載iris和digits兩個數據集。【譯註:一些代碼慣例就不寫了,提示符>>>之類的學過Python的都懂】

$ python
>>>from sklearn import datasets >>>iris = datasets.load_iris() >>>digits = datasets.load_digits()

一個數據集是一個包含數據全部元數據的類字典對象。這個數據存儲在 '.data'成員變量中,是一個nnn∗n的數組,行表示樣例,列表示特徵。在有監督學習問題中,一個或多個響應變量(Y)存儲在‘.target’成員變量中。不一樣數據集的更多細節能夠在dedicated section中找到。

例如,對於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])

數據數組的形狀
儘管原始數據也許有不一樣的形狀,但實際使用的數據一般是一個二維數組(n個樣例,n個特徵)。對於數字數據集,每個原始的樣例是一張(8 x 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.]])

3、學習和預測

對於數字數據集(digits dataset),任務是預測一張圖片中的數字是什麼。數字數據集提供了0-9每個數字的可能樣例,能夠用它們來對位置的數字圖片進行擬合分類。

在scikit-learn中,用以分類的擬合(評估)函數是一個Python對象,具體有fit(X,Y)和predic(T)兩種成員方法。

其中一個擬合(評估)樣例是sklearn.svmSVC類,它實現了支持向量分類(SVC)。一個擬合(評估)函數的構造函數須要模型的參數,可是時間問題,咱們將會把這個擬合(評估)函數做爲一個黑箱:

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

選擇模型參數
咱們調用擬合(估測)實例clf做爲咱們的分類器。它如今必需要擬合模型,也就是說,他必需要學習模型。這能夠經過把咱們的訓練集傳遞給fit方法。做爲訓練集,咱們使用其中除最後一組的全部圖像。咱們能夠經過Python的分片語法[:-1]來選取訓練集,這個操做將產生一個新數組,這個數組包含digits.dataz中除最後一組數據的全部實例。

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

如今你能夠預測新的數值了。咱們可讓這個訓練器告訴咱們digits數據集咱們沒有做爲訓練數據使用的最後一張圖像是什麼數字。

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

相應的圖片以下圖:

正如你所看到的,這是一個頗有挑戰的任務:這張圖片的分辨率很低。你贊成分類器給出的答案嗎?

這個分類問題的完整示例在這裏識別手寫數字,你能夠運行並使用它。[譯:看本文附錄]

4、模型持久化

可使用Python的自帶模塊——pickle來保存scikit中的模型:

>>>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, degree=3, gamma=0.0, 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)更有趣。由於它在處理帶數據時更高效。可是遺憾的是它只能把數據持久化到硬盤而不是一個字符串(譯註:搬到string字符串意味着數據在內存中):

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

日後你就能夠加載這個轉儲的模型(也能在另外一個Python進程中使用),以下:

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

注意
joblib.dump返回一個文件名的列表,每個numpy數組元素包含一個clf在文件系統上的名字,在用joblib.load加載的時候全部的文件須要在相同的文件夾下

注意pickle有一些安全和可維護方面的問題。請參考Model persistent 得到在scikit-learn中模型持久化的細節。

5、慣例約定

scikit-learn的各類擬合(評估)函數遵循一些肯定的規則以使得他們的用法可以被預想到(譯:使得各類學習方法的用法統一塊兒來)

  • ①類型轉換

    除非特別指定,輸入將被轉換爲float64

    import numpy from sklearn import random_projection rng = np.random.RandomState(0) X = rng.rand(10,2000) X = np.array(X,dtype ='float32') print x.dtype transformer = random_projection.GaussianRandomProjection() X_new = transformer.fit_transform(X) print X_new.dtype

    在這個例子中,X是float32,被fit_transform(X)轉換成float64,迴歸被轉換成float64,分類目標維持不變.

from sklearn import datesets from sklearn.svm import SVC iris = datasets.load_iris() clf =SVC() clf.fit(iris.data,iris.target) print list(clf.predict(iris.data[:3])) clf.fit(iris.data,iris.target_names[iris.target]) print list(clf.predict(iris.data[:3]))

這裏第一個predict()返回一個整數數組,是由於iris.target(一個整數數組)被用於擬合。第二個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) clf.predict(X_test) clf.set_params(kernel='rbf').fit(X,Y) clf.predict(X_test) 

    這裏,用SVC()構造以後,開始擬合(評估)函數默認的'rbf'核被改編成'linear',後來又改回'rbf'去重擬合作第二次的預測。

附:

  • ①digits數據集:一個展現怎樣用scikit-learn識別手寫數字的樣例:繪製數字:

    # Code source: Gaël Varoquaux # Modified for documentation by Jaques Grobler # License: BSD 3 clause from sklearn import datasets import matplotlib.pyplot as plt #Load the digits dataset digits = datasets.load_digits() #Display the first digit plt.figure(1, figsize=(3, 3)) plt.imshow(digits.images[-1], cmap=plt.cm.gray_r, interpolation='nearest') plt.show()
  • ②繪製數字分類 (plot_digits_classification.py)

    # Author: Gael Varoquaux <gael dot varoquaux at normalesup dot org> # License: BSD 3 clause # Standard scientific Python imports import matplotlib.pyplot as plt # Import datasets, classifiers and performance metrics from sklearn import datasets, svm, metrics # The digits dataset digits = datasets.load_digits() # The data that we are interested in is made of 8x8 images of digits, let's # have a look at the first 3 images, stored in the `images` attribute of the # dataset. If we were working from image files, we could load them using # pylab.imread. Note that each image must have the same size. For these # images, we know which digit they represent: it is given in the 'target' of # the dataset. images_and_labels = list(zip(digits.images, digits.target)) for index, (image, label) in enumerate(images_and_labels[:4]): plt.subplot(2, 4, index + 1) plt.axis('off') plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest') plt.title('Training: %i' % label) # To apply a classifier on this data, we need to flatten the image, to # turn the data in a (samples, feature) matrix: n_samples = len(digits.images) data = digits.images.reshape((n_samples, -1)) # Create a classifier: a support vector classifier classifier = svm.SVC(gamma=0.001) # We learn the digits on the first half of the digits classifier.fit(data[:n_samples / 2], digits.target[:n_samples / 2]) # Now predict the value of the digit on the second half: expected = digits.target[n_samples / 2:] predicted = classifier.predict(data[n_samples / 2:]) print("Classification report for classifier %s:\n%s\n" % (classifier, metrics.classification_report(expected, predicted))) print("Confusion matrix:\n%s" % metrics.confusion_matrix(expected, predicted)) images_and_predictions = list(zip(digits.images[n_samples / 2:], predicted)) for index, (image, prediction) in enumerate(images_and_predictions[:4]): plt.subplot(2, 4, index + 5) plt.axis('off') plt.imshow(image, cmap=plt.cm.gray_r, interpolation='nearest') plt.title('Prediction: %i' % prediction) plt.show()

[譯]針對科學數據處理的統計學習教程(scikit-learn官方教程2)

 

#針對科學數據處理的統計學習教程

翻譯:Tacey Wong

統計學習
隨着科學實驗數據的迅速增加,機器學習成了一種愈來愈重要的技術。問題從構建一個預測函數將不一樣的觀察數據聯繫起來,到將觀測數據分類,或者從未標記數據中學習到一些結構。
本教程將探索機器學習中統計推理的統計學習的使用:將手中的數據作出結論
Scikit-learn 是一個緊密結合Python科學計算庫(Numpy、Scipy、matplotlib),集成經典機器學習算法的Python模塊。

1、統計學習:scikit-learn中的設置與評估函數對象

(1)數據集

scikit-learn 從二維數組描述的數據中學習信息。他們能夠被理解成多維觀測數據的列表。如(n,m),n表示樣例軸,y表示特徵軸。

使用scikit-learn裝載一個簡單的樣例:iris數據集

>>from sklearn import datasets >>iris = datasets.load_iris() >>data = iris.data >>data.shape (150, 4)

它有150個iris觀測數據構成,每個樣例被四個特徵所描述:他們的萼片、花瓣長度、花瓣寬度,具體的信息能夠經過iris》DESCR查看。

當數據初始時不是(n樣例,n特徵)樣式時,須要將其預處理以被scikit-learn使用。

經過數字數據集講述數據變形
數字數據集由1797個8x8手寫數字圖片組成

>>>digits = datasets.load_digits()
>>>digits.images.shape
(1797, 8, 8) >>> import pylab as pl >>>pl.imshow(digits.images[-1], cmap=pl.cm.gray_r) <matplotlib.image.AxesImage object at ...>


在scikit-learn中使用這個數據集,咱們須要將其每個8x8圖片轉換成長64的特徵向量

python >>>data = digits.images.reshape((digits.images.shape[0],-1)) 

(2)估計函數對象

擬合數據:scikit-learn實現的主要API是估計函數。估計函數是用以從數據中學習的對象。它多是分類、迴歸、聚類算法,或者提取過濾數據特徵的轉換器。

一個估計函數帶有一個fit方法,以dataset做爲參數(通常是個二維數組)

>>>estimator.fit(data)

估計函數對象的參數:每個估測器對象在實例化或者修改其相應的屬性,其參數都會被設置。

>>>estimator = Estimator(param1=1, param2=2) >>>estimator.param1 1

估測後的參數

>>>estimator.estimated_param_

2、有監督學習:從高維觀察數據預測輸出變量

有監督學習解決的問題
有監督學習主要是學習將兩個數據集聯繫起來:觀察數據x和咱們要嘗試預測的外置變量y,y一般也被稱做目標、標籤。多數狀況下,y是一個和n個觀測樣例對應的一維數組。
scikit-learn中實現的全部有監督學習評估對象,都有fit(X,Y)方法來擬合模型,predict(X)方法根據未加標籤的觀測數據X
返回預測的標籤y。

詞彙:分類和迴歸
若是預測任務是將觀測數據分類到一個有限的類別集中,換句話說,給觀測對象命名,那麼這個任務被稱做分類任務。另外一方面,若是任務的目標是預測測目標是一個連續性變量,那麼這個任務成爲迴歸任務。
用scikit-learn解決分類問題時,y是一個整數或字符串組成的向量
注意:查看[]快速瞭解用scikit-learn解決機器學習問題過程當中的基礎詞彙。

(1)近鄰和高維災難

iris分類
iris分類是根據花瓣、萼片長度、萼片寬度來識別三種不一樣類型的iris的分類任務:

>> import numpy as np >> from sklearn import datasets >> iris = datasets.load_iris() >> iris_X = iris.data >> iris_y = iris.target >> np.unique(iris_y) array([0, 1, 2])

最近鄰分類器
近鄰也許是最簡的分類器:獲得一個新的觀測數據X-test,從訓練集的觀測數據中尋找特徵最相近的向量。(【】)

訓練集和測試集
當嘗試任何學習算法的時候,評估一個學習算法 的預測精度是很重要的。因此在作機器學習相關的問題的時候,一般將數據集分紅訓練集和測試集。

KNN(最近鄰)分類示例

# Split iris data in train and test data # A random permutation, to split the data randomly np.random.seed(0) indices = np.random.permutation(len(iris_X)) iris_X_train = iris_X[indices[:-10]] iris_y_train = iris_y[indices[:-10]] iris_X_test = iris_X[indices[-10:]] iris_y_test = iris_y[indices[-10:]] # Create and fit a nearest-neighbor classifier from sklearn.neighbors import KNeighborsClassifier knn = KNeighborsClassifier() knn.fit(iris_X_train, iris_y_train) knn.predict(iris_X_test) iris_y_test

高維災難
對於一個有效的學習算法,你須要最近n個點之間的距離d(依賴於具體的問題)。在一維空間中,須要平局n1/d各點,在上文中提到的K-NN例子中,若是數據只是有一個0-1之間的特徵和n個訓練觀測數據所表述的畫,那麼新數據將不會超過1/n。所以,最近鄰決策規則很是高效,由於與類間特徵變化的範圍相比,1/n小的多。

若是特徵數是P,你就須要n 1/d^p個點。也就是說,若是咱們在一維度狀況下須要10個點,在P維度狀況下須要10^p個點。當P變大的時候,爲得到一個好的預測函數須要的點數將急劇增加。

這被稱爲高維災難(指數級增加),也是機器學習領域的一個核心問題。

(2)線性模型:從迴歸到稀疏性

Diabets數據集(糖尿病數據集)
糖尿病數據集包含442個患者的10個生理特徵(年齡,性別、體重、血壓)和一年之後疾病級數指標。

diabetes = datasets.load_diabetes()
diabetes_X_train = diabetes.data[:-20]
diabetes_X_test = diabetes.data[-20:]
diabetes_y_train = diabetes.target[:-20]
diabetes_y_test = diabetes.target[-20:]
手上的任務是從生理特徵預測疾病級數
線性迴歸:
【線性迴歸】的最簡單形式給數據集擬合一個線性模型,主要是經過調整一系列的參以使得模型的殘差平方和儘可能小。

線性模型:y = βX+b  X:數據 y:目標變量 β:迴歸係數  b:觀測噪聲(bias,誤差)
from sklearn import linear_model regr = linear_model.LinearRegression() regr.fit(diabetes_X_train, diabetes_y_train) print(regr.coef_) # The mean square error np.mean((regr.predict(diabetes_X_test)-diabetes_y_test)**2) # Explained variance score: 1 is perfect prediction # and 0 means that there is no linear relationship # between X and Y. regr.score(diabetes_X_test, diabetes_y_test) 

收縮(Shrinkage)
若是每一維的數據點不多,噪聲將會形成很大的誤差影響:

X = np.c_[ .5, 1].T y = [.5, 1] test = np.c_[ 0, 2].T regr = linear_model.LinearRegression() import pylab as pl pl.figure() np.random.seed(0) for _ in range(6): this_X = .1*np.random.normal(size=(2, 1)) + X regr.fit(this_X, y) pl.plot(test, regr.predict(test)) pl.scatter(this_X, y, s=3) 

高維統計學習的一個解決方案是將回歸係數縮小到0:觀測數據中隨機選擇的兩個數據集近似不相關。這被稱爲嶺迴歸(Ridge Regression):

regr = linear_model.Ridge(alpha=.1) pl.figure() np.random.seed(0) for _ in range(6): this_X = .1*np.random.normal(size=(2, 1)) + X regr.fit(this_X, y) pl.plot(test, regr.predict(test)) pl.scatter(this_X, y, s=3) 

這是一個誤差/方差(bias/variance)的權衡:嶺α參數越大,誤差(bias)越大,方差(variance)越小

咱們能夠選擇α以最小化排除錯誤,這裏使用糖尿病數據集而不是人爲製造的數據:

alphas = np.logspace(-4, -1, 6) from __future__ import print_function print([regr.set_params(alpha=alpha ).fit(diabetes_X_train, diabetes_y_train, ).score(diabetes_X_test, diabetes_y_test) for alpha in alphas]) 

【注意】撲捉擬合參數的噪聲使得模型不能推廣到新的數據被稱爲過擬合。嶺迴歸形成的誤差被稱爲正則化(歸整化,regularization)

稀疏性
只擬合特徵1和特徵2:

【注意】整個糖尿病數據包含11維數據(10個特徵維,一個目標變量),很難對這樣的數據直觀地表現出來,可是記住那是一個很空的空間也許是有用的。

咱們能夠看到,儘管特徵2在整個模型中佔據很大的係數,可是和特徵1相比,對結果y形成的影響很小。

爲了提高問題的情況(考慮到高維災難),只選擇信息含量較大的(對結果y形成的影響較大的)的特徵,不選擇信息含量較小的特徵會頗有趣,如把特徵2的係數調到0.嶺迴歸將會減小信息含量較小的係數的值,而不是把它們設置爲0.另外一種抑制措施——Lasso(最小絕對收縮和選擇算子)可使得一些參數爲0.這些方法被稱做稀疏方法。係數操做能夠看做是奧卡姆的剃刀:模型越簡單越好。

regr = linear_model.Lasso()
scores = [regr.set_params(alpha=alpha
            ).fit(diabetes_X_train, diabetes_y_train
            ).score(diabetes_X_test, diabetes_y_test)
       for alpha in alphas] best_alpha = alphas[scores.index(max(scores))] regr.alpha = best_alpha regr.fit(diabetes_X_train, diabetes_y_train) print(regr.coef_)

針對相同問題的不一樣算法:
不一樣的算法能夠被用來解決相同的數學問題。例如scikit-learn中的Lasso對象使用coordinate decent方法解決lasso迴歸問題,在大數據集上是頗有效的。然而,scikit-learn也使用LARS算法提供了LassoLars對象,對於處理權重向量很是稀疏的數據很是有效(數據的觀測實例很是少)。

  • 分類:
    對於分類問題,好比iris標定任務,線性迴歸不是正確的方法。由於它會給數據得出大量遠離決策邊界的權重。一個線性方法是你和一個sigmoid函數或者logistic函數:
logistic = linear_model.LogisticRegression(C=1e5) logistic.fit(iris_X_train, iris_y_train)

這就是有名的logistic迴歸

  • 多分類:
    若是你有多個類別須要預測,一個可行的方法是 「一對多」分類,接着根據投票決定最終的決策。

經過Logistic迴歸進行收縮和稀疏

在LogisticRegression對象中C參數控制着正則化的數量:C越大,正則化數目越少。penalty= "12" 提供收縮(非稀疏化係數),penalty="11"提供稀疏化。

練習
嘗試使用近鄰算法和線性模型對數字數據集進行分類。留出最後的10%做爲測試集用來測試預測的精確度。

from sklearn import datasets, neighbors, linear_model digits = datasets.load_digits() X_digits = digits.data y_digits = digits.target

【完整代碼】

from sklearn import datasets, neighbors, linear_model digits = datasets.load_digits() X_digits = digits.data y_digits = digits.target n_samples = len(X_digits) X_train = X_digits[:.9 * n_samples] y_train = y_digits[:.9 * n_samples] X_test = X_digits[.9 * n_samples:] y_test = y_digits[.9 * n_samples:] knn = neighbors.KNeighborsClassifier() logistic = linear_model.LogisticRegression() print('KNN score: %f' % knn.fit(X_train, y_train).score(X_test, y_test)) print('LogisticRegression score: %f' % logistic.fit(X_train, y_train).score(X_test, y_test))

(3)支持向量機(SVMs)

線性SVNs
支持向量機屬於判別模型家族:它們嘗試尋找樣例的一個組合,構建一個兩類之間的最大邊緣平面。經過C參數進行正則化:一個較小的C意味着邊緣是經過分割線周圍的全部觀測樣例進行計算獲得的(更規整化,正則化);一個較大的C意味着邊緣是經過鄰近分割線的觀測樣例計算獲得的(更少的規整化,正則化):

  • 非正則化SVN:

  • 正則化 SVM(默認):

樣例:Plot different SVM分類器 iris數據集

SVMs可以被用於迴歸——SVR(支持向量迴歸)—用於分類——SVC(支持向量分類)
from sklearn import svm
svc = svm.SVC(kernel='linear')
svc.fit(iris_X_train, iris_y_train)
【警告】:規格化數據
對於大多數的估測模型,包括SVMs,處理好單位標準誤差對於得到一個好的預測是很重要的。

使用核函數:
在特徵空間中類別不常常是線性可分的。解決方案是構建一個非線性但能用多項式代替的決策函數。這要經過核技巧實現:使用核能夠被看做經過設置核在觀測樣例上建立決策力量。

  • 線性核:

  • 多項式核:

  • 徑向基函數核(RBF,Radial Basis Function):

svc = svm.SVC(kernel='rbf')

交互式樣例:
參照SVM GUI,下載svm_gui.py;經過鼠標左右鍵設置兩類數據點,擬合模型並改變參數和數據。

練習:

嘗試使用SVMs根據iris數據集前兩個特徵將其分紅兩類。留出每一類的10%做爲測試樣例。
【警告】數據集中的數據是按照分類順序排列的,不要留出最後的10%做爲測試樣例,要否則你只能測試一種類別。(獲取訓練集和測試集是注意要進行混淆)
提示:你能夠在一個網格上使用decision_function方法得到直觀的呈現。

iris = datasets.load_iris()
X = iris.data
y = iris.target
X = X[y != 0, :2] y = y[y != 0]

完整代碼:

""" ================================ SVM Exercise ================================ A tutorial exercise for using different SVM kernels. This exercise is used in the :ref:`using_kernels_tut` part of the :ref:`supervised_learning_tut` section of the :ref:`stat_learn_tut_index`. """ print(__doc__) import numpy as np import matplotlib.pyplot as plt from sklearn import datasets, svm iris = datasets.load_iris() X = iris.data y = iris.target X = X[y != 0, :2] y = y[y != 0] n_sample = len(X) np.random.seed(0) order = np.random.permutation(n_sample) X = X[order] y = y[order].astype(np.float) X_train = X[:.9 * n_sample] y_train = y[:.9 * n_sample] X_test = X[.9 * n_sample:] y_test = y[.9 * n_sample:] # fit the model for fig_num, kernel in enumerate(('linear', 'rbf', 'poly')): clf = svm.SVC(kernel=kernel, gamma=10) clf.fit(X_train, y_train) plt.figure(fig_num) plt.clf() plt.scatter(X[:, 0], X[:, 1], c=y, zorder=10, cmap=plt.cm.Paired) # Circle out the test data plt.scatter(X_test[:, 0], X_test[:, 1], s=80, facecolors='none', zorder=10) plt.axis('tight') x_min = X[:, 0].min() x_max = X[:, 0].max() y_min = X[:, 1].min() y_max = X[:, 1].max() XX, YY = np.mgrid[x_min:x_max:200j, y_min:y_max:200j] Z = clf.decision_function(np.c_[XX.ravel(), YY.ravel()]) # Put the result into a color plot Z = Z.reshape(XX.shape) plt.pcolormesh(XX, YY, Z > 0, cmap=plt.cm.Paired) plt.contour(XX, YY, Z, colors=['k', 'k', 'k'], linestyles=['--', '-', '--'], levels=[-.5, 0, .5]) plt.title(kernel) plt.show()

3、模型選擇:選擇模型和他們的參數

(1)分數,和交叉驗證分數

衆所周知,每個模型會得出一個score方法用於裁決模型在新的數據上擬合的質量。其值越大越好。

from sklearn import datasets, svm digits = datasets.load_digits() X_digits = digits.data y_digits = digits.target svc = svm.SVC(C=1, kernel='linear') svc.fit(X_digits[:-100], y_digits[:-100]).score(X_digits[-100:], y_digits[-100:])

爲了得到一個更好的預測精確度度量,咱們能夠把咱們使用的數據摺疊交錯地分紅訓練集和測試集:

import numpy as np X_folds = np.array_split(X_digits, 3) y_folds = np.array_split(y_digits, 3) scores = list() for k in range(3): # We use 'list' to copy, in order to 'pop' later on X_train = list(X_folds) X_test = X_train.pop(k) X_train = np.concatenate(X_train) y_train = list(y_folds) y_test = y_train.pop(k) y_train = np.concatenate(y_train) scores.append(svc.fit(X_train, y_train).score(X_test, y_test)) print(scores)

這被稱爲KFold交叉驗證

(2)交叉驗證生成器

上面將數據劃分爲訓練集和測試集的代碼寫起來非常沉悶乏味。scikit-learn爲此自帶了交叉驗證生成器以生成目錄列表:
from sklearn import cross_validation k_fold = cross_validation.KFold(n=6, n_folds=3) for train_indices, test_indices in k_fold: print('Train: %s | test: %s' % (train_indices, test_indices))

接着交叉驗證就能夠很容易實現了:

kfold = cross_validation.KFold(len(X_digits), n_folds=3) [svc.fit(X_digits[train], y_digits[train]).score(X_digits[test], y_digits[test]) for train, test in kfold]

爲了計算一個模型的score,scikit-learn自帶了一個幫助函數:

cross_validation.cross_val_score(svc, X_digits, y_digits, cv=kfold, n_jobs=-1)

n_jobs=-1意味着將計算任務分派個計算機的全部CPU.

交叉驗證生成器:
KFold(n,k) 交叉分割,K-1上進行訓練,生於數據樣例用於測試
StratifiedKFold(y,K) 保存每個fold的類比率/標籤分佈
leaveOneOut(n) 至預留一個觀測樣例
leaveOneLabelOut(labels) 採用一個標籤數組把觀測樣例分組

練習:
使用digits數據集,繪製使用線性核的SVC進行交叉驗證的分數(使用對數座標軸,1——10)

import numpy as np from sklearn import cross_validation, datasets, svm digits = datasets.load_digits() X = digits.data y = digits.target svc = svm.SVC(kernel='linear') C_s = np.logspace(-10, 0, 10)

完整代碼:

 
    

(3)網格搜索和交叉驗證模型

網格搜索:
scikit-learn提供一個對象,他獲得數據能夠在採用一個參數的模型擬合過程當中選擇使得交叉驗證分數最高的參數。該對象的構造函數須要一個模型做爲參數:

from sklearn.grid_search import GridSearchCV Cs = np.logspace(-6, -1, 10) clf = GridSearchCV(estimator=svc, param_grid=dict(C=Cs), n_jobs=-1) clf.fit(X_digits[:1000], y_digits[:1000]) clf.best_score_ clf.best_estimator_.C # Prediction performance on test set is not as good as on train set clf.score(X_digits[1000:], y_digits[1000:]) 

默認狀況下,GridSearchCV使用3-fold交叉驗證。然而,當他探測到是一個分類器而不是迴歸量,將會採用分層的3-fold
嵌套 交叉驗證

cross_validation.cross_val_score(clf, X_digits, y_digits)

兩個交叉驗證循環是並行執行的:一個GridSearchCV模型設置gamma,另外一個使用cross_val_score 度量模型的預測表現。結果分數是在新數據預測分數的無誤差估測。

【警告】你不能在並行計算時嵌套對象(n_jobs不一樣於1)

交叉驗證估測:
在算法by算法的基礎上使用交叉驗證去設置參數更高效。這也是爲何對於一個特定的模型/估測器引入Cross-validation:評估估測器表現模型去自動的經過交叉驗證設置參數。

from sklearn import linear_model, datasets lasso = linear_model.LassoCV() diabetes = datasets.load_diabetes() X_diabetes = diabetes.data y_diabetes = diabetes.target lasso.fit(X_diabetes, y_diabetes) # The estimator chose automatically its lambda: lasso.alpha_ 

這些模型的稱呼和他們的對應模型很類似,只是在他們模型名字的後面加上了'CV'.

練習:
使用糖尿病數據集,尋找最佳的正則化參數α

  • 附加:你對選擇的α值信任度有多高?

    from sklearn import cross_validation, datasets, linear_model diabetes = datasets.load_diabetes() X = diabetes.data[:150] y = diabetes.target[:150] lasso = linear_model.Lasso() alphas = np.logspace(-4, -.5, 30)

    完整代碼:
    ```python

```

4、無監督學習:尋找數據的表明

(1)聚類:將觀測樣例彙集到一塊兒

聚類解決的問題:
好比對於iris數據集,若是咱們知道咱們知道有三種iris,可是咱們沒有標籤標定他們:咱們能夠嘗試聚類任務:將觀測樣例分紅分離的族羣中,這些族羣能夠被稱爲簇。

  • K-mean聚類(K均值聚類)
    注意存在不少不一樣的聚類標準和關聯算法。最簡的聚類算法是——K均值(K-means)
from sklearn import cluster, datasets iris = datasets.load_iris() X_iris = iris.data y_iris = iris.target k_means = cluster.KMeans(n_clusters=3) k_means.fit(X_iris) print(k_means.labels_[::10]) print(y_iris[::10])

注意:沒有絕對的保證可以恢復真實的分類。首先,儘管scikit-learn使用不少技巧來緩和問題的難度,但選擇簇的個數仍是是很困難的,初始狀態下算法是很敏感的,可能會陷入局部最小。
很差的初始狀態:

8個簇:

真實狀況:

不要「過解釋」聚類結果

應用實例:矢量化
K-means和通常的聚類,能夠看做是選擇少許的示例壓縮信息的方式。這個問題被稱之爲矢量化。例如,這能夠被用於分離一個圖像:

import scipy as sp try: lena = sp.lena() except AttributeError: from scipy import misc lena = misc.lena() X = lena.reshape((-1, 1)) # We need an (n_sample, n_feature) array k_means = cluster.KMeans(n_clusters=5, n_init=1) k_means.fit(X) values = k_means.cluster_centers_.squeeze() labels = k_means.labels_ lena_compressed = np.choose(labels, values) lena_compressed.shape = lena.shape

原始圖像:

K-means矢量化:

等段:(Equal bins)

圖像直方圖:

  • 分層凝聚聚類:Ward
    分層聚類方法是一種針對構建一個簇的分層的簇分析。一般它的實現方式有如下兩種:

    • 凝聚:自下而上的方法:每個觀測樣例開始於他本身的簇,以一種最小鏈接標準迭代合併。這種方法在觀測樣例較少的狀況下很是有效(有趣)。當簇的數量變大時,計算效率比K-means高的多。
    • 分裂:自上而下的方法:全部的觀測樣例開始於同一個簇。迭代的進行分層。對於預計簇不少的狀況,這種方法既慢(因爲全部的觀測樣例做爲一個簇開始的,是遞歸進行分離的)又有統計學行的病態。
  • 連同-驅使聚類(Conectivity-constrained clustering)
    使用凝聚聚類,經過一個連通圖能夠指定某些樣例能被彙集在一塊兒。scikit-learn中的圖經過鄰接矩陣來表示,且一般是一個稀疏矩陣。例如,在聚類一張圖片時檢索連通區域(有時也被稱做連同單元、部件):

    from sklearn.feature_extraction.image import grid_to_graph from sklearn.cluster import AgglomerativeClustering ############################################################################### # Generate data lena = sp.misc.lena() # Downsample the image by a factor of 4 lena = lena[::2, ::2] + lena[1::2, ::2] + lena[::2, 1::2] + lena[1::2, 1::2] X = np.reshape(lena, (-1, 1)) ############################################################################### # Define the structure A of the data. Pixels connected to their neighbors. connectivity = grid_to_graph(*lena.shape) ############################################################################### # Compute clustering print("Compute structured hierarchical clustering...") st = time.time() n_clusters = 15 # number of regions ward = AgglomerativeClustering(n_clusters=n_clusters, linkage='ward', connectivity=connectivity).fit(X) label = np.reshape(ward.labels_, lena.shape) print("Elapsed time: ", time.time() - st) print("Number of pixels: ", label.size) print("Number of clusters: ", np.unique(label).size)

特徵凝聚:
咱們已經知道稀疏性能夠緩和高維災難。i.e相對於特徵數量觀測樣例數量不足的狀況。另外一種方法是合併類似的特徵:特徵凝聚。這種方法經過在特徵方向上進行聚類實現。在特徵方向上聚類也能夠理解爲聚合轉置的數據。

digits = datasets.load_digits()
images = digits.images
X = np.reshape(images, (len(images), -1)) connectivity = grid_to_graph(*images[0].shape) agglo = cluster.FeatureAgglomeration(connectivity=connectivity, n_clusters=32) agglo.fit(X) X_reduced = agglo.transform(X) X_approx = agglo.inverse_transform(X_reduced) images_approx = np.reshape(X_approx, images.shape)

transeform 和invers_transeform方法
有些模型帶有轉置方法。例如用來下降數據集的維度

(2)分解:從一個信號到成分和加載

成分及其加載:
若是X是咱們的多變量數據,那麼咱們要要嘗試解決的問題就是在不一樣的觀測樣例上覆寫寫它:咱們想要學習加載L和其它一系列的成分C,如X = LC。存在不一樣的標準和條件去選擇成分。

  • 主成分分析:PCA
    主成分分析(PCA)選擇在信號上解釋極大方差的連續成分。

上面觀測樣例的點分佈在一個方向上是很是平坦的:三個特徵單變量的一個甚至能夠有其餘兩個準確的計算出來。PCA用來發現數據在哪一個方向上是不平坦的。

當被用來轉換數據的時候,PCA能夠經過投射到一個主子空間來下降數據的維度。:

# Create a signal with only 2 useful dimensions x1 = np.random.normal(size=100) x2 = np.random.normal(size=100) x3 = x1 + x2 X = np.c_[x1, x2, x3] from sklearn import decomposition pca = decomposition.PCA() pca.fit(X) print(pca.explained_variance_) # As we can see, only the 2 first components are useful pca.n_components = 2 X_reduced = pca.fit_transform(X) X_reduced.shape
  • 獨立成分分析:ICA
    獨立成分分析(ICA)選擇合適的成分使得他們的分佈載有最大的獨立信息量。能夠恢復非高斯獨立信號:

    # Generate sample data time = np.linspace(0, 10, 2000) s1 = np.sin(2 * time) # Signal 1 : sinusoidal signal s2 = np.sign(np.sin(3 * time)) # Signal 2 : square signal S = np.c_[s1, s2] S += 0.2 * np.random.normal(size=S.shape) # Add noise S /= S.std(axis=0) # Standardize data # Mix data A = np.array([[1, 1], [0.5, 2]]) # Mixing matrix X = np.dot(S, A.T) # Generate observations # Compute ICA ica = decomposition.FastICA() S_ = ica.fit_transform(X) # Get the estimated sources A_ = ica.mixing_.T np.allclose(X, np.dot(S_, A_) + ica.mean_)

5、聯合起來

(1)管道(流水線)

咱們已經知道了一些估測器(模型)可以轉換數據,一些能夠預測變量。咱們也可以將其結合到一塊兒:

from sklearn import linear_model, decomposition, datasets from sklearn.pipeline import Pipeline from sklearn.grid_search import GridSearchCV logistic = linear_model.LogisticRegression() pca = decomposition.PCA() pipe = Pipeline(steps=[('pca', pca), ('logistic', logistic)]) digits = datasets.load_digits() X_digits = digits.data y_digits = digits.target ############################################################################### # Plot the PCA spectrum pca.fit(X_digits) plt.figure(1, figsize=(4, 3)) plt.clf() plt.axes([.2, .2, .7, .7]) plt.plot(pca.explained_variance_, linewidth=2) plt.axis('tight') plt.xlabel('n_components') plt.ylabel('explained_variance_') ############################################################################### # Prediction n_components = [20, 40, 64] Cs = np.logspace(-4, 4, 3) #Parameters of pipelines can be set using ‘__’ separated parameter names: estimator = GridSearchCV(pipe, dict(pca__n_components=n_components, logistic__C=Cs)) estimator.fit(X_digits, y_digits) plt.axvline(estimator.best_estimator_.named_steps['pca'].n_components, linestyle=':', label='n_components chosen') plt.legend(prop=dict(size=12))

(2)使用特徵聯進行人臉識別

該實例使用的數據集是從「Labeled Faces in the Wild」節選預處理獲得的。更爲熟知的名字是LFW。

http://vis-www.cs.umass.edu/lfw/lfw-funneled.tgz(233 MB)

""" =================================================== Faces recognition example using eigenfaces and SVMs =================================================== The dataset used in this example is a preprocessed excerpt of the "Labeled Faces in the Wild", aka LFW_: http://vis-www.cs.umass.edu/lfw/lfw-funneled.tgz (233MB) .. _LFW: http://vis-www.cs.umass.edu/lfw/ Expected results for the top 5 most represented people in the dataset:: precision recall f1-score support Gerhard_Schroeder 0.91 0.75 0.82 28 Donald_Rumsfeld 0.84 0.82 0.83 33 Tony_Blair 0.65 0.82 0.73 34 Colin_Powell 0.78 0.88 0.83 58 George_W_Bush 0.93 0.86 0.90 129 avg / total 0.86 0.84 0.85 282 """ from __future__ import print_function from time import time import logging import matplotlib.pyplot as plt from sklearn.cross_validation import train_test_split from sklearn.datasets import fetch_lfw_people from sklearn.grid_search import GridSearchCV from sklearn.metrics import classification_report from sklearn.metrics import confusion_matrix from sklearn.decomposition import RandomizedPCA from sklearn.svm import SVC print(__doc__) # Display progress logs on stdout logging.basicConfig(level=logging.INFO, format='%(asctime)s %(message)s') ############################################################################### # Download the data, if not already on disk and load it as numpy arrays lfw_people = fetch_lfw_people(min_faces_per_person=70, resize=0.4) # introspect the images arrays to find the shapes (for plotting) n_samples, h, w = lfw_people.images.shape # for machine learning we use the 2 data directly (as relative pixel # positions info is ignored by this model) X = lfw_people.data n_features = X.shape[1] # the label to predict is the id of the person y = lfw_people.target target_names = lfw_people.target_names n_classes = target_names.shape[0] print("Total dataset size:") print("n_samples: %d" % n_samples) print("n_features: %d" % n_features) print("n_classes: %d" % n_classes) ############################################################################### # Split into a training set and a test set using a stratified k fold # split into a training and testing set X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.25) ############################################################################### # Compute a PCA (eigenfaces) on the face dataset (treated as unlabeled # dataset): unsupervised feature extraction / dimensionality reduction n_components = 150 print("Extracting the top %d eigenfaces from %d faces" % (n_components, X_train.shape[0])) t0 = time() pca = RandomizedPCA(n_components=n_components, whiten=True).fit(X_train) print("done in %0.3fs" % (time() - t0)) eigenfaces = pca.components_.reshape((n_components, h, w)) print("Projecting the input data on the eigenfaces orthonormal basis") t0 = time() X_train_pca = pca.transform(X_train) X_test_pca = pca.transform(X_test) print("done in %0.3fs" % (time() - t0)) ############################################################################### # Train a SVM classification model print("Fitting the classifier to the training set") t0 = time() param_grid = {'C': [1e3, 5e3, 1e4, 5e4, 1e5], 'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1], } clf = GridSearchCV(SVC(kernel='rbf', class_weight='auto'), param_grid) clf = clf.fit(X_train_pca, y_train) print("done in %0.3fs" % (time() - t0)) print("Best estimator found by grid search:") print(clf.best_estimator_) ############################################################################### # Quantitative evaluation of the model quality on the test set print("Predicting people's names on the test set") t0 = time() y_pred = clf.predict(X_test_pca) print("done in %0.3fs" % (time() - t0)) print(classification_report(y_test, y_pred, target_names=target_names)) print(confusion_matrix(y_test, y_pred, labels=range(n_classes))) ############################################################################### # Qualitative evaluation of the predictions using matplotlib def plot_gallery(images, titles, h, w, n_row=3, n_col=4): """Helper function to plot a gallery of portraits""" plt.figure(figsize=(1.8 * n_col, 2.4 * n_row)) plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35) for i in range(n_row * n_col): plt.subplot(n_row, n_col, i + 1) plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray) plt.title(titles[i], size=12) plt.xticks(()) plt.yticks(()) # plot the result of the prediction on a portion of the test set def title(y_pred, y_test, target_names, i): pred_name = target_names[y_pred[i]].rsplit(' ', 1)[-1] true_name = target_names[y_test[i]].rsplit(' ', 1)[-1] return 'predicted: %s\ntrue: %s' % (pred_name, true_name) prediction_titles = [title(y_pred, y_test, target_names, i) for i in range(y_pred.shape[0])] plot_gallery(X_test, prediction_titles, h, w) # plot the gallery of the most significative eigenfaces eigenface_titles = ["eigenface %d" % i for i in range(eigenfaces.shape[0])] plot_gallery(eigenfaces, eigenface_titles, h, w) plt.show()
預測:

特徵臉:

數據集中最有表明性的五我的臉的指望結果:

precision recall f1-score support

Gerhard_Schroeder 0.91 0.75 0.82 28
Donald_Rumsfeld 0.84 0.82 0.83 33
Tony_Blair 0.65 0.82 0.73 34
Colin_Powell 0.78 0.88 0.83 58
George_W_Bush 0.93 0.86 0.90 129

avg / total 0.86 0.84 0.85 282

(3)開放性問題:股票市場結構

咱們是否能夠根據給定的時間幀預測股票的價格變化。
[學習一個圖結構]

6、尋求幫助

###(1)項目郵件列表
若是你碰到scikit-learn的BUG或者文檔中須要澄清聲明的部分,請放心大膽的在郵件列表裏詢問[maillist]

(2)問答(Q&A)機器學習從業者參與的社區

  • Metaoptimize/QA:
    一個 機器學習、天然語言處理和其餘數據分析方面討論的論壇(相似針對開發者的Stackoverflow):http://metaoptimize.com/qa

    一個比較容易開始參與的討論:good freely available textbooks on machine learning(機器學習方面優秀的免費電子書)
  • Quora.com:
    Quora 有一個關於機器學習相關的問題主題,也有不少有趣的討論:http://quora.com/Machine-learning

    瀏覽一下最佳問題的部分,例如:What are some good resources for learning about machine learning(關於機器學習的優秀資源有哪些)
  • ---斯坦福的 Andrew Ng教授 教授的 關於機器學習的優秀在線免費課程{網易公開課有,搜一下機器學習就能夠了}
相關文章
相關標籤/搜索