Scikit-learn學習
來自專欄 Python程序員237 人贊了文章
同志們別只收藏,記得點贊啊??!
Sklearn作為python機器學習領域舉足輕重的庫,在人工智慧很火的今天,也受到了廣泛的關注。Sklearn其中包含了數據預處理、特徵選取、模型選擇、交叉驗證、聚類等方面的函數,確實非常的強大。首先照例導入老相識庫。
import numpy as npimport matplotlib.pyplot as plt
1、數據預處理
數據預處理指的是將原始數據通過一定的處理變成機器學習演算法的輸入,一般來說,數據預處理決定了演算法準確率的上界,因此這在機器學習中是非常重要的一部分。主要分為標準化、二值化、缺失值處理。
標準化
標準化對於很對機器學習都很重要,它指的是通過平移中心、除以方差得到平均值為0、方差為1的標準正態分布。這裡不介紹直接使用函數的用法,介紹sklearn中常用的將其作為一個對象處理的方法。
from sklearn import preprocessing
X_train = np.array([[ 1., -1., 2.], [ 2., 0., 0.], [ 0., 1., -1.]])# 通過設置參數也可只平移或縮放standard_scaler = preprocessing.StandardScaler().fit(X_train)standard_scaler
StandardScaler(copy=True, with_mean=True, with_std=True)
standard_scaler.transform(X_train)
array([[ 0. , -1.22474487, 1.33630621], [ 1.22474487, 0. , -0.26726124], [-1.22474487, 1.22474487, -1.06904497]])
除此之外,通常也有將數據縮放到某個範圍的需要,這時可以用MinMaxScaler或者MaxAbsScaler(後者是絕對值縮放)。
X_train = np.array([[ 1., -1., 2.], [ 2., 0., 0.], [ 0., 1., -1.]])min_max_scaler = preprocessing.MinMaxScaler([0,4])X_train_minmax = min_max_scaler.fit_transform(X_train)X_train_minmax
array([[2. , 0. , 4. ], [4. , 2. , 1.33333333], [0. , 4. , 0. ]])
二值化
二值化是將連續的數值特徵轉換為0-1兩種類型的數據的過程,主要的參數是閾值threshold。
X = [[ 1., -1., 2.], [ 2., 0., 0.], [ 0., 1., -1.]]binarizer = preprocessing.Binarizer().fit(X)binarizer.transform(X)
array([[1., 0., 1.], [1., 0., 0.], [0., 1., 0.]])
類別編碼
類別編碼主要是用來處理文本數據,將文本數據轉化為不同的數字。類別編碼分為兩種,第一種是每個類別用一個數字表示,一個特徵處理後的數據仍然是一列數據,第二種是one-hot編碼,每個類別變為一個特徵。
le = preprocessing.LabelEncoder()le.fit(["paris", "paris", "tokyo", "amsterdam"])le.transform(["tokyo", "tokyo", "paris"])
array([2, 2, 1], dtype=int64)
lb = preprocessing.LabelBinarizer()lb.fit(["paris", "paris", "tokyo", "amsterdam"])lb.transform(["tokyo", "tokyo", "paris"])
array([[0, 0, 1], [0, 0, 1], [0, 1, 0]])
值得注意的是這兩個函數也能夠處理int類型的變數,比oneHoter功能較強。但是這兩個均一次只能夠處理一列數據,因此對整個數據集處理需要循環。新版本0.20的CategoricalEncoder擴展了這兩個功能。
缺失數據處理
實際上這一步應該在最開始介紹,因為缺失數據可能會影響一些預處理演算法的正常運行。處理缺失數據最簡單的方法是丟失有缺失值的行或者列,這樣簡單粗暴的方法也會丟掉一些有用信息。因此比較常用的方法是利用中位數、平均數或者出現頻率最高的數字來填充。
imp = preprocessing.Imputer(missing_values=NaN, strategy=mean, axis=0)imp.fit([[1, 2], [np.nan, 3], [7, 6]])X = [[np.nan, 2], [6, np.nan], [7, 6]]print(imp.transform(X))
[[4. 2. ] [6. 3.66666667] [7. 6. ]]
這樣簡單的數字數據的缺失問題就得到了解決,但是字元類型的缺失問題並沒有解決。字元類型的一般需要使用Pandas來解決。
2、特徵提取
在進行完機器學習最麻煩的預處理之後(個人認為),我們需要選擇有意義的特徵輸入機器學習的演算法和模型進行訓練。通常來說,從特徵是否發散和特徵與目標的相關性來進行選擇。
單變數因素分析:通過一定的指標來判斷單個特徵與目標值的關聯關係,這裡可以利用卡方分布,F值等指標,互信息指標。* 回歸指標:f_regression,mutual_info_regression
* 分類指標:卡方分布chi2 ,f_classif, mutual_info_classif 遞歸特徵消除: 利用一個模型來評價每個特徵的權重,刪除不重要的一個,然後繼續迭代* 利用模型直接消除: 利用一個模型來評價每個特徵的重要性,刪除重要性低於閾值的特徵from sklearn import datasets
# 從數據集中得到手寫數字識別數據和目標X = datasets.load_digits()[data]Y = datasets.load_digits()[target](X.shape,Y.shape)
((1797, 64), (1797,))
# 1 單變數因素分析from sklearn.feature_selection import SelectKBestfrom sklearn.feature_selection import mutual_info_classifselect = SelectKBest(mutual_info_classif,40)X_new = select.fit_transform(X,Y)select.scores_
array([0. , 0.14120498, 0.3707164 , 0.1941337 , 0.15140587, 0.25471565, 0.19489996, 0.03661306, 0.00101285, 0.2808442 , 0.33928455, 0.13923242, 0.18945522, 0.34258656, 0.14226452, 0.01062065, 0. , 0.16635666, 0.25401044, 0.27412697, 0.36716099, 0.44267935, 0.22933705, 0. , 0. , 0.25861679, 0.40714241, 0.26678509, 0.3885343 , 0.30943624, 0.4015582 , 0.02315389, 0.00244486, 0.41920534, 0.4473156 , 0.30890697, 0.35854987, 0.26247734, 0.33611487, 0.04012269, 0.01429927, 0.28080319, 0.39868866, 0.39528717, 0.31216306, 0.16912318, 0.32176004, 0.02106102, 0. , 0.05830372, 0.26623367, 0.27167508, 0.18002977, 0.32275494, 0.37804414, 0.09408823, 0. , 0.07899824, 0.36541609, 0.23500028, 0.2754045 , 0.38913411, 0.26470638, 0.08786643])
# 最終選出了前40個特徵X_new.shape
(1797, 40)
# 2 遞歸特徵消除法from sklearn import feature_selectionfrom sklearn import linear_modelselect = feature_selection.RFE(estimator=linear_model.LogisticRegression(),n_features_to_select=40)select.fit_transform(X,Y)
array([[ 0., 5., 13., ..., 0., 0., 0.], [ 0., 0., 12., ..., 10., 0., 0.], [ 0., 0., 4., ..., 16., 9., 0.], ..., [ 0., 1., 11., ..., 6., 0., 0.], [ 0., 2., 10., ..., 12., 0., 0.], [ 0., 10., 14., ..., 12., 1., 0.]])
select.ranking_# 最終選擇的表示為1
array([25, 1, 1, 1, 1, 1, 1, 16, 1, 1, 15, 4, 1, 1, 1, 5, 14, 3, 1, 1, 1, 1, 1, 1, 10, 1, 1, 1, 1, 12, 1, 20, 24, 1, 1, 9, 1, 17, 1, 23, 22, 1, 1, 1, 1, 1, 1, 18, 19, 7, 8, 6, 1, 1, 1, 1, 21, 11, 2, 1, 13, 1, 1, 1])
# 3 直接使用模型 默認是閾值均值select = feature_selection.SelectFromModel(linear_model.LogisticRegression(penalty="l1", C=0.1))X_new = select.fit_transform(X,Y)X_new.shape
(1797, 48)
3、監督學習模型
監督學習是機器學習中最普遍的一類學習方法,也就是學習X到Y的一個映射,常見的學習方法有,決策樹、邏輯回歸、SVM和一些集成學習方法。使用主要分為兩個部分訓練和測試。其實具體方法不需要介紹,只需要知道將處理好的模型先選定參數進行訓練,然後得到結果(個人認為是最簡單的一步)。
# 將數據分為訓練集和測試集from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.33)
# 這裡直接使用KNN最近鄰方法來解決問題from sklearn.neighbors import KNeighborsClassifiermodel = KNeighborsClassifier()model.fit(X_train,y_train)
KNeighborsClassifier(algorithm=auto, leaf_size=30, metric=minkowski, metric_params=None, n_jobs=1, n_neighbors=5, p=2, weights=uniform)
如果對於一個演算法我們有許多超參數需要調試,可以使用交叉驗證來進行調參,有0.3比例的簡單交叉驗證,也可以使用K折交叉驗證。
from sklearn.model_selection import GridSearchCV# 定義要調試的參數par = {n_neighbors:np.arange(5,10),algorithm:[auto,brute]}grid = GridSearchCV(KNeighborsClassifier(),par,cv = 3)grid.fit(X_train,y_train)
GridSearchCV(cv=3, error_score=raise, estimator=KNeighborsClassifier(algorithm=auto, leaf_size=30, metric=minkowski, metric_params=None, n_jobs=1, n_neighbors=5, p=2, weights=uniform), fit_params=None, iid=True, n_jobs=1, param_grid={algorithm: [auto, brute], n_neighbors: array([5, 6, 7, 8, 9])}, pre_dispatch=2*n_jobs, refit=True, return_train_score=warn, scoring=None, verbose=0)
# 得到測試分數grid.cv_results_[mean_test_score]
array([0.97921862, 0.97256858, 0.9758936 , 0.97007481, 0.97007481, 0.97921862, 0.97256858, 0.9758936 , 0.97007481, 0.96924356])
# 得到表現最好的參數對應的模型model = grid.best_estimator_model
KNeighborsClassifier(algorithm=auto, leaf_size=30, metric=minkowski, metric_params=None, n_jobs=1, n_neighbors=5, p=2, weights=uniform)
4、模型評估
得到了訓練的模型之後,我們可以在測試集或者訓練集對這個模型進行評價。首先可以使用K折交叉驗證(每個都是先訓練然後再驗證)來評價模型的效果,或者學習曲線。
from sklearn.model_selection import cross_validatefrom sklearn.model_selection import validation_curve
result = cross_validate(model,X_train,y_train)result
c:userszhoucappdatalocalprogramspythonpython35libsite-packagessklearnutilsdeprecation.py:122: FutureWarning: You are accessing a training score (train_score), which will not be available by default any more in 0.21. If you need training scores, please set return_train_score=True warnings.warn(*warn_args, **warn_kwargs){fit_time: array([0.00300527, 0.00200486, 0.00201297]), score_time: array([0.05665517, 0.05461693, 0.04962397]), test_score: array([0.97777778, 0.98503741, 0.97481108]), train_score: array([0.99122807, 0.98628429, 0.98883375])}
學習曲線這個函數很有趣,是通過可視化的結果來觀察某個參數和訓練結果的關係。下面我們使用SVC(SVM的分類形式)來介紹一下畫圖。
from sklearn.svm import SVCparam_range = np.logspace(-6, -1, 5)train_scores, test_scores = validation_curve(SVC(), X, Y, param_name="gamma", param_range=param_range,cv=10, scoring="accuracy")# 得到的訓練結果是k折的,所以需要取一下平均train_scores_mean = np.mean(train_scores, axis=1)test_scores_mean = np.mean(test_scores, axis=1)plt.semilogx(param_range, train_scores_mean, label="Training score")plt.semilogx(param_range, test_scores_mean, label="Cross-validation score")plt.title("Validation Curve with SVM")plt.xlabel("$gamma$")plt.ylabel("Score")plt.ylim(0.0, 1.1)plt.legend(loc="best")plt.show()
我們接下來對結果進行進一步的指標衡量,sklearn.metrics模塊包含分數、優劣的衡量。
# 分類衡量from sklearn import metricsmetrics.accuracy_score(y_test,model.predict(X_test))
0.9814814814814815
print(metrics.classification_report(y_test,model.predict(X_test)))
precision recall f1-score support 0 1.00 1.00 1.00 60 1 0.95 0.98 0.97 62 2 1.00 1.00 1.00 59 3 0.97 0.98 0.98 63 4 0.98 0.98 0.98 62 5 0.97 1.00 0.98 60 6 1.00 1.00 1.00 60 7 0.96 1.00 0.98 54 8 0.98 0.93 0.96 58 9 1.00 0.93 0.96 56avg / total 0.98 0.98 0.98 594
5、聚類分析
Sklearn.cluster包括許多流行的聚類演算法。聚類屬於非監督學習,是將類似的數據進行聚合的過程。輸入需要分類的數據和分類數量,的到分類的結果,也可以對數據進行測試。這一塊做得比較少,簡單舉個例子。
from sklearn.cluster import KMeansimport numpy as npX = np.array([[1, 2], [1, 4], [1, 0], [4, 2], [4, 4], [4, 0]])kmeans = KMeans(n_clusters=2, random_state=0).fit(X)kmeans.labels_
array([0, 0, 0, 1, 1, 1])
kmeans.cluster_centers_
array([[1., 2.], [4., 2.]])
6、總結
Python數據分析相關的庫有Numpy、Pandas、Matplotlib、Scipy、Sklearn和Tensorflow等等。庫在不斷地更新,也在不斷地增加,對於我們使用者來說,沒有辦法顧全庫的方方面面,因此我們需要有選擇的學習庫的使用。對我來說就是首先需要明確庫的用途和場合,以便之後解決問題。其次對庫的框架有一個清晰地了解,對每一部分的功能和基本概念有所了解。最後就是學習資料的搜集和整理(首選官方文檔,之後是一些學習經驗)。學習庫不是目的,我們最終的目的是培養解決問題的思維和能力,知行合一。
推薦閱讀:
※爬取豆瓣電影短評做中文分詞與數據分析
※從數據分析結果到決策
※python 數據分析的基礎學習
※大數據計算服務MaxCompute 5月新功能發布一覽
※談談數據科學