Python 機器學習 基礎 之? 構建第一個機器學習應用
目錄
Python 機器學習 基礎 之? 構建第一個機器學習應用
一、簡單介紹
二、第一個機器學習測試應用介紹:鳶尾花分類
三、第一個機器學習測試應用 :前置環境,知識點介紹
jupyter notebook 進行開發
知識點介紹
四、第一個機器學習測試應用 :打亂數據,構建訓練數據與測試數據
五、第一個機器學習測試應用 :繪制示意圖,觀察數據
六、第一個機器學習測試應用:構建第一個模型 - k近鄰算法,進行預測和評估
1、引入 k 鄰近算法,進行數據訓練
2、進行預測
3、評估
七、第一個機器學習測試應用:小結
附錄
一、簡單介紹
Python是一種跨平臺的計算機程序設計語言。是一種面向對象的動態類型語言,最初被設計用于編寫自動化腳本(shell),隨著版本的不斷更新和語言新功能的添加,越多被用于獨立的、大型項目的開發。Python是一種解釋型腳本語言,可以應用于以下領域: Web 和 Internet開發、科學計算和統計、人工智能、教育、桌面界面開發、軟件開發、后端開發、網絡爬蟲。
Python 機器學習是利用 Python 編程語言中的各種工具和庫來實現機器學習算法和技術的過程。Python 是一種功能強大且易于學習和使用的編程語言,因此成為了機器學習領域的首選語言之一。Python 提供了豐富的機器學習庫,如Scikit-learn、TensorFlow、Keras、PyTorch等,這些庫包含了許多常用的機器學習算法和深度學習框架,使得開發者能夠快速實現、測試和部署各種機器學習模型。
Python 機器學習涵蓋了許多任務和技術,包括但不限于:
- 監督學習:包括分類、回歸等任務。
- 無監督學習:如聚類、降維等。
- 半監督學習:結合了有監督和無監督學習的技術。
- 強化學習:通過與環境的交互學習來優化決策策略。
- 深度學習:利用深度神經網絡進行學習和預測。
通過 Python 進行機器學習,開發者可以利用其豐富的工具和庫來處理數據、構建模型、評估模型性能,并將模型部署到實際應用中。Python 的易用性和龐大的社區支持使得機器學習在各個領域都得到了廣泛的應用和發展。
二、第一個機器學習測試應用介紹:鳶尾花分類
鳶尾花分類(Iris Classification)是機器學習領域中一個經典的示例,通常用于介紹和學習機器學習算法的基本原理和實踐方法。這個問題的目標是根據鳶尾花的花萼長度、花萼寬度、花瓣長度和花瓣寬度等特征,來預測鳶尾花的品種。鳶尾花數據集是由統計學家 Ronald Fisher 在 1936 年收集整理的,其中包含了三種不同品種的鳶尾花(山鳶尾、變色鳶尾和維吉尼亞鳶尾),每種鳶尾花樣本采集了四個特征。
鳶尾花(Iris)是一種常見的花卉植物,屬于百合科鳶尾屬(Iris)植物,是世界上最古老的觀賞植物之一。鳶尾花通常生長在溫帶和亞熱帶地區,有許多不同的品種和變種。它們以花朵美麗、多樣的顏色和形狀而聞名,是園藝愛好者和花卉收藏家喜愛的對象之一。
鳶尾花的特征包括:
花朵形狀多樣:鳶尾花的花朵形狀多樣,有些品種的花朵呈扇形、有些呈圓形,還有些呈喇叭形。
花色豐富:鳶尾花的花色非常豐富,包括紫色、白色、黃色、粉色等各種顏色,有些品種還有斑紋或條紋。
葉片長而細:鳶尾花的葉片通常比較長而細,呈劍形或線狀,葉片的顏色也有所不同,有些品種呈深綠色,有些呈淺綠色。
鳶尾花在園藝上被廣泛種植,并且常常作為花園和景觀中的裝飾植物。由于其美麗的花朵和多樣的品種,鳶尾花也經常被用于花束、插花和花藝設計中。此外,鳶尾花在文學、藝術和文化中也有著特殊的象征意義,被賦予了各種寓意和象征。
下面是實現鳶尾花分類的一般步驟:
-
數據準備和加載:首先,需要準備鳶尾花數據集,并加載到程序中。可以使用 Python 中的 Pandas 庫或者直接使用 Scikit-learn 提供的鳶尾花數據集。
-
數據預處理:對數據進行預處理,包括數據清洗、缺失值處理、特征選擇、特征縮放等。通常情況下,鳶尾花數據集是比較干凈的,不需要進行太多的預處理。
-
數據分割:將數據集劃分為訓練集和測試集,通常使用交叉驗證的方法來進行劃分,保證訓練集和測試集中的樣本分布均勻。
-
選擇模型:選擇適合解決鳶尾花分類問題的機器學習模型,常用的包括 K 近鄰算法、支持向量機(SVM)、決策樹、隨機森林等。
-
模型訓練:使用訓練集對選定的模型進行訓練,學習模型的參數和特征權重。
-
模型評估:使用測試集對訓練好的模型進行評估,通常使用準確率、精確率、召回率、F1 分數等指標來評估模型的性能。
-
模型調優:根據評估結果對模型進行調優,包括調整超參數、特征選擇、模型融合等。
-
模型應用:使用訓練好的模型對新的未知樣本進行預測和分類。
一個簡單的鳶尾花分類的實現步驟,具體的實現代碼可以使用 Python 中的 Scikit-learn 庫來完成。Scikit-learn 提供了豐富的機器學習算法和工具,能夠方便地進行模型訓練、評估和預測。
三、第一個機器學習測試應用 :前置環境,知識點介紹
jupyter notebook 進行開發
1、機器學習的虛擬環境,輸入命名打開 jupyter notebook
如果沒有安裝如下圖
這時候,輸入 pip install jupyter 安裝即可
此時,安裝成功后,再次輸入 jupyter notebook
2、打開 jupyter notebook
知識點介紹
假設有一名植物學愛好者對她發現的鳶尾花的品種很感興趣。她收集了每朵鳶尾花的一些測量數據:花瓣的長度和寬度以及花萼的長度和寬度,所有測量結果的單位都是厘米。
scikit-learn 還有一些鳶尾花的測量數據,這些花之前已經被植物學專家鑒定為屬于 setosa、versicolor 或 virginica 三個品種之一。對于這些測量數據,她可以確定每朵鳶尾花所屬的品種。我們假設這位植物學愛好者在野外只會遇到這三種鳶尾花。
我們的目標是構建一個機器學習模型,可以從這些已知品種的鳶尾花測量數據中進行學習,從而能夠預測新鳶尾花的品種。
因為我們有已知品種的鳶尾花的測量數據,所以這是一個監督學習問題。在這個問題中,我們要在多個選項中預測其中一個(鳶尾花的品種)。這是一個分類 (classification)問題的示例。可能的輸出(鳶尾花的不同品種)叫作類別 (class)。數據集中的每朵鳶尾花都屬于三個類別之一,所以這是一個三分類問題。
本例中我們用到了鳶尾花(Iris)數據集,這是機器學習和統計學中一個經典的數據集。它包含在?scikit-learn
?的?datasets
?模塊中。
1、調用?load_iris
?函數來加載數據:
from sklearn.datasets import load_iris
iris_dataset = load_iris()
2、load_iris
?返回的?iris
?對象是一個?Bunch
?對象與字典非常相似,里面包含鍵和值:
print("Keys of iris_dataset: \n{}".format(iris_dataset.keys()))
上面的一些鍵進行簡單說明
1)、DESCR
鍵對應的值是數據集的簡要說明。我們這里給出說明的開頭部分(你可以自己查看其余的內容):
2)target_names
鍵對應的值是一個字符串數組,里面包含我們要預測的花的品種:
3)feature_names
鍵對應的值是一個字符串列表,對每一個特征進行了說明:
4)數據包含在?target
?和?data
?字段中。data
?里面是花萼長度、花萼寬度、花瓣長度、花瓣寬度的測量數據,格式為 NumPy 數組:
data
:機器學習中的個體叫作樣本 (sample),其屬性叫作特征 (feature)。data
數組的形狀 (shape)是樣本數乘以特征數。這是 scikit-learn
中的約定,你的數據形狀應始終遵循這個約定。
5)data
數組的每一行對應一朵花,列代表每朵花的四個測量數據:
6)data
數組打印前 5 個樣本的特征數值:
data
?里面是花萼長度、花萼寬度、花瓣長度、花瓣寬度的測量數據
從數據中可以看出,前 5 朵花的花瓣寬度都是 0.2cm,第一朵花的花萼最長,是 5.1cm。
7)target
?數組包含的是測量過的每朵花的品種,也是一個 NumPy 數組:
8)target
?是一維數組,每朵花對應其中一個數據:
9)target 品種被轉換成從 0 到 2 的整數:
對應屬于 setosa、versicolor 或 virginica 三個品種
上述數字的代表含義由?iris['target_names']
?數組給出:0 代表 setosa,1 代表 versicolor,2 代表 virginica。
四、第一個機器學習測試應用 :打亂數據,構建訓練數據與測試數據
利用 scikit-learn 這些數據構建一個機器學習模型,用于預測新測量的鳶尾花的品種。但在將模型應用于新的測量數據之前,需要知道模型是否有效,也就是說,是否應該相信它的預測結果。
不幸的是,不能將用于構建模型的數據用于評估模型。因為模型會一直記住整個訓練集,所以對于訓練集中的任何數據點總會預測正確的標簽。這種“記憶”無法告訴模型的泛化能力如何(換句話說,在新數據上能否正確預測)。
要用新數據來評估模型的性能。新數據是指模型之前沒有見過的數據,而有這些新數據的標簽。通常的做法是將收集好的帶標簽數據(此例中是 150 朵花的測量數據)分成兩部分。一部分數據用于構建機器學習模型,叫作訓練數據(training data)或訓練集(training set)。其余的數據用來評估模型性能,叫作測試數據(test data)、測試集(test set)或留出集(hold-out set)。
scikit-learn 中的 train_test_split 函數可以打亂數據集并進行拆分。這個函數將 75% 的行數據及對應標簽作為訓練集,剩下 25% 的數據及其標簽作為測試集。訓練集與測試集的分配比例可以是隨意的,但使用 25% 的數據作為測試集是很好的經驗法則。
scikit-learn 中的數據通常用大寫的 X 表示,而標簽用小寫的 y 表示。這是受到了數學標準公式 f(x)=y 的啟發,其中 x 是函數的輸入,y 是輸出。用大寫的 X 是因為數據是一個二維數組(矩陣),用小寫的 y 是因為目標是一個一維數組(向量),這也是數學中的約定。
1、對數據調用?train_test_split
?,并對輸出結果采用下面這種命名方法:
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)
在對數據進行拆分之前,train_test_split
?函數利用偽隨機數生成器將數據集打亂。如果我們只是將最后 25% 的數據作為測試集,那么所有數據點的標簽都是?2
?,因為數據點是按標簽排序的(參見之前?iris['target']
?的輸出)。測試集中只有三個類別之一,這無法告訴我們模型的泛化能力如何,所以我們將數據打亂,確保測試集中包含所有類別的數據。
為了確保多次運行同一函數能夠得到相同的輸出,我們利用?random_state
?參數指定了隨機數生成器的種子。這樣函數輸出就是固定不變的,所以這行代碼的輸出始終相同。本書用到隨機過程時,都會用這種方法指定?random_state
?。
2、train_test_split
?函數的輸出為?X_train
?、X_test
?、y_train
?和?y_test
?,它們都是 NumPy 數組。X_train
?包含 75% 的行數據,X_test
?包含剩下的 25%:
print("X_train shape: {}".format(X_train.shape))
print("y_train shape: {}".format(y_train.shape))
print("X_test shape: {}".format(X_test.shape))
print("y_test shape: {}".format(y_test.shape))
五、第一個機器學習測試應用 :繪制示意圖,觀察數據
在構建機器學習模型之前,通常最好檢查一下數據,看看如果不用機器學習能不能輕松完成任務,或者需要的信息有沒有包含在數據中。
此外,檢查數據也是發現異常值和特殊值的好方法。舉個例子,可能有些鳶尾花的測量單位是英寸而不是厘米。在現實世界中,經常會遇到不一致的數據和意料之外的測量數據。
檢查數據的最佳方法之一就是將其可視化。一種可視化方法是繪制散點圖 (scatter plot)。
數據散點圖將一個特征作為 x 軸,另一個特征作為 y 軸,將每一個數據點繪制為圖上的一個點。不幸的是,計算機屏幕只有兩個維度,所以我們一次只能繪制兩個特征(也可能是 3 個)。用這種方法難以對多于 3 個特征的數據集作圖。解決這個問題的一種方法是繪制散點圖矩陣 (pair plot),從而可以兩兩查看所有的特征。如果特征數不多的話,比如我們這里有 4 個,這種方法是很合理的。但是你應該記住,散點圖矩陣無法同時顯示所有特征之間的關系,所以這種可視化方法可能無法展示數據的某些有趣內容。
訓練集中特征的散點圖矩陣。數據點的顏色與鳶尾花的品種相對應。為了繪制這張圖,我們首先將 NumPy 數組轉換成
pandas DataFrame
。pandas
有一個繪制散點圖矩陣的函數,叫作scatter_matrix
。
矩陣的對角線是每個特征的直方圖:
import pandas as pd
import matplotlib.pyplot as plt
from pandas.plotting import scatter_matrix
import mglearn# 利用X_train中的數據創建DataFrame
# 利用iris_dataset.feature_names中的字符串對數據列進行標記
iris_dataframe = pd.DataFrame(X_train, columns=iris_dataset.feature_names)
# 利用DataFrame創建散點圖矩陣,按y_train著色
grr = scatter_matrix(iris_dataframe, c=y_train, figsize=(15, 15), marker='o',hist_kwds={'bins': 20}, s=60, alpha=.8, cmap=mglearn.cm3)
plt.show()
從圖中可以看出,利用花瓣和花萼的測量數據基本可以將三個類別區分開。這說明機器學習模型很可能可以學會區分它們。
六、第一個機器學習測試應用:構建第一個模型 - k近鄰算法,進行預測和評估
k近鄰算法
現在我們可以開始構建真實的機器學習模型了。在 scikit-learn 中有許多可用的分類算法,我們選擇使用 k 近鄰分類器,因為這是一個很容易理解的算法。構建此模型只需要保存訓練集即可。對一個新的數據點做出預測時,算法會在訓練集中尋找與這個新數據點距離最近的數據點,然后將找到的數據點的標簽賦值給這個新數據點。
在 k 近鄰算法中,k 的含義是我們可以考慮訓練集中與新數據點最近的任意 k 個鄰居(例如,距離最近的 3 個或 5 個鄰居),而不是只考慮最近的那一個。然后,我們可以用這些鄰居中數量最多的類別來做出預測。
在 scikit-learn 中,所有的機器學習模型都在各自的類中實現,這些類被稱為 Estimator 類。k 近鄰分類算法是在 neighbors 模塊的 KNeighborsClassifier 類中實現的。我們需要將這個類實例化為一個對象,然后才能使用這個模型。這時我們需要設置模型的參數。KNeighborsClassifier 最重要的參數就是鄰居的數目,這里我們將其設為 1。
1、引入 k 鄰近算法,進行數據訓練
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=1)
knn
?對象對算法進行了封裝,既包括用訓練數據構建模型的算法,也包括對新數據點進行預測的算法。它還包括算法從訓練數據中提取的信息。對于?KNeighborsClassifier
?來說,里面只保存了訓練集。
想要基于訓練集來構建模型,需要調用?knn
?對象的?fit
?方法,輸入參數為?X_train
?和?y_train
?,二者都是 NumPy 數組,前者包含訓練數據,后者包含相應的訓練標簽:
knn.fit(X_train, y_train)
fit
?方法返回的是?knn
?對象本身并做原處修改,因此我們得到了分類器的字符串表示。從中可以看出構建模型時用到的參數。幾乎所有參數都是默認值,但你也會注意到?n_neighbors=1
?,這是我們傳入的參數。scikit-learn
?中的大多數模型都有很多參數,但多用于速度優化或非常特殊的用途。你無需關注這個字符串表示中的其他參數。
2、進行預測
在我們可以用這個模型對新數據進行預測了,我們可能并不知道這些新數據的正確標簽。想象一下,我們在野外發現了一朵鳶尾花,花萼長 5cm 寬 2.9cm,花瓣長 1cm 寬 0.2cm。這朵鳶尾花屬于哪個品種?我們可以將這些數據放在一個 NumPy 數組中,再次計算形狀,數組形狀為樣本數(1)乘以特征數(4):
import numpy as np
X_new = np.array([[5, 2.9, 1, 0.2]])
print("X_new.shape: {}".format(X_new.shape))
注意,我們將這朵花的測量數據轉換為二維 NumPy 數組的一行,這是因為?scikit-learn
?的輸入數據必須是二維數組。
我們調用?knn
?對象的?predict
?方法來進行預測:
prediction = knn.predict(X_new)
print("Prediction: {}".format(prediction))
print("Predicted target name: {}".format(iris_dataset['target_names'][prediction]))
根據我們模型的預測,這朵新的鳶尾花屬于類別 0,也就是說它屬于 setosa 品種。但我們怎么知道能否相信這個模型呢?我們并不知道這個樣本的實際品種,這也是我們構建模型的重點啊!
3、評估
這里需要用到之前創建的測試集。這些數據沒有用于構建模型,但我們知道測試集中每朵鳶尾花的實際品種。
因此,我們可以對測試數據中的每朵鳶尾花進行預測,并將預測結果與標簽(已知的品種)進行對比。
1)我們可以通過計算精度 (accuracy)來衡量模型的優劣,精度就是品種預測正確的花所占的比例:
y_pred = knn.predict(X_test)
print("Test set predictions:\n {}".format(y_pred))
print("Test set score: {:.2f}".format(np.mean(y_pred == y_test)))
2)我們還可以使用?knn
?對象的?score
?方法來計算測試集的精度:
print("Test set score: {:.2f}".format(knn.score(X_test, y_test)))
對于這個模型來說,測試集的精度約為 0.97,也就是說,對于測試集中的鳶尾花,我們的預測有 97% 是正確的。根據一些數學假設,對于新的鳶尾花,可以認為我們的模型預測結果有 97% 都是正確的。對于我們的植物學愛好者應用程序來說,高精度意味著模型足夠可信,可以使用。
七、第一個機器學習測試應用:小結
我們構思了一項任務,要利用鳶尾花的物理測量數據來預測其品種。我們在構建模型時用到了由專家標注過的測量數據集,專家已經給出了花的正確品種,因此這是一個監督學習問題。一共有三個品種:setosa、versicolor 或 virginica,因此這是一個三分類問題。在分類問題中,可能的品種被稱為類別 (class),每朵花的品種被稱為它的標簽 (label)。
鳶尾花(Iris)數據集包含兩個 NumPy 數組:一個包含數據,在
scikit-learn
中被稱為X
;一個包含正確的輸出或預期輸出,被稱為y
。數組X
是特征的二維數組,每個數據點對應一行,每個特征對應一列。數組y
是一維數組,里面包含一個類別標簽,對每個樣本都是一個 0 到 2 之間的整數。我們將數據集分成訓練集 (training set)和測試集 (test set),前者用于構建模型,后者用于評估模型對前所未見的新數據的泛化能力。
我們選擇了 k 近鄰分類算法,根據新數據點在訓練集中距離最近的鄰居來進行預測。該算法在
KNeighborsClassifier
類中實現,里面既包含構建模型的算法,也包含利用模型進行預測的算法。我們將類實例化,并設定參數。然后調用fit
方法來構建模型,傳入訓練數據(X_train
)和訓練輸出(y_trian
)作為參數。我們用score
方法來評估模型,該方法計算的是模型精度。我們將score
方法用于測試集數據和測試集標簽,得出模型的精度約為 97%,也就是說,該模型在測試集上 97% 的預測都是正確的。
關鍵代碼:訓練和評估過程所必需的代碼
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)))
這個代碼片段包含了應用 scikit-learn
中任何機器學習算法的核心代碼。fit
、predict
和 score
方法是 scikit-learn
監督學習模型中最常用的接口
附錄
參考文獻:[德] Andreas C. Müller [美] Sarah Guido 《Python Machine Learning Basics Tutorial》