第二章 使用scikit-learn進行分類預測

2020-12-25 學習其實很有趣

本文主要介紹了scikit-learn estimators、Nearest neighbors、Distance metrics、pipeline等數據分析中經常用到的知識 。

本文是小編根據課程教材及網絡收集的資料結合自己所學所思翻譯整理,糾錯指正、深入探討,咱們評論區見。

01

scikit-learn estimators

estimators,允許算法的標準化實現和測試一個通用的、輕量級的接口,供分類器遵循。通過使用這個接口,我們可以將這些工具應用於任意分類器,而不需要擔心算法如何工作。

可以簡單的理解為這個估算器就是scikit-learn這個強大的工具包中的各個小工具的統稱。

estimators 必須具備以下兩個重要的函數:

fit():該函數執行算法的訓練--設置內部參數值。這個函數執行算法的訓練--設置內部參數的值。fit()需要兩個輸入,即訓練樣本數據集和這些樣本對應的類。predict():這裡我們提供的測試樣本作為唯一的輸入。這個函數返回一個NumPy數組,裡面有每個輸入測試樣本的預測值。 大多數scikit-learn估計器都使用NumPy數組或相關格式作為輸入和輸出。然而這是慣例,並不是使用接口的必要條件。scikit-learn中實現了很多估計器,其他開源項目中也有更多的估計器使用相同的接口。例如(SVM)、隨機森林。後面的章節將會提到這些算法。在本章將使用最近鄰算法。

02

Nearest neighbors

其原理是取最相似的樣本,並預測這些附近樣本中的大多數樣本所具有的相同類別。

基於此算法下圖中的星號最可能是紅色橢圓。

最近鄰域幾乎可用於任何數據集。然而計算所有樣本對之間的距離,計算成本很高。例如,如果數據集中有10個樣本,就有45個獨立的距離需要計算。然而,如果有1000個樣本,則有近500,000個樣本。 有各種方法可以提高這個速度,比如使用樹形結構進行距離計算。其中一些算法可能相當複雜,但值得慶幸的是,scikit-learn中已經實現了一個版本,使我們能夠在更大的數據集上進行分類。由於這些樹形結構是scikit-learn中的默認結構,我們不需要配置任何東西就可以使用它。在基於分類的數據集上,最近鄰算法做得很差,有分類特徵的數據集,應該用另一種算法來代替。Nearest Neighbor的問題是由於難以比較分類值的差異,這一點最好留給可以給每個特徵的重要性加權的算法。比較分類特徵可以通過一些距離度量或預處理步驟來完成,比如後面章節中使用的 one hot encoding 。為任務選擇正確的算法是數據挖掘中的難點之一,通常情況下,測試一組算法,看看哪種算法在你的任務上表現最好,是最簡單的選擇方式。

03

Distance metrics

數據挖掘中一個關鍵的基礎概念是距離。如果我們有兩個樣本,我們需要回答這樣的問題:這兩個樣本是否比其他兩個樣本更相似?回答這樣的問題對數據挖掘工作的結果很重要。最常用的是歐氏距離,也就是現實世界中兩個物體之間的距離。如果你要把點繪製在圖上,用尺子測量距離,結果就是歐氏距離。

常見的還有曼哈頓距離和餘弦距離

曼哈頓距離是每個特徵的絕對差異之和(不使用平方距離)。

餘弦距離更適合於一些特徵比其他特徵大,以及數據集中有很多零的情況。

假設有很多特徵,隨機樣本之間的歐氏距離會收斂(由於著名的維度詛咒)。高維度的歐氏距離很難比較樣本,因為距離總是幾乎相同。曼哈頓距離在這種情況下可以更穩定,但如果一些特徵的值非常大,就會蓋過其他特徵的很多相似性。例如,如果特徵A的值在1到2之間,而另一個特徵B的值在1000到2000之間,在這種情況下,特徵A不太可能對結果有任何影響。這個問題可以通過歸一化來解決,這使得曼哈頓(和歐幾裡得)距離在不同特徵下更加可靠,這一點我們將在本章後面看到。最後,Cosine距離是比較具有許多特徵的項目的一個很好的度量,但是它丟棄了一些關於向量長度的信息,這在一些應用中是有用的。由於文本挖掘中固有的大量特徵,我們經常會在文本挖掘中使用Cosine距離。

在本章將繼續使用歐氏距離,在後面的章節中使用其他度量。不過大家可以嘗試將度量設置為曼哈頓,看看這對結果有什麼影響。

04

讀取數據

數據集電離層,天線的目的是確定電離層和高層大氣中是否有結構的區域。我們認為有結構的讀數是好的,而沒有結構的讀數被認為是壞的。本應用的目的是建立一個數據挖掘分類器,可以判斷一個圖像是好還是壞。

首先像前一章那樣新建一個jupyter notebook。

或者選擇一個你喜歡的在線編譯網站新建一個python3項目,首先導入將要用到的應用庫,並導入我們將要處理的數據,我已將所要用到的數據上傳到了自己的GitHub.

import pandas as pd import numpy as npimport csvdata_filename = 'https://raw.githubusercontent.com/neowalter/DA-tour/master/charpter2/ionosphere.data'df = pd.read_csv(data_filename)df.describe

這裡我們可以先用describe功能看一下數據讀取是否成功。

讀取正常

05

標準工作流程

這裡我們通過對數據的屬性來對其進行分類。

這裡我們需要重新將文件下載到本地,再進行讀取操作。下面的文件地址需要修改為自己的文件存放地址

#change this to the location where your file is locateddata_filename = "/content/ionosphere.data"print(data_filename)X = np.zeros((351, 34), dtype='float')y = np.zeros((351,), dtype='bool')with open(data_filename, 'r') as input_file: reader = csv.reader(input_file) for i, row in enumerate(reader):# Get the data, converting each item to a float data = [float(datum) for datum in row[:-1]]# Set the appropriate row in our dataset X[i] = data# 1 if the class is 'g', 0 otherwise y[i] = row[-1] == 'g'

我們在測試集上使用fit()方法訓練算法。我們在測試集上使用predict()方法對其進行評估。

from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, random_state=14)print("There are {} samples in the training dataset".format(X_train.shape[0]))print("There are {} samples in the testing dataset".format(X_test.shape[0]))print("Each sample has {} features".format(X_train.shape[1]))from sklearn.neighbors import KNeighborsClassifierestimator = KNeighborsClassifier()estimator.fit(X_train, y_train)y_predicted = estimator.predict(X_test)accuracy = np.mean(y_test == y_predicted) * 100print("The accuracy is {0:.1f}%".format(accuracy))

這個模型的準確率達到了86.4%,對於一個默認算法和幾行代碼來說,這是很少見的。

得到這樣的結果會不會是隨機分組的樣本數據集很合適,所以得分才高呢?我們可以測試一下每個樣本的準確率。

from sklearn.model_selection import cross_val_scorescores = cross_val_score(estimator, X, y, scoring='accuracy')average_accuracy = np.mean(scores) * 100print("The average accuracy is {0:.1f}%".format(average_accuracy))

我們的新代碼返回了一個略微溫和的82.3%的結果,但考慮到我們還沒有嘗試設置更好的參數,這個結果還是相當不錯的。

06

設置參數

幾乎所有的參數,用戶都可以設置,讓算法更專注於特定的數據集,而不是只適用於小範圍的特定問題。設置這些參數是相當困難的,因為選擇好的參數值往往高度依賴於數據集的特徵。最近鄰算法有幾個參數,但最重要的一個參數是在預測未見歸屬的類時使用的最近鄰數量。在scikit-learn中,這個參數叫做n_neighbors。在下圖中,我們表明,當這個數字太低時,隨機標記的樣本會導致錯誤。相反,當它過高時,實際最近的鄰居對結果的影響較小。

最近鄰域一個很難解決的問題,因為參數會產生巨大的差異。幸運的是,大多數時候,具體的參數值不會對最終結果產生很大影響,標準值(通常是5或10)往往已經足夠接近。

考慮到這一點,我們可以測試出一個數值範圍,並研究這個參數對性能的影響。如果我們想測試n_neighbors參數的若干值,例如,從1到20的每個值,我們可以通過設置n_neighbors來重新運行實驗很多次,並觀察結果。下面的代碼就是這樣做的,將數值存儲在avg_scores和all_scores變量中。

avg_scores = []all_scores = []parameter_values = list(range(1, 91))for n_neighbors in parameter_values: estimator = KNeighborsClassifier(n_neighbors=n_neighbors) scores = cross_val_score(estimator, X, y, scoring='accuracy') avg_scores.append(np.mean(scores)) all_scores.append(scores)

然後我們可以繪製n_neighbors的值和精度之間的關係。

from matplotlib import pyplot as pltplt.figure(figsize=(22,10))plt.plot(parameter_values, avg_scores, '-o', linewidth=2, markersize=6)

雖然有很多差異,但隨著n_neighbors的增加,該圖顯示出下降的趨勢。

07

數據預處理

對於一個基於數學的算法來說,要比較這些特徵的每一個特徵,尺度、範圍和單位的差異可能很難解釋。如果我們在很多算法中使用上述特徵,由於只有較大的數字,而與特徵的實際效果無關,因此權重可能是影響最大的特徵。其中一種可能的策略是將特徵歸一化,使它們都有相同的範圍,或者將數值變成小、中、大等類別。特徵類型的巨大差異對算法的影響較小,可以使準確率大幅提高。

預處理還可以用來只選擇更有效的特徵,創建新的特徵等。scikit-learn中的預處理是通過Transformer對象來完成的,Transformer對象將一個數據集以一種形式存在,並在對數據進行一定的轉換後返回一個改變後的數據集。這些不一定是數值上的,因為Transformer也是用來提取特徵的。

理論上來說,這對結果的影響應該不是很大。畢竟,這些特徵的數值還是比較相同的。主要的問題是尺度發生了變化,現在奇數特徵比偶數特徵大。我們可以通過計算精度來觀察這個影響。

我們將對這個實驗進行的預處理叫做基於特徵的歸一化,我們使用scikit-learn的MinMaxScaler類來執行。

from sklearn.preprocessing import MinMaxScalerX_transformed = MinMaxScaler().fit_transform(X)estimator = KNeighborsClassifier()transformed_scores = cross_val_score(estimator, X_transformed, y, scoring='accuracy')print("The average accuracy for is {0:.1f}%".format(np.mean(transformed_scores) * 100))

預處理是數據挖掘管道中的一個關鍵步驟,它可能意味著結果之間的巨大差異。

08

Pipeline

隨著實驗的增長,操作的複雜性也在增加。我們可能會拆分數據集,對特徵進行二元化,執行基於特徵的縮放,執行基於樣本的縮放,以及更多的操作。追蹤這些操作可能會變得相當混亂,並可能導致無法複製結果。問題包括忘記了一個步驟,錯誤地應用了一個變換,或者添加了一個不需要的變換。

在後面的章節中,我們將使用更高級的測試方法,而設置管道是確保代碼複雜度不至於不可收拾地增長的好方法。

from sklearn.pipeline import Pipelinescaling_pipeline = Pipeline([('scale', MinMaxScaler()),('predict', KNeighborsClassifier())])scores = cross_val_score(scaling_pipeline, X, y, scoring='accuracy')print("The pipeline scored an average accuracy for is {0:.1f}%".format(np.mean(transformed_scores) * 100))

完整代碼已上傳至github :

https://github.com/neowalter/DA-tour/tree/master/charpter2

END

其他筆記推薦

項目管理學習筆記匯總

相關焦點

  • 使用scikit-learn進行機器學習
    1.基本用例:訓練和測試分類器練習2.更高級的用例:在訓練和測試分類器之前預處理數據2.1 標準化您的數據2.2 錯誤的預處理模式2.3 保持簡單,愚蠢:使用scikit-learn的管道連接器練習3.當更多優於更少時:交叉驗證而不是單獨拆分練習4.超參數優化:微調管道內部練習5.總結:我的scikit-learn管道只有不到10行代碼(跳過import語句)6.異構數據:當您使用數字以外的數據時練習
  • 使用scikit-learn進行數據預處理
    1.基本用例:訓練和測試分類器練習2.更高級的用例:在訓練和測試分類器之前預處理數據2.1 標準化您的數據2.2 錯誤的預處理模式2.3 保持簡單,愚蠢:使用scikit-learn的管道連接器練習3.當更多優於更少時:交叉驗證而不是單獨拆分練習4.超參數優化:微調管道內部練習5.總結:我的scikit-learn管道只有不到10行代碼(跳過import語句)6.異構數據:當您使用數字以外的數據時練習
  • Scikit-learn估計器分類
    Scikit-learn實現了一系列數據挖掘算法,提供通用編程接口、標準化的測試和調參公局,便於用戶嘗試不同算法對其進行充分測試和查找最優參數值。本次講解數據挖掘通用框架的搭建方法。有了這樣一個框架,後續章節就可以把講解重點放到數據挖掘應用和技術上面。為幫助用戶實現大量分類算法,scikit-learn把相關功能封裝成估計器。估計器用於分類任務,它主要包括兩個函數。
  • 一遍就懂的Scikit-Learn機器學習分類過程
    監督學習具備針對特定問題的輸入及輸出數據(也稱為訓練數據,通常由領域專家提供),目標是讓機器在進行訓練後,能夠發現輸入數據到輸出數據的一般映射規則。經過適當的訓練後,機器可以在特定精度水平下預測任何輸入的輸出。例如我們將在本文中討論的分類問題(鳶尾花問題)。
  • scikit-learn機器學習簡介
    其中包括:分類:樣本屬於兩個或多個類別,我們想從已經標記的數據中學習如何預測未標記數據的類別。分類問題的一個例子是手寫數字識別,手寫數字識別的目的是將每個輸入向量分配給有限的離散類別中的一個。分類問題作為一種離散的(與連續相反)監督學習形式,它有有限的類別,並且對於所提供的n個預測樣本中的每個樣本,嘗試使用正確的類別來標記。回歸:如果所期待的輸出包含一個或多個連續變量,則該任務稱為回歸。
  • 使用Scikit-learn 理解隨機森林
    我的一些代碼包正在做相關工作,然而,大多數隨機森林算法包(包括 scikit-learn)並沒有給出預測過程的樹路徑。因此 sklearn 的應用需要一個補丁來展現這些路徑。幸運的是,從 0.17 版本的 scikit-learn 開始,在 api 中有兩個新增功能,這使得這個過程相對而言比較容易理解 : 獲取用於預測的所有葉子節點的 id ,並存儲所有決策樹的所有節點中間值,而不僅僅只存葉子節點的。通過這些,我們可以提取每個單獨預測的樹路徑,並通過檢查路徑來分解這些預測過程。
  • Scikit-learn使用總結
    在機器學習和數據挖掘的應用中,scikit-learn是一個功能強大的python包。在數據量不是過大的情況下,可以解決大部分問題。學習使用scikit-learn的過程中,我自己也在補充著機器學習和數據挖掘的知識。這裡根據自己學習sklearn的經驗,我做一個總結的筆記。另外,我也想把這篇筆記一直更新下去。
  • python機器學習之使用scikit-learn庫
    引言數據分析由一連串的步驟組成,對於其中預測模型的創建和驗證這一步,我們使用scikit-learn這個功能強大的庫來完成。scikit-learning庫python庫scikit-learn整合了多種機器學習算法。
  • Scikit-Learn機器學習實踐:垃圾簡訊識別
    Scikit-Learn的API設計非常合理和高效,對於初觸機器學習的同學來說非常友好,值得大家嘗試和使用。本人也經常在實驗環境和工作環境中使用scikit-learn進行機器學習的建模。下面,我們就使用scikit-learn模塊,通過其樸素貝葉斯算法API對簡訊數據進行一次垃圾簡訊的識別。
  • 用 Scikit-learn 與 Pandas 進行線性回歸預測
    也不用我們搞,後面scikit-learn在線性回歸時會先幫我們把歸一化搞定。好了,有了這個csv格式的數據,我們就可以大幹一場了。我們先打開ipython notebook,新建一個notebook。當然也可以直接在python的交互式命令行裡面輸入,不過還是推薦用notebook。下面的例子和輸出我都是在notebook裡面跑的。
  • Python + Scikit-learn 完美入門機器學習指南 ​
    如果你是一名 Python 程式設計師,又正好想學習一下人工智慧技術,scikit-learn 可能是你最好的選擇之一。實驗樓上線了一門新課 —《scikit-learn 機器學習入門實戰》,可以帶大家快速掌握 scikit-learn 框架使用方法、機器學習基礎概念、常用算法等知識點,並通過模型的搭建和選擇,進一步提升你的實踐能力。
  • 極簡Scikit-Learn入門
    ,scikit-learn是一個功能強大的python包。scikit-learn內置了很多機器學習模塊,也提供了很多數據集。http://scikit-learn.org/stable/modules/classes.html#module-sklearn.datasetsSklearn包含的常用算法裡介紹過常用的算法,scikit-learn中學習模式的調用,有很強的統一性,很多都是類似的,學會一個,其他基本差不多。
  • 使用 scikit-learn 玩轉機器學習——集成學習
    假如森林中有 N 棵樹,那麼就隨機取出 N 個訓練數據集,對 N 棵樹分別進行訓練,通過統計每棵樹的預測結果來得出隨機森林的預測結果。換句話說,就是對於特徵集 X,隨機森林只是在行上隨機,Extremely Randomized Trees是在行和列上都隨機,下面我們調用演示下 scikit-learn 中的 Extremely Randomized Trees 的分類器:
  • 直答理工:機器學習——scikit-learn入門
    這樣問題的目標可能是發現相似例子的類別,也叫聚類,或是決定輸入數據的分布,作為密度預測,或是映射高維空間的數據到二到三維用於可視化。接下來將從具體介紹機器學習的基本概念及其在scikit-learn中實際操作。
  • Python中的人工智慧入門:在scikit-learn中的建模
    此外,我們將使用seaborn和scikit-plot庫進行可視化,所以我們也將安裝它們。!pip install seaborn scikit-plot使用如此知名的數據集的方便之處在於,我們可以很容易地從很多包中加載數據集,例如,像這樣。
  • scikit-learn—樸素貝葉斯
    伯努利樸素貝葉斯不同於多項式樸素貝葉斯的規則,因為伯努利樸素貝葉斯顯式地懲罰了作為類y的預測因子,對於不出現的特徵i,多項式樸素貝葉斯會簡單地忽略掉。在文本分類的情況下,可以使用單詞出現向量(而不是單詞計數向量)來訓練和使用該分類器。BernoulliNB可能在一些數據集上表現得更好,尤其是那些短文檔的數據集。如果時間允許,最好對兩種模型進行評估。C.D. Manning, P.
  • Scikit-Learn決策樹算法類庫使用小結
    scikit-learn決策樹算法類庫內部實現是使用了調優過的CART樹算法,既可以做分類,又可以做回歸。
  • 7個常用的Scikit-learn使用技巧
    Python的scikit學習庫。learn 技巧4–建立分類的baseline模型Scikit learn 技巧7-Pickle持久化模型Scikit learn 技巧1–用於回歸的虛擬數據讓我們從最基本的開始,你可以使用sklearn的make_regression函數生成自己的隨機數據來執行線性回歸。
  • 用 Scikit-learn Pipeline 創建機器學習流程
    本文翻譯自:https://medium.com/vickdata/a-simple-guide-to-scikit-learn-pipelines
  • 4步預測網絡暴力!用scikit-learn解救蔡徐坤
    本文介紹一個自動檢測仇恨言論系統——使用scikit-learn構建,並通過Heroku上的Docker進行部署。作為線上留言板或評論區的監管員,在網上評論開始出現攻擊性、和辱罵性言語時能得到快速提醒。及時採取控制措施。工作流程只需四步:1. 用scikit-learn訓練並堅持使用一個預測模型2.