Python機器學習及實踐——基礎篇:監督學習經典模型(分類學習)
機器學習中監督學習模型的任務重點在于,根據已有經驗知識對未知樣本的目標/標記進行預測。根據目標預測變量的類型不同,可以把監督學習任務大體分為分類學習和回歸預測兩類。
監督學習任務的基本架構和流程:首先準備訓練數據,可以是文本、圖像、音頻等;然后抽取所需要的特征,形成特征向量(Feature Vectors);接著,把這些特征向量連同對應的標記/目標(Labels)一并送入學習算法(Machine Learning Algorithm)中,訓練出一個預測模型(Predictive Model);然后采用同樣的特征抽取方法作用于新測試數據,得到用于測試的特征向量;最后,使用預測模型對這些待測試的特征向量進行預測并得到結果(Expected Label)。
監督學習基本架構和流程
1.線性分類器
線性分類器(Linear Classifier)是一種假設特征與分類結果存在線性關系的模型。這個模型通過累加計算每個維度的特征與各自權重的乘積來幫助類別決策。
應用案例:良/惡性腫瘤預測 :原始數據共有699條樣本,每條樣本有11列不同的數值:1列用于檢索的id,9列與腫瘤相關的醫學特征,以及一列表征腫瘤類型的數值。所有9列用于表示腫瘤醫學特質的數值均被量化為1~10之間的數字,而腫瘤的類型也借由數字2和數字4分別指代良性與惡性。不過,這份數據也聲明其中包含16個缺失值,并用“?”標出。事實上,缺失值問題廣泛存在于現實數據中,也是機器學習任務無法回避的問題。
# 良/惡性乳腺癌腫瘤數據預處理
import pandas as pd
import numpy as np
# 創建特征列表
colnames = ['SampleNum', 'Clump Thickness', 'Cell Size', 'Cell Shape', 'Marginal Adhesion',
'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin', 'Normal Nucleoli', 'Mitoses', 'Class']
# 使用pandas.read_csv函數從網絡上讀取指定數據
data = pd.read_csv(
'https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data',
names=colnames)
# print(data.head(10))
通常情況下,25%的數據會作為測試機,75%的數據會用于訓練集。
# 準備良/惡性乳腺癌腫瘤訓練、測試數據
# 使用sklearn.model_selection里的train_test_split模塊用于分割數據
from sklearn.model_selection import train_test_split
# 隨機采樣25%的數據用于測試,剩下的75%用于構建訓練集合
X_train,X_test,y_train,y_test = train_test_split(data[colnames[1:10]],data[colnames[10]],test_size=0.25,random_state=33)
# 查驗訓練樣本的數量和類別分布
print(y_train.value_counts())
# 查驗測試樣本的數量和類別分布
print(y_test.value_counts())
接下來,使用Logistic回歸和隨機梯度參數估計兩種方法對上述處理后的訓練數據進行學習,并且根據測試樣本特征進行預測。
# 從sklearn.preprocessing里導入StandardScaler。
from sklearn.preprocessing import StandardScaler
# 從sklearn.linear_model里導入LogisticRegression與SGDClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import SGDClassifier
# 標準化數據,保證每個維度的特征數據方差為1,均值為0。使得預測結果不會被某些維度過大的特征值而主導
ss = StandardScaler()
X_train = ss.fit_transform(X_train)
X_test = ss.fit_transform(X_test)
# 初始化LogisticRegression與SGDClassifier
lr = LogisticRegression()
sgdc = SGDClassifier()
# 調用LogisticRegression中的fit函數/模塊用來訓練模型參數
lr.fit(X_train, y_train)
# 使用訓練好的模型lr對X_test進行預測,結果存儲在變量lr_y_predict中
lr_y_predict = lr.predict(X_test)
# 調用SGDClassifier中的fit函數/模塊用來訓練模型參數。
sgdc.fit(X_train, y_train)
# 使用訓練好的模型sgdc對X_test進行預測,結果存儲在變量sgdc_y_predict中
sgdc_y_predict = sgdc.predict(X_test)
接下來,我們需要對性能進行測評,主要使用的指標有準確性(Accuracy)、召回率(Recall)、精確率(Precision)以及F1指標(F1 measure):
# 使用線性分類模型從事良/惡性腫瘤預測任務的性能分析
from sklearn.metrics import classification_report
# 使用Logistic回歸模型自帶的評分函數score獲得模型在測試集上的準確性結果
print("Accuracy of LR Classifier: ", lr.score(X_test, y_test))
# 利用classification_report模塊獲得LogisticRegression其他三個指標的結果
print(classification_report(y_test, lr_y_predict, target_names=['Benign', 'Malignant']))
# 使用隨機梯度下降模型自帶的評分函數score獲得模型在測試集上的準確性結果
print("Accuracy of SGD Classifier: ", sgdc.score(X_test, y_test))
# 利用classification_report模塊獲得SGDClassifier其他三個指標的結果
print(classification_report(y_test, sgdc_y_predict, target_names=['Benign', 'Malignant']))
發現LogisticRegression比SGDClassifier在測試集上的表現有更高的準確性。這是因為Scikit-learn中采用解析的方式精確計算LogisticRegression的參數,而使用梯度法估計SGDClassifier的參數。
一般而言,對于訓練數據規模在10萬量級以上的數據,考慮到時間的消耗,推薦使用隨機梯度算法對模型參數進行估計。
?2.支持向量機(分類)
支持向量機分類器(Support Vector Classifier)是根據訓練樣本的分布,搜索所有可能的線性分類器中最佳的那個。決定其直線位置的樣本并不是所有訓練數據,而是其中的兩個空間間隔最小的兩個不同類別的數據點,把這種可以用來真正幫助決策最優線性分類模型的數據點叫做“支持向量”
應用案例:手寫字體數字圖像識別
# 從sklearn.datasets中導入手寫體數字加載器
from sklearn.datasets import load_digits
# 從通過數據加載器獲得手寫體數字的數碼圖像數據并存儲在digits變量中
digits = load_digits()
# 檢查數據規模和特征維度
print(digits.data.shape)
通過數據分隔獲取75%的訓練樣本和25%的測試樣本
# 使用sklearn.model_selection里的train_test_split模塊用于分割數據
from sklearn.model_selection import train_test_split
# 隨機采樣25%的數據用于測試,剩下的75%用于構建訓練集合
X_train, X_test, y_train, y_test = train_test_split(digits.data, digits.target, test_size=0.25, random_state=33)
# 檢查訓練數據和測試數據的規模
#print(y_train.shape)
#print(y_test.shape)
使用樣本訓練基于線性假設的支持向量機模型。
# 使用支持向量機(分類)對手寫體數字圖像進行識別
# 從sklearn.preprocessing中導入數據標準化模塊
from sklearn.preprocessing import StandardScaler
# 從sklearn.svm中導入基于線性假設的支持向量機分類器LinearSVC
from sklearn.svm import LinearSVC
# 對訓練和測試的特征數據進行標準化
ss = StandardScaler()
X_train = ss.fit_transform(X_train)
X_test = ss.fit_transform(X_test)
# 初始化線性假設的支持向量機分類器LinearSVC
lsvc = LinearSVC()
# 進行模型訓練
lsvc.fit(X_train, y_train)
# 利用訓練好的模型對測試樣本的數字類別進行預測,預測結果保存到變量y_predict
y_predict = lsvc.predict(X_test)
與之前一樣,使用準確性、召回率、精確率和F1指標。
# 性能測評
# 使用模型自帶的評估函數進行準確性測評
print("The Accuracy of LinearSVC is: ", lsvc.score(X_test, y_test))
# 利用classification_report模塊獲得SGDClassifier其他三個指標的結果
from sklearn.metrics import classification_report
print(classification_report(y_test, y_predict, target_names=digits.target_names.astype(str)))
注意:召回率、準確率和F1指標最先適用于二分類任務。這里有10個類別,即10個數字,無法直接計算上述指標,通常的做法是逐一評估某個類別的這三個性能指標:把所有其他的類別堪稱陰性(負)樣本?,這樣一來,就創造了10個二分類任務。
3.樸素貝葉斯
樸素貝葉斯(Naive Bayes)分類器的構造基礎是貝葉斯理論。
樸素貝葉斯分類器會單獨考量每一維度特征被分類的條件概率,進而綜合這些概率并對其所在的特征向量做出分類預測。因此,這個模型的基本數學假設是:各個維度上的特征被分類的 條件概率之間是相互獨立的 。
應用案例:新聞文本分類
讀取20類新聞文本的數據細節
# 從sklearn.datasets中導入新聞數據抓取器fetch_20newsgroups
from sklearn.datasets import fetch_20newsgroups
# fetch_20newsgroups即時從互聯網下載數據
news = fetch_20newsgroups(subset='all')
# 查看數據規模和細節
print(len(news.data))
print(news.data[0])
20類新聞文本數據分割
# 使用sklearn.model_selection里的train_test_split模塊用于分割數據
from sklearn.model_selection import train_test_split
# 隨機采樣25%的數據樣本作為測試集
X_train, X_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.25, random_state=33)
先將文本轉化為特征向量,然后利用樸素貝葉斯模型從訓練數據中估計參數,最后利用這些概率參數對同樣轉化為特征向量的測試新聞樣本進行類別預測。
使用樸素貝葉斯分類器對新聞文本數據進行類別預測
# 從sklearn.feature_extraction.text中導入用于文本特征向量轉化模塊
from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer()
X_train = vec.fit_transform(X_train)
X_test = vec.transform(X_test)
# 從sklearn.native_bayes中導入樸素貝葉斯模型
from sklearn.naive_bayes import MultinomialNB
# 使用默認參數初始化樸素貝葉斯模型
mnb = MultinomialNB()
# 利用訓練數據對模型參數進行估計
mnb.fit(X_train, y_train)
# 對測試樣本進行類別預測,結果存儲在變量y_predict中
y_predict = mnb.predict(X_test)
對樸素貝葉斯分類器在新聞文本數據上的表現性能進行評估
# 利用classification_report模塊獲得詳細的分類性能報告
from sklearn.metrics import classification_report
print('The Accuracy of Naive Bayes Classifier is:', mnb.score(X_test, y_test))
print(classification_report(y_test, y_predict, target_names=news.target_names))
樸素貝葉斯模型被廣泛應用于海量互聯網文本分類任務。由于其較強的特征條件獨立假設,使得模型預測所需要估計的參數規模從冪指數量級向線性量級減少,極大地節約了內存消耗和計算時間。但是,也正是收到這種強假設的限制,模型訓練時無法將各個特征之間的聯系考量在內,使得該模型在其他數據特征關聯性較強的分類任務上的性能表現不佳。
?4.K近鄰(分類)
尋找與待分類的樣本在特征空間中距離最近的K個已標記樣本作為參考,幫助做出分類決策。隨著K的不同,會獲得不同效果的分類器。
應用案例:鳶尾花分類
地區Iris數據集細節資料
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@File : Iris.py
@Author: Xinzhe.Pang
@Date : 2019/7/20 16:17
@Desc :
"""
# 從sklearn.datasets導入Iris數據加載器
from sklearn.datasets import load_iris
# 使用加載器讀取數據并存入變量iris
iris = load_iris()
# 查看數據規模
print(iris.data.shape)
# 查看數據說明
print(iris.DESCR)
對數據進行隨機分割,25%的樣本用于測試,75%的樣本用于模型的訓練
# 使用sklearn.model_selection里的train_test_split模塊用于分割數據
from sklearn.model_selection import train_test_split
# 使用train_test_split,利用隨機種子random_state采樣25%的數據作為測試集
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.25, random_state=33)
使用K緊鄰分類器對鳶尾花數據進行類別預測
# 從sklearn.preprocessing中導入數據標準化模塊
from sklearn.preprocessing import StandardScaler
# 從sklearn.neighbors選擇導入KNeighborsClassifier,即K近鄰分類器
from sklearn.neighbors import KNeighborsClassifier
# 對訓練和測試的特征數據進行標準化
ss = StandardScaler()
X_train = ss.fit_transform(X_train)
X_test = ss.fit_transform(X_test)
# 使用K近鄰分類器對測試數據進行類別預測,預測結果存儲在變量y_predict中
knc = KNeighborsClassifier()
knc.fit(X_train, y_train)
y_predict = knc.predict(X_test)
對K近鄰分類器在鳶尾花數據上的預測性能進行評估
# 使用模型自帶的評估函數進行準確性測評
print("The Accuracy of K-Nearest Neighbor Classifier: ", knc.score(X_test, y_test))
# 利用classification_report模塊獲得詳細的分類性能報告
from sklearn.metrics import classification_report
print(classification_report(y_test, y_predict, target_names=iris.target_names))
K近鄰算法與其他模型最大的不同在于:該模型沒有參數訓練過程。也就是說,沒有通過任何學習算法分析訓練數據,而只是根據測試樣本在訓練數據的分布直接做出分類決策。因此,K近鄰屬于無參模型(Nonparametric model)中非常簡單的一種。但是需要非常高的計算復雜度和內存消耗,是一種平方級別的算法。
5.決策樹
決策樹是描述非線性關系的不二之選。使用多種不同特征組合搭建搓成決策樹中需要考慮特征節點的選取順序。常用的度量方式有信息熵(In'formation Gain)和基尼不純性(Gini Impurity)。
應用案例:泰坦尼克號乘客生存預測
import pandas as pd
titanic = pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt')
print(titanic.head())
使用決策樹模型預測泰坦尼克號乘客的生還情況
# 特征的選擇
X = titanic[['pclass','age','sex']]
y = titanic['survived']
# 對當前選擇的特征進行選擇
print(X.info())
根據上面的輸出結果,有幾個數據處理任務:
1)age列,只有633個,需要補全
2)sex和pclass兩個數據列的值都是類別的,需要轉化為數值特征,用0/1代替
# 首先補充age數據,使用平均數或者中位數
X['age'].fillna(X['age'].mean(), inplace=True)
# 重新檢查數據完整性
print(X.info())
對數據進行分割,劃分訓練集和測試集,并執行決策樹分類器
# 數據分割
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=33)
# 使用scikit-learn.feature_extraction中的特征轉換器
from sklearn.feature_extraction import DictVectorizer
vec = DictVectorizer(sparse=False)
# 轉換特征后,發現所有的類別型的特征都被單獨剝離出來了,形成單獨的一列特征,數值型的則保持不變
X_train = vec.fit_transform(X_train.to_dict(orient='record'))
print(vec.feature_names_)
# 同樣需要對測試數據的特征進行轉化
X_test = vec.transform(X_test.to_dict(orient='record'))
# 從sklearn.tree中導入決策樹分類器
from sklearn.tree import DecisionTreeClassifier
# 使用默認參數初始化決策樹分類器
dtc = DecisionTreeClassifier()
# 使用分割到的訓練數據進行模型學習
dtc.fit(X_train, y_train)
# 用訓練好的決策樹模型對測試特征數據進行預測
y_predict = dtc.predict(X_test)
決策樹模型對泰坦尼克號乘客是否生還的預測性能
# 從sklearn.metrics導入classification_report
from sklearn.metrics import classification_report
# 輸出預測準確性
print(dtc.score(X_test, y_test))
# 輸出詳細分類性能結果
print(classification_report(y_predict, y_test, target_names=['died', 'survived']))
?決策樹在模型描述上有著巨大的優勢。決策樹推理邏輯直觀,具有清晰的可解釋性,方便模型的可視化。但是決策樹屬于有參數模型,需要花費時間進行調參。
6.集成學習(分類)
集成(Ensemble)分類模型是綜合考量多個分類器的預測結果,從而做出決策。大體分為兩類:一類是利用相同的訓練數據同時搭建多個獨立的分類模型,然后通過投票的方式,以少數服從多數的原則作為最終的分類決策。如隨機森林分類器(Ran'do'm Forest Classifier);另一種則是按照一定次序搭建多個分類模型。這些模型之間彼此存在以來關系。例如梯度提升決策樹(Gradient Tree Boosting)
應用案例:泰坦尼克號乘客生存預測
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@File : TitanicEnsemble.py
@Author: Xinzhe.Pang
@Date : 2019/7/21 1:38
@Desc :
"""
import pandas as pd
titanic = pd.read_csv('http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt')
# 特征的選擇
X = titanic[['pclass', 'age', 'sex']]
y = titanic['survived']
# 首先補充age數據,使用平均數或者中位數
X['age'].fillna(X['age'].mean(), inplace=True)
# 數據分割
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=33)
# 使用scikit-learn.feature_extraction中的特征轉換器
from sklearn.feature_extraction import DictVectorizer
vec = DictVectorizer(sparse=False)
X_train = vec.fit_transform(X_train.to_dict(orient='record'))
X_test = vec.transform(X_test.to_dict(orient='record'))
# 從sklearn.tree中導入決策樹分類器
from sklearn.tree import DecisionTreeClassifier
# 使用默認參數初始化決策樹分類器
dtc = DecisionTreeClassifier()
# 使用分割到的訓練數據進行模型學習
dtc.fit(X_train, y_train)
# 用訓練好的決策樹模型對測試特征數據進行預測
dtc_y_predict = dtc.predict(X_test)
# 使用隨機森林分類器進行集成模型的訓練以及預測分析
from sklearn.ensemble import RandomForestClassifier
rfc = RandomForestClassifier()
rfc.fit(X_train, y_train)
rfc_y_predict = rfc.predict(X_test)
# 使用梯度提升決策樹進行集成模型的訓練以及預測分析
from sklearn.ensemble import GradientBoostingClassifier
gbc = GradientBoostingClassifier()
gbc.fit(X_train, y_train)
gbc_y_predict = gbc.predict(X_test)
在測試數據集上比對單一決策樹、隨機森林分類器以及梯度提升決策樹的性能差異。
# 從sklearn.metrics導入classification_report
from sklearn.metrics import classification_report
# 輸出單一決策樹在測試集上的分類準確性、精確率、召回率以及F1指標
print('The Accuracy of decision tree is: ', dtc.score(X_test, y_test))
print(classification_report(dtc_y_predict, y_test))
# 輸出隨機森林分類器在測試集上的分類準確性、精確率、召回率以及F1指標
print('The Accuracy of random forest classifier is: ', rfc.score(X_test, y_test))
print(classification_report(rfc_y_predict, y_test))
# 輸出梯度提升決策樹在測試集上的分類準確性、精確率、召回率以及F1指標
print('The Accuracy of gradient tree boosting is: ', gbc.score(X_test, y_test))
print(classification_report(gbc_y_predict, y_test))
一般而言,工業界為了追求更加強勁的預測性能,經常使用隨機森林分類模型作為基線系統(Baseline System)。
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
