随机森林模型,针对回归问题的预测值,可以使用所有树的平均值;而分类问题的预测值,可以使用所有决策树的投票来决定。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")
下面使用泰坦尼克号二分类数据集,介绍如何使用随机森林算法建立分类模型。首先是数据准备程序:
## 读取数据泰坦尼克号预处理后数据 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曲线
针对多类数据的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
针对所有类别的数据使用一条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曲线可视化模型结果
针对每个类别的预测效果,也可以使用下面的程序可视化每个类别的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曲线