機器學習(machine learning)是從數(shù)據(jù)中提取知識。它是統(tǒng)計學茅信、人工智能和計算機科學交叉的研究領域屹徘,也被稱為預測分析(predictive analytics)或統(tǒng)計學習(statistical learning)。近年來沐旨,機器學習方法已經應用到日常生活的方方面面森逮。從自動推薦看什么電影、點什么食物磁携、買什么商品褒侧,到個性化的在線電臺和從照片中識別好友,許多現(xiàn)代化網站和設備的核心都是機器學習算法。當你訪問像 Facebook闷供、 Amazon 或 Netflix 這樣的復雜網站時烟央,很可能網站的每一部分都包含多種機器學習模型。
除了商業(yè)應用之外歪脏,機器學習也對當前數(shù)據(jù)驅動的研究方法產生了很大影響疑俭。本書中介紹的工具均已應用在各種科學問題上,比如研究恒星婿失、尋找遙遠的行星钞艇、發(fā)現(xiàn)新粒子、分析DNA 序列移怯,以及提供個性化的癌癥治療方案香璃。
不過,如果想受益于機器學習算法舟误,你的應用無需像上面那些例子那樣給世界帶來重大改變葡秒,數(shù)據(jù)量也用不著那么大。本章將解釋機器學習如此流行的原因嵌溢,并探討機器學習可以解決哪些類型的問題眯牧。然后將向你展示如何構建第一個機器學習模型,同時介紹一些重要的概念赖草。
1.1 為何選擇機器學習
在“智能”應用的早期学少,許多系統(tǒng)使用人為制訂的“if”和“else”決策規(guī)則來處理數(shù)據(jù),或根據(jù)用戶輸入的內容進行調整秧骑。想象有一個垃圾郵件過濾器版确,其任務是酌情將收到的某些郵件移動到垃圾郵件文件夾。你可以創(chuàng)建一個關鍵詞黑名單乎折,所有包含這些關鍵詞的郵件都會被標記為垃圾郵件绒疗。這是用專家設計的規(guī)則體系來設計“智能”應用的一個示例。
人為制訂的決策規(guī)則對某些應用來說是可行的骂澄,特別是人們對其模型處理過程非常熟悉的應用吓蘑。但是,人為制訂決策規(guī)則主要有兩個缺點坟冲。
? 做決策所需要的邏輯只適用于單一領域和單項任務磨镶。任務哪怕稍有變化,都可能需要重寫整個系統(tǒng)健提。
? 想要制訂規(guī)則琳猫,需要對人類專家的決策過程有很深刻的理解。
這種人為制訂規(guī)則的方法并不適用的一個例子就是圖像中的人臉檢測私痹。如今沸移,每臺智能手機都能夠檢測到圖像中的人臉痪伦。但直到 2001 年,人臉檢測問題才得到解決雹锣。其主要問題在于网沾,計算機“感知”像素(像素組成了計算機中的圖像)的方式與人類感知面部的方式有非常大的不同。正是由于這種表征差異蕊爵,人類想要制訂出一套好的規(guī)則來描述數(shù)字圖像的人臉構成辉哥,基本上是不可能的。但有了機器學習算法攒射,僅向程序輸入海量人臉圖像醋旦,就足以讓算法確定識別人臉需要哪些特征。
1.1.1 機器學習能夠解決的問題
最成功的機器學習算法是能夠將決策過程自動化的那些算法会放,這些決策過程是從已知示例中泛化得出的饲齐。在這種叫作監(jiān)督學習(supervised learning)的方法中,用戶將成對的輸入和預期輸出提供給算法咧最,算法會找到一種方法捂人,根據(jù)給定輸入給出預期輸出。尤其是在沒有人類幫助的情況下矢沿,給定前所未見的輸入滥搭,算法也能夠給出相應的輸出〉肪ǎ回到前面垃圾郵件分類的例子瑟匆,利用機器學習算法,用戶為算法提供大量電子郵件(作為輸入)栽惶,以及這些郵件是否為垃圾郵件的信息(作為預期輸出)愁溜。給定一封新郵件,算法就能夠預測它是否為垃圾郵件外厂。
從輸入 / 輸出對中進行學習的機器學習算法叫作監(jiān)督學習算法(supervised learning algorithm)祝谚,因為每個用于算法學習的樣例都對應一個預期輸出, 好像有一個“老師”在監(jiān)督著算法酣衷。雖然創(chuàng)建一個包含輸入和輸出的數(shù)據(jù)集往往費時又費力,但監(jiān)督學習算法很好理解次泽,其性能也易于測量穿仪。如果你的應用可以表示成一個監(jiān)督學習問題,并且你能夠創(chuàng)建包含預期輸出的數(shù)據(jù)集意荤,
那么機器學習很可能可以解決你的問題啊片。
監(jiān)督機器學習任務的示例如下。
識別信封上手寫的郵政編碼
這里的輸入是掃描的手寫數(shù)字玖像,預期輸出是郵政編碼中的實際數(shù)字紫谷。想要創(chuàng)建用于構建機器學習模型的數(shù)據(jù)集,你需要收集許多信封。然后你可以自己閱讀郵政編碼笤昨,將數(shù)字保存為預期輸出祖驱。
基于醫(yī)學影像判斷腫瘤是否為良性
這里的輸入是影像,輸出是腫瘤是否為良性瞒窒。想要創(chuàng)建用于構建模型的數(shù)據(jù)集捺僻,你需要一個醫(yī)學影像數(shù)據(jù)庫。你還需要咨詢專家的意見崇裁,因此醫(yī)生需要查看所有影像匕坯,然后判斷哪些腫瘤是良性的,哪些不是良性的拔稳。除了影像內容之外葛峻,甚至可能還需要做額外的診斷來判斷影像中的腫瘤是否為癌變。
檢測信用卡交易中的詐騙行為
這里的輸入是信用卡交易記錄巴比,輸出是該交易記錄是否可能為詐騙术奖。假設你是信用卡的發(fā)行單位,收集數(shù)據(jù)集意味著需要保存所有的交易匿辩,并記錄用戶是否上報過任何詐騙交易腰耙。
在這些例子中需要注意一個有趣的現(xiàn)象,就是雖然輸入和輸出看起來相當簡單铲球,但三個例子中的數(shù)據(jù)收集過程卻大不相同挺庞。閱讀信封雖然很辛苦,卻非常簡單稼病,也不用花多少錢选侨。與之相反,獲取醫(yī)學影像和診斷不僅需要昂貴的設備然走,還需要稀有又昂貴的專家知識援制,更不要說倫理問題和隱私問題了。在檢測信用卡詐騙的例子中芍瑞,收集數(shù)據(jù)要容易得多晨仑。你的顧客會上報詐騙行為,從而為你提供預期輸出拆檬。要獲取所有欺詐行為和非欺詐行為的輸入/輸出對洪己,你只需等待即可。
本書會講到的另一類算法是無監(jiān)督學習算法(unsupervised learning algorithm)竟贯。在無監(jiān)督學習中答捕,只有輸入數(shù)據(jù)是已知的,沒有為算法提供輸出數(shù)據(jù)屑那。雖然這種算法有許多成功的應用拱镐,但理解和評估這些算法往往更加困難艘款。
無監(jiān)督學習的示例如下。
確定一系列博客文章的主題
如果你有許多文本數(shù)據(jù)沃琅,可能想對其進行匯總哗咆,并找到其中共同的主題。事先你可能并不知道都有哪些主題阵难,或者可能有多少個主題岳枷。所以輸出是未知的。
將客戶分成具有相似偏好的群組
給定一組客戶記錄呜叫,你可能想要找出哪些客戶比較相似空繁,并判斷能否根據(jù)相似偏好對這些客戶進行分組。對于一家購物網站來說朱庆,客戶分組可能是“父母”“書蟲”或“游戲玩家”盛泡。由于你事先并不知道可能有哪些分組,甚至不知道有多少組娱颊,所以并不知道輸出是什么傲诵。
檢測網站的異常訪問模式
想要識別網站的濫用或 bug,找到異常的訪問模式往往是很有用的箱硕。每種異常訪問模式都互不相同拴竹,而且你可能沒有任何記錄在案的異常行為示例。在這個例子中你只是觀察流量剧罩,并不知道什么是正常訪問行為和異常訪問行為栓拜,所以這是一個無監(jiān)督學習問題。
無論是監(jiān)督學習任務還是無監(jiān)督學習任務惠昔,將輸入數(shù)據(jù)表征為計算機可以理解的形式都是十分重要的幕与。通常來說,將數(shù)據(jù)想象成表格是很有用的镇防。你想要處理的每一個數(shù)據(jù)點(每一封電子郵件啦鸣、每一名客戶、每一次交易)對應表格中的一行来氧,描述該數(shù)據(jù)點的每一項屬性(比如客戶年齡诫给、交易金額或交易地點)對應表格中的一列。你可能會從年齡啦扬、性別中狂、賬號創(chuàng)建時間、在你的購物網站上的購買頻率等方面來描述用戶考传。你可能會用每一個像素的灰度值來描述腫瘤圖像,也可能利用腫瘤的大小证鸥、形狀和顏色進行描述僚楞。
在機器學習中勤晚,這里的每個實體或每一行被稱為一個樣本(sample)或數(shù)據(jù)點,而每一列(用來描述這些實體的屬性)則被稱為特征(feature)泉褐。
本書后面會更詳細地介紹如何構建良好的數(shù)據(jù)表征赐写,這被稱為特征提取(feature extraction)或特征工程(feature engineering)膜赃。但你應該記住挺邀,如果沒有數(shù)據(jù)信息的話,所有機器學習算法都無法做出預測跳座。舉個例子端铛,如果你只有病人的姓氏這一個特征,那么任何算法都無法預測其性別疲眷。這一信息并未包含在數(shù)據(jù)中禾蚕。如果你添加另一個特征,里面包含病人的名字狂丝,那么你預測正確的可能性就會變大换淆,因為通過一個人的名字往往可以判斷其性別。
1.1.2 熟悉任務和數(shù)據(jù)
在機器學習過程中几颜,最重要的部分很可能是理解你正在處理的數(shù)據(jù)倍试,以及這些數(shù)據(jù)與你想要解決的任務之間的關系。隨機選擇一個算法并將你的數(shù)據(jù)輸入進去蛋哭,這種做法是不會有什么用的县习。在開始構建模型之前,你需要理解數(shù)據(jù)集的內容具壮。每一種算法的輸入數(shù)據(jù)類型和最適合解決的問題都是不一樣的准颓。在構建機器學習解決方案的過程中,你應該給出下列問題的答案棺妓,或者至少要將這些問題記在腦中攘已。
? 我想要回答的問題是什么?已經收集到的數(shù)據(jù)能夠回答這個問題嗎怜跑?
? 要將我的問題表示成機器學習問題样勃,用哪種方法最好?
? 我收集的數(shù)據(jù)是否足夠表達我想要解決的問題性芬?
? 我提取了數(shù)據(jù)的哪些特征峡眶?這些特征能否實現(xiàn)正確的預測?
? 如何衡量應用是否成功植锉?
? 機器學習解決方案與我的研究或商業(yè)產品中的其他部分是如何相互影響的辫樱?
從更大的層面來看,機器學習算法和方法只是解決特定問題的過程中的一部分俊庇,一定要始終牢記整個項目的大局狮暑。許多人浪費大量時間構建復雜的機器學習解決方案鸡挠,最終卻發(fā)現(xiàn)沒有解決正確的問題。
當深入研究機器學習的技術細節(jié)時(本書會講到這些細節(jié))搬男,很容易忽視最終目標拣展。我們雖然不會詳細討論上面列出的問題,但仍然鼓勵你記住自己在開始構建機器學習模型時做出的假設缔逛,無論是明確的還是隱含的假設备埃。
1.2 為何選擇Python
Python 已經成為許多數(shù)據(jù)科學應用的通用語言。它既有通用編程語言的強大功能褐奴,也有特定領域腳本語言(比如 MATLAB 或 R)的易用性按脚。 Python 有用于數(shù)據(jù)加載、可視化歉糜、統(tǒng)計乘寒、自然語言處理、圖像處理等各種功能的庫匪补。這個大型工具箱為數(shù)據(jù)科學家提供了大量的通用功能和專用功能伞辛。使用 Python 的主要優(yōu)點之一,就是利用終端或其他類似 Jupyter Notebook 的工具能夠直接與代碼進行交互夯缺;我們很快會講到 Jupyter Notebook蚤氏。機器學習和數(shù)據(jù)分析本質上都是迭代過程,由數(shù)據(jù)驅動分析踊兜。這些過程必須要有快速迭代和易于交互的工具竿滨。
作為通用編程語言, Python 還可以用來創(chuàng)建復雜的圖形用戶界面(graphical user interface捏境,GUI)和 Web 服務于游,也可以集成到現(xiàn)有系統(tǒng)中。
1.3 scikit-learn
scikit-learn 是一個開源項目垫言,可以免費使用和分發(fā)贰剥,任何人都可以輕松獲取其源代碼來查看其背后的原理。 scikit-learn 項目正在不斷地開發(fā)和改進中筷频,它的用戶社區(qū)非嘲龀桑活躍。它包含許多目前最先進的機器學習算法凛捏,每個算法都有詳細的文檔(http://scikit-learn.org/stable/documentation)担忧。 scikit-learn 是一個非常流行的工具,也是最有名的 Python 機器學習庫坯癣。它廣泛應用于工業(yè)界和學術界瓶盛,網上有大量的教程和代碼片段函筋。 scikit-learn也可以與其他大量 Python 科學計算工具一起使用榴啸,本章后面會講到相關內容净响。
在閱讀本書的過程中酵镜,我們建議你同時瀏覽 scikit-learn 用戶指南(http://scikit-learn.org/stable/user_guide.html)和 API 文檔馍驯,里面給出了每個算法的更多細節(jié)和更多選項够挂。在線文檔非常全面掉分,而本書會介紹機器學習的所有必備知識逐虚,以便于你深入了解禽额。
安裝scikit-learn
scikit-learn 依賴于另外兩個 Python 包: NumPy 和 SciPy锯厢。若想繪圖和進行交互式開發(fā),還應該安裝 matplotlib脯倒、 IPython 和 Jupyter Notebook实辑。我們推薦使用下面三個預先打包的Python 發(fā)行版之一,里面已經裝有必要的包藻丢。
Anaconda(https://store.continuum.io/cshop/anaconda/)
用于大規(guī)模數(shù)據(jù)處理剪撬、預測分析和科學計算的 Python 發(fā)行版。 Anaconda 已經預先安裝好 NumPy悠反、 SciPy残黑、 matplotlib、 pandas斋否、 IPython梨水、 Jupyter Notebook 和 scikit-learn。它可以在 Mac OS茵臭、 Windows 和 Linux 上運行疫诽,是一種非常方便的解決方案。對于尚未安裝 Python 科學計算包的人旦委,我們建議使用 Anaconda奇徒。 Anaconda 現(xiàn)在還免費提供商用的 Intel MKL 庫。 MKL(在安裝 Anaconda 時自動安裝)可以使 scikit-learn 中許多算法的速度大大提升缨硝。
Enthought Canopy(https://www.enthought.com/products/canopy/)
用于科學計算的另一款 Python 發(fā)行版摩钙。它已經預先裝有 NumPy、 SciPy追葡、 matplotlib腺律、pandas 和 IPython,但免費版沒有預先安裝 scikit-learn宜肉。如果你是能夠授予學位的學術機構的成員匀钧,可以申請學術許可,免費使用 Enthought Canopy 的付費訂閱版谬返。Enthought Canopy 適用于 Python 2.7.x之斯,可以在 Mac OS、 Windows 和 Linux 上運行遣铝。
Python(x,y)(http://python-xy.github.io/)
專門為 Windows 打造的 Python 科學計算免費發(fā)行版佑刷。 Python(x,y) 已經預先裝有 NumPy莉擒、SciPy、 matplotlib瘫絮、 pandas涨冀、 IPython 和 scikit-learn。
如果你已經安裝了 Python麦萤,可以用 pip 安裝上述所有包:
$ pip install numpy scipy matplotlib ipython scikit-learn pandas
1.4 必要的庫和工具
了解 scikit-learn 及其用法是很重要的鹿鳖,但還有其他一些庫也可以改善你的編程體驗。scikit-learn 是基于 NumPy 和 SciPy 科學計算庫的壮莹。除了 NumPy 和 SciPy翅帜,我們還會用到 pandas 和 matplotlib。我們還會介紹 Jupyter Notebook命满,一個基于瀏覽器的交互編程環(huán)境涝滴。簡單來說,對于這些工具胶台,你應該了解以下內容歼疮,以便充分利用 scikit-learn。 1
1.4.1 Jupyter Notebook
Jupyter Notebook 是可以在瀏覽器中運行代碼的交互環(huán)境诈唬。這個工具在探索性數(shù)據(jù)分析方面非常有用腋妙,在數(shù)據(jù)科學家中廣為使用。雖然 Jupyter Notebook 支持多種編程語言讯榕,但我們只需要支持 Python 即可骤素。用 Jupyter Notebook 整合代碼、文本和圖像非常方便愚屁,實際上本書所有內容都是以 Jupyter Notebook 的形式進行編寫的济竹。所有代碼示例都可以在 GitHub 下載(https://github.com/amueller/introduction_to_ml_with_python)。
1.4.2 NumPy
NumPy 是 Python 科學計算的基礎包之一霎槐。它的功能包括多維數(shù)組送浊、高級數(shù)學函數(shù)(比如線性代數(shù)運算和傅里葉變換),以及偽隨機數(shù)生成器丘跌。
在 scikit-learn 中袭景, NumPy 數(shù)組是基本數(shù)據(jù)結構。 scikit-learn 接受 NumPy 數(shù)組格式的數(shù)據(jù)闭树。你用到的所有數(shù)據(jù)都必須轉換成 NumPy 數(shù)組耸棒。 NumPy 的核心功能是 ndarray 類,即多維(n 維)數(shù)組报辱。數(shù)組的所有元素必須是同一類型与殃。 NumPy 數(shù)組如下所示:
In[2]:
import numpy as np
x = np.array([[1, 2, 3], [4, 5, 6]])
print("x:\n{}".format(x))
Out[2]:
x:
[[1 2 3]
[4 5 6]]
本書會經常用到 NumPy。對于 NumPy ndarray 類的對象,我們將其簡稱為“NumPy 數(shù)組”或“數(shù)組”幅疼。
1.4.3 SciPy
SciPy 是 Python 中用于科學計算的函數(shù)集合米奸。它具有線性代數(shù)高級程序、數(shù)學函數(shù)優(yōu)化爽篷、信號處理悴晰、特殊數(shù)學函數(shù)和統(tǒng)計分布等多項功能。 scikit-learn 利用 SciPy 中的函數(shù)集合來實現(xiàn)算法逐工。對我們來說膨疏, SciPy 中最重要的是 scipy.sparse:它可以給出稀疏矩陣(sparse matrice),稀疏矩陣是 scikit-learn 中數(shù)據(jù)的另一種表示方法钻弄。如果想保存一個大部分元素都是 0 的二維數(shù)組,就可以使用稀疏矩陣:
In[3]:
from scipy import sparse
#創(chuàng)建一個二維NumPy數(shù)組者吁,對角線為1窘俺,其余都為0
eye = np.eye(4)
print("NumPy array:\n{}".format(eye))
Out[3]:
NumPy array:
[[ 1. 0. 0. 0.]
[ 0. 1. 0. 0.]
[ 0. 0. 1. 0.]
[ 0. 0. 0. 1.]]
In[4]:
# 將NumPy數(shù)組轉換為CSR格式的SciPy稀疏矩陣
# 只保存非零元素
sparse_matrix = sparse.csr_matrix(eye)
print("\nSciPy sparse CSR matrix:\n{}".format(sparse_matrix))
Out[4]:
SciPy sparse CSR matrix:
(0, 0) 1.0
(1, 1) 1.0
(2, 2) 1.0
(3, 3) 1.0
通常來說,創(chuàng)建稀疏數(shù)據(jù)的稠密表示(dense representation)是不可能的(因為太浪費內存)复凳,所以我們需要直接創(chuàng)建其稀疏表示(sparse representation)瘤泪。下面給出的是創(chuàng)建同一稀疏矩陣的方法,用的是 COO 格式:
In[5]:
data = np.ones(4)
row_indices = np.arange(4)
col_indices = np.arange(4)
eye_coo = sparse.coo_matrix((data, (row_indices, col_indices)))
print("COO representation:\n{}".format(eye_coo))
Out[5]:
COO representation:
(0, 0) 1.0
(1, 1) 1.0
(2, 2) 1.0
(3, 3) 1.0
關于 SciPy 稀疏矩陣的更多內容可查閱 SciPy 講稿(http://www.scipy-lectures.org/)育八。
1.4.4 matplotlib
matplotlib 是 Python 主要的科學繪圖庫对途,其功能為生成可發(fā)布的可視化內容,如折線圖髓棋、直方圖实檀、散點圖等。將數(shù)據(jù)及各種分析可視化按声,可以讓你產生深刻的理解膳犹,而我們將用 matplotlib 完成所有的可視化內容。在 Jupyter Notebook 中签则, 你可以使用%matplotlib notebook
和 %matplotlib inline
命令须床,將圖像直接顯示在瀏覽器中。我們推薦使用 %matplotlib notebook
命令渐裂,它可以提供交互環(huán)境(雖然在寫作本書時我們用的是 %matplotlib inline
)豺旬。舉個例子,下列代碼會生成圖 1-1 中的圖像:
In[6]:
%matplotlib inline
import matplotlib.pyplot as plt
# 在-10和10之間生成一個數(shù)列柒凉,共100個數(shù)
x = np.linspace(-10, 10, 100)
# 用正弦函數(shù)創(chuàng)建第二個數(shù)組
y = np.sin(x)
# plot函數(shù)繪制一個數(shù)組關于另一個數(shù)組的折線圖
plt.plot(x, y, marker="x")
1.4.5 pandas
pandas 是用于處理和分析數(shù)據(jù)的 Python 庫族阅。它基于一種叫作 DataFrame 的數(shù)據(jù)結構,這種數(shù)據(jù)結構模仿了 R 語言中的 DataFrame膝捞。簡單來說耘分,一個 pandas DataFrame 是一張表格,類似于 Excel 表格。 pandas 中包含大量用于修改表格和操作表格的方法求泰,尤其是可以像 SQL 一樣對表格進行查詢和連接央渣。NumPy 要求數(shù)組中的所有元素類型必須完全相同,而 pandas 不是這樣渴频,每一列數(shù)據(jù)的類型可以互不相同(比如整型芽丹、日期、浮點數(shù)和字符串)卜朗。pandas 的另一個強大之處在于拔第,它可以從許多文件格式和數(shù)據(jù)庫中提取數(shù)據(jù),如SQL场钉、 Excel 文件和逗號分隔值(CSV)文件蚊俺。 pandas 的詳細功能介紹已經超出了本書的范圍。但 Wes McKinney 的《Python 數(shù)據(jù)處理》一書是很好的參考指南逛万。下面是利用字典建 DataFrame 的一個小例子:
In[7]:
import pandas as pd
from IPython.display import display
# 創(chuàng)建關于人的簡單數(shù)據(jù)集
data = {'Name': ["John", "Anna", "Peter", "Linda"],
'Location' : ["New York", "Paris", "Berlin", "London"],
'Age' : [24, 13, 53, 33]
}
data_pandas = pd.DataFrame(data)
# IPython.display可以在Jupyter Notebook中打印出“美觀的” DataFrame
display(data_pandas)
查詢這個表格的方法有很多種泳猬。舉個例子:
In[8]:
# 選擇年齡大于30的所有行
display(data_pandas[data_pandas.Age > 30])
1.4.6 mglearn
本書的附加代碼可以在 GitHub 下載(https://github.com/amueller/introduction_to_ml_with_python)。附加代碼不僅包括本書中的所有示例宇植,還包括 mglearn 庫得封。 這是我們?yōu)楸緯帉懙膶嵱煤瘮?shù)庫,以免將代碼清單與繪圖和數(shù)據(jù)加載的細節(jié)混在一起指郁。感興趣的話忙上,你可以查看倉庫中的所有函數(shù),但 mglearn 模塊的細節(jié)并不是本書的重點闲坎。如果你在代碼中看到了對 mglearn 的調用疫粥,通常是用來快速美化繪圖,或者用于獲取一些有趣的數(shù)據(jù)腰懂。本書會頻繁使用 NumPy手形、 matplotlib 和 pandas。所有代碼都默認導入了這些庫:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import mglearn
我們還假設你在 Jupyter Notebook 中運行代碼悯恍,并使用%matplotlib notebook
或 %matplotlib inline
魔法命令來顯示圖像库糠。如果你沒有使用 Jupyter Notebook 或這些魔法命令,那么就需要調用 plt.show
來顯示圖像涮毫。
1.5 Python 2與Python 3的對比
目前 Python 主要有兩大版本廣為使用: Python 2(更確切地說是 Python 2.7)和 Python 3(寫作本書時的最新版本是 Python 3.5)瞬欧。有時這會造成一些混亂。 Python 2 已經停止開發(fā)罢防,但由于 Python 3 包含許多重大變化艘虎,所以 Python 2 的代碼通常無法在 Python 3 中運行。如果你是 Python 新手咒吐,或者要從頭開發(fā)一個新項目野建,我們強烈推薦使用最新版本的 Python 3属划,你無需做任何更改。如果你要依賴一個用 Python 2 編寫的大型代碼庫候生,可以暫時不升級同眯。但你應該盡快遷移到 Python 3。在編寫任何新代碼時唯鸭,想要編寫能夠在 Python 2 和 Python 3 中同時運行的代碼须蜗,大多數(shù)情況下都是很容易的。 如果你無需與舊版軟件進行交互的話目溉,一定要使用 Python 3明肮。本書所有代碼在兩個版本下都可以運行,但具體的輸出在 Python 2中可能會略有不同缭付。
1.6 本書用到的版本
對于前面提到的這些庫柿估,本書用到的版本如下:
In[9]:
import sys
print("Python version: {}".format(sys.version))
import pandas as pd
print("pandas version: {}".format(pd.__version__))
import matplotlib
print("matplotlib version: {}".format(matplotlib.__version__))
import numpy as np
print("NumPy version: {}".format(np.__version__))
import scipy as sp
print("SciPy version: {}".format(sp.__version__))
import IPython
print("IPython version: {}".format(IPython.__version__))
import sklearn
print("scikit-learn version: {}".format(sklearn.__version__))
Out[9]:
Python version: 3.5.2 |Anaconda 4.1.1 (64-bit)| (default, Jul 2 2016, 17:53:06)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]
pandas version: 0.18.1
matplotlib version: 1.5.1
NumPy version: 1.11.1
SciPy version: 0.17.1
IPython version: 5.1.0
scikit-learn version: 0.18
這些版本不一定要精確匹配,但 scikit-learn 的版本不應低于本書使用的版本陷猫。
現(xiàn)在都已經安裝完畢秫舌,我們來學習第一個機器學習應用。
本書假設你的 scikit-learn 版本不低于 0.18烙丛。 0.18 版新增了 model_selection 模塊,如果你用的是較早版本的 scikit-learn羔味,那么需要修改從這個模塊導入的內容河咽。
1.7 第一個應用: 鳶尾花分類
本節(jié)我們將完成一個簡單的機器學習應用,并構建我們的第一個模型赋元。同時還將介紹一些核心概念和術語忘蟹。
假設有一名植物學愛好者對她發(fā)現(xiàn)的鳶尾花的品種很感興趣。她收集了每朵鳶尾花的一些測量數(shù)據(jù):花瓣的長度和寬度以及花萼的長度和寬度搁凸,所有測量結果的單位都是厘米(見圖 1-2)媚值。
她還有一些鳶尾花的測量數(shù)據(jù),這些花之前已經被植物學專家鑒定為屬于 setosa护糖、versicolor 或 virginica 三個品種之一褥芒。對于這些測量數(shù)據(jù),她可以確定每朵鳶尾花所屬的品種嫡良。我們假設這位植物學愛好者在野外只會遇到這三種鳶尾花锰扶。
我們的目標是構建一個機器學習模型,可以從這些已知品種的鳶尾花測量數(shù)據(jù)中進行學習寝受,從而能夠預測新鳶尾花的品種坷牛。
因為我們有已知品種的鳶尾花的測量數(shù)據(jù),所以這是一個監(jiān)督學習問題很澄。在這個問題中京闰,我們要在多個選項中預測其中一個(鳶尾花的品種)颜及。這是一個分類(classification)問題的示例□彘梗可能的輸出(鳶尾花的不同品種)叫作類別(class)俏站。數(shù)據(jù)集中的每朵鳶尾花都屬于三個類別之一,所以這是一個三分類問題捐迫。
單個數(shù)據(jù)點(一朵鳶尾花)的預期輸出是這朵花的品種乾翔。對于一個數(shù)據(jù)點來說,它的品種叫作標簽(label)施戴。
1.7.1 初識數(shù)據(jù)
本例中我們用到了鳶尾花(Iris)數(shù)據(jù)集反浓,這是機器學習和統(tǒng)計學中一個經典的數(shù)據(jù)集。它包含在 scikit-learn 的 datasets 模塊中赞哗。我們可以調用 load_iris 函數(shù)來加載數(shù)據(jù):
In[10]:
from sklearn.datasets import load_iris
iris_dataset = load_iris()
load_iris 返回的 iris 對象是一個 Bunch 對象雷则,與字典非常相似,里面包含鍵和值:
In[11]:
print("Keys of iris_dataset: \n{}".format(iris_dataset.keys()))
Out[11]:
Keys of iris_dataset:
dict_keys(['target_names', 'feature_names', 'DESCR', 'data', 'target'])
DESCR 鍵對應的值是數(shù)據(jù)集的簡要說明肪笋。我們這里給出說明的開頭部分(你可以自己查看其余的內容):
In[12]:
print(iris_dataset['DESCR'][:193] + "\n...")
Out[12]:
Iris Plants Database
====================
Notes
-----
Data Set Characteristics:
:Number of Instances: 150 (50 in each of three classes)
:Number of Attributes: 4 numeric, predictive att
...
-----
target_names 鍵對應的值是一個字符串數(shù)組月劈,里面包含我們要預測的花的品種:
In[13]:
print("Target names: {}".format(iris_dataset['target_names']))
Out[13]:
Target names: ['setosa' 'versicolor' 'virginica']
feature_names 鍵對應的值是一個字符串列表,對每一個特征進行了說明:
In[14]:
print("Feature names: \n{}".format(iris_dataset['feature_names']))
Out[14]:
Feature names:
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)','petal width (cm)']
數(shù)據(jù)包含在 target 和 data 字段中藤乙。 data 里面是花萼長度猜揪、花萼寬度、花瓣長度坛梁、花瓣寬度的測量數(shù)據(jù)而姐,格式為 NumPy 數(shù)組:
In[15]:
print("Type of data: {}".format(type(iris_dataset['data'])))
Out[15]:
Type of data: <class 'numpy.ndarray'>
data 數(shù)組的每一行對應一朵花,列代表每朵花的四個測量數(shù)據(jù):
In[16]:
print("Shape of data: {}".format(iris_dataset['data'].shape))
Out[16]:
Shape of data: (150, 4)
可以看出划咐,數(shù)組中包含 150 朵不同的花的測量數(shù)據(jù)拴念。前面說過,機器學習中的個體叫作樣本(sample)褐缠,其屬性叫作特征(feature)政鼠。 data 數(shù)組的形狀(shape)是樣本數(shù)乘以特征數(shù)。 這是 scikit-learn 中的約定队魏,你的數(shù)據(jù)形狀應始終遵循這個約定公般。下面給出前5個樣本的特征數(shù)值:
In[17]:
print("First five rows of data:\n{}".format(iris_dataset['data'][:5]))
Out[17]:
First five rows of data:
[[ 5.1 3.5 1.4 0.2]
[ 4.9 3. 1.4 0.2]
[ 4.7 3.2 1.3 0.2]
[ 4.6 3.1 1.5 0.2]
[ 5. 3.6 1.4 0.2]]
從數(shù)據(jù)中可以看出,前 5 朵花的花瓣寬度都是 0.2cm胡桨,第一朵花的花萼最長俐载,是 5.1cm。
target 數(shù)組包含的是測量過的每朵花的品種登失,也是一個 NumPy 數(shù)組:
In[18]:
print("Type of target: {}".format(type(iris_dataset['target'])))
Out[18]:
Type of target: <class 'numpy.ndarray'>
target 是一維數(shù)組遏佣,每朵花對應其中一個數(shù)據(jù):
In[19]:
print("Shape of target: {}".format(iris_dataset['target'].shape))
Out[19]:
Shape of target: (150,)
品種被轉換成從 0 到 2 的整數(shù):
In[20]:
print("Target:\n{}".format(iris_dataset['target']))
Out[20]:
Target:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]
上述數(shù)字的代表含義由 iris['target_names'] 數(shù)組給出: 0 代表 setosa, 1 代表 versicolor揽浙,2 代表 virginica状婶。
1.7.2 衡量模型是否成功: 訓練數(shù)據(jù)與測試數(shù)據(jù)
我們想要利用這些數(shù)據(jù)構建一個機器學習模型意敛,用于預測新測量的鳶尾花的品種。但在將模型應用于新的測量數(shù)據(jù)之前膛虫,我們需要知道模型是否有效草姻,也就是說,我們是否應該相信它的預測結果稍刀。
不幸的是撩独,我們不能將用于構建模型的數(shù)據(jù)用于評估模型。因為我們的模型會一直記住整個訓練集账月,所以對于訓練集中的任何數(shù)據(jù)點總會預測正確的標簽综膀。這種“記憶”無法告訴我們模型的泛化(generalize)能力如何(換句話說,在新數(shù)據(jù)上能否正確預測)局齿。我們要用新數(shù)據(jù)來評估模型的性能剧劝。新數(shù)據(jù)是指模型之前沒有見過的數(shù)據(jù),而我們有這些新數(shù)據(jù)的標簽抓歼。通常的做法是將收集好的帶標簽數(shù)據(jù)(此例中是 150 朵花的測量數(shù)據(jù))分成兩部分讥此。一部分數(shù)據(jù)用于構建機器學習模型,叫作訓練數(shù)據(jù)(training data)或訓練集(training set)谣妻。其余的數(shù)據(jù)用來評估模型性能萄喳,叫作測試數(shù)據(jù)(test data)、 測試集(test set)或留出集(hold-out set)蹋半。
scikit-learn 中的 train_test_split 函數(shù)可以打亂數(shù)據(jù)集并進行拆分他巨。這個函數(shù)將 75% 的行數(shù)據(jù)及對應標簽作為訓練集,剩下 25% 的數(shù)據(jù)及其標簽作為測試集湃窍。訓練集與測試集的分配比例可以是隨意的闻蛀,但使用 25% 的數(shù)據(jù)作為測試集是很好的經驗法則匪傍。
scikit-learn 中的數(shù)據(jù)通常用大寫的 X 表示您市,而標簽用小寫的 y 表示。這是受到了數(shù)學標準公式 f(x)=y 的啟發(fā)役衡,其中 x 是函數(shù)的輸入茵休, y 是輸出。我們用大寫的 X 是因為數(shù)據(jù)是一個二維數(shù)組(矩陣)手蝎,用小寫的 y 是因為目標是一個一維數(shù)組(向量)榕莺,這也是數(shù)學中的約定。
對數(shù)據(jù)調用 train_test_split棵介,并對輸出結果采用下面這種命名方法:
In[21]:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
iris_dataset['data'], iris_dataset['target'], random_state=0)
在對數(shù)據(jù)進行拆分之前钉鸯, train_test_split 函數(shù)利用偽隨機數(shù)生成器將數(shù)據(jù)集打亂。如果我們只是將最后 25% 的數(shù)據(jù)作為測試集邮辽,那么所有數(shù)據(jù)點的標簽都是 2唠雕,因為數(shù)據(jù)點是按標簽排序的(參見之前 iris['target'] 的輸出)贸营。測試集中只有三個類別之一,這無法告訴我們模型的泛化能力如何岩睁,所以我們將數(shù)據(jù)打亂钞脂,確保測試集中包含所有類別的數(shù)據(jù)。
為了確保多次運行同一函數(shù)能夠得到相同的輸出捕儒,我們利用 random_state 參數(shù)指定了隨機數(shù)生成器的種子冰啃。這樣函數(shù)輸出就是固定不變的,所以這行代碼的輸出始終相同刘莹。本書用到隨機過程時阎毅,都會用這種方法指定 random_state。train_test_split 函數(shù)的輸出為 X_train栋猖、 X_test净薛、 y_train 和 y_test,它們都是 NumPy數(shù)組蒲拉。 X_train 包含 75% 的行數(shù)據(jù)肃拜, X_test 包含剩下的 25%:
In[22]:
print("X_train shape: {}".format(X_train.shape))
print("y_train shape: {}".format(y_train.shape))
Out[22]:
X_train shape: (112, 4)
y_train shape: (112,)
In[23]:
print("X_test shape: {}".format(X_test.shape))
print("y_test shape: {}".format(y_test.shape))
Out[23]:
X_test shape: (38, 4)
y_test shape: (38,)
1.7.3 要事第一: 觀察數(shù)據(jù)
在構建機器學習模型之前,通常最好檢查一下數(shù)據(jù)雌团,看看如果不用機器學習能不能輕松完成任務燃领,或者需要的信息有沒有包含在數(shù)據(jù)中。此外锦援,檢查數(shù)據(jù)也是發(fā)現(xiàn)異常值和特殊值的好方法猛蔽。舉個例子,可能有些鳶尾花的測量單位是英寸而不是厘米灵寺。在現(xiàn)實世界中曼库,經常會遇到不一致的數(shù)據(jù)和意料之外的測量數(shù)據(jù)。
檢查數(shù)據(jù)的最佳方法之一就是將其可視化略板。一種可視化方法是繪制散點圖(scatter plot)毁枯。數(shù)據(jù)散點圖將一個特征作為 x 軸,另一個特征作為 y 軸叮称,將每一個數(shù)據(jù)點繪制為圖上的一個點种玛。不幸的是,計算機屏幕只有兩個維度瓤檐,所以我們一次只能繪制兩個特征(也可能是3 個)赂韵。用這種方法難以對多于 3 個特征的數(shù)據(jù)集作圖。解決這個問題的一種方法是繪制散點圖矩陣(pair plot)挠蛉,從而可以兩兩查看所有的特征祭示。如果特征數(shù)不多的話,比如我們這里有 4 個谴古,這種方法是很合理的质涛。但是你應該記住悄窃,散點圖矩陣無法同時顯示所有特征之間的關系,所以這種可視化方法可能無法展示數(shù)據(jù)的某些有趣內容蹂窖。
圖 1-3 是訓練集中特征的散點圖矩陣轧抗。數(shù)據(jù)點的顏色與鳶尾花的品種相對應。為了繪制這張圖瞬测,我們首先將 NumPy 數(shù)組轉換成 pandas DataFrame横媚。 pandas 有一個繪制散點圖矩陣的函數(shù),叫作 scatter_matrix月趟。矩陣的對角線是每個特征的直方圖:
In[24]:
# 利用X_train中的數(shù)據(jù)創(chuàng)建DataFrame
# 利用iris_dataset.feature_names中的字符串對數(shù)據(jù)列進行標記
iris_dataframe = pd.DataFrame(X_train, columns=iris_dataset.feature_names)
# 利用DataFrame創(chuàng)建散點圖矩陣灯蝴,按y_train著色
grr = pd.scatter_matrix(iris_dataframe, c=y_train, figsize=(15, 15), marker='o',
hist_kwds={'bins': 20}, s=60, alpha=.8, cmap=mglearn.cm3)
從圖中可以看出孝宗,利用花瓣和花萼的測量數(shù)據(jù)基本可以將三個類別區(qū)分開穷躁。這說明機器學習模型很可能可以學會區(qū)分它們。
1.7.4 構建第一個模型: k近鄰算法
現(xiàn)在我們可以開始構建真實的機器學習模型了因妇。 scikit-learn 中有許多可用的分類算法问潭。這里我們用的是 k 近鄰分類器,這是一個很容易理解的算法婚被。構建此模型只需要保存訓練集即可狡忙。要對一個新的數(shù)據(jù)點做出預測,算法會在訓練集中尋找與這個新數(shù)據(jù)點距離最近的數(shù)據(jù)點址芯,然后將找到的數(shù)據(jù)點的標簽賦值給這個新數(shù)據(jù)點灾茁。k 近鄰算法中 k 的含義是,我們可以考慮訓練集中與新數(shù)據(jù)點最近的任意 k 個鄰居(比如說谷炸,距離最近的 3 個或 5 個鄰居)北专,而不是只考慮最近的那一個。然后旬陡,我們可以用這些鄰居中數(shù)量最多的類別做出預測拓颓。第 2 章會進一步介紹這個算法的細節(jié),現(xiàn)在我們只考慮一個鄰居的情況季惩。
scikit-learn 中所有的機器學習模型都在各自的類中實現(xiàn)录粱,這些類被稱為 Estimator類腻格。 k 近鄰分類算法是在 neighbors 模塊的 KNeighborsClassifier 類中實現(xiàn)的画拾。我們需要將這個類實例化為一個對象,然后才能使用這個模型菜职。這時我們需要設置模型的參數(shù)青抛。KNeighborsClassifier 最重要的參數(shù)就是鄰居的數(shù)目,這里我們設為 1:
In[25]:
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=1)
knn 對象對算法進行了封裝酬核,既包括用訓練數(shù)據(jù)構建模型的算法蜜另,也包括對新數(shù)據(jù)點進行預測的算法适室。它還包括算法從訓練數(shù)據(jù)中提取的信息。對于 KNeighborsClassifier 來說举瑰,里面只保存了訓練集捣辆。
想要基于訓練集來構建模型,需要調用 knn 對象的 fit 方法此迅,輸入參數(shù)為 X_train 和 y_train汽畴,二者都是 NumPy 數(shù)組,前者包含訓練數(shù)據(jù)耸序,后者包含相應的訓練標簽:
In[26]:
knn.fit(X_train, y_train)
Out[26]:
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
metric_params=None, n_jobs=1, n_neighbors=1, p=2,
weights='uniform')
fit 方法返回的是 knn 對象本身并做原處修改忍些,因此我們得到了分類器的字符串表示。從中可以看出構建模型時用到的參數(shù)坎怪。幾乎所有參數(shù)都是默認值罢坝,但你也會注意到 n_neighbors=1,這是我們傳入的參數(shù)搅窿。 scikit-learn 中的大多數(shù)模型都有很多參數(shù)嘁酿,但多用于速度優(yōu)化或非常特殊的用途。你無需關注這個字符串表示中的其他參數(shù)男应。打印 scikitlearn 模型會生成非常長的字符串痹仙,但不要被它嚇到。我們會在第 2 章講到所有重要的參數(shù)殉了。在本書的其他章節(jié)中开仰,我們不會給出 fit 的輸出,因為里面沒有包含任何新的信息薪铜。
1.7.5 做出預測
現(xiàn)在我們可以用這個模型對新數(shù)據(jù)進行預測了众弓,我們可能并不知道這些新數(shù)據(jù)的正確標簽。想象一下隔箍,我們在野外發(fā)現(xiàn)了一朵鳶尾花谓娃,花萼長 5cm 寬 2.9cm,花瓣長 1cm 寬0.2cm蜒滩。這朵鳶尾花屬于哪個品種滨达?我們可以將這些數(shù)據(jù)放在一個 NumPy 數(shù)組中,再次計算形狀俯艰,數(shù)組形狀為樣本數(shù)(1)乘以特征數(shù)(4):
In[27]:
X_new = np.array([[5, 2.9, 1, 0.2]])
print("X_new.shape: {}".format(X_new.shape))
Out[27]:
X_new.shape: (1, 4)
注意捡遍,我們將這朵花的測量數(shù)據(jù)轉換為二維 NumPy 數(shù)組的一行,這是因為 scikit-learn的輸入數(shù)據(jù)必須是二維數(shù)組竹握。
我們調用 knn 對象的 predict 方法來進行預測:
In[28]:
prediction = knn.predict(X_new)
print("Prediction: {}".format(prediction))
print("Predicted target name: {}".format(
iris_dataset['target_names'][prediction]))
Out[28]:
Prediction: [0]
Predicted target name: ['setosa']
根據(jù)我們模型的預測画株,這朵新的鳶尾花屬于類別 0,也就是說它屬于 setosa 品種。但我們怎么知道能否相信這個模型呢谓传?我們并不知道這個樣本的實際品種蜈项,這也是我們構建模型的重點啊续挟!
1.7.6 評估模型
這里需要用到之前創(chuàng)建的測試集紧卒。這些數(shù)據(jù)沒有用于構建模型,但我們知道測試集中每朵鳶尾花的實際品種诗祸。
因此常侦,我們可以對測試數(shù)據(jù)中的每朵鳶尾花進行預測,并將預測結果與標簽(已知的品種)進行對比贬媒。我們可以通過計算精度(accuracy)來衡量模型的優(yōu)劣聋亡,精度就是品種預測正確的花所占的比例:
In[29]:
y_pred = knn.predict(X_test)
print("Test set predictions:\n {}".format(y_pred))
Out[29]:
Test set predictions:
[2 1 0 2 0 2 0 1 1 1 2 1 1 1 1 0 1 1 0 0 2 1 0 0 2 0 0 1 1 0 2 1 0 2 2 1 0 2]
In[30]:
print("Test set score: {:.2f}".format(np.mean(y_pred == y_test)))
Out[30]:
Test set score: 0.97
我們還可以使用 knn 對象的 score 方法來計算測試集的精度:
In[31]:
print("Test set score: {:.2f}".format(knn.score(X_test, y_test)))
Out[31]:
Test set score: 0.97
對于這個模型來說,測試集的精度約為 0.97际乘,也就是說坡倔,對于測試集中的鳶尾花,我們的預測有 97% 是正確的脖含。根據(jù)一些數(shù)學假設罪塔,對于新的鳶尾花,可以認為我們的模型預測結果有 97% 都是正確的养葵。對于我們的植物學愛好者應用程序來說征堪,高精度意味著模型足夠可信,可以使用关拒。在后續(xù)章節(jié)中佃蚜,我們將討論提高性能的方法,以及模型調參時的注意事項着绊。
1.8 小結與展望
總結一下本章所學的內容谐算。我們首先簡要介紹了機器學習及其應用,然后討論了監(jiān)督學習和無監(jiān)督學習之間的區(qū)別归露,并簡要介紹了本書將會用到的工具洲脂。隨后,我們構思了一項任務剧包,要利用鳶尾花的物理測量數(shù)據(jù)來預測其品種恐锦。我們在構建模型時用到了由專家標注過的測量數(shù)據(jù)集,專家已經給出了花的正確品種疆液,因此這是一個監(jiān)督學習問題一铅。一共有三個品種: setosa、 versicolor 或 virginica枚粘,因此這是一個三分類問題馅闽。在分類問題中,可能的品種被稱為類別(class)馍迄,每朵花的品種被稱為它的標簽(label)福也。
鳶尾花(Iris)數(shù)據(jù)集包含兩個 NumPy 數(shù)組:一個包含數(shù)據(jù),在 scikit-learn 中被稱為 X攀圈;一個包含正確的輸出或預期輸出暴凑,被稱為 y浮驳。數(shù)組 X 是特征的二維數(shù)組赔嚎,每個數(shù)據(jù)點對應一行,每個特征對應一列锐涯。數(shù)組 y 是一維數(shù)組犬辰,里面包含一個類別標簽嗦篱,對每個樣本都是一個 0 到 2 之間的整數(shù)。
我們將數(shù)據(jù)集分成訓練集(training set)和測試集(test set)幌缝,前者用于構建模型灸促,后者用于評估模型對前所未見的新數(shù)據(jù)的泛化能力。
我們選擇了 k 近鄰分類算法涵卵,根據(jù)新數(shù)據(jù)點在訓練集中距離最近的鄰居來進行預測浴栽。該算法在 KNeighborsClassifier 類中實現(xiàn),里面既包含構建模型的算法轿偎,也包含利用模型進行預測的算法典鸡。我們將類實例化,并設定參數(shù)坏晦。然后調用 fit 方法來構建模型萝玷,傳入訓練數(shù)據(jù)(X_train)和訓練輸出(y_trian)作為參數(shù)。我們用 score 方法來評估模型昆婿,該方法計算的是模型精度间护。我們將 score 方法用于測試集數(shù)據(jù)和測試集標簽,得出模型的精度約為 97%挖诸,也就是說汁尺,該模型在測試集上 97% 的預測都是正確的。
這讓我們有信心將模型應用于新數(shù)據(jù)(在我們的例子中是新花的測量數(shù)據(jù))多律,并相信模型在約 97% 的情況下都是正確的痴突。
下面匯總了整個訓練和評估過程所必需的代碼:
In[32]:
X_train, X_test, y_train, y_test = train_test_split(
iris_dataset['data'], iris_dataset['target'], random_state=0)
knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(X_train, y_train)
print("Test set score: {:.2f}".format(knn.score(X_test, y_test)))
Out[32]:
Test set score: 0.97
這個代碼片段包含了應用 scikit-learn 中任何機器學習算法的核心代碼。 fit狼荞、 predict 和score 方法是 scikit-learn 監(jiān)督學習模型中最常用的接口辽装。學完本章介紹的概念,你可以將這些模型應用到許多機器學習任務上相味。下一章拾积,我們會更深入地介紹 scikit-learn 中各種類型的監(jiān)督學習模型,以及這些模型的正確使用方法。