Deephub翻譯組:Alexander Zhao
癌症檢測是不平衡分類問題的一個普遍例子,因為非癌症病例往往比實際癌症病例多得多。
一個典型的不平衡分類數據集是乳腺攝影數據集,這個數據集用於從放射掃描中檢測乳腺癌(特別是在乳腺攝影中出現明亮的微鈣化簇)。研究人員通過掃描圖像,對目標進行分割,然後用計算機視覺算法描述分割對象,從而獲得了這一數據集。
由於類別不平衡十分嚴重,這是一個非常流行的不平衡分類數據集。其中98%的候選圖像不是癌症,只有2%被有經驗的放射科醫生標記為癌症。
在本教程中,您將發現如何開發和評估乳腺癌鉬靶攝影數據集的不平衡分類模型。完成本教程後,您將知道:
如何加載和探索數據集,並從中獲得預處理數據與選擇模型的靈感。如何使用代價敏感算法評估一組機器學習模型並提高其性能。如何擬合最終模型並使用它預測特定情況下的類標籤。我們開始吧。
教程概述
本教程分為五個部分,分別是:
乳腺攝影數據集瀏覽數據集模型試驗和基準結果評估模型評估機器學習算法評估代價敏感算法對新數據進行預測乳腺攝影數據集
在這個項目中,我們將使用一個典型的不平衡機器學習數據集,即「乳腺攝影」數據集,有時稱為「Woods乳腺攝影數據集」。
數據集歸Kevin Woods等人所有,有關這項工作可以參考1993年發表的題為「Comparative Evaluation Of Pattern Recognition Techniques For Detection Of Microcalcifications In Mammography」的論文。
這個問題的焦點是通過放射掃描來檢測乳腺癌,特別是在乳房X光片上出現的微小鈣化團。
該數據集首先從24張已知癌症診斷結果的乳房X光片開始掃描,然後使用圖像分割計算機視覺算法對圖像進行預處理,從乳腺圖像中提取候選目標。這些候選目標被分割後,就會被一位經驗豐富的放射科醫生手工標記。
Woods等人首先從分割的對象中選取與模式識別最相關的對象並進行特徵提取,總共提取了29個特徵,這些特徵被減少到18個,然後最後減少到7個,具體如下(摘自論文原文):
對象的面積(像素)對象的平均灰度對象周長像素的漸變強度對象中的均方根噪聲波動對比度,也即對象的平均灰度減去對象周圍兩個像素寬邊框的平均值基於形狀描述子的低階矩這是一個二分類任務,目的是利用給定分割對象的特徵來區分乳腺影片中的微鈣化和非微鈣化。
非微鈣化: 負類,或多數類微鈣化: 正類,或少數類作者評價與比較了一系列機器學習模型,包括人工神經網絡、決策樹、k近鄰算法等。各個模型用受試者操作特性曲線(ROC)進行評估,並且用曲線下面積(AUC)進行比較。
選擇ROC與AUC作為評估指標,其目的是最小化假陽性率(FPR,即特異性Specificity的補數)並最大化真陽性率(TPR,即敏感性Sensitivity),這也即ROC曲線的兩軸。選用ROC曲線的另一個原因是可以讓研究人員確定一個概率閾值,從而對可以接受的最大FPR與TPR進行權衡(因為隨著TPR的上升FPR也不可避免地上升,譯者注)。
研究結果表明,線性分類器(原文中應該是一個高斯樸素貝葉斯分類器)的AUC為0.936(100次實驗的平均值),表現最好。
接下來,讓我們仔細看看數據。
探索數據集
乳腺攝影數據集是一個廣泛使用的標準機器學習數據集,用於探索和演示許多專門為不平衡分類設計的技術。一個典型的例子是流行的SMOTE技術。
我們使用的數據集是其中的一個版本,它與原始文件中描述的數據集有一些不同。
首先,下載數據集並將其保存在當前的工作目錄中,名為「mammography.csv」
下載乳房攝影數據集(maxomography.csv)檢查文件的內容。文件的前幾行應如下所示:
0.23001961,5.0725783,-0.27606055,0.83244412,-0.37786573,0.4803223,'-1'
0.15549112,-0.16939038,0.67065219,-0.85955255,-0.37786573,-0.94572324,'-1'
-0.78441482,-0.44365372,5.6747053,-0.85955255,-0.37786573,-0.94572324,'-1'
0.54608818,0.13141457,-0.45638679,-0.85955255,-0.37786573,-0.94572324,'-1'
-0.10298725,-0.3949941,-0.14081588,0.97970269,-0.37786573,1.0135658,'-1'
我們可以看到數據集有6個輸入變量,而不是7個輸入變量。有可能從這個版本的數據集中刪除了論文中列出的第一個輸入變量(用像素描述的對象面積)。
輸入變量是數值類型,而目標變量是多數類置為「-1」、少數類置為「1」的字符串。這些值需要分別編碼為0和1,以滿足分類算法對二進位不平衡分類問題的期望。
可以使用read_csv()這一Pandas函數將數據集加載為DataFrame數據結構,注意指定header=None。
...
# define the dataset location
filename = 'mammography.csv'
# load the csv file as a data frame
dataframe = read_csv(filename, header=None)
載入完畢後,我們調用DataFrame的shape方法列印其行列數。
...
# summarize the shape of the dataset
print(dataframe.shape)
我們還可以通過使用Counter來確認數據,獲取各類的比例。
...
# summarize the class distribution
target = dataframe.values[:,-1]
counter = Counter(target)
for k,v in counter.items():
per = v / len(target) * 100
print('Class=%s, Count=%d, Percentage=%.3f%%' % (k, v, per))
把這兩步放在一起,完整的載入與確認數據的代碼如下:
# load and summarize the dataset
from pandas import read_csv
from collections import Counter
# define the dataset location
filename = 'mammography.csv'
# load the csv file as a data frame
dataframe = read_csv(filename, header=None)
# summarize the shape of the dataset
print(dataframe.shape)
# summarize the class distribution
target = dataframe.values[:,-1]
counter = Counter(target)
for k,v in counter.items():
per = v / len(target) * 100
print('Class=%s, Count=%d, Percentage=%.3f%%' % (k, v, per))
運行示例代碼,首先加載數據集並確認行和列的數量,即11183行、6個輸入變量和1個目標變量。
然後確認類別分布,我們會觀察到嚴重的類別不平衡:多數類(無癌症)約佔98%,少數類(癌症)約佔2%。
(11183, 7)
Class='-1', Count=10923, Percentage=97.675%
Class='1', Count=260, Percentage=2.325%
從反例和正例的比例來看,數據集似乎與SMOTE論文中描述的數據集基本匹配。
A typical mammography dataset might contain 98% normal pixels and 2% abnormal pixels.
— SMOTE: Synthetic Minority Over-sampling Technique, 2002.
此外,正反例的數量也基本與論文相符。
The experiments were conducted on the mammography dataset. There were 10923 examples in the majority class and 260 examples in the minority class originally.
— SMOTE: Synthetic Minority Over-sampling Technique, 2002.
我相信這是同一個數據集,儘管我無法解釋輸入特徵數量的不匹配現象,例如我們的數據集中只有6個輸入數據,而原始論文中有7個。
我們還可以為每個變量創建直方圖來觀察輸入變量的分布,下面列出了完整的示例。
# create histograms of numeric input variables
from pandas import read_csv
from matplotlib import pyplot
# define the dataset location
filename = 'mammography.csv'
# load the csv file as a data frame
df = read_csv(filename, header=None)
# histograms of all variables
df.hist()
pyplot.show()
運行該示例代碼將為數據集中的六個輸入變量分別創建一個直方圖。我們可以看到,這些變量有不同的取值範圍,而且大多數變量都是指數分布的,例如,大多數情況下變量只佔據直方圖的一列,而其他情況下則留下一個長尾,而最後一個變量則似乎具有雙峰分布。
根據我們選擇的算法,將數據分布縮放到相同的取值範圍是可能是很有用的,也許還需要使用一些冪變換,這將在後文進行討論。
數據分布
我們還可以為每對輸入變量創建一個散點圖,稱為散點圖矩陣。這有助於我們了解是否有任何變量是相互關聯的,或在同一方向上發生變化。我們還可以根據類標籤給每個散點圖上色。我們將多數類(沒有癌症)標記為藍點,少數類(癌症)標記為紅點。
下面列出了完整的示例。
# create pairwise scatter plots of numeric input variables
from pandas import read_csv
from pandas.plotting import scatter_matrix
from matplotlib import pyplot
# define the dataset location
filename = 'mammography.csv'
# load the csv file as a data frame
df = read_csv(filename, header=None)
# define a mapping of class values to colors
color_dict = {"'-1'":'blue', "'1'":'red'}
# map each row to a color based on the class value
colors = [color_dict[str(x)] for x in df.values[:, -1]]
# pairwise scatter plots of all numerical variables
scatter_matrix(df, diagonal='kde', color=colors)
pyplot.show()
運行該示例將創建一個6組*6組的散點圖矩陣,用於六個輸入變量的相互比較。矩陣的對角線表示每個變量的密度分布。
每一對變量的分布比較都出現了兩次,分別位於主對角線元素的左側與上側(或右側與下側)。這提供了兩種查看變量分布的尺度。
我們可以看到,對於正類與負類,許多變量的分布確實不同,這表明在癌症病例和非癌症病例之間進行合理的區分是可行的。
散點圖矩陣
散點圖矩陣
現在我們已經回顧了數據集,接下來讓我們來評估與測試備選模型。
模型測試與基準結果
我們將使用重複的分層k折交叉驗證來評估候選模型。
k-fold交叉驗證程序可以提供一個良好的模型性能總體估計值,與單次的留出驗證相比,這種方法不容易帶來過高的偏差。我們取k=10,這意味著每折將包含約11183/10或約1118個示例。
分層意味著每折的數據分布將與整體數據分布保持一致,即大約98%的無癌症對象與2%的有癌症對象。重複則意味著會進行多次重複實驗,以幫助避免僥倖結果並更好地確定所選模型的方差。我們將重複進行三次實驗。這意味著將對單個模型進行10×3即30次擬合和評估,並統計運行結果的平均值和標準差。這可以通過使用重複的scikit-learn庫的RepeatedStratifiedKFold類來實現。
我們將使用roc_auc_score()函數計算的AUC來評估和比較模型效果。
我們可以定義一個函數來加載數據集,並將列拆分為輸入和輸出變量。我們將類標籤重新編碼為0和1。下面的load_dataset()函數實現了這一點。
# load the dataset
def load_dataset(full_path):
# load the dataset as a numpy array
data = read_csv(full_path, header=None)
# retrieve numpy array
data = data.values
# split into input and output elements
X, y = data[:, :-1], data[:, -1]
# label encode the target variable to have the classes 0 and 1
y = LabelEncoder().fit_transform(y)
return X, y
然後,我們可以定義一個函數,用於在數據集上評估給定模型,並返回每折和與每次重複實驗的AUC列表。
下面的evaluate_model()函數實現了這一點,將數據集和模型作為參數並返回分數列表。
# evaluate a model
def evaluate_model(X, y, model):
# define evaluation procedure
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# evaluate model
scores = cross_val_score(model, X, y, scoring='roc_auc', cv=cv, n_jobs=-1)
return scores
最後,我們可以使用這個測試工具評估數據集上的基準模型。對每個樣本進行隨機預測的分類器的AUC期望值為0.5,這是該數據集性能的基線。這個隨機預測的分類器一個所謂的「無效」分類器。
這可以通過scikit-learn庫的DummyClassifier類來實現,將參數「strategy」設置為『stratified『。
...
# define the reference model
model = DummyClassifier(strategy='stratified')
一旦模型評估完成,我們就可以直接獲得AUC得分的平均值和標準差。
...
# evaluate the model
scores = evaluate_model(X, y, model)
# summarize performance
print('Mean ROC AUC: %.3f (%.3f)' % (mean(scores), std(scores)))
將這幾部分結合起來,下面列出了加載數據集、評估基準模型和報告分類器性能的完整示例。
# test harness and baseline model evaluation
from collections import Counter
from numpy import mean
from numpy import std
from pandas import read_csv
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.dummy import DummyClassifier
# load the dataset
def load_dataset(full_path):
# load the dataset as a numpy array
data = read_csv(full_path, header=None)
# retrieve numpy array
data = data.values
# split into input and output elements
X, y = data[:, :-1], data[:, -1]
# label encode the target variable to have the classes 0 and 1
y = LabelEncoder().fit_transform(y)
return X, y
# evaluate a model
def evaluate_model(X, y, model):
# define evaluation procedure
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# evaluate model
scores = cross_val_score(model, X, y, scoring='roc_auc', cv=cv, n_jobs=-1)
return scores
# define the location of the dataset
full_path = 'mammography.csv'
# load the dataset
X, y = load_dataset(full_path)
# summarize the loaded dataset
print(X.shape, y.shape, Counter(y))
# define the reference model
model = DummyClassifier(strategy='stratified')
# evaluate the model
scores = evaluate_model(X, y, model)
# summarize performance
print('Mean ROC AUC: %.3f (%.3f)' % (mean(scores), std(scores)))
運行示例,首先加載並匯總數據集。我們可以看到加載的行數是正確的,並且有6個輸入變量。重要的是,我們可以看到類標籤具有到整數的正確映射,多數類記為0,少數類記為1,通常用於不平衡的二分類數據集。
接下來,報告AUC得分的平均值。
如預期的那樣,無效分類器獲得了平均AUC約為0.5的最壞性能。這為性能提供了一個基線,在這個基線之上,可以認為模型在這個數據集是有效的。
(11183, 6) (11183,) Counter({0: 10923, 1: 260})
Mean ROC AUC: 0.503 (0.016)
現在我們有了測試工具和基準性能,我們可以開始在這個數據集上評估一些模型。
模型評估
在本節中,我們將使用上一節中開發的測試工具在數據集上評估不同的分類算法。
我們的目的是演示如何系統地解決問題,並展示某些專門為不平衡分類問題設計的算法的效果。我們獲得的模型性能良好,但是仍未高度優化(例如,我們沒有優化模型超參數)。
你能做得更好嗎?我很樂意看到讀者們能用同樣的測試工具獲得更好的AUC,歡迎在評論區留言。
機器學習算法評估
首先,我們在這個數據集上評估一些普通的機器學習模型。
我們可以在數據集上檢測一系列不同的線性或非線性算法,這會很有用:這樣我們可以快速了解到哪些算法在數據集上表現良好,而哪些算法則不值得我們關注。我們將在乳腺攝影數據集上評估以下機器學習模型:
邏輯回歸(LR)支持向量機(SVM)Bagging算法(BAG)隨機森林(RF)梯度提升機(GBM)我們將主要使用默認的模型超參數,除了集成學習算法中的n_estimator,我們將其設置為1000。
我們將依次定義每個模型並將它們添加到列表中,以便可以按順序對它們進行評估。我們定義下面的*get_models()*函數來評估模型效果並繪圖。
# define models to test
def get_models():
models, names = list(), list()
# LR
models.append(LogisticRegression(solver='lbfgs'))
names.append('LR')
# SVM
models.append(SVC(gamma='scale'))
names.append('SVM')
# Bagging
models.append(BaggingClassifier(n_estimators=1000))
names.append('BAG')
# RF
models.append(RandomForestClassifier(n_estimators=1000))
names.append('RF')
# GBM
models.append(GradientBoostingClassifier(n_estimators=1000))
names.append('GBM')
return models, names
然後,我們可以依次列舉模型列表中的每個模型並進行評估,記錄AUC並存儲在列表中以供以後繪製。
...
# define models
models, names = get_models()
results = list()
# evaluate each model
for i in range(len(models)):
# evaluate the model and store results
scores = evaluate_model(X, y, models[i])
results.append(scores)
# summarize and store
print('>%s %.3f (%.3f)' % (names[i], mean(scores), std(scores)))
在運行結束時,我們可以繪製模型表現的箱線圖,以便直接比較模型表現。
# plot the results
pyplot.boxplot(results, labels=names, showmeans=True)
pyplot.show()
將這些結合起來,下面列出了評估乳腺攝影數據集上一套機器學習算法的完整示例。
# spot check machine learning algorithms on the mammography dataset
from numpy import mean
from numpy import std
from pandas import read_csv
from matplotlib import pyplot
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import BaggingClassifier
# load the dataset
def load_dataset(full_path):
# load the dataset as a numpy array
data = read_csv(full_path, header=None)
# retrieve numpy array
data = data.values
# split into input and output elements
X, y = data[:, :-1], data[:, -1]
# label encode the target variable to have the classes 0 and 1
y = LabelEncoder().fit_transform(y)
return X, y
# evaluate a model
def evaluate_model(X, y, model):
# define evaluation procedure
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# evaluate model
scores = cross_val_score(model, X, y, scoring='roc_auc', cv=cv, n_jobs=-1)
return scores
# define models to test
def get_models():
models, names = list(), list()
# LR
models.append(LogisticRegression(solver='lbfgs'))
names.append('LR')
# SVM
models.append(SVC(gamma='scale'))
names.append('SVM')
# Bagging
models.append(BaggingClassifier(n_estimators=1000))
names.append('BAG')
# RF
models.append(RandomForestClassifier(n_estimators=1000))
names.append('RF')
# GBM
models.append(GradientBoostingClassifier(n_estimators=1000))
names.append('GBM')
return models, names
# define the location of the dataset
full_path = 'mammography.csv'
# load the dataset
X, y = load_dataset(full_path)
# define models
models, names = get_models()
results = list()
# evaluate each model
for i in range(len(models)):
# evaluate the model and store results
scores = evaluate_model(X, y, models[i])
results.append(scores)
# summarize and store
print('>%s %.3f (%.3f)' % (names[i], mean(scores), std(scores)))
# plot the results
pyplot.boxplot(results, labels=names, showmeans=True)
pyplot.show()
運行該示例以依次評估每個算法並報告AUC的平均值和標準差。由於學習算法的隨機性,您的特定結果會有所不同;您可以考慮多次運行這一程序。
我們看到,我們評估的所有算法都是有效的,都實現了高於基準值0.5的AUC。
結果表明,基於決策樹的集成學習算法(包括Bagging算法與隨機森林)在這個數據集上表現得更好,其中隨機森林表現最好,AUC約為0.950。
值得注意的是,我們獲取的結果好於論文中描述的結果(0.93),雖然我們的評估流程略有不同。
評估結果對LR和支持向量機算法有點不公平,因為我們在擬合模型之前沒有縮放輸入變量。我們可以在下一節探討這個問題。
>LR 0.919 (0.040)
>SVM 0.880 (0.049)
>BAG 0.941 (0.041)
>RF 0.950 (0.036)
>GBM 0.918 (0.037)
我們為每一個算法創建一個箱線圖。箱線圖中的「箱子」顯示了數據的中間50%的分布範圍,每個框中間的橙色線顯示樣本的中位數,每個框中的綠色三角形顯示樣本的平均值。
我們可以看到,BAG和RF的分布都很緊密,平均值和中位數也很接近,這意味著得分的分布可能為無偏的高斯分布,如穩定分布。
箱型圖
機器學習算法箱型圖
現在我們已經有了一組很好的結果,讓我們看看是否可以使用代價敏感的分類器來改進它們。
評估代價敏感算法
一些機器學習算法在擬合模型時可以更注意其中的某一類,這些模型被稱為代價敏感的機器學習模型,通過指定與類分布成反比的代價值,它們可以用於不平衡分類。例如,對於多數類和少數類,它們的比例分別為98%和2%,因此我們可以指定少數類分類錯誤的代價為98,多數類分類錯誤的代價為2。
能夠實現此功能的三種算法是:
邏輯回歸(LR)支持向量機(SVM)隨機森林(RF)這可以在scikit-learn中實現,方法是將*"class_weight"參數設置為「balanced」*,賦予這些算法代價敏感性。
例如,下面更新的get_models()函數定義了要在數據集上進行計算的三種算法的代價敏感版本。
# define models to test
def get_models():
models, names = list(), list()
# LR
models.append(LogisticRegression(solver='lbfgs', class_weight='balanced'))
names.append('LR')
# SVM
models.append(SVC(gamma='scale', class_weight='balanced'))
names.append('SVM')
# RF
models.append(RandomForestClassifier(n_estimators=1000))
names.append('RF')
return models, names
此外,在探索數據集時,我們注意到許多變量的數據分布呈指數分布。有時我們可以通過對每個變量使用冪變換來取得更好的數據分布。這將特別有助於LR和SVM算法,也可能有助於RF算法。
我們可以使用Pipeline類在交叉驗證模型評估的每一折上中實現它。Pipeline的第一步定義PowerTransformer,然後應用於每一折的訓練集和測試集;第二步則是我們正在評估的模型。然後可以使用evaluate_model()函數直接對Pipeline進行計算,示例代碼如下:
...
# defines pipeline steps
steps = [('p', PowerTransformer()), ('m',models[i])]
# define pipeline
pipeline = Pipeline(steps=steps)
# evaluate the pipeline and store results
scores = evaluate_model(X, y, pipeline)
把這一步結合在我們之前的代碼中,下面列出了在乳腺攝影數據集上評估進行冪變換後的代價敏感型機器學習算法的完整示例。
# cost-sensitive machine learning algorithms on the mammography dataset
from numpy import mean
from numpy import std
from pandas import read_csv
from matplotlib import pyplot
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import PowerTransformer
from sklearn.pipeline import Pipeline
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
# load the dataset
def load_dataset(full_path):
# load the dataset as a numpy array
data = read_csv(full_path, header=None)
# retrieve numpy array
data = data.values
# split into input and output elements
X, y = data[:, :-1], data[:, -1]
# label encode the target variable to have the classes 0 and 1
y = LabelEncoder().fit_transform(y)
return X, y
# evaluate a model
def evaluate_model(X, y, model):
# define evaluation procedure
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# evaluate model
scores = cross_val_score(model, X, y, scoring='roc_auc', cv=cv, n_jobs=-1)
return scores
# define models to test
def get_models():
models, names = list(), list()
# LR
models.append(LogisticRegression(solver='lbfgs', class_weight='balanced'))
names.append('LR')
# SVM
models.append(SVC(gamma='scale', class_weight='balanced'))
names.append('SVM')
# RF
models.append(RandomForestClassifier(n_estimators=1000))
names.append('RF')
return models, names
# define the location of the dataset
full_path = 'mammography.csv'
# load the dataset
X, y = load_dataset(full_path)
# define models
models, names = get_models()
results = list()
# evaluate each model
for i in range(len(models)):
# defines pipeline steps
steps = [('p', PowerTransformer()), ('m',models[i])]
# define pipeline
pipeline = Pipeline(steps=steps)
# evaluate the pipeline and store results
scores = evaluate_model(X, y, pipeline)
results.append(scores)
# summarize and store
print('>%s %.3f (%.3f)' % (names[i], mean(scores), std(scores)))
# plot the results
pyplot.boxplot(results, labels=names, showmeans=True)
pyplot.show()
運行該示例以依次評估每個算法並報告AUC的平均值和標準差。由於學習算法的隨機性,您的特定結果會有所不同;您可以考慮多次運行這一程序。
在這種情況下,我們可以看到,相比進行冪變換與添加代價敏感性之前,所有三個被測試的算法在AUC上都實現了提升。讀者還可以試著在不進行冪變換的情況下進行重複實驗,來探索算法性能提升的原因是冪變換,還是代價敏感算法,亦或是二者皆有。
在這種情況下,我們可以看到支持向量機取得了最好的性能,在本節和上一節中的性能優於RF,並且實現了大約0.957的平均AUC。
>LR 0.922 (0.036)
>SVM 0.957 (0.024)
>RF 0.951 (0.035)
我們繪製了箱線圖來對比不同算法AUC的分布。與其它兩種模型相比,支持向量機的分布更為緊湊。因此,它的性能可能是最穩定的,可以作為最終模型的一個良好候選。
代價敏感箱線圖
接下來,讓我們看看如何使用最終模型對新數據進行預測。
對新數據進行預測
在本節中,我們將擬合一個最終模型,並使用它對單行數據進行預測。
我們將使用代價敏感的支持向量機模型作為最終模型,在對模型進行擬合和預測之前對數據進行冪變換。使用pipeline將確保始終正確地對輸入數據執行轉換。
首先,我們可以將模型定義為pipeline。
...
# define model to evaluate
model = SVC(gamma='scale', class_weight='balanced')
# power transform then fit model
pipeline = Pipeline(steps=[('t',PowerTransformer()), ('m',model)])
定義之後,我們可以在整個訓練集上擬合模型。
...
# fit the model
pipeline.fit(X, y)
擬合完成後,我們可以調用*predict()*函數來對新數據進行預測。函數將返回0(意味著沒有癌症)或1(意味著癌症)。示例代碼如下:
...
# define a row of data
row = [...]
# make prediction
yhat = model.predict([row])
為了演示上述流程,我們使用擬合後的模型對我們已經知道癌症與否的部分數據進行預測。示例代碼如下:
# fit a model and make predictions for the on the mammography dataset
from pandas import read_csv
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import PowerTransformer
from sklearn.svm import SVC
from sklearn.pipeline import Pipeline
# load the dataset
def load_dataset(full_path):
# load the dataset as a numpy array
data = read_csv(full_path, header=None)
# retrieve numpy array
data = data.values
# split into input and output elements
X, y = data[:, :-1], data[:, -1]
# label encode the target variable to have the classes 0 and 1
y = LabelEncoder().fit_transform(y)
return X, y
# define the location of the dataset
full_path = 'mammography.csv'
# load the dataset
X, y = load_dataset(full_path)
# define model to evaluate
model = SVC(gamma='scale', class_weight='balanced')
# power transform then fit model
pipeline = Pipeline(steps=[('t',PowerTransformer()), ('m',model)])
# fit the model
pipeline.fit(X, y)
# evaluate on some no cancer cases (known class 0)
print('No Cancer:')
data = [[0.23001961,5.0725783,-0.27606055,0.83244412,-0.37786573,0.4803223],
[0.15549112,-0.16939038,0.67065219,-0.85955255,-0.37786573,-0.94572324],
[-0.78441482,-0.44365372,5.6747053,-0.85955255,-0.37786573,-0.94572324]]
for row in data:
# make prediction
yhat = pipeline.predict([row])
# get the label
label = yhat[0]
# summarize
print('>Predicted=%d (expected 0)' % (label))
# evaluate on some cancer (known class 1)
print('Cancer:')
data = [[2.0158239,0.15353258,-0.32114211,2.1923706,-0.37786573,0.96176503],
[2.3191888,0.72860087,-0.50146835,-0.85955255,-0.37786573,-0.94572324],
[0.19224721,-0.2003556,-0.230979,1.2003796,2.2620867,1.132403]]
for row in data:
# make prediction
yhat = pipeline.predict([row])
# get the label
label = yhat[0]
# summarize
print('>Predicted=%d (expected 1)' % (label))
運行該示例,首先會在整個培訓數據集上擬合模型。接下來,從數據集中選擇一些沒有癌症的數據進行預測,我們可以看到所有的情況都被正確地預測了;然後我們輸入一些癌症數據再對標籤進行預測,正如我們所希望的那樣,在這兩種情況下數據的標籤都得到了正確的預測。
No Cancer:
>Predicted=0 (expected 0)
>Predicted=0 (expected 0)
>Predicted=0 (expected 0)
Cancer:
>Predicted=1 (expected 1)
>Predicted=1 (expected 1)
>Predicted=1 (expected 1)
延伸閱讀
如果您想深入了解,本節將提供有關此主題的更多資源。
論文
Comparative Evaluation Of Pattern Recognition Techniques For Detection Of Microcalcifications In Mammography, 1993.SMOTE: Synthetic Minority Over-sampling Technique, 2002.API
sklearn.model_selection.RepeatedStratifiedKFold API.sklearn.metrics.roc_auc_score API.sklearn.dummy.DummyClassifier API.sklearn.svm.SVC API.數據集
Mammography Dataset.Mammography Dataset Description總結
在本教程中,您學習了如何開發和評估乳腺攝影數據集的不平衡分類模型。具體來說,您學到了:
如何加載和探索數據集,並從中獲得預處理數據與選擇模型的靈感。如何使用代價敏感算法評估一組機器學習模型並提高其性能。如何擬合最終模型並使用它預測特定情況下的類標籤。還有什麼問題嗎?歡迎在評論區提出你的問題,我會盡力回答,關注DeepHup,可以獲得更多的乾貨文章哦
文章代碼較多,粉絲請私信 20200307獲取pdf版本網盤下載地址