第三章 模型搭建和評估–建模
經(jīng)過前面的兩章的知識點的學(xué)習(xí),我可以對數(shù)數(shù)據(jù)的本身進(jìn)行處理,比如數(shù)據(jù)本身的增刪查補(bǔ),還可以做必要的清洗工作。那么下面我們就要開始使用我們前面處理好的數(shù)據(jù)了。這一章我們要做的就是使用數(shù)據(jù),我們做數(shù)據(jù)分析的目的也就是,運(yùn)用我們的數(shù)據(jù)以及結(jié)合我的業(yè)務(wù)來得到某些我們需要知道的結(jié)果。那么分析的第一步就是建模,搭建一個預(yù)測模型或者其他模型;我們從這個模型的到結(jié)果之后,我們要分析我的模型是不是足夠的可靠,那我就需要評估這個模型。今天我們學(xué)習(xí)建模,下一節(jié)我們學(xué)習(xí)評估。
我們擁有的泰坦尼克號的數(shù)據(jù)集,那么我們這次的目的就是,完成泰坦尼克號存活預(yù)測這個任務(wù)。
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all'
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from IPython.display import Image
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負(fù)號
plt.rcParams['figure.figsize'] = (10, 6) # 設(shè)置輸出圖片大小
載入這些庫,如果缺少某些庫,請安裝他們
【思考】這些庫的作用是什么呢?你需要查一查
【思考題回答】
pandas:Pandas的名稱來自于面板數(shù)據(jù)(panel data)和python數(shù)據(jù)分析(data analysis)。是基于NumPy 的一種工具,該工具是為了解決數(shù)據(jù)分析任務(wù)而創(chuàng)建的。Pandas 納入了大量庫和一些標(biāo)準(zhǔn)的數(shù)據(jù)模型,提供了高效地操作大型數(shù)據(jù)集所需的工具。pandas提供了大量能使我們快速便捷地處理數(shù)據(jù)的函數(shù)和方法。
numpy:NumPy是Python中科學(xué)計算的基礎(chǔ)包。它是一個Python庫,提供多維數(shù)組對象,各種派生對象(如掩碼數(shù)組和矩陣),以及用于數(shù)組快速操作的各種API,有包括數(shù)學(xué)、邏輯、形狀操作、排序、選擇、輸入輸出、離散傅立葉變換、基本線性代數(shù),基本統(tǒng)計運(yùn)算和隨機(jī)模擬等等。
matplotlib.pyplot:Matplotlib是Python的繪圖庫,其中的pyplot包封裝了很多畫圖的函數(shù)。Matplotlib.pyplot包含一系列類似 MATLAB 中繪圖函數(shù)的相關(guān)函數(shù)。
seaborn:Seaborn是一種基于matplotlib的圖形可視化python libraty。它提供了一種高度交互式界面,便于用戶能夠做出各種有吸引力的統(tǒng)計圖表。Seaborn其實是在matplotlib的基礎(chǔ)上進(jìn)行了更高級的API封裝,從而使得作圖更加容易,在大多數(shù)情況下使用seaborn就能做出很具有吸引力的圖,而使用matplotlib就能制作具有更多特色的圖。應(yīng)該把Seaborn視為matplotlib的補(bǔ)充,而不是替代物。同時它能高度兼容numpy與pandas數(shù)據(jù)結(jié)構(gòu)以及scipy與statsmodels等統(tǒng)計模式。
載入我們提供清洗之后的數(shù)據(jù)(clear_data.csv),大家也將原始數(shù)據(jù)載入(train.csv),說說他們有什么不同
# 讀取原數(shù)據(jù)數(shù)集
train = pd.read_csv('train.csv')
train.shape
(891, 12)
train.head()

#讀取清洗過的數(shù)據(jù)集
data = pd.read_csv('clear_data.csv')
data.shape
(891, 11)
data.head()

【回答】兩者區(qū)別:清洗過的數(shù)據(jù)集把PassengerId從0開始計數(shù),Survived應(yīng)該是被拿出當(dāng)label了。而Name、Ticket、Cabin 這些非類別型或分類較多、缺失值多的文本型數(shù)據(jù)的列被刪除了,而Sex和Embarked這些分類較少的類別型文本型數(shù)據(jù)被OneHotEncoded了。
模型搭建
--處理完前面的數(shù)據(jù)我們就得到建模數(shù)據(jù),下一步是選擇合適模型
--在進(jìn)行模型選擇之前我們需要先知道數(shù)據(jù)集最終是進(jìn)行監(jiān)督學(xué)習(xí)還是無監(jiān)督學(xué)習(xí)
--模型的選擇一方面是通過我們的任務(wù)來決定的。
--除了根據(jù)我們?nèi)蝿?wù)來選擇模型外,還可以根據(jù)數(shù)據(jù)樣本量以及特征的稀疏性來決定
--剛開始我們總是先嘗試使用一個基本的模型來作為其baseline,進(jìn)而再訓(xùn)練其他模型做對比,最終選擇泛化能力或性能比較好的模型
--這里我的建模,并不是從零開始,自己一個人完成完成所有代碼的編譯。我們這里使用一個機(jī)器學(xué)習(xí)最常用的一個庫(sklearn)來完成我們的模型的搭建
【補(bǔ)充】Scikit-learn(以前稱為scikits.learn,也稱為sklearn)是針對Python 編程語言的免費軟件機(jī)器學(xué)習(xí)庫 。它具有各種分類,回歸和聚類算法,包括支持向量機(jī),隨機(jī)森林,梯度提升,k均值和DBSCAN,并且旨在與Python數(shù)值科學(xué)圖書館NumPy和SciPy兼容。
下面給出sklearn的算法選擇路徑,供大家參考
# sklearn模型算法選擇路徑圖
Image('sklearn.png')

【思考】數(shù)據(jù)集哪些差異會導(dǎo)致模型在擬合數(shù)據(jù)時發(fā)生變化
【思考回答】
1.樣本數(shù)量
2.是否是分類問題
3.數(shù)據(jù)是否有標(biāo)記
4.是否數(shù)量預(yù)測
5.數(shù)據(jù)特征維度
任務(wù)一:切割訓(xùn)練集和測試集
這里使用留出法劃分?jǐn)?shù)據(jù)集
--將數(shù)據(jù)集分為自變量和因變量
--按比例切割訓(xùn)練集和測試集(一般測試集的比例有30%、25%、20%、15%和10%)
--使用分層抽樣
--設(shè)置隨機(jī)種子以便結(jié)果能復(fù)現(xiàn)
【思考】
劃分?jǐn)?shù)據(jù)集的方法有哪些?
為什么使用分層抽樣,這樣的好處有什么?
【思考回答】
劃分?jǐn)?shù)據(jù)集的方法:
留出法(Hold-out)
交叉驗證法(Cross validation)
自助法(Bootstrapping)
分層抽樣將總體單位按其屬性特征分成若干類型或?qū)樱缓笤陬愋突驅(qū)又须S機(jī)抽取樣本單位。好處是通過劃類分層,增大了各類型中單位間的共同性,容易抽出具有代表性的調(diào)查樣本,抽樣誤差比較小。
任務(wù)提示1
切割數(shù)據(jù)集是為了后續(xù)能評估模型泛化能力
sklearn中切割數(shù)據(jù)集的方法為train_test_split
查看函數(shù)文檔可以在jupyter notebook里面使用train_test_split?后回車即可看到
分層和隨機(jī)種子在參數(shù)里尋找
要從clear_data.csv和train.csv中提取train_test_split()所需的參數(shù)
from sklearn.model_selection import train_test_split
# 一般先取出X和y后再切割,有些情況會使用到未切割的,這時候X和y就可以用,x是清洗好的數(shù)據(jù),y是我們要預(yù)測的存活數(shù)據(jù)'Survived'
X = data # 樣本特征集
y = train['Survived'] # 樣本標(biāo)簽集
# 對數(shù)據(jù)集進(jìn)行切割
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=0) # 參數(shù)意義見【參考】
# 查看數(shù)據(jù)形狀
X_train.shape, X_test.shape
((668, 11), (223, 11))
【參考】sklearn的train_test_split()各函數(shù)參數(shù)含義解釋(非常全)
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html
【思考】
什么情況下切割數(shù)據(jù)集的時候不用進(jìn)行隨機(jī)選取
【思考回答】隨機(jī)選取就是通過隨機(jī)選取的樣本來代表總體,這樣樣本具有隨機(jī)性、代表性??梢圆挥秒S機(jī)選取的情況是數(shù)據(jù)集本身就足夠隨機(jī),這種情況一般是隨機(jī)處理后的。或者使用交叉驗證法中的留一法處理數(shù)據(jù)。
任務(wù)二:模型創(chuàng)建
創(chuàng)建基于線性模型的分類模型(邏輯回歸)
創(chuàng)建基于樹的分類模型(決策樹、隨機(jī)森林)
分別使用這些模型進(jìn)行訓(xùn)練,分別得到訓(xùn)練集和測試集的得分
查看模型的參數(shù),并更改參數(shù)值,觀察模型變化
提示
邏輯回歸不是回歸模型而是分類模型,不要與LinearRegression混淆
隨機(jī)森林其實是決策樹集成為了降低決策樹過擬合的情況
線性模型所在的模塊為sklearn.linear_model
樹模型所在的模塊為sklearn.ensemble
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
# 默認(rèn)參數(shù)邏輯回歸模型
lr = LogisticRegression()
lr.fit(X_train, y_train)
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, l1_ratio=None, max_iter=100,
multi_class='warn', n_jobs=None, penalty='l2',
random_state=None, solver='warn', tol=0.0001, verbose=0,
warm_start=False)
# 查看訓(xùn)練集和測試集score值
print("Training set score: {:.3f}".format(lr.score(X_train, y_train)))
print("Testing set score: {:.3f}".format(lr.score(X_test, y_test)))
Training set score: 0.805
Testing set score: 0.785
# 調(diào)整參數(shù)后的邏輯回歸模型
lr2 = LogisticRegression(C=100) # C為正則化系數(shù)λ的倒數(shù),這里取100,C值越大,對應(yīng)的正則化越弱,越容易過擬合。
lr2.fit(X_train, y_train)
LogisticRegression(C=100, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, l1_ratio=None, max_iter=100,
multi_class='warn', n_jobs=None, penalty='l2',
random_state=None, solver='warn', tol=0.0001, verbose=0,
warm_start=False)
print("Training set score: {:.3f}".format(lr2.score(X_train, y_train)))
print("Testing set score: {:.3f}".format(lr2.score(X_test, y_test)))
Training set score: 0.801
Testing set score: 0.794
【分析】可以看出與之前相比,訓(xùn)練集得分下降了,但是測試集得分上升了。這是調(diào)參確定懲罰項系數(shù),目標(biāo)是使得測試集的得分盡可能的高。
【注意】正則項系數(shù)初始值應(yīng)該設(shè)置為多少,好像也沒有一個比較好的準(zhǔn)則。建議一開始將正則項系數(shù)λ設(shè)置為0,先確定一個比較好的learning rate。然后固定該learning rate,給λ一個值(比如1.0),然后根據(jù)validation accuracy,將λ增大或者減小10倍(增減10倍是粗調(diào)節(jié),當(dāng)你確定了λ的合適的數(shù)量級后,比如λ = 0.01,再進(jìn)一步地細(xì)調(diào)節(jié),比如調(diào)節(jié)為0.02,0.03,0.009之類。)
# 默認(rèn)參數(shù)的隨機(jī)森林分類模型
rfc = RandomForestClassifier()
rfc.fit(X_train, y_train)
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
max_depth=None, max_features='auto', max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=10,
n_jobs=None, oob_score=False, random_state=None,
verbose=0, warm_start=False)
print("Training set score: {:.3f}".format(rfc.score(X_train, y_train)))
print("Testing set score: {:.3f}".format(rfc.score(X_test, y_test)))
Training set score: 0.979
Testing set score: 0.767
# 調(diào)整參數(shù)后的隨機(jī)森林分類模型
rfc2 = RandomForestClassifier(n_estimators=100, max_depth=5)
rfc2.fit(X_train, y_train)
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
max_depth=5, max_features='auto', max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=100,
n_jobs=None, oob_score=False, random_state=None,
verbose=0, warm_start=False)
print("Training set score: {:.3f}".format(rfc2.score(X_train, y_train)))
print("Testing set score: {:.3f}".format(rfc2.score(X_test, y_test)))
Training set score: 0.864
Testing set score: 0.816
【分析】可以看出此題隨機(jī)森林集成方法測試集比邏輯回歸分?jǐn)?shù)高很多,設(shè)置了更多的樹的數(shù)量(10棵→100棵)和控制最大樹深,這可以防止過擬合,測試效果果然有提升。
【參考】sklearn隨機(jī)森林分類類RandomForestClassifier
https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html
【思考】
為什么線性模型可以進(jìn)行分類任務(wù),背后是怎么的數(shù)學(xué)關(guān)系
對于多分類問題,線性模型是怎么進(jìn)行分類的
【思考回答】

如果函數(shù)值小于0,我們就預(yù)測類別-1,如果函數(shù)值大于0,我們就預(yù)測類別+1。對于所有用于分類的線性模型,這個預(yù)測規(guī)則都是通用的。對于用于分類的線性模型,決策邊界是輸入的線性函數(shù)。換句話說,(二元)線性分類器是利用直線、平面或超平面來分開兩個類別的分類器。
多分類的問題常常是使用差分策略,通過二分類學(xué)習(xí)來解決多分類問題,即將多分類問題拆解為多個二分類訓(xùn)練二分類學(xué)習(xí)器最后通過繼承得到結(jié)果,最經(jīng)典拆分策略有三種:“一對一”(OvO)、“一對其余”(OvR)和“多對多”(MvM),核心思想與示意圖如下所示:

具體選擇哪一種,要看具體情況下的存儲和時間開銷,以及性能高低。
一對一OvO:
假設(shè)訓(xùn)練集有四類樣本,C1,C2,C3,C4,訓(xùn)練時兩兩組合為二分類進(jìn)行訓(xùn)練,新樣本通過這C2N個分類器后會得到N(N?1)/2個分類結(jié)果,最終結(jié)果可根據(jù)這些分類結(jié)果投票產(chǎn)生。
一對其余OvR:
訓(xùn)練時一個類作為正例,其余所有類作為反例。這樣共有N個二分類器進(jìn)行訓(xùn)練,新樣本通過分類器時預(yù)測結(jié)果為正例的即為最終結(jié)果。
多對多MvM:
本質(zhì)上講前兩種情況都是MvM的特殊情況。基本思路是訓(xùn)練集每一類通過多個分類器訓(xùn)練會產(chǎn)生一組編碼結(jié)果,新樣本通過分類器產(chǎn)生的編碼結(jié)果與每個分類器的結(jié)果求距離,距離最短者即為最終結(jié)果。
【參考】線性模型-分類模型
????周志華《機(jī)器學(xué)習(xí)》
任務(wù)三:輸出模型預(yù)測結(jié)果
輸出模型預(yù)測分類標(biāo)簽
輸出不同分類標(biāo)簽的預(yù)測概率
提示3
一般監(jiān)督模型在sklearn里面有個predict能輸出預(yù)測標(biāo)簽,predict_proba則可以輸出標(biāo)簽概率
# 預(yù)測標(biāo)簽
pred = lr.predict(X_train)
# 此時我們可以看到0和1的數(shù)組
pred[:10]
array([0, 1, 1, 1, 0, 0, 1, 0, 1, 1], dtype=int64)
# 預(yù)測標(biāo)簽概率
pred_proba = lr.predict_proba(X_train) # X訓(xùn)練集默認(rèn)邏輯回歸的預(yù)測標(biāo)簽概率
pred_proba[:10] #前十個預(yù)測標(biāo)簽的概率,列表里面的元素前一個是標(biāo)簽為0的概率,后面一個是標(biāo)簽為1的概率
array([[0.62018758, 0.37981242],
[0.14977836, 0.85022164],
[0.46179245, 0.53820755],
[0.20586404, 0.79413596],
[0.86543626, 0.13456374],
[0.90619634, 0.09380366],
[0.13401825, 0.86598175],
[0.90068227, 0.09931773],
[0.05921015, 0.94078985],
[0.14323105, 0.85676895]])
【思考】
預(yù)測標(biāo)簽的概率對我們有什么幫助
【思考回答】預(yù)測標(biāo)簽的概率能夠讓我們判斷該標(biāo)簽的可信度,越接近1的話可信度越高,如果接近0.5的話,可信度就不高了。
模型評估
根據(jù)之前的模型的建模,我們知道如何運(yùn)用sklearn這個庫來完成建模,以及我們知道了的數(shù)據(jù)集的劃分等等操作。那么一個模型我們怎么知道它好不好用呢?以至于我們能不能放心的使用模型給我的結(jié)果呢?那么今天的學(xué)習(xí)的評估,就會很有幫助。
加載下面的庫
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from IPython.display import Image
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負(fù)號
plt.rcParams['figure.figsize'] = (10, 6) # 設(shè)置輸出圖片大小
任務(wù):加載數(shù)據(jù)并分割測試集和訓(xùn)練集
from sklearn.model_selection import train_test_split
# 一般先取出X和y后再切割,有些情況會使用到未切割的,這時候X和y就可以用,x是清洗好的數(shù)據(jù),y是我們要預(yù)測的存活數(shù)據(jù)'Survived'
data = pd.read_csv('clear_data.csv')
train = pd.read_csv('train.csv')
X = data
y = train['Survived']
# 對數(shù)據(jù)集進(jìn)行切割
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=0)
# 默認(rèn)參數(shù)邏輯回歸模型
lr = LogisticRegression()
lr.fit(X_train, y_train)
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, l1_ratio=None, max_iter=100,
multi_class='warn', n_jobs=None, penalty='l2',
random_state=None, solver='warn', tol=0.0001, verbose=0,
warm_start=False)
模型評估
模型評估是為了知道模型的泛化能力。
交叉驗證(cross-validation)是一種評估泛化性能的統(tǒng)計學(xué)方法,它比單次劃分訓(xùn)練集和測試集的方法更加穩(wěn)定、全面。
在交叉驗證中,數(shù)據(jù)被多次劃分,并且需要訓(xùn)練多個模型。
最常用的交叉驗證是 k 折交叉驗證(k-fold cross-validation),其中 k 是由用戶指定的數(shù)字,通常取 5 或 10。
準(zhǔn)確率(precision)度量的是被預(yù)測為正例的樣本中有多少是真正的正例
召回率(recall)度量的是正類樣本中有多少被預(yù)測為正類
f-分?jǐn)?shù)是準(zhǔn)確率與召回率的調(diào)和平均
【思考】:將上面的概念進(jìn)一步的理解,大家可以做一下總結(jié)
【思考回答】:
--即使學(xué)習(xí)器在訓(xùn)練集上表現(xiàn)得很好,它在測試集上的表現(xiàn)也不一定很好,它可能把訓(xùn)練樣本自身的一些特點當(dāng)作潛在樣本都會具有的一般性質(zhì),導(dǎo)致泛化能力下降,我們稱之為過擬合。我們的實際目的其實是希望學(xué)習(xí)器能在新樣本有很好的表現(xiàn),這就要對模型的泛化能力進(jìn)行模型評估。
--如何進(jìn)行模型評估和選擇?有幾種常見的評估方法:
1.留出法
2.交叉驗證法
3.自助法
--交叉驗證是一種普遍的模型評估方法,就是重復(fù)的使用數(shù)據(jù),把得到的樣本數(shù)據(jù)進(jìn)行切分,組合為不同的訓(xùn)練集和測試集,用訓(xùn)練集來訓(xùn)練模型,用測試集來評估模型預(yù)測的好壞。在此基礎(chǔ)上可以得到多組不同的訓(xùn)練集和測試集,某次訓(xùn)練集中的某樣本在下次可能成為測試集中的樣本,即所謂“交叉”。
--交叉驗證中常用的是k折交叉驗證(k-fold cross-validation),通過對 k 個不同分組訓(xùn)練的結(jié)果進(jìn)行平均來減少方差,因此模型的性能對數(shù)據(jù)的劃分就不那么敏感。k通常取5或10。
--TP(True Positive):被預(yù)測成了正類的正類,即正確預(yù)測的正類
FP(False Positive):被預(yù)測成了正類的負(fù)類
TN(True Negetive):被預(yù)測成了負(fù)類的負(fù)類,即正確預(yù)測的負(fù)類
FN(False Negetive):被預(yù)測成了負(fù)類的正類
--準(zhǔn)確率(precision):在預(yù)測結(jié)果中,正確預(yù)測的正類數(shù) / 預(yù)測為正類的數(shù)量 : TP / (TP+FP)
--召回率(Recall):在預(yù)測結(jié)果中,正確預(yù)測的正類數(shù) / 原本即為正類的數(shù)量 : TP / (TP+FN)
--f-分?jǐn)?shù):用precision和recall兩個指標(biāo)不直觀,索性把他們合并為一個變量——F-measure:Recall * Precision * 2 / (Recall + Precision)(越大越好,1為理想狀態(tài),此時precision為1,recall為1)
任務(wù)一:交叉驗證
用10折交叉驗證來評估之前的邏輯回歸模型
計算交叉驗證精度的平均值
#提示:交叉驗證
Image('Snipaste_2020-01-05_16-37-56.png')

提示4
交叉驗證在sklearn中的模塊為sklearn.model_selection
from sklearn.model_selection import cross_val_score
lr = LogisticRegression(C=100) # C值100,正則項系數(shù)λ=0.01
scores = cross_val_score(lr, X_train, y_train, cv=10) # 邏輯回歸,10折交叉驗證,參數(shù)意義見參考
# k折交叉驗證分?jǐn)?shù)
scores
array([0.82352941, 0.77941176, 0.80597015, 0.82089552, 0.8358209 ,
0.88059701, 0.72727273, 0.84848485, 0.75757576, 0.71212121])
# 平均交叉驗證分?jǐn)?shù)
print("Average cross-validation score: {:.3f}".format(scores.mean()))
Average cross-validation score: 0.799
【參考】
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.cross_val_score.html
【思考】
k折越多的情況下會帶來什么樣的影響?
【思考回答】一般而言,k折越多,評估結(jié)果的穩(wěn)定性和保真性越高,不過整個計算復(fù)雜度越高。一種特殊的情況是k=m,m為數(shù)據(jù)集樣本個數(shù),這種特例稱為留一法,結(jié)果往往比較準(zhǔn)確。
任務(wù)二:混淆矩陣
計算二分類問題的混淆矩陣
計算精確率、召回率以及f-分?jǐn)?shù)
【思考】什么是二分類問題的混淆矩陣,理解這個概念,知道它主要是運(yùn)用到什么任務(wù)中的
【思考回答】二分類問題的混淆矩陣是一個 2 維方陣,它主要用于評估二分類問題的好壞,如下圖所示。它主要運(yùn)用于二分類任務(wù)中。實際上,多分類問題依然可以轉(zhuǎn)換為二分類問題進(jìn)行處理。
#提示:混淆矩陣
Image('Snipaste_2020-01-05_16-38-26.png')

#提示:準(zhǔn)確率 (Accuracy),精確度(Precision),Recall,f-分?jǐn)?shù)計算方法
Image('Snipaste_2020-01-05_16-39-27.png')

提示5
--混淆矩陣的方法在sklearn中的sklearn.metrics模塊
--混淆矩陣需要輸入真實標(biāo)簽和預(yù)測標(biāo)簽
--精確率、召回率以及f-分?jǐn)?shù)可使用classification_report模塊
from sklearn.metrics import confusion_matrix
# 訓(xùn)練模型
lr = LogisticRegression(C=100)
lr.fit(X_train, y_train)
LogisticRegression(C=100, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, l1_ratio=None, max_iter=100,
multi_class='warn', n_jobs=None, penalty='l2',
random_state=None, solver='warn', tol=0.0001, verbose=0,
warm_start=False)
# 模型預(yù)測結(jié)果
pred = lr.predict(X_train)
# 混淆矩陣
confusion_matrix(y_train, pred)
array([[350, 62],
[ 71, 185]], dtype=int64)
from sklearn.metrics import classification_report
# 精確率、召回率以及f1-score
print(classification_report(y_train, pred))
precision recall f1-score support
0 0.83 0.85 0.84 412
1 0.75 0.72 0.74 256
accuracy 0.80 668
macro avg 0.79 0.79 0.79 668
weighted avg 0.80 0.80 0.80 668
【思考】
如果自己實現(xiàn)混淆矩陣的時候該注意什么問題
【思考回答】在 scikit-learn 中, 計算混淆矩陣用來評估分類的準(zhǔn)確度。
按照定義, 混淆矩陣 C 中的元素 Ci,j 等于真實值為組 i , 而預(yù)測為組 j 的觀測數(shù)(the number of observations)。 所以對于二分類任務(wù), 預(yù)測結(jié)果中, 正確的負(fù)例數(shù)(true negatives, TN)為 C0,0; 錯誤的負(fù)例數(shù)(false negatives, FN)為 C1,0; 真實的正例數(shù)為 C1,1; 錯誤的正例數(shù)為 C0,1。
如果 labels 為 None, scikit-learn 會把在出現(xiàn)在 y_true 或 y_pred 中的所有值添加到標(biāo)記列表 labels 中, 并排好序。
任務(wù)三:ROC曲線
繪制ROC曲線
【思考】什么是ROC曲線,ROC曲線的存在是為了解決什么問題?
【思考回答】ROC的全稱是Receiver Operating Characteristic Curve,中文名字叫“受試者工作特征曲線”,顧名思義,其主要的分析方法就是畫這條特征曲線。

在ROC曲線圖中,每個點以對應(yīng)的FPR值為橫坐標(biāo),以TPR值為縱坐標(biāo),其它符號的意義前面提過。
ROC曲線的存在主要用于衡量模型的泛化性能,即分類效果的好壞。
提示6
ROC曲線在sklearn中的模塊為sklearn.metrics
ROC曲線下面所包圍的面積越大越好
from sklearn.metrics import roc_curve
fpr, tpr, thresholds = roc_curve(y_test, lr.decision_function(X_test))
plt.plot(fpr, tpr, label="ROC Curve")
plt.xlabel("FPR")
plt.ylabel("TPR (recall)")
# 找到最接近于0的閾值
close_zero = np.argmin(np.abs(thresholds)) # 取得最接近0閾值的索引值
plt.plot(fpr[close_zero], tpr[close_zero], 'o', markersize=10, label="threshold zero", fillstyle="none", c='k', mew=2)
plt.legend(loc=4)

【參考】https://scikit-learn.org/stable/modules/generated/sklearn.metrics.roc_curve.html
思考6
對于多分類問題如何繪制ROC曲線
【思考回答】
經(jīng)典的ROC曲線適用于對二分類問題進(jìn)行模型評估,通常將它推廣到多分類問題的方式有兩種:
1.對于每種類別,分別計算其將所有樣本點的預(yù)測概率作為閾值所得到的TPR和FPR值(是這種類別為正,其他類別為負(fù)),最后將每個取定的閾值下,對應(yīng)所有類別的TPR值和FPR值分別求平均,得到最終對應(yīng)這個閾值的TPR和FPR值
2.首先,對于一個測試樣本:1)標(biāo)簽只由0和1組成,1的位置表明了它的類別(可對應(yīng)二分類問題中的“正”),0就表示其他類別(“負(fù)”);2)要是分類器對該測試樣本分類正確,則該樣本標(biāo)簽中1對應(yīng)的位置在概率矩陣P中的值是大于0對應(yīng)的位置的概率值的。
上面的兩個方法得到的ROC曲線是不同的,當(dāng)然曲線下的面積AUC也是不一樣的。 在python中,方法1和方法2分別對應(yīng)sklearn.metrics.roc_auc_score函數(shù)中參數(shù)average值為’macro’和’micro’的情況。
【思考】你能從這條ROC曲線的到什么信息?這些信息可以做什么?
【思考回答】根據(jù)曲線位置,把整個圖劃分成了兩部分,曲線下方部分的面積被稱為AUC(Area Under Curve),用來表示預(yù)測準(zhǔn)確性,AUC值越高,也就是曲線下方面積越大,說明預(yù)測準(zhǔn)確率越高。曲線越接近左上角(X越小,Y越大),預(yù)測準(zhǔn)確率越高。對角線對應(yīng)于“隨機(jī)猜測”模型,而點(0,1)則對應(yīng)于將所有正例排在所有反例之前的“理想模型”。從本圖中看,ROC曲線在對角線之上,肯定比“隨機(jī)猜測”模型要好。