Python——隨機森林模型與ROC曲線


隨機森林模型,針對回歸問題的預測值,可以使用所有樹的平均值;而分類問題的預測值,可以使用所有決策樹的投票來決定。Python中,使用sklearn庫就可以完成隨機森林模型的使用。針對隨機森林模型對測試樣本可預測出一個預測概率,然后將這個預測值與一個分類閾值進行比較,如果大於閾值則分為正類,否則為反類。例如:針對每一個測試樣本預測出一個[0,1]之間的概率,然后將這個值與0.5比較,如果大於0.5則判斷為正類,反之為負類。閾值的好壞直接反映了學習算法的泛化能力。根據預測值的概率,可以使用受試者工作特征曲線(ROC)來分析機器學習算法的泛化性能。在ROC曲線中,縱軸是真正例率(True positive rate),橫軸是假正例率(False Positive rate)。ROC曲線與橫軸圍成的面積大小稱為學習器的AUC(Area Under ROC curve),該值越接近於1,說明算法模型越好。本文章將會使用兩種數據集介紹如何對隨機森林模型可視化ROC曲線,對模型效果進行分析。首先導入會使用到的庫或模塊。

## 輸出高清圖像 %config InlineBackend.figure_format = 'retina' %matplotlib inline ## 圖像顯示中文的問題 import matplotlib matplotlib.rcParams['axes.unicode_minus']=False import seaborn as sns sns.set(font= "Kaiti",style="ticks",font_scale=1.4) import pandas as pd pd.set_option("max_colwidth", 200) import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.preprocessing import LabelEncoder,label_binarize from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import * ## 忽略提醒 import warnings warnings.filterwarnings("ignore")

1 二分類數據的ROC曲線可視化

下面使用泰坦尼克號二分類數據集,介紹如何使用隨機森林算法建立分類模型。首先是數據准備程序:

## 讀取數據泰坦尼克號預處理后數據
train = pd.read_csv("data/Titanic處理后數據.csv")
# 將字符串類型的分類變量進行重新編碼
label = LabelEncoder()
train["Name"] = label.fit_transform(train["Name"])
train["Embarked"] = label.fit_transform(train["Embarked"])
train["Sex"] = label.fit_transform(train["Sex"])
# 定於預測目標變量名
Target = ["Survived"]
## 定義模型的自變量名
train_x = ["Pclass", "Name", "Sex", "Age", "SibSp", "Parch","Fare","Embarked"]
##將訓練集切分為訓練集和驗證集
X_train,X_val,y_train,y_val = train_test_split(train[train_x], train[Target],
                                               test_size = 0.25,random_state = 1)
print("X_train.shape :",X_train.shape)
print("X_val.shape :",X_val.shape)
print(X_train.head())
 
X_train.shape : (668, 8)
X_val.shape : (223, 8)
     Pclass  Name  Sex   Age  SibSp  Parch     Fare  Embarked
35        1     2    1  42.0      1      0  52.0000         2
46        3     2    1  28.0      1      0  15.5000         1
453       1     2    1  49.0      1      0  89.1042         0
291       1     3    0  19.0      1      0  91.0792         0
748       1     2    1  19.0      1      0  53.1000         2

下面的程序中使用RandomForestClassifier()函數建立了包含100個決策樹,最大深度為5的隨機森林模型,針對訓練好的模型並計算出其它訓練集和驗證集上的預測精度。運行程序后可發現在訓練集上的預測集精度為0.86,在驗證集上的預測精度是0.79。

## 使用隨機森林對泰坦尼克數據進行分類
rfc1 = RandomForestClassifier(n_estimators = 100, # 樹的數量
                              max_depth= 5,       # 子樹最大深度
                              oob_score=True,
                              class_weight = "balanced",
                              random_state=1)
rfc1.fit(X_train,y_train)
## 輸出其在訓練數據和驗證數據集上的預測精度
rfc1_lab = rfc1.predict(X_train)
rfc1_pre = rfc1.predict(X_val)
print("隨機森林的OOB score:",rfc1.oob_score_)
print("訓練數據集上的精度:",accuracy_score(y_train,rfc1_lab))
print("驗證數據集上的精度:",accuracy_score(y_val,rfc1_pre))
 
隨機森林的OOB score: 0.8263473053892215
訓練數據集上的精度: 0.8607784431137725
驗證數據集上的精度: 0.7982062780269058

使用訓練數據集訓練得到隨機森林模型后,針對測試集的ROC曲線可以使用下面的程序進行可視化,運行程序后可得到圖1。通過圖1可以發現,隨機森林分類器在驗證集上的預測情況,並且AUC的取值為0.8614。

## 可視化在驗證集上的Roc曲線
pre_y = rfc1.predict_proba(X_val)[:, 1]
fpr_Nb, tpr_Nb, _ = roc_curve(y_val, pre_y)
aucval = auc(fpr_Nb, tpr_Nb)    # 計算auc的取值
plt.figure(figsize=(10,8))
plt.plot([0, 1], [0, 1], 'k--')
plt.plot(fpr_Nb, tpr_Nb,"r",linewidth = 3)
plt.grid()
plt.xlabel("假正率")
plt.ylabel("真正率")
plt.xlim(0, 1)
plt.ylim(0, 1)
plt.title("隨機森林ROC曲線")
plt.text(0.15,0.9,"AUC = "+str(round(aucval,4)))
plt.show()

圖1 二分類數據的ROC曲線

2 多分類數據的ROC曲線可視化

針對多類數據的ROC曲線的可視化方式有兩種:

第一種為:采用將原始數據的真實類別標簽矩陣和模型預測得到的概率矩陣分別按行展開,轉置后形成兩列,這就可以近似的看作獲得了一個二分類的結果,進而可以可視化ROC曲線。

第二種方式為:將每類一類數據和其他類別的數據看作為一個二分類類的數據模型,然后對數據可視化ROC曲線。為了方便計算每一類樣本的ROC曲線的相關取值,可以將類別標簽使用label_binarize進行編碼。

下面使用一個多分類的數據集,然后使用隨機森林模型對其建立分類器,然后針對預測的結果使用ROC曲線進行分析。先導入數據並建立模型,程序如下所示:

## 數據准備
bbcdata  = np.load("data/bbc_tfidf.npz")
train_tfidf = bbcdata['arr_0']
test_tfidf = bbcdata['arr_1']
y_train = bbcdata['arr_2']
y_test = bbcdata['arr_3']
print(train_tfidf.shape)
print(y_train.shape)
print(test_tfidf.shape)
print(y_test.shape)
## 為方便后面可視化ROC曲線,對標簽使用label_binarize進行編碼
y_test_lb = label_binarize(y_test,classes=[0,1,2,3,4])
 
(1557, 1000)
(1557,)
(668, 1000)
(668,)
 
## 使用隨機森林對數據進行分類
rfc1 = RandomForestClassifier(n_estimators = 100, # 樹的數量
                              max_depth= 5,       # 子樹最大深度
                              oob_score=True,
                              class_weight = "balanced",
                              random_state=1)
rfc1.fit(train_tfidf,y_train)
## 輸出其在訓練數據和測試數據集上的預測精度
rfc1_lab = rfc1.predict(train_tfidf)
rfc1_pre = rfc1.predict(test_tfidf)
print("隨機森林的OOB score:",rfc1.oob_score_)
print("訓練數據集上的精度:",accuracy_score(y_train,rfc1_lab))
print("測試數據集上的精度:",accuracy_score(y_test,rfc1_pre))

隨機森林的OOB score: 0.9004495825305073
訓練數據集上的精度: 0.9569685292228645
測試數據集上的精度: 0.937125748502994 

2.1 針對所有類別的數據可視化一條ROC曲線

針對所有類別的數據使用一條ROC曲線對模型結果進行可視化的程序如下,運行程序后可獲得如圖2所示的ROC曲線。

## 可視化算法的ROC曲線
plt.figure(figsize=(8,7))
## 對測試集進預測
pre_score = rfc1.predict_proba(test_tfidf)
## 計算繪制ROC曲線的取值
fpr_micro, tpr_micro, _ = roc_curve(y_test_lb.ravel(), pre_score.ravel())
AUC = auc(fpr_micro, tpr_micro)  # AUC大小
plt.plot([0, 1], [0, 1], 'k--')
plt.plot(fpr_micro, tpr_micro,"r",linewidth = 3)
plt.xlabel("假正率")
plt.ylabel("真正率")
plt.xlim(0, 1)
plt.ylim(0, 1)
plt.grid()
plt.title("隨機森林ROC曲線")
plt.text(0.2,0.8,"AUC = "+str(round(AUC,4)))
plt.show()

圖2 多分類模型使用一條ROC曲線可視化模型結果

2.2 針對每類數據均可視化一條ROC曲線

針對每個類別的預測效果,也可以使用下面的程序可視化每個類別的ROC曲線進行分析,運行下面的程序,可獲得如圖3所示的ROC曲線。

## 可視化每個類別的ROC曲線
lable_names = ["sport","business","politics","tech","entertainment"]
colors = ["r","b","g","m","k",]
linestyles =["-", "--", "-.", ":", "-"]
pre_score = rfc1.predict_proba(test_tfidf)
fig  = plt.figure(figsize=(8,7))
for ii, color in zip(range(pre_score.shape[1]), colors):
    ## 計算繪制ROC曲線的取值
    fpr_ii, tpr_ii, _ = roc_curve(y_test_lb[:,ii], pre_score[:,ii])
    plt.plot(fpr_ii, tpr_ii,color = color,linewidth = 2,
             linestyle = linestyles[ii],
             label = "class:"+lable_names[ii])
plt.plot([0, 1], [0, 1], 'k--')
plt.xlabel("假正率")
plt.ylabel("真正率")
plt.xlim(0, 1)
plt.ylim(0, 1)
plt.grid()
plt.legend()
plt.title("每個類別的ROC曲線")
## 添加局部放大圖
inset_ax = fig.add_axes([0.3, 0.45, 0.4, 0.4],facecolor="white")
for ii, color in zip(range(pre_score.shape[1]), colors):
    ## 計算繪制ROC曲線的取值
    fpr_ii, tpr_ii, _ = roc_curve(y_test_lb[:,ii], pre_score[:,ii])
    ## 局部放大圖
    inset_ax.plot(fpr_ii, tpr_ii,color = color,linewidth = 2,
                  linestyle = linestyles[ii])
    inset_ax.set_xlim([-0.01,0.1])
    inset_ax.set_ylim([0.88,1.01])
    inset_ax.grid()
plt.show()

圖3 多分類模型可視化每個類別的ROC曲線


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM