Scikit Learn: 在python中機器學習
Warning
警告:有些沒能理解的句子,我以自己的理解意譯。
翻譯自:Scikit Learn:Machine Learning in Python
作者: Fabian Pedregosa, Gael Varoquaux
先決條件
- Numpy, Scipy
- IPython
- matplotlib
- scikit-learn
目錄
警告:在0.9版中(2011年9月發行),scikit-learn的匯入路徑從scikits.learn更改為sklearn
載入示例資料
首先我們載入一些用來玩耍的資料。我們將使用的資料是非常簡單的著名的花朵資料——安德森鳶尾花卉資料集。
我們有一百五十個鳶尾花的一些尺寸的觀測值:萼片長度、寬度,花瓣長度和寬度。還有它們的亞屬:山鳶尾(Iris setosa)、變色鳶尾(Iris versicolor)和維吉尼亞鳶尾(Iris virginica)
向python物件載入資料:
In [1]: from sklearn import datasets
In [2]: iris = datasets.load_iris()
資料儲存在.data項中,是一個(n_samples, n_features)陣列。
In [3]: iris.data.shape
Out[3]: (150, 4)
每個觀察物件的種類存貯在資料集的.target屬性中。這是一個長度為n_samples的整數一維陣列:
In [5]: iris.target.shape
Out[5]: (150,)
In [6]: import numpy as np
In [7]: np.unique(iris.target)
Out[7]: array([0, 1, 2])
一個改變資料集大小的示例:數碼資料集(digits datasets)
數碼資料集1包括1797個影象,每一個都是個代表手寫數字的8x8畫素影象
In [8]: digits = datasets.load_digits()
In [9]: digits.images.shape
Out[9]: (1797, 8, 8)
In [10]: import pylab as pl
In [11]: pl.imshow(digits.images[0], cmap=pl.cm.gray_r)
Out[11]: <matplotlib.image.AxesImage at 0x3285b90>
In [13]: pl.show()
為了在scikit中使用這個資料集,我們把每個8x8影象轉換成長度為64的向量。(譯者注:或者直接用digits.data)
In [12]: data = digits.images.reshape((digits.images.shape[0], -1))
學習和預測
現在我們已經獲得一些資料,我們想要從中學習和預測一個新的資料。在scikit-learn中,我們通過建立一個估計器(estimator)從已經存在的資料學習,並且呼叫它的fit(X,Y)方法。
In [14]: from sklearn import svm
In [15]: clf = svm.LinearSVC()
In [16]: clf.fit(iris.data, iris.target) # learn from the data
Out[16]:
LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,
intercept_scaling=1, loss='l2', multi_class='ovr', penalty='l2',
tol=0.0001, verbose=0)
一旦我們已經從資料學習,我們可以使用我們的模型來預測未觀測資料最可能的結果。
In [17]: clf.predict([[ 5.0, 3.6, 1.3, 0.25]])
Out[17]: array([0], dtype=int32)
注意:我們可以通過它以下劃線結束的屬性存取模型的引數:
In [18]: clf.coef_
Out[18]:
array([[ 0.18424352, 0.45122644, -0.8079467 , -0.45071302],
[ 0.05190619, -0.89423619, 0.40519245, -0.93781587],
[-0.85087844, -0.98667529, 1.38088883, 1.86538111]])
分類
K最近鄰(KNN)分類器
最簡單的可能的分類器是最近鄰:給定一個新的觀測值,將n維空間中最靠近它的訓練樣本標籤給它。其中n是每個樣本中特性(features)數。
k最近鄰2分類器內部使用基於球樹(ball tree)3來代表它訓練的樣本。
KNN分類示例:
In [19]: # Create and fit a nearest-neighbor classifier
In [20]: from sklearn import neighbors
In [21]: knn = neighbors.KNeighborsClassifier()
In [22]: knn.fit(iris.data, iris.target)
Out[22]:
KNeighborsClassifier(algorithm='auto', leaf_size=30, n_neighbors=5, p=2,
warn_on_equidistant=True, weights='uniform')
In [23]: knn.predict([[0.1, 0.2, 0.3, 0.4]])
Out[23]: array([0])
訓練集和測試集
當驗證學習演算法時,不要用一個用來擬合估計器的資料來驗證估計器的預測非常重要。確實,通過kNN估計器,我們將總是獲得關於訓練集完美的預測。
In [24]: perm = np.random.permutation(iris.target.size)
In [25]: iris.data = iris.data[perm]
In [26]: iris.target = iris.target[perm]
In [27]: knn.fit(iris.data[:100], iris.target[:100])
Out[27]:
KNeighborsClassifier(algorithm='auto', leaf_size=30, n_neighbors=5, p=2,
warn_on_equidistant=True, weights='uniform')
In [28]: knn.score(iris.data[100:], iris.target[100:])
/usr/lib/python2.7/site-packages/sklearn/neighbors/classification.py:129: NeighborsWarning: kneighbors: neighbor k+1 and neighbor k have the same distance: results will be dependent on data order.
neigh_dist, neigh_ind = self.kneighbors(X)
Out[28]: 0.95999999999999996
Bonus的問題:為什麼我們使用隨機的排列?
分類支援向量機(SVMs)
線性支援向量機
SVMs4嘗試構建一個兩個類別的最大間隔超平面。它選擇輸入的子集,呼叫支援向量即離分離的超平面最近的樣本點。
In [60]: from sklearn import svm
In [61]: svc = svm.SVC(kernel='linear')
In [62]: svc.fit(iris.data, iris.target)
Out[62]:
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,
kernel='linear', probability=False, shrinking=True, tol=0.001,
verbose=False)
scikit-learn中有好幾種支援向量機實現。最普遍使用的是svm.SVC,svm.NuSVC和svm.LinearSVC;“SVC”代表支援向量分類器(Support Vector Classifier)(也存在迴歸SVMs,在scikit-learn中叫作“SVR”)。
練習
訓練一個數字資料集的svm.SVC。省略最後10%並且檢驗觀測值的預測表現。
使用核
類別不總是可以用超平面分離,所以人們指望有些可能是多項式或指數例項的非線性決策函式:
-
線性核
svc = svm.SVC(kernel=’linear’)
-
多項式核
svc = svm.SVC(kernel=’poly’, … degree=3) # degree: polynomial degree
-
RBF核(徑向基函式)5
svc = svm.SVC(kernel=’rbf’) # gamma: inverse of size of # radial kernel
練習
以上提到的哪些核對數字資料集有更好的預測效能?(譯者:前兩個)
聚類:將觀測值聚合
給定鳶尾花資料集,如果我們知道這有三種鳶尾花,但是無法得到它們的標籤,我們可以嘗試非監督學習:我們可以通過某些標準聚類觀測值到幾個組別裡。
k均值聚類
最簡答的聚類演算法是k均值演算法。這將一個資料分成k個叢集,以最小化觀測值(n維空間中)到聚類中心的均值來分配每個觀測點到叢集;然後均值重新被計算。這個操作遞迴執行直到聚類收斂,在max_iter回合內到最大值。6
(一個替代的k均值演算法實現在scipy中的cluster包中。這個scikit-learn實現與之不同,通過提供物件API和幾個額外的特性,包括智慧初始化。)
In [82]: from sklearn import cluster, datasets
In [83]: iris = datasets.load_iris()
In [84]: k_means = cluster.KMeans(k=3)
In [85]: k_means.fit(iris.data)
Out[85]:
KMeans(copy_x=True, init='k-means++', k=3, max_iter=300, n_init=10, n_jobs=1,
precompute_distances=True,
random_state=<mtrand.RandomState object at 0x7f4d860642d0>, tol=0.0001,
verbose=0)
In [86]: print k_means.labels_[::10]
[1 1 1 1 1 2 2 2 2 2 0 0 0 0 0]
In [87]: print iris.target[::10]
[0 0 0 0 0 1 1 1 1 1 2 2 2 2 2]
應用到影象壓縮
譯者注:Lena是經典的影象處理例項影象, 8位灰度色深, 尺寸512 x 512
聚類可以被看作是一種從資訊中選擇一小部分觀測值。例如,這個可以被用來海報化一個影象(將連續變化的色調轉換成更少幾個色調):
In [95]: from scipy import misc
In [96]: lena = misc.lena().astype(np.float32)
In [97]: X = lena.reshape((-1, 1)) # We need an (n_sample, n_feature) array
In [98]: k_means = cluster.KMeans(5)
In [99]: k_means.fit(X)
Out[99]:
KMeans(copy_x=True, init='k-means++', k=5, max_iter=300, n_init=10, n_jobs=1,
precompute_distances=True,
random_state=<mtrand.RandomState object at 0x7f4d860642d0>, tol=0.0001,
verbose=0)
In [100]: values = k_means.cluster_centers_.squeeze()
In [101]: labels = k_means.labels_
In [102]: lena_compressed = np.choose(labels, values)
In [103]: lena_compressed.shape = lena.shape
譯者注:想看效果?
In [31]: import matplotlib.pyplot as plt
In [32]: plt.gray()
In [33]: plt.imshow(lena_compressed)
Out[33]: <matplotlib.image.AxesImage at 0x4b2c510>
In [34]: plt.show()
原圖類似。
![Image]
用主成分分析降維
以上根據觀測值標記的點雲在一個方向非常平坦,所以一個特性幾乎可以用其它兩個確切地計算。PCA發現哪個方向的資料不是平的並且它可以通過在一個子空間投影來降維。
警告:PCA將在模組decomposition或pca中,這取決於你scikit-learn的版本。
In [75]: from sklearn import decomposition
In [76]: pca = decomposition.PCA(n_components=2)
In [77]: pca.fit(iris.data)
Out[77]: PCA(copy=True, n_components=2, whiten=False)
In [78]: X = pca.transform(iris.data)
現在我們可以視覺化(降維過的)鳶尾花資料集:
In [79]: import pylab as pl
In [80]: pl.scatter(X[:, 0], X[:, 1], c=iris.target)
Out[80]: <matplotlib.collections.PathCollection at 0x4104310>
PCA不僅在視覺化高維資料集時非常有用。它可以用來作為幫助加速對高維資料不那麼有效率的監督方法7的預處理步驟。
將一切放在一起:人臉識別
一個例項使用主成分分析來降維和支援向量機來分類進行人臉識別。
譯者注:讓程式自動下載(確保聯網,檔案較大,要等待很久)或者手動下載資料並放到./scikit_learn_data/lfw_home/下。
"""
Stripped-down version of the face recognition example by Olivier Grisel
http://scikit-learn.org/dev/auto_examples/applications/face_recognition.html
## original shape of images: 50, 37
"""
import numpy as np
import pylab as pl
from sklearn import cross_val, datasets, decomposition, svm
# ..
# .. load data ..
lfw_people = datasets.fetch_lfw_people(min_faces_per_person=70, resize=0.4)
perm = np.random.permutation(lfw_people.target.size)
lfw_people.data = lfw_people.data[perm]
lfw_people.target = lfw_people.target[perm]
faces = np.reshape(lfw_people.data, (lfw_people.target.shape[0], -1))
train, test = iter(cross_val.StratifiedKFold(lfw_people.target, k=4)).next()
X_train, X_test = faces[train], faces[test]
y_train, y_test = lfw_people.target[train], lfw_people.target[test]
# ..
# .. dimension reduction ..
pca = decomposition.RandomizedPCA(n_components=150, whiten=True)
pca.fit(X_train)
X_train_pca = pca.transform(X_train)
X_test_pca = pca.transform(X_test)
# ..
# .. classification ..
clf = svm.SVC(C=5., gamma=0.001)
clf.fit(X_train_pca, y_train)
# ..
# .. predict on new images ..
for i in range(10):
print lfw_people.target_names[clf.predict(X_test_pca[i])[0]]
_ = pl.imshow(X_test[i].reshape(50, 37), cmap=pl.cm.gray)
_ = raw_input()
全部程式碼:face.py
線性模型:從迴歸到稀疏
糖尿病資料集
糖尿病資料集包含442個病人的測量而得的10項生理指標(年齡,性別,體重,血壓),和一年後疾病進展的指示:
In [104]: diabetes = datasets.load_diabetes()
In [105]: diabetes_X_train = diabetes.data[:-20]
In [106]: diabetes_X_test = diabetes.data[-20:]
In [107]: diabetes_y_train = diabetes.target[:-20]
In [108]: diabetes_y_test = diabetes.target[-20:]
這個手頭的任務是用來從生理指標預測疾病。
稀疏模型
為了改善問題的條件(無資訊變數,減少維度的不利影響,作為一個特性(feature)選擇的預處理,等等),我們只關注有資訊的特性將沒有資訊的特性設定為0.這個罰則函式法8,叫作套索(Lasso)9,可以將一些係數設定為0.這些方法叫作稀疏方法(sparse method),稀疏化可以被視作奧卡姆剃刀:相對於複雜模型更傾向於簡單的。
In [109]: from sklearn import linear_model
In [110]: regr = linear_model.Lasso(alpha=.3)
In [111]: regr.fit(diabetes_X_train, diabetes_y_train)
Out[111]:
Lasso(alpha=0.3, copy_X=True, fit_intercept=True, max_iter=1000,
normalize=False, positive=False, precompute='auto', tol=0.0001,
warm_start=False)
In [112]: regr.coef_ # very sparse coefficients
Out[112]:
array([ 0. , -0. , 497.34075682, 199.17441034,
-0. , -0. , -118.89291545, 0. ,
430.9379595 , 0. ])
In [113]: regr.score(diabetes_X_test, diabetes_y_test)
Out[113]: 0.55108354530029791
這個分數和線性迴歸(最小二乘法)非常相似:
In [114]: lin = linear_model.LinearRegression()
In [115]: lin.fit(diabetes_X_train, diabetes_y_train)
Out[115]: LinearRegression(copy_X=True, fit_intercept=True, normalize=False)
In [116]: lin.score(diabetes_X_test, diabetes_y_test)
Out[116]: 0.58507530226905713
同一問題的不同演算法
同一數學問題可以用不同演算法解決。例如,sklearn中的Lasso物件使用座標下降(coordinate descent)方法10解決套索迴歸,這在大資料集時非常有效率。然而,sklearn也提供了LassoLARS物件,使用LARS這種在解決權重向量估計非常稀疏,觀測值很少的問題很有效率的方法。
模型選擇:選擇估計器和它們的引數
格點搜尋和交叉驗證估計器
格點搜尋
scikit-learn提供了一個物件,該物件給定資料,在擬合一個引數網格的估計器時計算分數,並且選擇引數最大化交叉驗證分數。這個物件在構建時採用一個估計器並且暴露一個估計器API:
In [117]: from sklearn import svm, grid_search
In [118]: gammas = np.logspace(-6, -1, 10)
In [119]: svc = svm.SVC()
In [120]: clf = grid_search.GridSearchCV(estimator=svc, param_grid=dict(gamma=gammas),n_jobs=-1)
In [121]: clf.fit(digits.data[:1000], digits.target[:1000])
Out[121]:
GridSearchCV(cv=None,
estimator=SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,
kernel='rbf', probability=False, shrinking=True, tol=0.001,
verbose=False),
fit_params={}, iid=True, loss_func=None, n_jobs=-1,
param_grid={'gamma': array([ 1.00000e-06, 3.59381e-06, 1.29155e-05, 4.64159e-05,
1.66810e-04, 5.99484e-04, 2.15443e-03, 7.74264e-03,
2.78256e-02, 1.00000e-01])},
pre_dispatch='2*n_jobs', refit=True, score_func=None, verbose=0)
In [122]: clf.best_score
/usr/lib/python2.7/site-packages/sklearn/utils/__init__.py:79: DeprecationWarning: Function best_score is deprecated; GridSearchCV.best_score is deprecated and will be removed in version 0.12. Please use ``GridSearchCV.best_score_`` instead.
warnings.warn(msg, category=DeprecationWarning)
Out[122]: 0.98600097103091122
In [123]: clf.best_estimator.gamma
/usr/lib/python2.7/site-packages/sklearn/utils/__init__.py:79: DeprecationWarning: Function best_estimator is deprecated; GridSearchCV.best_estimator is deprecated and will be removed in version 0.12. Please use ``GridSearchCV.best_estimator_`` instead.
warnings.warn(msg, category=DeprecationWarning)
Out[123]: 0.0021544346900318843
預設GridSearchCV使用三次(3-fold)交叉驗證。然而,如果它探測到一個分類器被傳遞,而不是一個迴歸量,它使用分層的3次。
交叉驗證估計器
交叉驗證在一個algorithm by algorithm基礎上可以更有效地設定引數。這就是為何,對給定的估計器,scikit-learn使用“CV”估計器,通過交叉驗證自動設定引數。
In [125]: from sklearn import linear_model, datasets
In [126]: lasso = linear_model.LassoCV()
In [127]: diabetes = datasets.load_diabetes()
In [128]: X_diabetes = diabetes.data
In [129]: y_diabetes = diabetes.target
In [130]: lasso.fit(X_diabetes, y_diabetes)
Out[130]:
LassoCV(alphas=array([ 2.14804, 2.00327, ..., 0.0023 , 0.00215]),
copy_X=True, cv=None, eps=0.001, fit_intercept=True, max_iter=1000,
n_alphas=100, normalize=False, precompute='auto', tol=0.0001,
verbose=False)
In [131]: # The estimator chose automatically its lambda:
In [132]: lasso.alpha
Out[132]: 0.013180196198701137
這些估計器是相似的,以‘CV’為它們名字的字尾。
練習
對糖尿病資料集,找到最優的正則化引數alpha。(0.016249161908773888)
相關文章
- 入門系列之Scikit-learn在Python中構建機器學習分類器Python機器學習
- Scikit-learn 機器學習庫介紹!【Python入門】機器學習Python
- 《scikit-learn機器學習實戰》簡介機器學習
- Scikit-learn學習
- 使用scikit-learn機器學習庫裡面的xgboost機器學習
- Scikit-Learn機器學習實踐——垃圾簡訊識別機器學習
- Scikit-learn的六大功能!Python學習Python
- Scikit-Learn 與 TensorFlow 機器學習實用指南學習筆記2 — 機器學習的主要挑戰機器學習筆記
- Scikit-Learn 與 TensorFlow 機器學習實用指南學習筆記1 — 機器學習基礎知識簡介機器學習筆記
- pytorch&scikit-learn機器學1- 賦予計算機從資料中學習的能力PyTorch計算機
- 人工智慧-機器學習-Python-第三方庫-scikit-learn(用於特徵工程)人工智慧機器學習Python特徵工程
- python中的scikit-learn庫來實現SVM分類器。Python
- scikit-learn: 使用conda安裝scikit-learn
- Scikit-learn可擴充套件學習簡介套件
- Scikit-Learn 與 TensorFlow 機器學習實用指南學習筆記 5 —— 如何為機器學習演算法準備資料?機器學習筆記演算法
- Scikit-Learn 與 TensorFlow 機器學習實用指南學習筆記 3 —— 資料獲取與清洗機器學習筆記
- 利用Scikit-learn機器學習庫的特徵分類進行vnpy期貨量化交易機器學習特徵
- 【scikit-learn基礎】--『監督學習』之 嶺迴歸
- 【scikit-learn基礎】--『監督學習』之 LASSO迴歸
- 利用Scikit-learn機器學習庫的特徵分類進行vnpy期貨量化交易(程式碼)機器學習特徵
- scikit-learn介紹
- python人工智慧機器學習工具書籍:scikit-learnCookbook2ndEditionPython人工智慧機器學習
- Scikit-Learn 與 TensorFlow 機器學習實用指南學習筆記 4 —— 資料探索與視覺化、發現規律機器學習筆記視覺化
- 如何將 Scikit-learn Python 庫用於資料科學專案Python資料科學
- Scikit-learn SVM 實現
- (資料科學學習手札138)使用sklearnex大幅加速scikit-learn運算資料科學
- 在 Python 中儲存和載入機器學習模型Python機器學習模型
- [python學習]機器學習 -- 感知機Python機器學習
- Python資料探勘入門與實踐---使用scikit-learn 估計器分類Python
- 【機器學習】--Python機器學習庫之Numpy機器學習Python
- 機器學習演算法(22)python實現用scikit-learn進行全連線的凝聚層次聚類演算法(Agglo-merative-Clustering)機器學習演算法Python聚類
- 如何使用Python、Transformers和scikit-learn對文字進行分類?PythonORM
- Python愛好者周知:Scikit-Learn中文文件正式釋出Python
- Scikit-learn從入門到放棄
- 監督學習,無監督學習常用演算法集合總結,引用scikit-learn庫(監督篇)演算法
- 在物聯網中應用機器學習機器學習
- scikit-learn 中 Boston Housing 資料集問題解決方案
- 一個完整的機器學習專案在Python中的演練(三)機器學習Python
- 一個完整的機器學習專案在Python中的演練(二)機器學習Python