在機器學習和數據挖掘的應用中,scikit-learn是一個功能強大的python包。在數據量不是過大的狀況下,能夠解決大部分問題。學習使用scikit-learn的過程當中,我本身也在補充着機器學習和數據挖掘的知識。這裏根據本身學習sklearn的經驗,我作一個總結的筆記。另外,我也想把這篇筆記一直更新下去。python
估計器,不少時候能夠直接理解成分類器,主要包含兩個函數:算法
轉換器用於數據預處理和數據轉換,主要是三個方法:spring
sklearn.pipeline包數組
流水線的輸入爲一連串的數據挖掘步驟,其中最後一步必須是估計器,前幾步是轉換器。輸入的數據集通過轉換器的處理後,輸出的結果做爲下一步的輸入。最後,用位於流水線最後一步的估計器對數據進行分類。
每一步都用元組( ‘名稱’,步驟)來表示。如今來建立流水線。網絡
scaling_pipeline = Pipeline([
('scale', MinMaxScaler()), ('predict', KNeighborsClassifier()) ])
主要在sklearn.preprcessing包下。dom
規範化:機器學習
編碼:函數
包:sklearn.feature_extraction
特徵抽取是數據挖掘任務最爲重要的一個環節,通常而言,它對最終結果的影響要高過數據挖掘算法自己。只有先把現實用特徵表示出來,才能藉助數據挖掘的力量找到問題的答案。特徵選擇的另外一個優勢在於:下降真實世界的複雜度,模型比現實更容易操縱。
通常最常使用的特徵抽取技術都是高度針對具體領域的,對於特定的領域,如圖像處理,在過去一段時間已經開發了各類特徵抽取的技術,但這些技術在其餘領域的應用卻很是有限。性能
示例學習
CountVectorize只數出現個數
TfidfVectorizer:個數+歸一化(不包括idf)
包:sklearn.feature_selection
特徵選擇的緣由以下:
(1)下降複雜度
(2)下降噪音
(3)增長模型可讀性
單個特徵和某一類別之間相關性的計算方法有不少。最經常使用的有卡方檢驗(χ2)。其餘方法還有互信息和信息熵。
包:sklearn.decomposition
包:sklearn.ensemble
組合技術即經過彙集多個分類器的預測來提升分類準確率。
經常使用的組合分類器方法:
(1)經過處理訓練數據集。即經過某種抽樣分佈,對原始數據進行再抽樣,獲得多個訓練集。經常使用的方法有裝袋(bagging)和提高(boosting)。
(2)經過處理輸入特徵。即經過選擇輸入特徵的子集造成每一個訓練集。適用於有大量冗餘特徵的數據集。隨機森林(Random forest)就是一種處理輸入特徵的組合方法。
(3)經過處理類標號。適用於多分類的狀況,將類標號隨機劃分紅兩個不相交的子集,再把問題變爲二分類問題,重複構建屢次模型,進行分類投票。
使用舉例
AdaBoostClassifier(DecisionTreeClassifier(max_depth=1), algorithm="SAMME", n_estimators=200)
解釋
裝袋(bagging):根據均勻機率分佈從數據集中重複抽樣(有放回),每一個自助樣本集和原數據集同樣大,每一個自助樣本集含有原數據集大約63%的數據。訓練k個分類器,測試樣本被指派到得票最高的類。
提高(boosting):經過給樣本設置不一樣的權值,每輪迭代調整權值。不一樣的提高算法之間的差異,通常是(1)如何更新樣本的權值,(2)如何組合每一個分類器的預測。其中Adaboost中,樣本權值是增長那些被錯誤分類的樣本的權值,分類器C_i的重要性依賴於它的錯誤率。
Boosting主要關注下降誤差,所以Boosting能基於泛化性能至關弱的學習器構建出很強的集成;Bagging主要關注下降方差,所以它在不剪枝的決策樹、神經網絡等學習器上效用更爲明顯。誤差指的是算法的指望預測與真實預測之間的誤差程度,反應了模型自己的擬合能力;方差度量了同等大小的訓練集的變更致使學習性能的變化,刻畫了數據擾動所致使的影響。
包:sklearn.metrics
sklearn.metrics包含評分方法、性能度量、成對度量和距離計算。
分類結果度量
參數大可能是y_true和y_pred。
其中,F1是以每一個類別爲基礎進行定義的,包括兩個概念:準確率(precision)和召回率(recall)。準確率是指預測結果屬於某一類的個體,實際屬於該類的比例。召回率是被正確預測爲某類的個體,與數據集中該類個體總數的比例。F1是準確率和召回率的調和平均數。
迴歸結果度量
多標籤的度量
聚類的度量
包:sklearn.cross_validation
LeaveOneOut(n) 至關於 KFold(n, n_folds=n) 至關於LeavePOut(n, p=1)。
LeaveP和LeaveOne差異在於leave的個數,也就是測試集的尺寸。LeavePLabel和LeaveOneLabel差異在於leave的Label的種類的個數。
LeavePLabel這種設計是針對可能存在第三方的Label,好比咱們的數據是一些季度的數據。那麼很天然的一個想法就是把1,2,3個季度的數據當作訓練集,第4個季度的數據當作測試集。這個時候只要輸入每一個樣本對應的季度Label,就能夠實現這樣的功能。
如下是實驗代碼,儘可能本身多實驗去理解。
#coding=utf-8 import numpy as np import sklearnfrom sklearn import cross_validation X = np.array([[1, 2], [3, 4], [5, 6], [7, 8],[9, 10]]) y = np.array([1, 2, 1, 2, 3]) def show_cross_val(method): if method == "lolo": labels = np.array(["summer", "winter", "summer", "winter", "spring"]) cv = cross_validation.LeaveOneLabelOut(labels) elif method == 'lplo': labels = np.array(["summer", "winter", "summer", "winter", "spring"]) cv = cross_validation.LeavePLabelOut(labels,p=2) elif method == 'loo': cv = cross_validation.LeaveOneOut(n=len(y)) elif method == 'lpo': cv = cross_validation.LeavePOut(n=len(y),p=3) for train_index, test_index in cv: print("TRAIN:", train_index, "TEST:", test_index) X_train, X_test = X[train_index], X[test_index] y_train, y_test = y[train_index], y[test_index] print "X_train: ",X_train print "y_train: ", y_train print "X_test: ",X_test print "y_test: ",y_test if __name__ == '__main__': show_cross_val("lpo")
經常使用方法
包:sklearn.grid_search
網格搜索最佳參數
包:sklearn.multiclass
#coding=utf-8 from sklearn import metrics from sklearn import cross_validation from sklearn.svm import SVC from sklearn.multiclass import OneVsRestClassifier from sklearn.preprocessing import MultiLabelBinarizer import numpy as np from numpy import random X=np.arange(15).reshape(5,3) y=np.arange(5) Y_1 = np.arange(5) random.shuffle(Y_1) Y_2 = np.arange(5) random.shuffle(Y_2) Y = np.c_[Y_1,Y_2] def multiclassSVM(): X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y, test_size=0.2,random_state=0) model = OneVsRestClassifier(SVC()) model.fit(X_train, y_train) predicted = model.predict(X_test) print predicted def multilabelSVM(): Y_enc = MultiLabelBinarizer().fit_transform(Y) X_train, X_test, Y_train, Y_test = cross_validation.train_test_split(X, Y_enc, test_size=0.2, random_state=0) model = OneVsRestClassifier(SVC()) model.fit(X_train, Y_train) predicted = model.predict(X_test) print predicted if __name__ == '__main__': multiclassSVM() # multilabelSVM()
上面的代碼測試了svm在OneVsRestClassifier的包裝下,分別處理多分類和多標籤的狀況。特別注意,在多標籤的狀況下,輸入必須是二值化的。因此須要MultiLabelBinarizer()先處理。包:sklearn.cross_validation
樸素貝葉斯的特色是分類速度快,分類效果不必定是最好的。
所謂使用什麼分佈的樸素貝葉斯,就是假設P(x_i|y)是符合哪種分佈,好比能夠假設其服從高斯分佈,而後用最大似然法估計高斯分佈的參數。
具體的擴展,一般要繼承sklearn.base包下的類。
關於什麼是Mixin(混合類),具體能夠看這個知乎連接。簡單地理解,就是帶有實現方法的接口,能夠將其看作是組合模式的一種實現。舉個例子,好比說經常使用的TfidfTransformer,繼承了BaseEstimator, TransformerMixin,所以它的基本功能就是單一職責的估計器和轉換器的組合。
在特徵抽取的時候,常常會發現本身的一些數據預處理的方法,sklearn裏可能沒有實現,但若直接在數據上改,又容易將代碼弄得混亂,難以重現實驗。這個時候最好本身建立一個轉換器,在後面將這個轉換器放到pipeline裏,統一管理。
例如《Python數據挖掘入門與實戰》書中的例子,咱們想接收一個numpy數組,根據其均值將其離散化,任何高於均值的特徵值替換爲1,小於或等於均值的替換爲0。
代碼實現:
from sklearn.base import TransformerMixin from sklearn.utils import as_float_array class MeanDiscrete(TransformerMixin): #計算出數據集的均值,用內部變量保存該值。 def fit(self, X, y=None): X = as_float_array(X) self.mean = np.mean(X, axis=0) #返回self,確保在轉換器中可以進行鏈式調用(例如調用transformer.fit(X).transform(X)) return self def transform(self, X): X = as_float_array(X) assert X.shape[1] == self.mean.shape[0] return X > self.mean